entry

output

filename: 输出文件的名称,为string类型。
path: 文件被写入硬盘的位置, 必须是string类型的绝对路径一般是通过path模块获取绝对路径拼接。
publicPath:dist文件夹中index.html引入js或css,图片等静态资源的起始路径,是相对路径。
image.png
这就是publicPath,他不会影响打包的存储路径而是会修改html中引用资源的起始路径
chunkFilename:chunkFilename是未被列在entry中的,但是又需要被打包出来的文件的命名配置,例如异步加载模块的时候

  1. {
  2. name: "About",
  3. path: "/about",
  4. component: () => import(
  5. /* webpackChunkName: "about" */
  6. "../view/About.vue"
  7. )
  8. }

此时about就会走chunkFilename

module

loader

1. 条件匹配: 通过配置test,include,exclude三个配置项来选中loader需要应用规则的文件。include的值可以是绝对地址字符串或是字符串数组
2. 应用规则: 对选中的文件通过use配置项来应用loader,可以只应用一个loader或者按照从右往左的顺序应用一组loader(切记:loader使用顺序是从右往左的),也可以向loader传入参数。

noParse

该配置项可以让webpack忽略对部分未采用模块化文件的递归解析和处理,该忽略的文件不能包含import,require, define等模块化语句。
那么这样做的好处是可以提高构建性能,比如像一些库jquery等就没有必要去使用webpack去递归解析和处理了。
使用配置代码如下:

  1. module.exports = {
  2. module: {
  3. noParse: /jquery|xxjs/
  4. }
  5. }
  6. /** or */
  7. module.exports = {
  8. module: {
  9. noParse: (content) => {
  10. // content代表一个模块的文件路径
  11. return /jquery|xxjs/.test(content);
  12. }
  13. }
  14. }

resolve

alias

通过别名来将原导入路径映射成一个新的导入路径。比如如下配置:

  1. {
  2. resolve: {
  3. alias: {
  4. '@': path.resolve(__dirname, '../src')
  5. }
  6. }
  7. }

extensions

在使用 import 导入文件时,有时候没有带入文件的后缀名,webpack会自动带上后缀去访问文件是否存在,那么默认的后缀名为[‘.js’, ‘.json’]

externals

通过externals 可以告诉webpack在javascript运行环境中已经内置了哪些全局变量,不用将这些代码打包到代码里面去。功能与HtmlWebpackExternalsPlugin插件相似。

  1. externals: {
  2. jquery: 'jQuery',
  3. vue: 'Vue'
  4. }

plugin

mode

  • development: 开发模式,打包后代码不会被压缩
  • production:生产模式, 打包后代码会进行压缩

    devtool

    Source Map

  • eval:使用eval包裹模块代码

  • source map:产生.map文件
    • 定位信息最全,但也.map文件最大,效率最低
  • cheap:不包含列信息也不包含loader的sourcemap
    • 错误信息只会定义到行,而不会定义到列,精度降低换去文件内容的缩小
    • 对于经由babel之类工具转义的代码,只能定位到转换后的代码
  • inline:将.map作为DataURL嵌入,不单独生成.map文件
    • 减少了文件数但增大了mian.js的大小
  • module:包含loader的sourceMap(比如jsx to js, babel的sourcemap),否则无法定义源文件
    • 会保留loader处理前后的文件信息映射
    • 解决对于使用cheap配置项导致无法定位到loader处理前的源代码问题

开发环境 最佳: eval-cheap-module-source-map

  • 本地开发首次打包慢点没关系,因为 eval 缓存的原因,rebuild 会很快
  • 开发中,我们每行代码不会写的太长,只需要定位到行就行,所以加上 cheap
  • 我们希望能够找到源代码的错误,而不是打包后的,所以需要加上 modele

    生产环境 最佳: none

  • 就是不想别人看到我的源代码

分离公共包
在react项目中对于react已经react-dom可以通过cdn的方式引入,使用html-webpack-externals-plugin配置需要忽略的库文件
externals 一可嘶带no嘶

devServer

port

该配置属性指定了开启服务器的端口号

host

该配置项用于配置 DevServer的服务器监听地址。比如想让局域网的其他设备访问自己的本地服务,则可以在启动DevServer时带上 —host 0.0.0.0 或是当前的局域网地址(如10.181.37.56)。host的默认值是 127.0.0.1

headers

该配置项可以在HTTP响应中注入一些HTTP响应头。

hot

该配置项是指模块替换换功能,DevServer 默认行为是在发现源代码被更新后通过自动刷新整个页面来做到实时预览的,
但是开启模块热替换功能后,它是通过在不刷新整个页面的情况下通过使用新模块替换旧模块来做到实时预览的。

open

该属性用于DevServer启动且第一次构建完成时,自动使用我们的系统默认浏览器去打开网页。

compress

