webpack4之路(3)-Plugins

tips:上一篇我们已经一起学习了webpack的loader配置,现在我们来学webpack的重要功能Plugins(插件)吧~~

什么是插件?

插件(Plugins)是用来拓展webpack功能的,它们会在整个构建过程中生效,执行相关任务。插件的目的在于解决loader无法实现的其他事。

插件与loader的区别

Loaders是打包构建过程中用来处理源文件如(JSX,Scss,Less...)一次处理一个;插件并不是直接操作单个文件,它直接对整个构建过程起作用。

插件的使用

使用插件,首先要用npm进行安装,然后在webpack.config.js配置文件的plugins(是一个数组)配置中添加该插件的实例。先从简单的版权声明插件开始

webpack.config.js

const path = require('path')
const webpack = require('webpack') // 版权声明插件不用安装,是基于webpack,所以只要引入webpack即可
module.exports = {
    mode: 'development',
    entry: {
        index: './scripts/index.js' // 入口文件,若不配置webpack4将自动查找src目录下的index.js文件
    },
    output: {
        filename: '[name].bundle.js', // 输出文件名,[name]表示入口文件js名
        path: path.join(__dirname, 'dist') // 输出文件路径
    },
    devServer: {
        host: 'localhost', // 主机地址
        compress: true, // 开发服务器是否启动gzip等压缩
        contentBase: './dist',//开发服务运行时的文件根目录
        inline: true,
        port: 9000 // 监听的端口
    },
    module: {
        rules: [
            {
                test: /\.css$/, // 正则匹配以.css结尾的文件
                use: ['style-loader', 'css-loader'] // 需要用的loader,一定是这个顺序,因为调用loader是从右往左编译的
            },
            {
                test: /\.(scss|sass)$/, // 正则匹配以.scss或者.sass结尾的文件
                use: ['style-loader', 'css-loader', 'sass-loader'] // 需要用的loader,一定是这个顺序,因为调用loader是从右往左编译的
            },
            {
                test: /\.js|\.jsx$/,
                loader: "babel-loader",
                exclude: /node_modules/ // 不包括依赖内的js文件
            }
        ]
    },
    plugins: [
        new webpack.BannerPlugin('版权所有,翻版必究') // new一个插件实例
    ]
}

运行npm run server. 我们就可以在打包出来的文件里查看

 

 提前预热完成,现在开始进入主题啦~~~

1.htmlWebpackPlugin

看名字就知道这是处理关于HTML的。这个插件简化了HTML的创建.它的主要两个作用分别是1.为html文件中引入的外部资源如script、link动态添加每次compile后的hash, 防止引用缓存的外部文件问题2.可以生成创建html入口文件,比如单页面可以生成一个html文件入口,配置N个html-webpack-plugin可以生成N个页面入口。

原理:

将 webpack中`entry`配置的相关入口chunk 和 `extract-text-webpack-plugin`抽取的css样式 插入到该插件提供的`template`或者`templateContent`配置项指定的内容基础上生成一个html文件,具体插入方式是将样式`link`插入到`head`元素中,`script`插入到`head`或者`body`中。

安装:

npm i html-webpack-plugin -D

然后我们要去项目结构进行一些更改,把dist整个文件夹删除;

然后就开始配置webpack.config.js

