Webpack

webpack打包原理

把所有依赖打包成一个 bundle.js 文件,通过代码分割成单元片段按需加载

webpack的优势

  1. webpack 是以 commonJS 的形式来书写脚本的,但对 AMD/CMD 的支持也很全面,方便旧项目进行代码迁移。

  2. 插件机制完善,扩展性强,比如打包、压缩混淆、图片转base64等功能。

  3. 能被模块化的不仅仅是 JS 了

什么是loader,什么是plugin

loader用于加载某些资源文件
因为webpack本身只能打包common.js规范的js文件,对于其他资源(如css,img等),是没有办法加载的,这时就需要对应的loader将资源转化,再加载。

plugin用于扩展webpack的功能
plugin的功能更加丰富,比如压缩打包,优化,不只局限于资源的加载。

bundle, chunk, module分别是什么

bundle: 是由webpack打包出来的文件

chunk: 是指webpack在进行模块依赖分析的时候,代码分割出来的代码块

module: 是开发中的单个模块

webpack 和 gulp 的区别?

webpack:

webpack是一个模块打包工具,更侧重模块打包,我们可以把开发中的所有资源都看成是模块,通过loader和plugin进行资源处理。

gulp:

gulp是一个前端自动化构建工具,可以通过配置一系列的task,定义这些task执行顺序,来让glup执行这些task,从而构建项目的开发流程。
自动化构建工具并不能把所有的模块打包到一起,也不能构建不同模块之间的依赖关系。

webpack 的构建流程是什么

  1. 初始化参数:解析webpack配置参数,合并shell传入和webpack.config.js文件配置的参数,形成最后的配置结果
  1. 开始编译:上一步得到的参数初始化compiler对象注册所有配置的插件,插件监听webpack构建生命周期的事件节点,做出相应的反应,执行对象的run方法开始执行编译;
  1. 确定入口:从配置的entry入口开始解析文件构建AST语法树,找出依赖递归下去
  1. 编译模块:递归中根据文件类型和loader配置,调用所有配置的loader对文件进行转换再找出该模块依赖的模块,再递归本步骤,直到所有入口依赖的文件都经过了本步骤的处理;
  1. 完成模块编译并输出:递归完成后,得到每个文件结果包含每个模块以及他们之间的依赖关系,根据entry或分包配置生成代码块chunk;
  1. 输出完成:输出所有的chunk到文件系统;

webpack 的热更新

模块热更新是webpack的一个功能,它可以使得代码修改之后,不用刷新浏览器就可以更新。
无需重新加载整个页面,而是刷新某个模块。
webpack-dev-server可以支持热更新,通过生成 文件的hash值来比对需要更新的模块,浏览器再进行热替换

如何⽤webpack来优化前端性能?

  1. 压缩代码:
    删除多余的代码、注释、简化代码的写法等⽅式。
    可以利⽤webpack的 UglifyJsPlugin 来压缩JS⽂件。
  2. 利⽤CDN加速:
    将引⽤的静态资源路径修改为CDN上对应的路径。
  3. Tree Shaking:
    将代码中永远不会⾛到的⽚段删除掉。
    可以通过追加参数 –optimize-minimize 来实现。
  4. Code Splitting:
    将代码按组件分块(chunk),这样做到按需加载。
  5. 提取公共第三⽅库:

SplitChunksPlugin插件来抽取公共模块,利⽤浏览器缓存可以⻓期缓存这些⽆需频繁变动的公共代码。

常⻅的 Loader

Loader作用:
1、实现对不同格式的文件的处理,比如说将scss转换为css,或者typescript转化为js

2、转换这些文件,从而使其能够被添加到依赖图中

babel-loader: 将js文件转换成现代浏览器能够支持的JS文件。把 ES6 转换成 ES5

css-loader,style-loader:,用来解析css文件,能够解释@import,url()

image-loader:加载并且压缩图⽚⽂件

ts-loader: ts转js

常见的 Plugin

UglifyJsPlugin: 压缩代码

OccurenceOrderPlugin: 为组件分配ID,通过这个插件webpack可以分析和优先考虑使用最多 的模块,然后为他们分配最小的ID

html-webpack-plugin可以根据模板自动生成html代码,并自动引用css和js文件

webpack loader 的机制

webpack loader是什么

webpack 本身只能处理 JavaScript 和 JSON 文件,而 loader 为 webpack 添加了处理其他类型文件的能力。
loader 将其他类型的文件转换成有效的 webpack modules。webpack 可以将其添加到依赖关系图中。
loader 本质上是一个函数,该函数对接收到的内容进行转换,返回转换后的结果。

loader的使用方式
  1. 在 webpack.config.js 文件中配置
    通过在 module.rules 中使用 test 匹配要转换的文件类型,使用 use 指定要使用的 loader。
1
2
3
4
5
6
7

module.exports = {
module: {
rules: [{ test: /\.ts$/, use: "ts-loader" }],
},
};

  1. 内联使用
    import Styles from "style-loader!css-loader?modules!./styles.css";
编写loader
  1. 同步 loader
    同步转换内容后,可以通过 return 返回结果。
    通过 this.callback() 可以返回除内容以外的其他信息(eg sourcemap)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

export default function loader(content, map, meta) {
this.callback(null, someSyncOperation(content), map, meta);
return; // 当调用 callback() 时,始终返回 undefined
}
```



2. 异步 loader
通过 this.async 可以获取异步操作的回调函数,并在回调函数中返回结果。


```js
export default function (content, map, meta) {
const callback = this.async();
someAsyncOperation(content, (err, result, sourceMaps, meta) => {
if (err) return callback(err);
callback(null, result, sourceMaps, meta);
});
}
webpack loader 工作机制
  • 一、 根据 module.rules 解析 loader 加载规则
    根据具体的配置情况,loader 会有不同的类型,可以影响 loader 的执行顺序。
    这些不同类型的 loader 的执行顺序是:pre -> normal -> inline -> post
1
2
3
4
5
6
7
8
9
10

rules: [
// pre 前置 loader
{ enforce: "pre", test: /\.js$/, loader: "eslint-loader" },
// normal loader
{ test: /\.js$/, loader: "babel-loader" },
// post 后置 loader
{ enforce: "post", test: /\.js$/, loader: "eslint-loader" },
];

webpack rules 中配置的 loader 可以是多个链式串联的。
在正常流程中,链式 loader 会按照从后往前的顺序执行。

查看评论