Appearance
模块化打包工具
模块打包工具的由来
- ES Modules存在兼容问题
- 模块文件过多,网络请求频繁
- 前端应用不仅仅JS的代码需要模块化,其他css等所有前端自由都需要模块化
所以,模块化是有必要的。我们还需要引用更好的工具,去解决上面的问题。
打包工具通用功能
这个工具需要:
- 开发阶段新特性编译代码
- 将散落的模块打包到一起
- 需要支持不同种类的资源类型
以webpack为例,其模块打包器(Module bundler),模块加载器(Loader),代码拆分(Code Splitting)进行模块的渐进式加载,资源模块(Asset Module)
这个打包工具解决的是前端整体的模块化,不单指javascript的模块化。
模块化打包工具
目前市面上比较火的模块打包工具有:
- webpack
- Vite
- Parcel
- Rollup
Webpack 新增
Vite 新增
Rollup
Parcel
打包工具选用规则
Rollup VS Webpack 选用规则
Rollup优缺点
Rollup | 内容 |
---|---|
优点 | - 输出结果更加扁平,执行效率更高 - 自动移除为引用代码 - 打包结果依然完全可读 |
缺点 | - 加载非ESM的第三方模块比较复杂,需要引用插件 - 模块最终都被打包到一个函数中,无法实现HMR - 浏览器环境中,代码拆分功能依赖AMD库 |
选用规则
webpack | Rollup |
---|---|
如果正在开发应用程序,会面临大量引入第三方模块的需求,也需要HMR这样的功能提升开发体验,应用大了之后必须面临分包 | 如果正在开发一个框架或者类库,Rollup的优点很有必要,缺点也可以忽略(例如开发类库的时候很少会依赖第三方开发的模块) 所以大多数知名框架/库(vue,react)都在使用Rollup作用模块打包器,并非是webpack |
开源社区中,大多数人希望二者并存,共同发展并且可以相互借鉴。
webpack、rollup、parcel 它们的优劣?
webpack | rollup | parcel | |
---|---|---|---|
配置 | - webpack需要配config文件,指明entry, output, plugin,transformations - webpack 没有对import/export所做的 node polyfills - 不支持相对路径,所以得使用 path.resolve/path.join | - rollup需要配config文件,指明entry, output, plugin,transformations - rollup 有对import/export所做的 node polyfills - rollup支持相对路径 | parcel则是完全开箱可用的,不用配置 |
入口文件 | webpack只支持js文件作为入口文件,如果要以其他格式的文件作为入口,比如html文件为入口,如要加第三方Plugin。 | rollup可以用html作为入口文件,但也需要plugin,比如rollup-plugin-html-entry。 | parcel可以用index.html作为入口文件,而且它会通过看index.html的script tag里包含的什么自己找到要打包生成哪些js文件。 |
transformations (transformations指的是把其他文件转化成js文件的过程,需要经过transformation才能够被打包。) | webpack使用Loaders来处理。 | rollup使用plugins来处理。 | parcel会自动去转换,当找到配置文件比如.babelrc, .postcssrc后就会自动转。 |
摇树优化 | 摇树优化是webpack的一大特性。需要: 1,用import/export语法 2,在package.json中加副作用的入口 3,加上支持去除死代码的缩小器(uglifyjsplugin) | rollup会统计引入的代码并排除掉那些没有被用到的。这使您可以在现有工具和模块的基础上构建,而无需添加额外的依赖项或膨胀项目的大小。 | parcel不支持摇树优化。 |
dev server | webpack用webpack-dev-server | rollup用rollup-plugin-serve和rollup-plugin-livereload共同作用 | parcel内置的有dev server |
热更新 | webpack的 wepack-dev-server支持hot模式 | rollup不支持hmr | parcel有内置的hmr |
代码分割 | webpack通过在entry中手动设置,使用CommonsChunkPlugin,和模块内的内联函数动态引入来做代码分割。 | rollup有实验性的代码分割特性。它是用es模块在浏览器中的模块加载机制本身来分割代码的。需要把experimentalCodeSplitting 和 experimentalDynamicImport 设为true。 | parcel支持0配置的代码分割。主要是通过动态improt。 |