Webpack第三弹之Plugin

450 阅读2分钟

这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战

第一弹在这里:Weboack总结第一弹

第二弹在这里:Weboack总结第二弹

Plugin介绍

顾名思义,plugin是插件的意思,它是一种遵循Webpack应用程序接口规范编写的程序,在webpack规定的系统下运行。plugin赋予其各种灵活的功能,例如打包优化、资源管理、环境变量注入等,它们会在webpack不同阶段(钩子函数、生命周期)中运行,贯穿了webpack的整个编译周期。

img

插件目的在于解决 loader无法实现的其他事。Webpack 提供很多开箱即用的插件

用法

由于插件可以携带参数/选项,你必须在 webpack 配置中,向 plugins 属性传入一个 new 实例。

取决于你的 webpack 用法,对应有多种使用插件的方式。

webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装
const webpack = require('webpack'); // 访问内置的插件
const path = require('path');

module.exports = {
  entry: './path/to/my/entry/file.js',
  output: {
    filename: 'my-first-webpack.bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        use: 'babel-loader',
      },
    ],
  },
  plugins: [
    new webpack.ProgressPlugin(),
    new HtmlWebpackPlugin({ template: './src/index.html' }),
  ],
};

常用插件

NameDescription
BabelMinifyWebpackPlugin使用 babel-minify进行压缩
BannerPlugin在每个生成的 chunk 顶部添加 banner
CommonsChunkPlugin提取 chunks 之间共享的通用模块
CompressionWebpackPlugin预先准备的资源压缩版本,使用 Content-Encoding 提供访问服务
ContextReplacementPlugin重写 require 表达式的推断上下文
CopyWebpackPlugin将单个文件或整个目录复制到构建目录
DefinePlugin允许在编译时(compile time)配置的全局常量
DllPlugin为了极大减少构建时间,进行分离打包
EnvironmentPluginDefinePluginprocess.env 键的简写方式。
ExtractTextWebpackPlugin从 bundle 中提取文本(CSS)到单独的文件
HotModuleReplacementPlugin启用模块热替换(Enable Hot Module Replacement - HMR)
HtmlWebpackPlugin简单创建 HTML 文件,用于服务器访问
I18nWebpackPlugin为 bundle 增加国际化支持
IgnorePlugin从 bundle 中排除某些模块
LimitChunkCountPlugin设置 chunk 的最小/最大限制,以微调和控制 chunk
LoaderOptionsPlugin用于从 webpack 1 迁移到 webpack 2
MinChunkSizePlugin确保 chunk 大小超过指定限制
MiniCssExtractPlugin为每个引入 CSS 的 JS 文件创建一个 CSS 文件
NoEmitOnErrorsPlugin在输出阶段时,遇到编译错误跳过
NormalModuleReplacementPlugin替换与正则表达式匹配的资源
NpmInstallWebpackPlugin在开发环境下自动安装缺少的依赖
ProgressPlugin报告编译进度
ProvidePlugin不必通过 import/require 使用模块
SourceMapDevToolPlugin对 source map 进行更细粒度的控制
EvalSourceMapDevToolPlugin对 eval source map 进行更细粒度的控制
UglifyjsWebpackPlugin可以控制项目中 UglifyJS 的版本
TerserPlugin允许控制项目中 Terser 的版本
ZopfliWebpackPlugin通过 node-zopfli 将资源预先压缩的版本

HtmlWebpackPlugin

在打包结束后,⾃动生成⼀个 html ⽂文件,并把打包生成的js 模块引⼊到该 html

npm install --save-dev html-webpack-plugin
// webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
 ...
  plugins: [
     new HtmlWebpackPlugin({
       title: "My App",
       filename: "app.html",
       template: "./src/html/index.html"
     }) 
  ]
};
<!--./src/html/index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title><%=htmlWebpackPlugin.options.title%></title>
</head>
<body>
    <h1>html-webpack-plugin</h1>
</body>
</html>

html 模板中,可以通过 <%=htmlWebpackPlugin.options.XXX%> 的方式获取配置的值

更多的配置可以自寻查找

clean-webpack-plugin

删除(清理)构建目录

npm install --save-dev clean-webpack-plugin
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
module.exports = {
 ...
  plugins: [
    ...,
    new CleanWebpackPlugin(),
    ...
  ]
}

mini-css-extract-plugin

提取 CSS 到一个单独的文件中

npm install --save-dev mini-css-extract-plugin
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
 ...,
  module: {
   rules: [
    {
     test: /\.s[ac]ss$/,
     use: [
      {
       loader: MiniCssExtractPlugin.loader
     },
          'css-loader',
          'sass-loader'
        ]
   }
   ]
 },
  plugins: [
    ...,
    new MiniCssExtractPlugin({
     filename: '[name].css'
    }),
    ...
  ]
}

DefinePlugin

允许在编译时创建配置的全局对象,是一个webpack内置的插件,不需要安装

const { DefinePlugun } = require('webpack')

module.exports = {
 ...
    plugins:[
        new DefinePlugin({
            BASE_URL:'"./"'
        })
    ]
}

这时候编译template模块的时候,就能通过下述形式获取全局对象

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

copy-webpack-plugin

复制文件或目录到执行区域,如vue的打包过程中,如果我们将一些文件放到public的目录下,那么这个目录会被复制到dist文件夹中

npm install copy-webpack-plugin -D

1

new CopyWebpackPlugin({
    parrerns:[
        {
            from:"public",
            globOptions:{
                ignore:[
                    '**/index.html'
                ]
            }
        }
    ]
})

复制的规则在patterns属性中设置:

  • from:设置从哪一个源中开始复制
  • to:复制到的位置,可以省略,会默认复制到打包的目录下
  • globOptions:设置一些额外的选项,其中可以编写需要忽略的文件