乐趣区

关于javascript:基于rolluptypescriptgulpless搭建react-前端组件库-三

这一节咱们将组件的大包配置,也就是使 gulp 同时工作的第三个 compileTypescript:

exports.default = gulp.series(
    removeDist,
    gulp.parallel(compileLess, styleScriptTask, compileTypescript),
);

这一步 gulp 的工作就是找到所有须要参加 rollup 编译的文件打包输入,当然一些测试脚本还有款式脚本须要排除在外:

// 编译 ts
function compileTypescript(cb) {
    const source = [
        'src/**/*.tsx',
        'src/**/*.ts',
        'src/**/*.d.ts',
        '!src/**/__test__/**',
        '!src/**/style/*.ts',
    ];

    const tsFiles = globArray(source);

    buildScript(
        tsFiles,
        {
            es: esDir,
            cjs: cjsDir,
        },
        cb,
    )
        .then(() => {cb();
        })
        .catch(err => {console.log('---> build err', err);
        });
    // 单文件输入
    buildBrowser('src/index.ts', umdDir, cb);
    cb();}

globArray 是本人找了一个匹配函数,须要匹配到指标文件并且返回文件目录列表:

const source = [
        'src/**/*.tsx', // 源码目录构造下的 tsx 文件都参加 rollup 打包
        'src/**/*.ts', // 源码目录构造下的 ts 文件都参加 rollup 打包
        'src/**/*.d.ts', 源码目录构造下的 ts 类型申明文件都参加 rollup 打包
        '!src/**/__test__/**', // 测试目录不参加
        '!src/**/style/*.ts', // 款式脚本独自解决的不参加
    ];

接下来看这个函数 buildScript 及 buildBrowser,次要是打包函数:


/**
 *@desc: 获取 rollup 输出打包配置
 *@Date: 2021-02-18 10:43:08
 *@param {Object} inputOptionOverride 笼罩 input 配置
 *@param {Array} additionalPlugins 新增的插件
 *@param {object} tsConfig
 *@return {void}
 */
function getRollUpInputOption(inputOptionOverride = {},
    tsConfig = {},
    additionalPlugins = [],) {const external = ['react', 'react-dom'];
    const babelOptions = {exclude: ['**/node_modules/**'],
        babelHelpers: 'bundled',
        presets: [
            // "stage-3",
            '@babel/preset-env',
            '@babel/preset-react',
            '@babel/preset-flow',
        ],
        extensions: ['tsx', 'ts', 'js', 'jsx'],
        plugins: [
            '@babel/transform-react-jsx',
            // ['@babel/plugin-transform-runtime', { useESModules: true}],
            [
                '@babel/plugin-proposal-class-properties',
                {loose: true,},
            ],
            [
                '@babel/plugin-proposal-decorators',
                {legacy: true,},
            ],
        ],
    };
    const onAnalysis = ({bundleSize}) => {console.log(`Bundle size bytes: ${bundleSize} bytes`);
        return;
    };
    const inputOptions = {
        external,
        plugins: [common(),
            nodeResolve({extensions: ['.js', '.jsx', '.ts', '.tsx', '.less'],
            }),
            alias({
                entries: [
                    {
                        find: '@',
                        replacement: path.resolve('./src'),
                    },
                    {
                        find: '~@',
                        replacement: path.resolve('./src'),
                    },
                ],
            }),
            replace({stylePre: JSON.stringify('ti'),
                'process.env.NODE_ENV': JSON.stringify('production'),
            }),
            less({
                option: {
                    globalVars: {
                        'theme-color': '#136BDE',
                        hack: `true; @import "${varsPath}"`,
                    },
                },
                output: false,
            }),
            typescript({
                tsconfigDefaults: {include: ['./src/**/*.ts', './src/**/*.tsx'],
                    compilerOptions: {lib: ['es5', 'es6', 'dom'],
                        // exclude: ['./src/**/style/*.ts'],
                        target: 'ES6',
                        // typeRoots: ["./types"],
                        moduleResolution: 'node',
                        module: 'ES6',
                        jsx: 'react',
                        allowSyntheticDefaultImports: true,
                        ...tsConfig,
                    },
                },
            }),
            babel(babelOptions),

            jsx({
                factory: 'React.createElement',
                extensions: ['js', 'jsx', 'tsx'],
            }),
            analyze({onAnalysis, skipFormatted: true, stdout: true}),
            ...additionalPlugins,
        ],
        ...inputOptionOverride,
    };
    return inputOptions;
}
// 组件 es cjs 标准编译输入
exports.buildScript = async function(inputPaths, outputConf) {
    // 输入格局
    const outputOptions = [
        {
            // file: outputPath,
            format: 'cjs',
            dir: outputConf.cjs,
            preserveModulesRoot: 'src',
            preserveModules: true,
            exports: 'named',
            hoistTransitiveImports: false, // 不导入其余模块代码
        },
        {
            // file: outputPath,
            format: 'esm',
            dir: outputConf.es,
            preserveModulesRoot: 'src',
            preserveModules: true,
            exports: 'named',
            hoistTransitiveImports: false, // 不导入其余模块代码
        },
    ];
    for (const outputOption of outputOptions) {
        const bundle = await rollup.rollup(
            getRollUpInputOption(
                {
                    input: inputPaths,
                    treeshake: true,
                },
                {declaration: true,},
            ),
        );
        await bundle.generate(outputOption);
        await bundle.write(outputOption);
        await bundle.close();}
};

// 打包成一个文件
exports.buildBrowser = async function(entryPath, outputDir, cb) {
    const outputOption = {
        file: outputDir + '/index.js',
        format: 'umd',
        // dir: outputDir, preserveModulesRoot: 'src', preserveModules: true,
        name: 'ti', // 浏览器应用时候须要裸露的库的名字
        exports: 'named',
        globals: {
            react: 'React', // 单个 打包须要裸露的全局变量
            'react-dom': 'ReactDOM',
        },
    };
    const bundle = await rollup.rollup(
        getRollUpInputOption(
            {
                input: entryPath,
                treeshake: true,
            },
            {},
            [uglify()],
        ),
    );
    await bundle.generate(outputOption);
    await bundle.write(outputOption);
    await bundle.close();
    cb();};

buildScript 是输入 es 和 cjs 标准的解决,buildBrowser 是 umd 标准的解决。组件打包都开启了树摇

退出移动版