const path = require('path')
const webpack = require('webpack') // 版权声明插件不用安装,是基于webpack,所以只要引入webpack即可
const HtmlWebpackPlugin = require('html-webpack-plugin')  // 引入插件
module.exports = {
    mode: 'development',
    entry: {
        index: './scripts/index.js' // 入口文件,若不配置webpack4将自动查找src目录下的index.js文件
    },
    output: {
        filename: '[name].bundle.js', // 输出文件名,[name]表示入口文件js名
        path: path.join(__dirname, './dist') // 输出文件路径
    },
    devServer: {
        host: 'localhost', // 主机地址
        compress: true, // 开发服务器是否启动gzip等压缩
        contentBase: './dist',//开发服务运行时的文件根目录
        historyApiFallback: true, // 不跳转
        inline: true,
        port: 9000 // 监听的端口
    },
    stats: {
        entrypoints: false,
        children: false
    },
    module: {
        rules: [
            {
                test: /\.css$/, // 正则匹配以.css结尾的文件
                use: ['style-loader', 'css-loader'] // 需要用的loader,一定是这个顺序,因为调用loader是从右往左编译的
            },
            {
                test: /\.(scss|sass)$/, // 正则匹配以.scss或者.sass结尾的文件
                use: ['style-loader', 'css-loader', 'sass-loader'] // 需要用的loader,一定是这个顺序,因为调用loader是从右往左编译的
            },
            {
                test: /\.js|\.jsx$/,
                loader: "babel-loader",
                exclude: /node_modules/ // 不包括依赖内的js文件
            }
        ]
    },
    plugins: [
        new webpack.BannerPlugin('版权所有,翻版必究'), // new一个插件实例
        new HtmlWebpackPlugin({
            title: 'Hello Webpack',
        })
    ]
}

 这里主要就是引入了HtmlWebpackPlugin插件,并做了修改标题操作。之前在package.json里是没有配置打包脚本的,为了方便先配置个脚本。

    "build": "webpack"

执行npm run build之后 你会 发现一个新的dist包。里面就是你打包出来的内容了。这样代表成功了哦

 到这里。不知道 有没有宝宝和我一样有一个疑惑,我本地也没有index.html的入口,只有一个js文件。那我监听的9000端口html在哪。这个疑问真是让我想了好久好久,最终和同事聊起才知道,它会看有没有有设置默认的入口,如果没有的话会给你建个缓存的html.

为了验证,那我就在根目录下建个index.html文件

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Hello Webpack</title>
  </head>
  <body>
    new html
  </body>
</html>

然后我们还要在webpack.config.js引入HtmlWebpackPlugin插件的地方进入简单的配置

 plugins: [
        new webpack.BannerPlugin('版权所有,翻版必究'), // new一个插件实例
        new HtmlWebpackPlugin({
            title: 'Hello Webpack',
            template: path.join(__dirname, 'index.html')
        })
    ]

现在运行npm run server就可以看到效果了

 

 这样就有你监听的html了,如果你要改什么html就可以在这里改。优秀。

2.ExtractTextWebpackPlugin(抽离css样式)

npm install --save-dev mini-css-extract-plugin

在webpack.config.js配置

const path = require('path')
const webpack = require('webpack') // 版权声明插件不用安装,是基于webpack,所以只要引入webpack即可
const HtmlWebpackPlugin = require('html-webpack-plugin')  // 引入插件
const miniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    mode: 'development',
    entry: {
        index: './scripts/index.js' // 入口文件,若不配置webpack4将自动查找src目录下的index.js文件
    },
    output: {
        filename: '[name].bundle.js', // 输出文件名,[name]表示入口文件js名
        path: path.join(__dirname, './dist') // 输出文件路径
    },
    devServer: {
        host: 'localhost', // 主机地址
        compress: true, // 开发服务器是否启动gzip等压缩
        contentBase: './dist',//开发服务运行时的文件根目录
        historyApiFallback: true, // 不跳转
        inline: true,
        port: 9000 // 监听的端口
    },
    stats: {
        entrypoints: false,
        children: false
    },
    module: {
        rules: [
            {
                test: /\.css$/, // 正则匹配以.css结尾的文件
                // use: ['style-loader', 'css-loader'] // 需要用的loader,一定是这个顺序,因为调用loader是从右往左编译的
                use: [
                    miniCssExtractPlugin.loader,
                    {
                        loader: 'css-loader',
                        options: {
                            url: false
                        }
                    }
                ]
            },
            {
                test: /\.(scss|sass)$/, // 正则匹配以.scss或者.sass结尾的文件
                use: ['style-loader', 'css-loader', 'sass-loader'] // 需要用的loader,一定是这个顺序,因为调用loader是从右往左编译的
            },
            {
                test: /\.js|\.jsx$/,
                loader: "babel-loader",
                exclude: /node_modules/ // 不包括依赖内的js文件
            },
        ]
    },
    plugins: [
        new webpack.BannerPlugin('版权所有,翻版必究'), // new一个插件实例
        new HtmlWebpackPlugin({
            title: 'Hello Webpack',
            template: path.join(__dirname, 'index.html')
        }),
        new miniCssExtractPlugin({
            filename: 'index.css'
        })
    ]
}

