前言
这段时间因为找工作,出于未来发展以及工作使用的考虑。所以决定用心学习一下webpack的各种知识点。
PS:各种知识点比较松散,主要用于记录自己的学习过程。以及在以后的使用中,在知识点有所遗忘或出错时,用于回顾反思。
Webpack是什么
webpack是一个前端资源构建(翻译)工具,一个轻量化的、开箱即用的模块打包工具
- 前端资源构建(翻译)工具:而当前流行的比如
sass、less、typescript以及ES6的新语法,这些是浏览器所不能直接识别的资源文件。而当我们希望这些资源能够在浏览器中工作时,就必须经过处理(也就是翻译)。而webpack就是干这事儿的。 - 模块打包工具:就是web开发过程中的各种资源文件,webpack根据引用关系,构建一个依赖关系图,然后利用这个关系图将所有静态模块打包成一个或多个bundle输出。
为什么我们需要用到webpack
上述小节就已经说明了webpack被需要的两个原因:一是前端资源的需要和浏览器的不支持;二是打包的问题。
那么除了这两点,我个人在学习和开发中无法避免使用webpack的情况还有:
- 主流框架的脚手架
vue-cli和create-react-app都是使用的webpack - webpack的按需加载、代码压缩、资源压缩和热更新等功能是开发中极其便利的功能
- webpack社区庞大,简单来说就是总有一款适合你
Loader
用途
[webpack中文文档](loader | webpack 中文网 (webpackjs.com))
loader 用于对模块的源代码进行转换。loader 可以使你在
import或"加载"模块时预处理文件。因此,loader 类似于其他构建工具中“任务(task)”,并提供了处理前端构建步骤的强大方法。loader 可以将文件从不同的语言(如 TypeScript)转换为 JavaScript,或将内联图像转换为 data URL。loader 甚至允许你直接在 JavaScript 模块中importCSS文件!
通俗易懂一点解释就是:loader会将一些webpack不可识别的文件,转换成webpack可识别的文件
使用方式
在项目中最常见、也是官方最推荐使用的方式是配置。即在webpack.config.js文件中,以配置项的形式来使用。
举例:css扩展语言sass、less的配置
module.exports = {
mode: "development",
module: {
rules: [
// Less 配置
{
test: /\.less$/,
use: ["style-loader", "css-loader", "less-loader"],
},
// Sass 配置
{
test: /\.scss$/,
use: ["style-loader", "css-loader", "sass-loader"],
},
],
},
};
众所周知,less和sass都是webpack无法直接识别的文件,所以需要使用loader配置去编译一次;而其编译顺序则是按照从右到左,从下到上的顺序来执行的。
除此之外,官方还提供了两种使用方法。
- 内联:在每次
import时,指定loader
import Styles from 'style-loader!css-loader?modules!./styles.css';
- CLI:在shell命令中指定
webpack --module-bind jade-loader --module-bind 'css=style-loader!css-loader'
babel-loader
简介
babel简单来说就是做一个兼容性的操作,使ES6语法转换成ES6之前的语法,以便支持旧版本的浏览器。
PS:一些情况下,ES2015及其之后的ES标准统称为ES6
编译流程
我们已经知道babel就是把源代码转换的一个过程。
转换过程主要分三步:
parser把源码转换成AST(抽象语法树)。transformer遍历AST,调用各种transform插件对AST进行修改。这一步操作主要是为了将旧AST转换成符合目标源码的AST。generator把转换后的 AST 打印成目标源码。
核心库 @babel/core
@babel/core的作用是把js代码分析成AST ,方便各个插件分析语法进行相应的处理。 有些新语法在低版本js中是不存在的,如箭头函数,rest 参数,函数默认值等,这种语言层面的不兼容只能通过将代码转为AST,分析其语法后再转为低版本js。
CLI命令行工具 @babel/cli
@babel/cli是babel 提供的命令行工具,它主要是提供 babel 这个命令。
安装了@babel/cli后我们就可以使用babel命令来编译js文件了。将src目录下的js编译到lib目录下。
npm install --save-dev @babel/core @babel/cli
./node_modules/.bin/babel src --out-dir li
插件 plugins & 预设 presets
插件列表 · Babel 中文文档 (docschina.org)
使用插件
如果该插件存在于npm库中,你可以传入插件的名字,Babel会检查它是否安装在 node_modules 中。
{
"plugins": ["@babel/plugin-transform-runtime"]
}
除了上面这一种方式,还可以通过输入绝对/相对路径来配置插件
{
"plugins": ["./node_modules/XXXX/plugin"]
}
插件应用顺序:按照数组顺序,正向使用
插件设置
同一插件以下三种写法的最终应用效果相同(无任何配置情况下)
{ "plugins": ["pluginA"] }
{ "plugins": [["pluginA"]] }
{ "plugins": [["pluginA", {}]] }
如果需要配置选项
{
"plugins": [[
"plugins-name",
{
"配置项键名": "配置项选项",
}
]]
}
预设相关
预设的使用及配置与插件完全相同,除了一点:预设的应用顺序为反向应用,即从后往前依次应用。当同时配置了插件与预设时,插件会先一步使用。
创建预设
module.exports = function() {
return {
plugins: ["pluginA", "pluginB", "pluginC"],
};
};
需要给有选项的插件或预设进行配置时,其实也和上述一样
module.exports = () => (
{
presets: [require("@babel/preset-env")],
plugins: [
[require("@babel/plugin-proposal-class-properties"), { loose: true }],
require("@babel/plugin-proposal-object-rest-spread"),
],
}
);
常见的Loader
style-loader把css代码注入到JavaScript中,通过DOM操作去加载CSS。(简单来说,就是把css文件转换成style标签,嵌入HTML中)css-loader加载 CSS,⽀持模块化、压缩、⽂件导⼊等特性file-loader把⽂件输出到⼀个⽂件夹中,在代码中通过相对 URL 去引⽤输出的⽂件url-loader和 file-loader 类似,但是能在⽂件很⼩的情况下以base64的⽅式把⽂件内容注⼊到代码中去
// 图片处理
{
test: /\.(png|jpg|gif|jpeg|webp|svg)$/,
// webpack5用法 不需要再使用file-loader和url-loader,已经内置了
// asset/resource asset/source asset/inline asset 四种,个人喜欢用asset
type: "asset"
}
source-map-loader加载额外的 Source Map ⽂件,以⽅便断点调试less-loader将less转换成csssass-loader将sass转换成cssraw-loader用来处理txt文件,使其变成字符串的形式
插件 plugins
用途
插件是 webpack 的支柱功能。webpack 自身也是构建于,你在 webpack 配置中用到的相同的插件系统之上! 插件目的在于解决 loader 无法实现的其他事。
以上是webpack官网给出的介绍
Loader是用来解决前端资源的适配问题,而plugin是用来做一些方位更广的任务。从打包优化和压缩,一直到重新定义环境中的变量等。
使用方式
引入事先安装好的插件,然后在webpack.config.js中引入,并在配置项中实例化
webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装
module.exports = {
plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })],
};
常见的plugins
html-webpack-plugin可以根据模板自动生成html代码,并自动引用css和js文件extract-text-webpack-plugin将js文件中引用的样式单独抽离成css文件DefinePlugin编译时配置全局变量,这对开发模式和发布模式的构建允许不同的行为非常有用。HotModuleReplacementPlugin热更新mini-css-extract-plugin将CSS提取到单独的文件中,为每个包含CSS的JS文件创建一个CSS文件,并且支持 CSS和SourceMaps的按需加载(基于webpack5)optimize-css-assets-webpack-plugin不同组件中重复的css可以快速去重webpack-bundle-analyzer一个webpack的bundle文件分析工具,将bundle文件以可交互缩放的treemap的形式展示。compression-webpack-plugin生产环境可采用gzip压缩JS和CSSclean-wenpack-plugin清理每次打包下没有使用的文件speed-measure-webpack-plugin打包构建速度分析、查看编译速度