webpack总结

112 阅读4分钟

1.常见的loader:

  • css-loader:解析css。
  • style-loader:将css样式插入到dom中。
  • less-loader:将less解析成css。
  • postcss-loader:它会根据根目录配置的browserslist的规则查询浏览器市场占有率来决定是否要做兼容,根据postcss-preset-env来给css样式添加前缀实现兼容。
  • file-loader:解析一些资源,例如图片、音频、字体。
  • url-loader:与file-loader类似。它可以设置超过limit大小,小于limit的资源会转位base64。base64会减少http请求缓解服务器压力,但是滥用会导致打包后的文件体积过大。
  • ts-loader:用来解析ts文件,会检验ts类型。但不能使用polyfill功能。
  • babel-loader:解析js文件,结合@babel/preset-env预设可以将代码转位es5。结合@babel/preset-typescript"预设可以解析ts文件,但需要结合tsc来检查类型。可以设置targer字段来实现目标兼容的浏览器,否则会根据browserslist的规则去实现兼容。
  • vue-loader:解析vue文件。

2.常见的plugin

  • clean-webpack-plugin:每次打包前都会将之前的的打包文件删除。
  • html-webpack-plugin:根据html模板生成到打包文件中的html。
  • copy-webpack-plugin:将某个文件夹下的资源复制到打包后的目录下,这些资源不会被打包压缩。
  • webpack.DefinePlugin:用来定义全局变量。
  • min-css-extract-plugin:将css单独打包成一个文件。
  • terser-webpack-plugin:丑化js,压缩js。
  • css-minimizer-webpack-plugin:对css进行压缩。
  • progress-bar-webpack-plugin:打包时显示进度

3.webpack打包流程

  • 初始化阶段。

webpack会根据传入的配置通过createCompiler创建一个compiler并返回,在创建compiler过程中会遍历用户的plugins调用插件的apply注册。调用 new WebpackOptionsApply().process 方法,加载各种内置插件。比如会注入 EntryOptionPlugin 插件,处理 entry 配置。

创建完compiler后就会调用compiler.run方法。run方法中会调用compile方法。compile方法中执行了beforeCompile、compile、make、finishMake、afterCompile钩子,并会创建compilation。在make阶段会执行entryOptionPlugin的EntryPlugin中注册的make函数。他会根据entry配置找到入口文件最终通过handleModuleCreate根据文件类型创建module子类,然后通过子类module.build开始构建。

  • 构建阶段。

build过程中会执行runLoaders转译 module 内容,会将各类资源类型转译为 JavaScript 文本,通过 acorn将js解析为ast,对于模块中的依赖会递归调用 runLoaders,直到所有依赖全部解析完毕,构建阶段结束。

  • 生成阶段

构建完成后通过compilation.seal会将所有的module转换为chunk,通过hooks.optimizeChunkModules优化压缩chunk,通过createChunkAssets创建资源。然后通过compilation.emitAssets将资源保存到compilation.assets中。最后通过fs.mkdir输出资源。

4.webpack热更新(HMR)原理

5.Babel原理 将源代码经过词法分析转换为token数组(每一个词都是数组中的对象,对象存放类型、值),再经过语法分析转换为AST,遍历AST访问每个节点通过插件对es6进行转换然后得到新的AST,最后生成es5代码。

6.vue-loader原理:

  1. webpack配置中在plugin中使用 new VueLoaderPlugin()会创建一个pitcher-loader。用户的rules中剔除vue-loader的rule,然后经过cloneRule 处理,再将用户定义的原始rules拼接成[pitcher, ...clonedRules, ...rules] 。

  2. webpack运行时,如果命中 /.vue$/i ,则会通过vue-loader去解析。通过parse解析器解析源文件得到描述符,分别处理template、script、style三个模块得到对应的import,加上type、lang参数。

  3. 这些import会命中pitcher-laoder,经过pitcher-loader处理后会根据用户提供的rules将每一模块的import组装成内联loader的方式。

  4. 通过内联调用loader就会重新来到vue-loader,通过selectBlock 处理不同type后传递给下一个loader做处理。template经过vue-loader后会再经过tempalte-laoder最终解析生成render函数生成vnode。script经过vue-loader会再经过babel-laoder。style模块经过vue-loader后会再经过css-loader、style-loader。

7.如何使用chunk:

  • 多入口方式,对于output.filename通过占位符区分不同的chunk。
  • 设置SplitChunks,通过里面的属性设置chunk的大小以及分包的条件。
  • 通过动态倒入import()方式也会实现分包。

8.treeShaking: 去除无用的代码

9.hash,chunkHash,contentHash的区别

  • hash:和整个项目有关,项目文件内容发生改变,hash值就会改变。
  • chunkHash:和Webpack打包的chunk有关,不同的入口会生成不同的chunkhash,当一个入口文件内容不改变时chunkhash不会改变。
  • contentHash:根据文件内容来定义hash,文件内容不变,则contenthash不变。适用情况,当一个文件在另一个文件中被导入,自身内容没有发生变化,导入他的文件发生改变了,如果使用chunckhash,这个文件名也会改变,如果使用contenthash则不会。