修改的地方分别是引入,rule与plugins插件实例。运行npm run webpack就可以看到打出来的css文件了。

 3.cleanWebpackPlugin

当我们每次打包完文件后,都会生成一个新的dist文件覆盖上一个dist文件,但如果上个dist的一 些其他文件没有被覆盖,他就会一直存在那里,随着打包次数的增多,这种无用而可能会影响我们的代码越来越多,会严重影响我们的性能。

cleanWebpackPlugin插件做的就是每次打包时都会删除上一次打包的文件,而不是覆盖。这样每次都是全新的包了。

npm i clean-webpack-plugin -D

配置webpack.config.js

const  CleanWebpackPlugin = require('clean-webpack-plugin') // 引入插件

plugins: [
        new webpack.BannerPlugin('版权所有,翻版必究'), // new一个插件实例
        new HtmlWebpackPlugin({
            title: 'Hello Webpack',
            template: path.join(__dirname, 'index.html')
        }),
        new miniCssExtractPlugin({
            filename: 'index.css'
        }),
        new CleanWebpackPlugin() 
    ]

运行,npm run build.报错了

 

 报错说,CleanWebpackPlugin不是一个构造函数。于是查阅资料知道由于clean-webpack-plugin.d.ts.文件中它是以一个对象属性的形式导出,所以我们引入的时候需要以解构方式来获取,所以我们修改引入方式

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

再次执行打包命令就正常了,而且没有冗余的文件了。

4.HotModuleReplacementPlugin(热更新)

HotModuleReplacementPlugin(HMR)可以在我们修改代码后自动刷新预览效果。

说一个我遇到的疑问吧,因为我之前是有在devServer下配置inline:ture所以每次我修改并保存后页面的东西就会变化,我就想着说这和热加载有什么区别:

// 1. 不会刷新浏览器
$ npm run server//2. 刷新浏览器
$ npm run server --inline
//3. 重新加载改变的部分,不会刷新页面
$ npm run server --hot
//4. 重新加载改变的部分,HRM失败则刷新页面
$ npm run server  --inline --hot

这个是在package.json里的设置,这样设置比在webpack.config.js设置更加简单。所以我们也可以这样使用哦。接着我们继续配置webpack.config.js中HotModuleReplacementPlugin,因为它是wbpack模块自带的,所以引入webpack后,就可以直接在plugins配置即可。

plugins: [
        new webpack.BannerPlugin('版权所有,翻版必究'), // new一个插件实例
        new HtmlWebpackPlugin({
            title: 'Hello Webpack',
            template: path.join(__dirname, 'index.html')
        }),
        new miniCssExtractPlugin({
            filename: 'index.css'
        }),
        new CleanWebpackPlugin(), // 传入要清理的文件夹名称、
        new webpack.HashedModuleIdsPlugin() // 热更新插件
    ]

除了这里配置外,我们还要到入口index.js里加入如下代码

//如果模块启用了HMR,就可以用 module.hot.accept(),监听模块的更新。
if (module.hot) {
    module.hot.accept('./helper.js', function() {
        header()
    })
}

当我们运行npm run server就可以看到控制台的输出:

 

插件我们就先了解到这里,更多插件使用可以查看官网。一起学习,一起进步。

 

 

 

 

查阅资料:

1)https://blog.csdn.net/cc18868876837/article/details/103238733 (CleanWebpackPlugin is not a constructor 的错误处理)

2)https://www.codercto.com/a/4836.html (webpack-dev-server 中 inline 和 HMR 的区别

3)https://www.webpackjs.com/plugins/ (webpack官网plugins)

posted @ 2020-03-22 22:15  lee是美少女  阅读(339)  评论(0编辑  收藏  举报