webpack4.15.1 学习笔记(九) — 11个基础的插件使用

webpack4.15.1 学习笔记(九) — 11个基础的插件使用

 

 

 

处理 webpack 在编译过程中的某个特定任务的功能模块,plugins 选项用于以各种方式自定义 webpack 构建过程。其中webpack 附带了各种内置插件,可以通过 webpack.[plugin-name] 访问这些插件。

webpack 打包的整个过程,它并不直接操作文件,而是基于事件机制工作,会监听 webpack 打包过程中的某些节点,执行广泛的任务。

html-webpack-plugin

简化了html文件的创建,以便为webpack包提供服务。该插件将生成一个 HTML5 文件,所有的 bundle 会自动添加到 html 中。

具体插入方式是将样式link插入到head元素中,script插入到head或者body中。

npm install html-webpack-plugin --save-dev
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    // ...
    plugins: [
      new HtmlWebpackPlugin({
        title: 'HtmlWebpackPlugin 插件学习',
        minify: {  
           removeComments: true, // 移除HTML中的注释
           collapseWhitespace: true, // 删除空白符与换行符
           minifyCSS: true, // 压缩内联css
        },
        inject: "head",  // 表示script标签插入位置,true(默认值), body, head, false(不插入)
      })
    ],
};

多页应用打包:

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
  entry: {
    index: './src/index.js',
    login: './src/login.js',
  },
  output: {
    filename: '[name].bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
  plugins: [
    new HtmlWebpackPlugin({  
       filename: 'index.html',  // 多个HtmlWebpackPlugin, filename字段不可缺省,否则默认生成的都是 index.html。
    }),
    new HtmlWebpackPlugin({
       filename: 'login.html',  
    }),
  ],
}

但是会发现 index.html 和 login.html 同时引入了 index.bundle.js 和 login.bundle.js,而通常只希望 index.html 中只引入 index.bundle.jslogin.html 只引入 login.bundle.js
HtmlWebpackPlugin 提供了一个 chunks 的参数,可以接受一个数组,配置此参数仅会将数组中指定的 js 引入到 html 文件中

module.exports = {
  plugins: [
    new HtmlWebpackPlugin({
      filename: 'index.html', 
      chunks: ['index'],   // index.html 中仅引入了 index.js 文件
    }),
    new HtmlWebpackPlugin(
      filename: 'login.html', 
      chunks: ['login'],  // login.html 中仅引入了 login.js 文件
    }),
  ],
}

clean-webpack-plugin

在每次构建前清理 /dist 文件夹,用于生产环境,因为生产环境会生成许多bundle文件,不及时清理的话每次都生成新的,导致文件夹比较大,打包前清理上一次生成的 bundle 文件是比较推荐的做法,因此只会生成用到的文件。

npm install clean-webpack-plugin --save-dev
const CleanWebpackPlugin = require('clean-webpack-plugin');

module.exports = {
    // ...
    plugins: [
         new CleanWebpackPlugin({
            // cleanStaleWebpackAssets 清除过时的网页包资产
            cleanStaleWebpackAssets: false   // 防止监听到改变时把没有改变的文件给清除了(当文件改变后不删除index.html文件)
        })
    ],
};

webpack-manifest-plugin

能够对「模块映射到输出 bundle 的过程」保持追踪。可以将数据提取到一个 json 文件中;说白了就是生成一个manifest.json 默认文件名, 是一个文件清单, 内容是打包前文件对应打包后的文件名。

npm install webpack-manifest-plugin --save-dev
const { WebpackManifestPlugin } = require('webpack-manifest-plugin');

module.exports = {
    // ...
    plugins: [
        new WebpackManifestPlugin() // 可以接受一个options 参数,默认在dist目录下生成 manifest.json
    ]
};

HotModuleReplacementPlugin(内置)

允许在运行时更新各种模块,而无需进行完全刷新。不适用于生产环境,意味着应当只在开发环境使用。启用HMR实际上就是更新 webpack-dev-server的配置,及使用 webpack 内置的 HMR 插件。

const webpack = require('webpack');
module.exports = {
    plugins: [
         new webpack.HotModuleReplacementPlugin(),
    ],
    devServer: {
        hot: true
    },
};
webpack要完全启用HMR需要使用webpack.HotModuleReplacementPlugin。如果webpack或webpack-dev-server 通过命令行添加 --hot 选项启动,该插件会自动添加,因此不需要将它添加到webpack.config.js中

但是经实际使用 webpack-dev-server 时发现,在webpack.config.js中仅仅配置了devServer.hot:true,并未添加上述插件时仍然实现了HMR
原来 webpack-dev-server 内部自动帮我们完成了这个事情。通过在Github 的 webpack-dev-server 搜索,找到以下源码:

if (options.hot || options.hotOnly) {
  config.plugins = config.plugins || [];
   // 判断了配置的插件中是否包含名为HotModuleReplacementPlugin的插件,如果没有则添加。
  if (
    !config.plugins.find(
      // Check for the name rather than the constructor reference in case
      // there are multiple copies of webpack installed
      (plugin) => plugin.constructor.name === 'HotModuleReplacementPlugin'
    )
  ) {
    config.plugins.push(new webpack.HotModuleReplacementPlugin());
  }
}

