功能概览

  1. 代码转换 (各种loader)
  2. 文件优化、压缩 (terser
  3. 代码分割、首屏优化()
  4. 模块合并()
  5. 自动刷新(HMR)
  6. 代码校验
  7. 自动发布

    优点

  • 专注于模块化项目
  • 开箱即用

    缺点

  • 编译慢,loader str=>ast=>str

    概念

    entry 项目入口文件
    chunk 多个模块组成的块
    module 一个文件
    loader
    plugin

    流程

    从项目入口文件(entry)开始,递归解析依赖的module,每个module通过loader进行转换,转换后解析出module依赖的module,生成一个chunk,将chunk输出为文件

    优化

    优化构建速度

  • 让尽可能少的文件被loader处理

  • 明确第三方模块的入口文件,减少搜索(缩小文件搜索范围)
    • resolve.modules配置三方模块的查找路径
    • resolve.alias 通过别名映射到三方库线上使用的文件(压缩的去模块化的文件)react =》 dist/react.min.js
    • resolve.extensions配置后缀匹配 、频率出现高的后缀优先进行匹配
    • resolve.modules.noParse忽略某些没有模块化的文件的递归解析处理
  • 重复模块只编译一次(编译后的模块暴露在全局,下次编译直接通过变量获取)
  • 多进程减少文件读写、压缩与其他计算密集型操作时间 happypack?
  • 动态链接库 dllPlugin 与代码分割的关系?
  • sourceMap

    优化开发体验

  • HMR

    优化输出质量

  • CDN加速

    • 静态资源文件带上hash值,防止被缓存
    • 将不同类型的资源放到不同域名cdn服务上,防止资源并行加载被阻塞、入口html文件放到业务服务器上,防止被缓存
    • 资源域名预解析?
  • 压缩
    • css压缩(cssnano)#ffoooo =》red 10px 20px 10px 20px =》 10px 20px
    • js压缩(Terser)内嵌已定义但是只用到一次的变量 提取出现多次但是没有定义成变量去引用的静态值 删除console 是否保留注释
    • 尽量使用ES6代码,代码量小,const申明读取速度快,去掉babel-preset-env插件配置
  • sourceMap
  • Tree Shaking、按需加载
  • 异步加载chunk
  • 提取公共chunk

Cache-loader
HappyPack

DefinePlugin

CommonsChunkPlugin=>optimization.splitChunks

模块
webpack生成的代码是一个IIFE
模块会被结构化,勒石于
module={id:@id,load:bool,exports:{}}
模块数据会以字典的形式保存在文件中
{‘path1’:代码,’path2’:代码}
这里的path可以看作moduleid值,生产模式会经过算法简化

webpack对于不同模块的实现,是基于自己实现的__webpack_require____webpack_exports__ ,装换成类似于commonjs的形式。对于es6模块通过__webpack_require__.r方法添加标识符

异步加载模块原理
import().then()
import 会被编译为webpack_require.e
该方法会返回一个决议后的promise,promise的resolve, reject被封装在loadingEnded函数内,同时通过document.createElement script加载异步脚本,
这个函数在script脚本加载执行之后触发onLoad事件执行,这个时候脚本已经执行,会在全局挂载新加载的moudle,manifest?
promi决议之后webpack_require通过模块标识符执行module,获取exports值返回给业务代码
类似于jsonp

长效缓存
runtime 提取
optimization.runtimeChunk