Skip to content

San-ssr Webpack 插件,用于将 `.san` 编译为可在 Node.js 中执行的 JavaScript 文件。

Notifications You must be signed in to change notification settings

searchfe/san-ssr-plugin

Repository files navigation

san-ssr-plugin

San-ssr Webpack 插件,用于将 .san 编译为可在 Node.js 中执行的 JavaScript 文件。

需要配合 san-loader 一起使用。

Language npm package npm package npm package semantic-release

快速开始

import webpack from 'webpack';
import SanLoaderPlugin from 'san-loader/lib/plugin';
import SanSSRPlugin from 'san-ssr-plugin';

export default {
    plugins: [
        new SanSSRPlugin({
            output: {
                path: 'js',
            }
        }),
        new SanLoaderPlugin()
    ],
    resolve: {
        extensions: ['.san'],
    },
    module: {
        rules: [
            {
                test: /\.san$/,
                loader: 'san-loader',
            }
        ],
    }
};

测试

npm run test

自定义样式输出格式

san-ssr 本身不负责样式的处理。本插件通过封装 san-ssr 产物(render 函数)的形式处理样式产物:

css = namedModuleCss.reduce((acc, cur) => {
    if (cur.css) {
        acc += `\n${cur.css}`;
    }
    return acc;
}, css);

if (css) {
    code += 'const originSanSSRRenders = module.exports.sanSSRRenders;\n';
    code += 'Object.keys(originSanSSRRenders).forEach(renderName => {\n';
    code += '    originSanSSRRenders[renderName] = makeRender(originSanSSRRenders[renderName]);\n';
    code += '});\n';
    code += 'module.exports = Object.assign(sanSSRResolver.getRenderer({id: "default"}), exports);\n';
    code += 'function makeRender(originRender) {\n';
    code += '    return function (data, ...params) {\n';
    code += '        if (global.__COMPONENT_CONTEXT__) {\n';
    code += `            global.__COMPONENT_CONTEXT__[${styleId}] = ${JSON.stringify(css)};\n`;
    code += '        }\n';
    if (Object.keys(locals).length > 0) {
        code += '        data[\'$style\'] = {\n';
        code += `            ${Object.keys(locals).map(item =>
            `${JSON.stringify(item)}: ${JSON.stringify(locals[item])}`
        ).join(',')}\n`;
        code += '        };\n';
    }
    namedModuleCss.forEach(({name, locals}) => {
        if (locals) {
            if (Object.keys(locals).length > 0) {
                code += `        data[\'$${name}\'] = {\n`;
                code += `            ${Object.keys(locals).map(item =>
                    `${JSON.stringify(item)}: ${JSON.stringify(locals[item])}`
                ).join(',')}\n`;
                code += '        };\n';
            }
        }
    });
    code += '        return originRender(data, ...params);\n';
    code += '    };\n';
    code += '}\n';
}

这段代码会添加在产物的最后,作为输出。

如果该内容不能满足要求,使用者可通过 appendRenderFunction 选项自行设置该内容:

plugins: [
    new SanSsrPlugin({
        appendRenderFunction(
            styleId: string,
            css: string = '',
            locals: Record<string, string>,
            namedModuleCss: Array<{
                name: string;
                css?: string;
                locals?: Record<string, string>;
            }> = []
        ) {
            return ``;
        }
    })
]

参数的具体内容可参考上方默认的输出。

Webpack V5

  1. html-loader 2 以上版本,与 san-loader 的 compileTemplate: 'aPack' 配合使用时,需要将 html-loader 的 sources 选项设置为 false,同时 HTML 中的静态资源无法再自动处理。需要等待 san-loader 适配。

  2. html-loader 与 css-loader 目前默认会输出 esModule 格式的内容,san-loader 与 san-ssr-plugin 都不支持这种写法,需要手动设置 esModule: false:

    {
        loader: 'css-loader',
        options: {
            esModule: false,
        },
    },
    {
        loader: 'html-loader',
        options: {
            esModule: false,
        }
    },

About

San-ssr Webpack 插件,用于将 `.san` 编译为可在 Node.js 中执行的 JavaScript 文件。

Resources

Stars

Watchers

Forks

Packages

No packages published