mini-css-extract-plugin

抽离css样式到统一的文件中。因为目前学习的版本是webpack4,所以不能直接下载最新版本,需要指定较低的插件版本,否则打包时会报错

npm instasll  mini-css-extract-plugin@1.6 -D

可以编写两个css文件,并在入口文件中引入,例如 index.js 中引入 require('index.css'),index.css 中引入 @import './style.css'

// index.js
console.log('index')
require('./index.css')


// index.css
@import './style.css';
.hello {
    color: blueviolet;
 }

// style.css 
body{
    background-color: pink;
}

配置文件中,配置css代码抽离目录,及loader配置,在规则中替换原来的style-loader,实际上 style-loader是将css样式插入到html中,该插件是创建一个link标签,将内容添加至link标签中。最后执行打包指令,就可以在出口目录中得到抽离后的css文件。

const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // webpack4 对应版本1.6
module.exports = {
    // ...
    plugins: [
         new MiniCssExtractPlugin({
             filename:'main.css'
         }),
    ],
     module: {
        rules: [
            {
                test: /\.css$/,
                use: [MiniCssExtractPlugin.loader, 'css-loader']
            },
            {
                test: /\.less$/,
                use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader'] 
            },
        ]
    }
};

autoprefixer

自动给浏览器添加前缀,需要配合一个 postcss-loader 去使用(webpack4中使用需要执行版本), 在css-loader之前使用(放在css-loader之后,因为loader 的执行顺序是从右往左),此时在执行打包指令时,会报一个错,提示缺失postcss config文件,创建一个postcss.config.js文件

 npm install postcss-loader@4.0 autoprefixer -D
// postcss.config.js
module.exports = {
    plugins: [require('autoprefixer')] // 给css添加浏览器前缀
}
// webpack.config.js
module.exports = {
    // ...
     module: {
        rules: [
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader', 'postcss-loader']
            },
        ]
    }
};

执行打包指令后,发现生成的样式并未能自动添加浏览器前缀,此时还需要修改package.json有关浏览器的配置,之后在执行打包执行,即可发现已经添加前缀

// package.json 
"browserslist": [
    "defaults",
    "not ie < 11",
    "last 2 versions",
    "> 1%",
    "iOS 7",
    "last 3 iOS versions"
]

optimize-css-assets-webpack-plugin

该插件用于压缩抽离的css文件。但是使用该插件以后将不能直接将打包后的 js 代码进行压缩,需要安装另一个插件完成js代码的压缩。下文介绍

npm install optimize-css-assets-webpack-plugin -D
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // webpack4 对应版本1.6
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin'); // webpack4 对应版本6.0
module.exports = {
    // ...
    optimization: {
        minimizer: [
            new OptimizeCssAssetsWebpackPlugin(), // 用了这个插件以后,会导致js代码无法压缩,需要使用UglifyJsPlugin插件,压缩js代码
        ]
    },
    plugins: [
         new MiniCssExtractPlugin({
             filename:'css/main.css'
         }),
    ],
     module: {
        rules: [
            {
                test: /\.css$/,
                use: [MiniCssExtractPlugin.loader, 'css-loader']
            },
        ]
    }
};

uglifyjs-webpack-plugin

用了optimize-css-assets-webpack-plugin插件压缩css后,会导致js代码无法压缩,需要使用UglifyJsPlugin插件,压缩js代码

npm install uglifyjs-webpack-plugin -D
const UglifyJsPlugin = require("uglifyjs-webpack-plugin")  // webpack4 对应版本2.2
module.exports = {
    // ...
    optimization: {
        minimizer: [
            new UglifyJsPlugin({ // 压缩js代码
                cache: true, // 缓存
                parallel: true, // 并发打包
                sourceMap: true // 源码映射
            })
        ]
    },
};

copy-webpack-plugin

用于拷贝文件的插件,官网显示的用法有很多,版本不同,用法参数各有不同,此处使用为webpack4,插件版本为5.x

npm install copy-webpack-plugin@5 -D
const CopyWebpackPlugin = require("copy-webpack-plugin")  // webpack4 对应版本5.1
module.exports = {
    // ...
    plugins: [
        new CopyWebpackPlugin([
            { from: './doc', to: './' }   // 将开发相关文档,拷贝至打包文件目录
        ])
    ],
};

ProvidePlugin(内置)

提供插件 — 可以用来向每个模块注入变量,但不能通过通过window.$来访问,并未暴露给全局,仅在每个模块中使用

npm install jquery
const webpack = require('webpack');
module: {
    // ...
    plugins: [
        new webpack.ProvidePlugin({
            $:'jquery'
        }),
    ],
 }

BannerPlugin(内置)

版权声明插件。会给每个打包生成的js文件头部,插入版权声明信息

const webpack = require('webpack');
module: {
    // ...
    plugins: [
        new webpack.BannerPlugin("make 2022 by echoyya ")
    ],
 }

posted on 2023-01-02 22:05  漫思  阅读(43)  评论(0编辑  收藏  举报

导航