参考
- What are CJS, AMD, UMD, and ESM in Javascript?
- rollup 文档
- 如何阅读大型前端开源项目的源码
- 官方贡献指南
- Inside Fiber: in-depth overview of the new reconciliation algorithm in React
- The how and why on React’s usage of linked list in Fiber to walk the component’s tree
构建流程
以构建 umd 版本 react.development.js 为例:
React 源代码使用 rollup 进行构建。
yarn build react/index,react-dom/index --type=UMD
会运行 ./scripts/rollup/build.js 文件,调用异步方法 buildEverything(),该方法内部核心代码:
for (const [bundle, bundleType] of bundles) {
await createBundle(bundle, bundleType);
}
批量调用 createBundle 方法,输出不同的文件:
通过命令行传的参数判断是否应该跳过某些类型的构建,本次运行只会构建 react、react-dom 包的 umd 版本。
shouldBundleDependencies: 判断是否需要绑定依赖项,umd 版本需要绑定 pureExternalModules: 如果为 true 则表示没有导入任何内容的外部依赖项不会产生副作用,例如修改全局变量等。该参数用于 treeshake。
构建 rollupConfig 对象,该对象包含一个 plugins 插件,使用方法参考插件开发。其中使用到自定义插件 getPlugins->sizes 方法用于记录本次构建生成的文件大小和 gzip 后的大小,该插件定义如下:
// 调用 sizes 函数返回一个插件对象
sizes({
getSize: (size, gzip) => {
const currentSizes = Stats.currentBuildResults.bundleSizes;
const recordIndex = currentSizes.findIndex(
record =>
record.filename === filename && record.bundleType === bundleType
);
const index = recordIndex !== -1 ? recordIndex : currentSizes.length;
currentSizes[index] = {
filename,
bundleType,
packageName,
size,
gzip,
};
},
}),
// 插件定义
const gzip = require('gzip-size');
module.exports = function sizes(options) {
return {
name: 'scripts/rollup/plugins/sizes-plugin',
generateBundle(outputOptions, bundle, isWrite) {
Object.keys(bundle).forEach(id => {
const chunk = bundle[id];
if (chunk) {
const size = Buffer.byteLength(chunk.code);
const gzipSize = gzip.sync(chunk.code);
options.getSize(size, gzipSize);
}
});
},
};
};
其中 generateBundle 为 rollup 暴露出来的 Output Generation Hooks。回调 getSize 函数后,会改变 Stats.currentBuildResults 对象,用于最终输出构建前后文件大小的比较的结果。
使用 rollupConfig 调用 rollup.rollup() 函数,并将结果写入输出目录下
const result = await rollup.rollup(rollupConfig);
await result.write(rollupOutputOptions);
createBundle 方法执行完毕。
最终使用 Stats.printResults() 输出构建结果,使用 cli-table 输出表格样式的构建前后文件对比图示。并将构建文件信息写入到 build/bundle-sizes.json 文件。
本系列文件开源在 read-source-code