Skip to main content

常用的plugin

Plugin 介绍

前面我们学习的 loader 的作用是用于 特定的模块类型解析,而对于 plugin,可以用于执行更加广泛的任务贯穿 webpack 打包的生命周期,比如打包优化、资源管理、环境变量注入等。

使用 plugin 的方式也十分简单,大部分的 plugin 都是一个类,当你安装完要使用的 plugin 后,需要将其导入 webpack.config.js,然后将其实例添加到 plugins 数组中。

CleanWebpackPlugin

该 plugin 的作用是,在 webpack 打包前清空 output 目录。

首先安装该 plugin。

$ npm i clean-webpack-plugin -D

然后在 webpack.config.js 中进行如下配置。

const { CleanWebpackPlugin } = require("clean-webpack-plugin");

module.exports = {
// 省略...

plugins: [new CleanWebpackPlugin()],
};
important

在 webpack5 之后,在 output 字段中设置 clean 属性为 true 也可以实现同样效果。

output: {
filename: "bundle.js",
path: path.resolve(__dirname, "build"),
clean: true,
},

DefinePlugin

该 plugin 的作用是,定义一个全局变量,webpack 打包过程中会将全局变量注入到项目中,这样我们可以在项目的任何地方都能直接访问到该全局变量。

该 plugin 内置到了 webpack 中,我们可以直接通过 webpack 引入它,不用再进行额外下载。

const { DefinePlugin } = require("webpack");

module.exports = {
// 省略...

plugins: [
new DefinePlugin({
GLOBAL_VAR: "'Hello MoMo'",
}),
],
};

这样就定义好了一个 GLOBAL_VAR 的全局变量。

我们可以在项目任何地方去使用它,比如我们在 index.js 入口文件中打印它。

index.js
console.log(GLOBAL_VAR);

项目在经过 webpack 打包后,这里的 GLOBAL_VAR 会被直接替换为 'Hello MoMo'

该插件比较常用的一个使用场景就是,对于开发环境和生产环境,可能需要调用不同服务器上的 API,此时我们就可以定义一个 SERVICE_URL 全局变量,在不同的环境下仅需要在 webpack 配置文件中替换 SERVICE_URL 的值即可,不需要在实际代码中去修改。

CopyWebpackPlugin

该 plugin 的作用是,将项目中指定目录下的所有文件拷贝到打包后的目标目录中。

首先安装该 plugin。

$ npm i copy-webpack-plugin -D

然后在 webpack.config.js 中进行如下配置。

const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = {
// ... 省略

plugins: [
new CopyWebpackPlugin({
patterns: [{
from: 'public',
globOptions: {
ignore: [ // 忽略拷贝文件
'**/index.html',
'**/.DS_Store'
]
}
}]
})
]
}

webpack 在打包过程中,会将 public 目录下的所有文件拷贝到 output 的根目录,其中会忽略 public 下的 index.html.DS_Store 文件。

更多配置参考 文档

HtmlWebpackPlugin

该 plugin 的作用是,在打包的目录中生成一个 html 文件,并且会自动生成 script 标签引入 webpack 打包后的出口文件。

首先安装该 plugin。

$ npm i html-webpack-plugin -D

然后在 webpack.config.js 中进行如下配置。

const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
// ... 省略

plugins: [new HtmlWebpackPlugin()],
};

这样 webpack 在打包后就会生成一个 index.htmloutput 的根目录。

另外,我们也可以给该 plugin 传递一些参数,来定制生成的 html 文件的格式,比如文件名、title ...

其中最常用的几个配置项目如下:

  • title 用于配置 html 网页的标题
  • template 用于指定一个 html 模版,打包生成的 index.html 会基于该模版填入一些变量

更多配置项,详见 文档

首先我们在项目根目录中新建一个如下目录。

public
├── favicon.ico
└── index.html

其中 index.html 就是模版,它的内容如下。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />

<link rel="icon" href="<%= BASE_URL %>favicon.ico" />

<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong
>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work
properly without JavaScript enabled. Please enable it to
continue.</strong
>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

请注意模版中的 <% 变量 %> 这种语法,该插件在使用模版生成 index.html 过程中,会先从 DefinePlugin 定义的全局变量中寻找变量,然后再到自身实例的 options 属性去找相关变量,最后将变量赋值,生成 index.html

因此,对于该模版,我们还需要使用 DefinePlugin 来定义一个 BASE_URL 全局变量。

另外我们还需要一个图标文件,所以还需要借助 copy-webpack-plugin 将 public 目录下的 favicon.svg 拷贝到 output 根目录下。

完整的配置如下。

const { DefinePlugin } = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");

module.exports = {
// ... 省略

plugins: [
new DefinePlugin({
BASE_URL: "./",
}),
new HtmlWebpackPlugin({
title: "auro app",
template: "./public/index.html"
}),
new CopyWebpackPlugin({
patterns: [{
from: 'public',
globOptions: {
ignore: [ // 忽略拷贝文件
'**/index.html',
'**/.DS_Store'
]
}
}]
})
],
};

MiniCSSExtractPlugin

在前面我们通过 webpack 打包样式时,是使用 style-loader 将样式内容直接通过 style 标签插入到页面中的。更多时候我们希望能在打包后生产单独的样式文件,此时需要使用该插件上的 loader 即 MiniCSSExtractPlugin.loader 来替换 style-loader

首先安装插件。

$ npm i mini-css-extract-plugin -D

然后在 webpack.config.js 中添加如下配置。

const MiniCSSExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
// 省略...

module: {
rules: [
{
test: /\.css$/,
use: [
MiniCSSExtractPlugin.loader,
{
loader: "css-loader",
options: {
importLoaders: 1,
},
},
"postcss-loader",
],
}
],
},
plugins: [
new MiniCSSExtractPlugin(),
],
};

这样在 webpack 打包样式时,就会将样式抽离出来打包为单独的文件,并且在 HtmlWebpackPlugin 生成的 index.html 中会通过 link 自动引入这个样式文件。

更多配置详见 文档