webpack5基础用法2

webpack的基础用法2

webpack的优化方向

  1. 提升开发体验
  2. 提升打包构建速度
  3. 减少代码体积
  4. 优化代码运行性能
SourceMap

生成一个.map文件,形成一个映射, 可以通过错误找到源文件

开发模式: cheap-module-source-map

  • 优点: 打包编译速度快, 值包含行映射

  • 缺点: 没有映射列

生产模式: source-map

  • 优点: 包含行列映射

  • 缺点: 打包编译速度更慢

使用

// 开发模式
devtool: 'cheap-module-source-map',
// 模式
mode: 'development'
// 生产模式
devtool: 'source-map',
// 模式
mode: 'production'
HotModuleReplacement (热模块替换)

目前修改文件, 网页会重新加载,因为webpack重新打包了

css里面的style-loader已经实现了热模块替换

js默认不能实现hmr

// 手动实现hmr

if(module.hot) {	// 如果支持hmr
    module.hot.accept('./js/count')
}

但是在vue中有使用vue-loader实现了hmr, 不需要自己去配置

小结: 不用配置, 默认是开启的, 或手动开启

devServer: {
        host: 'localhost',  // 服务器域名
        port: '3000',       // 端口
        open: true,          // 自动打开浏览器
        hot: true
    },
OneOf

每一个文件只能被一个rules里面的规则编译,开发模式和生产模式都可以

rules: [
            {
                oneOf: [
                    // loader的配置
                    {
                        test: /\.css$/, // 只检测css文件
                        use: [
                            // 执行顺序: 从右到左, 从上到下
                            'style-loader', // 将js中的css通过创建style标签的方式添加到html文件中生效
                            'css-loader'    // 将css资源编译成commonjs的模块到js中
                        ]
                    },
                    {
                        test: /\.less$/, // 只检测less文件
                        // use 可以使用多个loader, loader只能使用一个laoder
                        use: [
                            // 执行顺序: 从右到左, 从上到下
                            'style-loader', // 将js中的css通过创建style标签的方式添加到html文件中生效
                            'css-loader',    // 将css资源编译成commonjs的模块到js中
                            'less-loader', // 将 less编译成css
                        ]
                    },
                    {
                        test: /\.s[ac]ss$/, // 检测scss或sass
                        // use 可以使用多个loader, loader只能使用一个laoder
                        use: [
                            // 执行顺序: 从右到左, 从上到下
                            'style-loader', // 将js中的css通过创建style标签的方式添加到html文件中生效
                            'css-loader',    // 将css资源编译成commonjs的模块到js中
                            'sass-loader', // 将 scssss编译成css
                        ]
                    },
                    {
                        test: /\.(png|jpe?g|gif|webp|svg)$/,
                        type: 'asset',  // 这个会转base64
                        parser: {
                            dataUrlCondition: {
                                // 小于10kb转base64
                                // 优点: 请求减少, 缺点: 体积变大
                                maxSize: 15 * 1024, // 10 kb
                            }
                        },
                        generator: {
                            // 输出图片名称, hash 更具文件内容生成的hash值 :10 取前10位, ext: 文件的后缀 query 查询
                            filename: 'static/images/[hash:10][ext][query]'
                        }
                    },
                    {
                        test: /\.(ttf|woff2?|mp3|mp4|avi)$/,
                        type: 'asset/resource', // 会原封不动的输出
                        generator: {
                            // 输出图片名称, hash 更具文件内容生成的hash值 :10 取前10位, ext: 文件的后缀 query 查询
                            filename: 'static/media/[hash:10][ext][query]'
                        }
                    },
                    {
                        test: /\.js$/,
                        exclude: /node_modules/,    // 排除node_modules里面的js文件
                        loader: 'babel-loader',
                        // options: {
                        //     presets: ["@babel/preset-env"]
                        // }
                    }
                ]
            }
        ]

// rules里面的内容剪切, 里面放一个对象, oneOf: [剪切的内容]
Include和Exclude

包含和排除, 只能写一个

用法: loader和plugins里面都能用

// eslint的配置
new ESLintPlugin({
    // 检测哪些文件
    context: path.resolve(__dirname, '../src'),
    exclude: "node_modules"     // 也需要exclude
}),
            
{
                        test: /\.js$/,
                        exclude: /node_modules/,    // 排除node_modules里面的js文件
                        // include: path.resolve(__dirname, '../src'),     // 只处理src下面的文件, 绝对路径,跟上面exclude只能写一个
                        loader: 'babel-loader',
                        // options: {
                        //     presets: ["@babel/preset-env"]
                        // }
                    }          
cache 缓存

对eslint检查 和 babel编译的结果缓存, 加快地二次打包速度

babel:

 {
                        test: /\.js$/,
                        exclude: /node_modules/,    // 排除node_modules里面的js文件
                        // include: path.resolve(__dirname, '../src'),     // 只处理src下面的文件, 绝对路径,跟上面exclude只能写一个
                        loader: 'babel-loader',
                        options: {
                            // presets: ["@babel/preset-env"],
                            cacheDirectory: true,       // 开启babel缓存
                            cacheCompression: false,    // 关闭缓存压缩

                        }
                    }

重新运行后会在node_modules里面生成一个.cache/babel-loader文件

eslint:

 new ESLintPlugin({
            // 检测哪些文件
            context: path.resolve(__dirname, '../src'),
            exclude: "node_modules",     // 也需要exclude
            cache: true,    // 开启缓存
            cacheLocation: path.resolve(__dirname, '../node_modules/.cache/eslintcache')
        }),

开启缓存, 创建一个缓存路径, 重新运行后就有生成文件夹了

多进程打包

在特别耗时的任务中使用, 每个进程启动大约为600ms

下载

npm i thread-loader -D

分为 babel, eslint, 和 js压缩

babel:

const os = require('os')        // 获取内核

const threads = os.cpus().length    // 获取cpu核数

// babel里面使用多进程, 使用use, 添加一个 thread-loader

 {
                test: /\.js$/,
                exclude: /node_modules/,    // 排除node_modules里面的js文件
                // loader: 'babel-loader',
                use: [
                    {
                        loader: 'thread-loader',    // 开启多进程
                        options: {
                            works: threads      // 进程数量
                        }
                    },
                    {
                        loader: 'babel-loader',
                        options: {
                            cacheDirectory: true,       // 开启babel缓存
                            cacheCompression: false,    // 关闭缓存压缩
                        }
                    }
                ]
                
            }

eslint

 // eslint的配置,  多进程直接添加一个threads就行了
        new ESLintPlugin({
            // 检测哪些文件
            context: path.resolve(__dirname, '../src'),
            exclude: "node_modules",     // 也需要exclude
            cache: true,    // 开启缓存
            cacheLocation: path.resolve(__dirname, '../node_modules/.cache/eslintcache'),
            threads,    // 开启多进程和进程数量
        }),

js压缩, 生成模式默认会压缩, 里面用的是内置的 terser 插件

// 引入
const TerserWebpackPlugin = require('terser-webpack-plugin')

// 使用
new TerserWebpackPlugin({
    parallel: threads
})

一般压缩可可以放在optimization 里面

optimization: {
        minimizer: [
            // 压缩css
            new cssMinimizerPlugin(),

            new TerserWebpackPlugin({
                parallel: threads
            })
        ]
    },
        
// 将plugins里面的两项去掉同样可以达到效果
treeshaking

**依赖 es module ** 自动移除无用的代码

webpack默认开启了这个功能 (生产模式)

babel

减少babel生成文件的体积

babel会为编译每个文件都插入辅助代码, 使代码体积过大

babel对一些公共方法使用了非常小的辅助代码, 如 _extend , 默认情况下会被添加到每一个需要它的文件中

可以将这些辅助代码作为一个独立的文件, 来避免重复引入

@babel/plugin-transform-runtime: 禁用了bable自动对每个文件的runtime注入, 而是引入 @babel/plugin-transform-runtime 并且使所有辅助代码从这里引入

下载 (开发和生产都可以)

npm i @babel/plugin-transform-runtime -D

使用

{
    test: /\.js$/,
        exclude: /node_modules/,
            loader: 'babel-loader',
                options: {
                    cacheDirectory: true,       // 开启babel缓存
                        cacheCompression: false,    // 关闭缓存压缩
                            plugins: ["@babel/plugin-transform-runtime"],   // 减少代码体积
                }
}
图片压缩

下载

npm i image-minimizer-webpack-plugin imagemin -D

无损压缩

npm i imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo -D

有损压缩

npm i imagemin-gifsicle imagemin-mozjpeg imagemin-pngquant image-svgo -D

使用 包很难下

// 引入
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin')

optimization: {
        minimizer: [
            // 压缩css
            new cssMinimizerPlugin(),
            // 并行压缩js
            new TerserWebpackPlugin({
                parallel: threads
            }),
            // 压缩图片
            new ImageMinimizerPlugin({
                minimizer: {
                    implementation: ImageMinimizerPlugin.imageminGenerate,
                    options: {
                        plugins: [
                            ['gifsicle', { interlaced: true}],
                            ['jpegtran', { progressive: true}],
                            ['optipng', { optimizationLevel: 5}],
                            [
                                'svgo',
                                {
                                    plugins: [
                                        'preset-default',
                                        'prefixIds',
                                        {
                                            name: 'sortAttrs',
                                            params: {
                                                xmlnsOrder: 'alphabetical'
                                            }
                                        }
                                    ]
                                }
                            ]
                        ]
                    }
                }
            })
        ]
    },
code split

代码分割, 按需加载

entry: {
    app: './src/app.js',
    main: './src/main.js'
},
    output: {
        path: resolve(__dirname, 'dist'),
        filename: '[name].js'  // 以文件名自己命名
    }
提取公共模块
optimization: {
    splitChunks: {
        chunks: all, // 对所有模块分割
            // 一堆默认值, 按需修改
            ...
    }
}
统一命名
filename: [name].[ext]
chunkFilename: [name].chunk.[ext]	// 动态导入的chunk
posted @ 2022-07-20 23:16  littlelittleship  阅读(63)  评论(0编辑  收藏  举报