zoukankan      html  css  js  c++  java
  • 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)

  • 相关阅读:
    zookeeper.KeeperException$UnimplementedException: KeeperErrorCode = Unimplemented for {root.path}
    IDEA对新建java线程池的建议
    Hbase配置WEB UI界面
    Tomcat清理日志文件无法立即释放磁盘空间
    Tomcat多应用启动报错:org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading Illegal access: this web application instance has been stopped already. Could not load [].
    Soliworks 2016建模细节总结(1)
    关于自学C语言开始时应该注意的问题分享—未完待续......
    Word或者WPS里证件照的背景底色和像素调整
    Linux命令大全(非常全,史上最全)
    Android项目结构介绍
  • 原文地址:https://www.cnblogs.com/yilihua/p/12500848.html
Copyright © 2011-2022 走看看