Webpack 解决什么问题
Webpack
是从入口文件开始,经过模块依赖加载、分析和打包 三个流程完成项目的构建。在加载、分析和打包的三个过程中,可以针对性的做一些解决方案,比如 code split
(拆分公共代码等)。 还可以轻松的解决传统构建工具解决的问题:
- 模块化打包,一切皆模块,
JS
是模块,CSS
等也是模块; - 语法糖转换:比如
ES6
转ES5
、TypeScript
; - 预处理器编译:比如
Less
、Sass
等; - 项目优化:比如压缩、
CDN
; - 解决方案封装:通过强大的
loader
和插件机制,可以完成解决方案的封装,比如PWA
; - 流程对接:比如测试流程、语法检测等。
externals 作用
externals
配置项用于去除输出的打包文件中依赖的某些第三方 js 模块(例如 jquery
, vue
等等),减小打包文件的体积。该功能通常在开发自定义 js 库(library)的时候用到,用于去除自定义 js 库依赖的其他第三方 js 模 块。这些被依赖的模块应该由使用者提供,而不应该包含在 js 库文件中。例如开发一个 jQuery
插件或者 Vue
扩 展,不需要把 jQuery
和 Vue
打包进我们的 bundle,引入库的方式应该交给使用者。
那使用者如何使用我们的库?
lib 导出方式 | output.libraryTarget | 使用者引入方式 | 使用者提供给被依赖模块的方式 |
---|---|---|---|
默认 | output.libraryTarget=‘var’ | 只能以 script 标签的形式引入我们的库 | 只能以全局变量的形式提供这些被依赖的模块 |
commonjs | output.libraryTarget=‘commonjs’ | 只能按照 commonjs 的规范引入我们的库 | 被依赖模块需要按照 commonjs 规范引入 |
amd | output.libraryTarget=‘amd’ | 只能按照 amd 规范引入 | 被依赖模块需要按照 amd 规范引入 |
umd | output.libraryTarget=‘umd’ | 可以用 script、commonjs、amd 引入 | 被依赖模块需要按照对应方式引入 |
devtool 配置项
devtool
是来控制怎么显示 sourcemap,通过 sourcemap 我们可以快速还原代码的错误位置。 一般在实际项目中,我个人推荐生产环境不使用或者使用 source-map(如果有 Sentry 这类错误跟踪系统),开发环境使用 cheap-module-eval-source-map 。 官方文档
[hash] 、[chunkhash] 和 [contenthash] 之间的区别
[hash] :是整个项目的 hash 值,其根据每次编译内容计算得到,每次编译之后都会生成新的 hash,即修改任 何文件都会导致所有文件的 hash 发生改变;在一个项目中虽然入口不同,但是 hash 是相同的;hash 无法实现 前端静态资源在浏览器上长缓存,这时候应该使用 chunkhash; [chunkhash] :根据不同的入口文件(entry)进行依赖文件解析,构建对应的 chunk,生成相应的 hash;只要组成 entry 的模块文件没有变化,则对应的 hash 也是不变的,所以一般项目优化时,会将公共库代码拆分到一 起,因为公共库代码变动较少的,使用 chunkhash 可以发挥最长缓存的作用; [contenthash] :使用 chunkhash 存在一个问题,当在一个 JS 文件中引入了 CSS 文件,编译后它们的 hash 是 相同的。而且,只要 JS 文件内容发生改变,与其关联的 CSS 文件 hash 也会改变,针对这种情况,可以把 CSS 从 JS 中使用 mini-css-extract-plugin 或 extract-text-webpack-plugin 抽离出来并使用 contenthash。