该属性是一个布尔型的值,默认为false,当他为true的时候,它会对所有服务器资源采用gzip进行压缩。

  1. module.exports = {
  2. devServer: {
  3. headers: {
  4. 'X-chen': 4999
  5. },
  6. hot: true,
  7. compress: true,
  8. port: '8081',
  9. open: true,
  10. host: '10.181.37.15',
  11. proxy: {
  12. '/api': {
  13. target: 'http://news.baidu.com', // 目标接口的域名
  14. // secure: true, // https 的时候 使用该参数
  15. changeOrigin: true, // 是否跨域
  16. pathRewrite: {
  17. '^/api' : '' // 重写路径
  18. }
  19. }
  20. }
  21. }
  22. }

optimization

splitChunks

chunks
  • all : 把动态和非动态模块同时进行优化打包,所有模块都扔到vendors.bundle.js里面
  • async: 把动态模块打包进vender,非动态模块保持原样(不优化)

    cacheGroups(缓存组)

    cacheGroups的作用是将chunks按照cacheGroups中给定的条件分组输出

    test

    正则匹配,[\/] 来表示路径分隔符的原因,是为了适配window与Linux系统。可通过(antd|@ant-design)匹配多个文件夹,达到将特定几个文件放入一个chunk中

    priority

    优先级,默认组的优先级为负,自定义组的默认值为0
    1. optimization: {
    2. splitChunks: {
    3. chunks: 'async', // 仅提取按需载入的module
    4. minSize: 30000, // 提取出的新chunk在两次压缩(打包压缩和服务器压缩)之前要大于30kb
    5. maxSize: 0, // 提取出的新chunk在两次压缩之前要小于多少kb,默认为0,即不做限制
    6. minChunks: 1, // 被提取的chunk最少需要被多少chunks共同引入
    7. maxAsyncRequests: 5, // 最大按需载入chunks提取数
    8. maxInitialRequests: 3, // 最大初始同步chunks提取数
    9. automaticNameDelimiter: '~', // 默认的命名规则(使用~进行连接)
    10. name: true,
    11. cacheGroups: { // 缓存组配置,默认有vendors和default
    12. vendors: {
    13. test: /[\\/]node_modules[\\/]/,
    14. priority: -10
    15. },
    16. default: {
    17. minChunks: 2,
    18. priority: -20,
    19. reuseExistingChunk: true
    20. }
    21. }
    22. }
    23. }

什么是loader

Loader可以理解为是模块和资源的转换器,它本身也是一个函数,接收源文件作为参数,返回转换的结果。

webpack-dev-server

webpack-dev-server是一个使用了express的Http服务器,它的作用主要是为了监听资源文件的改变,该http服务器和client使用了websocket通信协议,只要资源文件发生改变,webpack-dev-server就会实时的进行编译。

Tree-Shaking

1 个模块可能有多个⽅法,只要其中的某个⽅法使⽤到了,则整个⽂件都会被打到
bundle ⾥⾯去,tree shaking 就是只把⽤到的⽅法打⼊ bundle ,没⽤到的⽅法会在
uglify 阶段被擦除掉。

scope hoisting

将所有模块的代码按照引⽤顺序放在⼀个函数作⽤域⾥,然后适当的重命名⼀
些变量以防⽌变量名冲突 通过 scope hoisting 可以减少函数声明代码和内存开销
image.png
mode为production时会默认开始tree-shaking和scope hoisting

懒加载

方式

CommonJS: require.ensure
ES6: 动态import

加快构建速度

多进程构建

实际上在小型项目中,开启多进程打包反而会增加时间成本,因为启动进程和进程间通信都会有一定开销。
可以通过 thread-loader 开启多进程打包,在webpack5中已经弃用 happypack 进行多进程打包了

利用缓存

一些性能开销比较大的 loader 的处理结果可以进行缓存可以有效提高重复构建时的速度
对于babel-loader可以使用配置项 cacheDirectory 设为true 开启编译内容缓存
其他没有自带缓存配置的loader可以使用cache-loader来完成缓存

hard-source-webpack-plugin

在webpack5之前可以使用 hard-source-webpack-plugin 为模块提供了中间缓存,重复构建时间大约可以减少 80%,但是在 webpack5 中已经内置了模块缓存,不需要再使用此插件

dll

在webpack5之前可以配置webpack.dll.config.js使用DllPlugin将不常更新的类库如vue.js, react.,react-dom这些进行提前打包生成打包后的dll.js文件跟manifest.json, 通过manifest.json读取打包前文件后打包后文件的对应关系, 再在webpack.dev.js中使用DllReferencePlugin将manifest.json引入,使用AddAssetHtmlPlugin将提前打包的库文件引到html中, 不过在 webpack5中已经不建议使用这种方式进行模块缓存,因为其已经内置了更好体验的 cache 方法

cache 持久化缓存

缓存生成的 webpack 模块和 chunk,来改善构建速度。cache 会在开发模式被设置成memory并且在 生产模式 中设为false。

文件指纹(hash)

Hash:和整个项目的构建相关,只要项目文件有修改,整个项目构建的 hash 值就会更改
chunkhash:和 webpack 打包的 chunk 有关,不同的 entry 会生成不同的 chunkhash 值
contenthash:根据文件内容来定义 hash ,文件内容不变,则 contenthash 不变

  • JS文件指纹用 chunkhash
  • css文件指纹用contenthash
  • 媒体文件(图片音频)用hash