直接上代码,主要利用manualChunks属性来手动配置基础的业务打包配置,并从中窥视rollup打包的秘密。 rollup.config.js配置
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
export default {
input: {
"entry_main": 'src/main',
"entry_1": 'src/entry_1',
},
output: {
dir: 'dist',
// format: 'cjs',
// entryFileNames: 'main-app.js',
manualChunks(id, { getModuleInfo }) {
// 这里可以按路由拆分
if (id.includes('src/router_a')) {
return 'router_a';
}
if (id.includes('src/router_b')) {
return 'router_b';
}
// 打包依赖
if (id.includes('node_modules')) {
return 'vendor';
}
const reg = /(.*)\/src\/components\/(.*)/
if (reg.test(id)) {
const importersLen = getModuleInfo(id).importers.length;
// 被多处引用
if (importersLen > 1) {
return 'common';
}
}
}
},
plugins: [
nodeResolve(),
commonjs()
]
}
main.js
import fn_a from './router_a';
import fn_b from './router_b';
const main = () => {
console.log('main');
fn_a();
fn_b();
}
export default main
router_a.js
import fn_c from './components/c';
import dayjs from 'dayjs';
// deadcode,打包会被treeShaking去除
const deadCode = () => {
console.log('deadCode');
}
const Comp_A = () => {
console.log('a', dayjs().format('YYYY-MM-DD'))
fn_c();
}
export default Comp_A;
router_c.js
import fn_c from './components/c';
const Comp_B = () => {
console.log('b');
fn_c();
}
export default Comp_B;
entry_1.js
import fn_c from './components/c';
const fn = () => {
console.log('entry_1');
fn_c();
}
export default fn;
组件c.js
const fn_c = () => {
console.log('c');
}
export default fn_c;
以上是文件引用关系,如下我们简谈处理模块文件引用关系,怎么拆分包:
- 定义每个模块文件,id为文件的全路径, 从rollup中观察到rollup对模块的定义(rollupjs.org/guide/en/#t… )如下图
type ModuleInfo = {
id: string; // the id of the module, for convenience
code: string | null; // the source code of the module, `null` if external or not yet available
ast: ESTree.Program; // the parsed abstract syntax tree if available
isEntry: boolean; // is this a user- or plugin-defined entry point
isExternal: boolean; // for external modules that are referenced but not included in the graph
importedIds: string[]; // the module ids statically imported by this module
importers: string[]; // the ids of all modules that statically import this module
dynamicallyImportedIds: string[]; // the module ids imported by this module via dynamic import()
dynamicImporters: string[]; // the ids of all modules that import this module via dynamic import()
implicitlyLoadedAfterOneOf: string[]; // implicit relationships, declared via this.emitFile
implicitlyLoadedBefore: string[]; // implicit relationships, declared via this.emitFile
hasModuleSideEffects: boolean | 'no-treeshake'; // are imports of this module included if nothing is imported from it
meta: { [plugin: string]: any }; // custom module meta-data
syntheticNamedExports: boolean | string; // final value of synthetic named exports
};
- 从入口配置文件出发,分析文件的引用关系,然后匹配output中的配置(这里直接指manualChunks),重新构建引用关系。(这其中就是按规则构建新文件,更新引用)。
关于打包其他的部分,比如去重,转换(babel),压缩(这里还可以了解Huffman编码)就不在这里介绍了。
参照: