【专项学习】 —— Webpack5从入门到精通课程学习(四)

这篇主要介绍《webpack优化环境配置(上)》。(demo代码github地址

知识点包括:


 

一、开发环境性能优化(HMR)

1、将webpack生产环境配置汇总工程完整复制一份,并重命名。

在终端输入npx webpack serve启动热更新服务。

然后我们简单修改index.less内的样式,会发现只单独更新了样式模块。

 2、此时在简单修改index.js和index.html文件,则不会仅仅更新js或者html模块,而是整个工程进行更新

在webpack.config.js内代码中有注释说明。

/**
 * 启动devServer命令:
 * npx webpack serve
 * 开发环境的性能优化(HMR):hot module replacement热模块替换/模块热替换
    作用:一个模块发生变化,只会重新打包这一个模块(而不是打包所有模块)极大提升构建速度.
    样式文件:可以使用HMR功能:因为style-loader内部实现了~
    js文件:默认不能使用HMR功能,我们可以在入口文件中引入其他js文件,实现修改其他js文件,达成HMR功能
    html文件:默认不能使用HMR功能.同时会导致问题: html文件不能热更新了~,在入口entry属性中配置上html文件即可解决
 */
const { resolve } = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { entry: ['./src/index.js', './src/index.html'], output: { filename: 'built.js', path: resolve(__dirname, 'build') }, module: { rules: [ // loader的配置 { //处理less资源 test: /\.less$/, use: [ 'style-loader', 'css-loader', 'less-loader' ], }, { //处理css资源 test: /\.css$/, use: [ 'style-loader', 'css-loader' ], }, { //处理图片资源Ⅰ test: /\.(jpg|png|gif)$/, loader: 'url-loader', options: { limit: 8 * 1024, // 关闭ES6模块化 esMoudle: false }, type: 'javascript/auto' }, { //处理html中img资源 test: /\.html$/, loader: 'html-loader', options: { esModule: false, } }, { //处理其他资源 exclude: /\.(html|js|css|less|jpg|png|gif)$/, loader: 'file-loader', options: { esModule: false, }, type: 'javascript/auto' } ] }, plugins: [ // plugins的配置 new HtmlWebpackPlugin({ template: './src/index.html' }) ], devServer: { compress: true, port: 3000, open: true, // 开启hmr功能,webpack5默认开启了 // hot: true }, mode: 'development' }

3、入口文件index.js不能使用HMR功能,那么在入口文件中,引入其他的js则可以使用,不过要修改代码。

index.js:

import '../src/iconfont';
import '../src/index.less';
import print from './print';


console.log('index.js文件被加载了');
function add(x, y) {
    return x + y;
}
console.log(add(1, 8));
if (module.hot) {
    // 一旦 module.hot为true,说明开启了HMR功能。--> 让HMR功能代码生效
    module.hot.accept('../src/print.js', function () {
        //方法会监听 print.js文件的变化,一旦发生变化,其他模块不会重新打包构建。
        //会执行后面的回调函数
        print();
    })
}

4、我们新建的另一个print.js

function print() {
    const content = 'print.js被加载了';
    console.log(content);
    
}
export default print;

此时修改print.js文件,则会发生HMR热更新模块功能。

但是,注意:入口文件index.js一修改是只能整个工程全部更新。  

 

二、source-map

source-map:一种提供源代码到构建后(打包)代码映射技术(如果构建后(打包)代码出错了,通过映射可以追踪源代码错误)。

1、将上一小节工程文件复制,并重命名。修改webpack.config.js代码

/**
 * 启动devServer命令:
 * npx webpack serve
 * 开发环境的性能优化(HMR):hot module replacement热模块替换/模块热替换
    作用:一个模块发生变化,只会重新打包这一个模块(而不是打包所有模块)极大提升构建速度.
    样式文件:可以使用HMR功能:因为style-loader内部实现了~
    js文件:默认不能使用HMR功能
    html文件:默认不能使用HMR功能.同时会导致问题: html文件不能热更新了~,在入口entry属性中配置上html文件即可解决


 */
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
    entry: ['./src/index.js', './src/index.html'],
    output: {
        filename: 'built.js',
        path: resolve(__dirname, 'build')
    },
    module: {
        rules: [
            // loader的配置
            {
                //处理less资源
                test: /\.less$/,
                use: [
                    'style-loader',
                    'css-loader',
                    'less-loader'
                ],
            },
            {
                //处理css资源
                test: /\.css$/,
                use: [
                    'style-loader',
                    'css-loader'
                ],
            },
            {
                //处理图片资源Ⅰ
                test: /\.(jpg|png|gif)$/,
                loader: 'url-loader',
                options: {
                    limit: 8 * 1024,
                    // 关闭ES6模块化
                    esMoudle: false
                },
                type: 'javascript/auto'
            },
            {
                //处理html中img资源
                test: /\.html$/,
                loader: 'html-loader',
                options: {
                    esModule: false,
                }
            },
            {
                //处理其他资源
                exclude: /\.(html|js|css|less|jpg|png|gif)$/,
                loader: 'file-loader',
                options: {
                    esModule: false,
                },
                type: 'javascript/auto'
            }
        ]
    },
    plugins: [
        // plugins的配置
        new HtmlWebpackPlugin({
            template: './src/index.html'
        })
    ],
    devServer: {
        compress: true,
        port: 3000,
        open: true,
        // 开启hmr功能,webpack5默认开启了
        // hot: true
    },
    // source-map:一种提供源代码到构建后(打包)代码映射技术(如果构建后(打包)代码出错了,
    //通过映射可以追踪源代码错误)。
    // 开启source-map,打包后会生成一个.js.map文件
    devtool: 'source-map',
    // 测试不同种类的source-map
    // devtool: 'eval-source-map',
    mode: 'development'
}
/*
有如下几个组合source-map
[inline-|hidden-|eval-] [nosources-] [cheap-[ module-]] source-map
inline-source-map:把原本单独生成的built.js.map文件,整体内嵌到了built.js中尾部去了
hidden-source-map:单独生成一个built.js.map文件,
eval-source-map:内嵌到built.js中,但是是以分段的形式,从头至尾,遍布于整个.js文件中
nosources-source-map:单独生成一个built.js.map文件
cheap-source-map:单独生成一个built.js.map文件
cheap-module-source-map:单独生成一个built.js.map文件。
*/ 

2、输入npm run dev进行打包。  

3、然后输入npx webpack serve开启热更新。效果如下

 

 

4、那么我们为了验证代码出错时是否有映射关系。把print.js中代码人为制造一个错误。

function print() {
    // 人为制造一个log的错误 —— 多加两个逗号
    const content = 'print.js被加载了',,
    console.log(content)
}
export default print;

自动热更新后,网页报错的提示。  

 小结,不同的sourece-map对比:

 

三、oneOf

1、将webpack生产环境配置工程复制,并重命名oneOf。

oneOf功能是:使每个类型的文件,只匹配到一个适用的loader即可,不会把代码中写的所有loader挨个匹配一遍,优化了构建速度

2、在webpack.config.js代码如下,把相关的loader放入oneOf选项中。

const { resolve } = require('path');
const minicssextractplugin = require('mini-css-extract-plugin');
// css浏览器兼容性处理,默认是运行在生产环境下,若要运行于开发环境,还需做以下代码
process.env.NODE_ENV = 'development'
const cssminimizerwebpackplugin = require('css-minimizer-webpack-plugin');
const Htmlwebpackplugin = require('html-webpack-plugin');
const Eslintwebpackplugin = require('eslint-webpack-plugin');

module.exports = {
    entry: './src/js/index.js',
    output: {
        filename: 'js/built.js',
        path: resolve(__dirname, 'build')
    },
    module: {
        rules: [{
            // oneOf是每一个文件,只匹配到一个loader即可,
            //不像之前,每个文件都要把下列loader全部匹配一遍
            // 注意不能有两个loader处理同一个类型文件
            oneOf: [
                {
                    // 检测css文件,并打包
                    test: /\.css$/,
                    use: [
                        minicssextractplugin.loader,
                        'css-loader',
                        {
                            // 对css做兼容性处理
                            // 还需要在package.json中定义browserslist
                            loader: 'postcss-loader',
                            options: {
                                postcssOptions: {
                                    plugins: [require('postcss-preset-env')()]
                                }
                            }
                        }
                    ]
                },
                {
                    // 检测less文件,并打包
                    test: /\.less$/,
                    // use内代码,是从下往上的顺序执行的
                    use: [
                        minicssextractplugin.loader,
                        'css-loader',
                        {
                            // 还需要在package.json中定义browserslist
                            loader: 'postcss-loader',
                            options: {
                                postcssOptions: {
                                    plugins: [require('postcss-preset-env')()]
                                }
                            }
                        },
                        'less-loader'
                    ]
                },
                // 正常来讲,一个文件只能被一个loader处理,比如一个index.js文件。
                //当一个文件要被多个loader处理,那么一定要指定loader执行的先后顺序
                // {
                //     //在package.json中定义eslintConfig --> airbnb
                //     // js语法检查,webpack4写法
                //     test: /\.js$/,
                //     exclude: /node_modules/,
                //     // 优先执行eslint-loader,对js文件进行处理
                //     enforce: 'pre',
                //     loader: 'eslint-loader',
                //     options: {
                //         // 自动修复语法检查的报错
                //         fix: true
                //     }
                // },
                {
                    // js兼容性处理
                    test: /\.js$/,
                    exclude: /node_modules/,
                    loader: 'babel-loader',
                    options: {
                        presets: [
                            [
                                '@babel/preset-env', {
                                    useBuiltIns: 'usage',
                                    corejs:
                                    {
                                        version: 3
                                    },
                                    targets: {
                                        // 浏览器兼容的版本
                                        chrome: '60',
                                        firefox: '50'
                                    }
                                }
                            ]
                        ]
                    }

                },
                {
                    //对图片进行打包处理
                    test: /\.(jpg|png|gif)$/,
                    loader: 'url-loader',
                    options: {
                        limit: 8 * 1024,
                        outputPath: 'imgs',
                        esModule: false
                    },
                    type: 'javascript/auto'
                },
                {
                    // 处理html中的图片文件
                    test: /\.html$/,
                    loader: 'html-loader',
                    options: {
                        esModule: false,
                    }

                },
                {
                    // 处理其他文件,如字体图标等
                    exclude: /\.(js|css|less|html|jpg|png|gif)$/,
                    loader: 'file-loader',
                    options: {
                        outputPath: 'media',
                        esModule: false,
                    },
                    type: 'javascript/auto'
                }
            ]
        }
        ]
    },
    plugins: [
        new minicssextractplugin({
            // 打包提取成单独文件
            filename: 'css/built.css'
        }),
        new cssminimizerwebpackplugin(
            // 压缩css文件
        ),
        new Htmlwebpackplugin({
            template: './src/index.html',
            // 压缩html
            minify: {
                collapseWhitespace: true,
                removeComments: true
            }
        }),
        new Eslintwebpackplugin({
            // 使用默认配置
            fix: true
        })
    ],
    // 生产环境下,js自动压缩
    mode: 'production'
}

注:笔记转载自疯子的梦想@博客,课程来自尚硅谷b站Webpack5实战课程

posted @ 2022-03-07 15:54  柳洁琼Elena  阅读(89)  评论(0编辑  收藏  举报