webpack使用手册

《webpack实战-入门、进阶和调优》读后总结

webpack打包原理

(function(modules) {
  // 模块缓存
  var installedModules = {};
  // 实现require
  function __webpack_require__(moduleId) {
    ...
  }
  // 执行入口模块的加载
  return __webpack_require__(__webpack_require__.s = 0);
})({
  // modules: 以key-value的形式储存所有被打包的模块
  0: function(module, exports, __webpack_require__) {
    // 打包入口
    module.exports = __webpack_require__("3qiv")
  },
  "3qiv": function(module, exports, __webpack_require__) {
    // index.js 内容
  }
})
  • 最外层立即执行匿名函数。包裹bundle,构成自身作用域
  • installedModules 对象。每个模块只在第一次被加载的时候执行,导出值存储到这个对象里面,当再次被加载的时候就从中取值,不会重新执行。
  • __webpack_require__函数。对模块加载的实现。
  • modules 对象。工程中所有产生了依赖关系的模块都会以key-value形式放在这里。
  • bundle运行时,先加载入口模块,再依次执行模块代码,解析模块依赖。

entry

webpack通过context和entry两个配置项共同决定入口文件路径。
enrty的配置支持字符串、数组、对象、函数形式。

  • 数组类型入口:将多个资源预先合并,数组的最后一个元素是实际的入口路径。
  • 对象类型入口:key是chunk name,value是入口路径。
  • 函数类型入口:支持返回Promise对象来进行异步操作

此处可以应用优化 optimization.splitChunks,提取公共模块。可以利用客户端缓存,加快页面渲染速度。

output

  1. filename
    输出资源文件名,支持相对路径,支持模板语法动态生成文件名。
变量名称 描述
[name] 指代chunk name
[hash] 指代webpack此次打包所有资源生成的hash
[chunkhash] 指代当前chunk内容的hash
[id] 指代当前chunk的id
[query] 指代filename配置项中的query
  1. path
    指定资源输出的位置,必须为绝对路径。
  2. publicPath
    指代资源的请求位置,请求url相对路径的前缀。

loader

webpack一切皆模块,loader帮助webpack识别js、json之外的文件,从而维护模块之间的关系。
output = loader(input)

loader 配置

  • 引入loader
module.exports = {
  // ...
  module: {
    rules: [{
      test: /\.css$/,
      use: ['css-loader'],
    }]
  }
}

test 接受正则表达式/正则表达式数组,只有匹配的模块才使用该规则;
use 接受一个数组,将从后向前的调用数组中定义的loader。

  • exclude/include
    exclude优先级高于include

此处配置exclude: /node_modules/可以提高不必要的loader执行,提高编译效率

  • enforce
    接受pre post 两种字符串类型值,强制指定loader的执行顺序

自定义loader

  • 启用缓存:使用this.cacheable控制
  • 获取options:引入const loaderUtils = require("loader-utils");,通过loaderUtils.getOptions(this)获取配置对象

代码分片

代码分片和公共模块提取

通过入口划分代码,适合于接口绑定在全局对象上的库,和多页面应用。

SplitChunksPlugin

将多个chunk中公共的部分提取出来

资源异步加载

模块数量过多,资源体积过大时,可以吧一些暂时使用不到的模块延迟加载。
原理:import().then() require.ensure
配置:使用特有注释对chunk命名

import(/* webpackChunkName: "bar" */ './bar.js').then(({add}) => {
  // ...
})

生产环境配置

开启production模式、环境变量配置

module.exports = {
  mode: 'production',
  plugins: [
    new webpack.DefinePlugin({
      ENV: 'production'
    })
  ]
}

source map

source map指的是将编译、打包、压缩后的代码映射回源代码的过程。帮助追查线上问题。
devtool: 'source-map'

安全问题
source map会暴露源码,但是没有map文件无法调试代码,解决方案如下:
hidden-source-map: 编译产出完整map文件,但是不会引用。利用第三方工具(Sentry),手动上传map文件;
nisources-source-map:隐藏文件具体内容,但是可以查看错误栈和日志的准确行数;
nginx对白名单开放.map文件访问权限。

资源压缩

配置项: config.optimization.minimize,开启了mode: production 后不需要人为设置。
自定义压缩插件 terser-webpack-plugin

module.exports = {
  optimization: {
    // 覆盖默认的 minimizer
    minimizer: [
      new TerserPlugin({
        test: /\.js(\?.*)?$/i,    // 作用范围
        exclude: /\/exculdes/,
        cache: true,    // 是否开启缓存,传入字符串可以指定缓存目录
        parallel: 2,  //  允许多进程压缩
        sourceMap: true    // 生成 source map,需要同事配置 devtool
      })
    ]
  }
}

缓存

output.filename: 'bundle@[chunkhash].js'
通常使用chunkhash作为文件版本号,使用 html-webpack-plugin 输出动态HTML,自动更新最新的资源名到html中。

打包优化

缩小打包作用域

动态链接库和 DllPlugin

DllPlugin和Code Splitting有点类似,都可以用来提取公共模块。Code Splitting思路是设置一些特定的规则并在打包过程中根据这些规则提取模块,Dlllpugin则是将vendor完全拆出,独立打包,实际工程构建是就不用对它再做处理,直接取用。

tree shaking

开发环境调优

webpack开发效率插件

模块热替换 HMR

你可能感兴趣的:(webpack使用手册)