rollup的manualChunks手动配置DEMO

8,664 阅读2分钟

直接上代码,主要利用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()
  ]
}

截屏2021-12-23 下午10.36.06.png

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;

以上是文件引用关系,如下我们简谈处理模块文件引用关系,怎么拆分包:

  1. 定义每个模块文件,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
};
  1. 从入口配置文件出发,分析文件的引用关系,然后匹配output中的配置(这里直接指manualChunks),重新构建引用关系。(这其中就是按规则构建新文件,更新引用)。

关于打包其他的部分,比如去重,转换(babel),压缩(这里还可以了解Huffman编码)就不在这里介绍了。

DEMO地址

参照:

  1. rollupjs.org/guide/en/#o…
  2. rollupjs.org/guide/en/#b…