这一节咱们将组件的大包配置,也就是使 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 标准的解决。组件打包都开启了树摇