webpack打包系列-3.使用plugin插件扩展

950 阅读3分钟

上一篇

webpack打包系列-2.react项目打包及图片样式资源引入

详细讲解了如何对图片和样式资源打包引入。至此,一个完整的react项目便可以进行开发了。

不过,让时间倒退一下

咱们有一步操作,是在打包完的dist文件夹里面新建index.html文件,并引入打包好后的bundle.js从而执行并查看效果。在这个过程中,我们是操作了构建后的产物dist,这里在实际项目开发过程中会有两个问题

  1. 如果是自动部署的话,你并没有权限去修改dist文件的内容
  2. 如果是手动部署的话,对dist产物的污染,可能会导致问题出现

那么要如何解决呢?

这个时候就需要插件去进行处理了

HtmlWebpackPlugin

HtmlWwebpackPlugin这款插件的功能就是根据你的模板文件,生成html文件,在webpack编译完成的阶段,将你需要用到的js,css等资源或者某些内容嵌入至html中,输出到你的output输出文件夹中。

安装

npm i html-webpack-plugin -D

新建模板

image.png

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">
    <title>Document</title>
</head>
<body>
    <div id="root"></div>
</body>
</html>

使用HtmlWebpackPlugin

webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: './src/index.js',
    output: {
        path: path.join(__dirname, './dist'),
        filename: 'bundle.js'
    },
    mode: 'production',
    module: {
        rules: [
            {
                test: /\.js$/,
                use: 'babel-loader'
            },
            {
                test: /\.css$/,
                use: [
                    'style-loader',
                    'css-loader'
                ]
            },
            {
                test: /\.(png|jpe?g|webp|svg|gif)$/,
                use: 'file-loader'
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html'
        })  // 实例化插件
    ]
}

引入html-webpack-plugin并且在plugins中添加该插件的实例化

html-webpack-plugin可以传入对应参数进行配置,这里的template是以 index.html为模板

详细配置可查阅html-webpack-plugin文档

这个时候重新构建一次npm run build

会发现已经自动生成了一个index.html文件在dist并且是压缩过的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">
    <title>Document</title>
    <script defer="defer" src="bundle.js"></script>
</head>

<body>
    <div id="root"></div>
</body>

</html>

显然,这里已经自动引用了bundle.js 打开index.html看看效果:

image.png

OK,能够正常展示!

MiniCssExtractPlugin

image.png

在元素审查中,我们发现,这个样式还是使用的style标签,这其实会拖慢html的解析速度,那能够拿出来用link引用么?

MiniCssExtractPlugin插件就能完成这种事

安装

npm i mini-css-extract-plugin -D

使用MiniCssExtractPlugin

webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    entry: './src/index.js',
    output: {
        path: path.join(__dirname, './dist'),
        filename: 'bundle.js'
    },
    mode: 'production',
    module: {
        rules: [
            {
                test: /\.js$/,
                use: 'babel-loader'
            },
            {
                test: /\.css$/,
                use: [
    // 这里由于是要使用<link>标签引用了,所以不需要再在头部插入<style>标签,因此style-loader已经没有用处了
    // 并且这里要使用mini-css-extract-plugin自带的loader
                    MiniCssExtractPlugin.loader,
                    'css-loader'
                ]
            },
            {
                test: /\.(png|jpe?g|webp|svg|gif)$/,
                use: 'file-loader'
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html'
        }),
        new MiniCssExtractPlugin()  // 插件实例化
    ]
}

再次构建npm run build

image.png 这里清楚的看到dist产物底下生成了main.css文件

再去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">
    <title>Document</title>
    <script defer="defer" src="bundle.js"></script>
    <link href="main.css" rel="stylesheet">
</head>

<body>
    <div id="root"></div>
</body>

</html>

OK,head标签已插入link标签,也正常引用了main.css文件,打开一看,展示正常!

CleanWebpackPlugin

现在做一个操作

修改webpack.config.js中的output的输出bundle.js加上hash以便利用好浏览器缓存

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    entry: './src/index.js',
    output: {
        path: path.join(__dirname, './dist'),
        filename: 'bundle_[hash].js'  // 给生成的JS文件加上HASH
    },
    mode: 'production',
    module: {
        rules: [
            {
                test: /\.js$/,
                use: 'babel-loader'
            },
            {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader'
                ]
            },
            {
                test: /\.(png|jpe?g|webp|svg|gif)$/,
                use: 'file-loader'
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, './src/index.html'),
        }),
        new MiniCssExtractPlugin(),
    ]
}

执行npm run build

image.png

会发现,会生成新的hundle+哈希的文件,老的bundle.js依旧还在,如果每次改动,hash值都会发生变化,那么会导致文件越多,这是一件很不好的事情,因为老的bundle其实已经不用了

CleanWebpackPlugin这个插件能在构建之前将整个output对应的文件夹内容清除掉,始终保持dist文件夹是最新的需要利用的文件

安装

npm i clean-webpack-plugin -D

使用CleanWebpackPlugin

webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
    entry: './src/index.js',
    output: {
        path: path.join(__dirname, './dist'),
        filename: 'bundle_[hash].js'
    },
    mode: 'production',
    module: {
        rules: [
            {
                test: /\.js$/,
                use: 'babel-loader'
            },
            {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader'
                ]
            },
            {
                test: /\.(png|jpe?g|webp|svg|gif)$/,
                use: 'file-loader'
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, './src/index.html'),
        }),
        new MiniCssExtractPlugin(),
        new CleanWebpackPlugin(),
    ]
}

再次执行npm run build

image.png

dist文件夹变干净了!

总结

本文主要讲了开发基础的常用的三种插件

  1. html-webpack-plugin
  2. mini-css-extract-plugin
  3. clean-webpack-plugin

每一个插件的执行,都对应着webpack构建过程中的不同节点,可以在开发过程中根据需要,使用对应的插件,甚至可以编写自定义插件,以适应开发的需要!

在webpack打包整个过程中,发现每次改动都需要重新构建一次,并且再打开index.html来查看结果是否正确,项目小,需要打包的文件少,打包速度还可以,当然问题不太大,但是如果项目大,文件数量多,那将是一件非常耗时的工作,因此需要更快速的开发构建,欢迎期待下一篇:

webpack打包系列-4.文件观察及开发热重载

我是aWuYa,如果觉得我的文章对你有小小的帮助,麻烦给我点个赞,创作不易,你的点赞就是我最大的动力,万分感谢!