模块化打包工具

前端工程化模块化开发

# 模块打包工具的由来

  • ES Modules存在兼容问题
  • 模块文件过多,网络请求频繁
  • 前端应用不仅仅JS的代码需要模块化,其他css等所有前端自由都需要模块化

所以,模块化是有必要的。我们还需要引用更好的工具,去解决上面的问题。

# 打包工具通用功能

这个工具需要:

  1. 开发阶段新特性编译代码
  2. 将散落的模块打包到一起
  3. 需要支持不同种类的资源类型

以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。
更新时间: 2022-01-26 22:04