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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,817评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,329评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,354评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,498评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,600评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,829评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,979评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,722评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,189评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,519评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,654评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,329评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,940评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,762评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,993评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,382评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,543评论 2 349

推荐阅读更多精彩内容

  • 作者:小 boy (沪江前端开发工程师)本文原创,转载请注明作者及出处。原文地址:https://www.smas...
    iKcamp阅读 2,747评论 0 18
  • webpack 是什么? 本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(mo...
    IT老马阅读 3,308评论 2 27
  • 目录 开始使用 管理依赖 管理资源样式图片字体数据 管理输出内容注入清理目录文件清单 代码分离多个入口提取模板动态...
    一点金光阅读 868评论 0 1
  • 前端将大型项目分成一个个单独的模块,一般封装好的每个模块都会实现一个目的明确的完成的功能。如何处理这些模块以及模块...
    pixels阅读 3,419评论 1 14
  • 人和人的感情,有时候好像毛衣,织的时候一针一线,小心谨慎,拆的时候只要轻轻一拉,也许只是一句玩笑话,也许是无意间的...
    EQ11阅读 630评论 0 2