webpack笔记(2)-进阶用法一

104 阅读3分钟

几个概念:

  • bundle:打包最终生成的文件
  • chunk:每个chunk是由多个module组成,可以通过代码分割成多个chunk
  • module:webpack中的模块(js、css、图片等等)

自动清理构建目录产物

使用clean-webpack-plugin插件

plugins: [
    new CleanWebpackPlugin()
]

webpack5在output中配置clean: true即可

autoprefixer自动补齐前缀

安装postcss-loader和autoprefixer,autoprefixer属于后置处理器。
postcss-loader 执行顺序必须保证在 css-loader 之前,建议还是放在 less或者 sass 等预处理器之后更好。即 loader 顺序: less-loader -> postcss-loader -> css-loader -> style-loader 或者 MiniCssExtractPlugin.loader

module: {
    rules: [{
        {
            test: /.less$/,
            use: [
                MiniCssExtractPlugin.loader,
                'css-loader',
                {
                    loader: 'postcss-loader',
                    options: {
                        // 现在配置Use browserslist key in package.json or .browserslistrc file
                        plugins: () => [
                            require('autoprefixer')({
                                browsers: ['last 2 version', '>1%']
                            })
                        ]
                    }
                },
                'less-loader'
            ]
        }
    }]
}

px自动转rem

使用px2rem-loader插件,可以自动转化。lib-flexible库可以在页面渲染时计算根元素的font-size值。lib-flexible需要打包时候就内联进来,否则会有闪动问题。

module: {
    rules: [{
        {
            test: /.less$/,
            use: [
                MiniCssExtractPlugin.loader,
                'css-loader',
                {
                    loader: 'postcss-loader',
                    options: {
                        // 现在配置Use browserslist key in package.json or .browserslistrc file
                        plugins: () => [
                            require('autoprefixer')({
                                browsers: ['last 2 version', '>1%']
                            })
                        ]
                    }
                },
                {
                    loader: 'px2rem-loader',
                    options: {
                        // 一个rem对应75px
                        remUnit: 75,
                        // 转换后的小数点位数
                        remPrecision: 8
                    }
                },
                // 注意解析顺序
                'less-loader'
            ]
        }
    }]
}

// 不想进行转化时,需要在页面中加上注释语法
// 这个px2rem-loader 也是可以设置 exclude 的,可以把 node_modules 里面的模块 exclude 掉,防止第三方库的px也转换掉
.page { 
    font-size: 12px; /*no*/ 
    width: 375px; /*no*/ 
    height: 40px;
}

注意:lib-flexible的官方都不推荐使用这种方式了,以下是官方的md: 由于viewport单位得到众多浏览器的兼容,lib-flexible这个过渡方案已经可以放弃使用,不管是现在的版本还是以前的版本,都存有一定的问题。建议大家开始使用viewport来替代此方案。

多页面打包

思路:动态获取目录下指定的入口文件

const glob = require('glob');

const setMPA = () => {
    const entry = {};
    const htmlWebpackPlugins = [];
    const entryFiles = glob.sync(path.join(__dirname, 'src/*/index.js'));

    // 此处是全方案,entryFiles是数组,本例中可直接map
    Object.keys(entryFiles).map(index => {
        const entryFile = entryFiles[index];
        const match = entryFile.match(/src\/(.*)\/index.js/);
        const fileName = match && match[1]; // index search
        entry[fileName] = entryFile;
        htmlWebpackPlugins.push(
            new HtmlWebpackPlugin({
                template: path.join(__dirname, `src/${fileName}/index.html`),
                filename: `${fileName}.html`,
                chunks: [fileName],
                inject: true,
                minify: {
                    html5: true,
                    collapseWhitespace: true,
                    preserveLineBreaks: false,
                    minifyCSS: true,
                    minifyJS: true,
                    removeComments: false
                }
            })
        );
    })

    return {
        entry,
        htmlWebpackPlugins
    }
}

const {entry, htmlWebpackPlugins} = setMPA();

// 
plugins: [
    new MiniCssExtractPlugin({
        filename: '[name]_[contentHash:8].css'
    }),
    new OptimizeCssAssetsWebpackPlugin({
        assetNameRegExp: /\.css$/g,
        // cssnano是属于默认配置,可以不写不安装
        cssProcessor: require('cssnano')
    }),
    new CleanWebpackPlugin()
].concat(htmlWebpackPlugins)

glob语法:juejin.cn/post/687636…

利用source map进行代码调试

官网中source map说明:v4.webpack.docschina.org/configurati…

module.exports = {
    devtool: 'source-map'
}

提取公共文件

optimization: {
    splitChunks: {
        chunks: 'async', // async:异步引入的库进行分离(默认),initial: 同步引入的库进行分离,all:所有引入的库进行分离(推荐)
        minSize: 30000, // 抽离的公共包最小的大小,单位字节
        maxSize: 0, // 最大的大小
        minChunks: 1, // 资源使用的次数(在多个页面使用到), 大于1, 最小使用次数
        maxAsyncRequests: 5,  // 并发请求的数量
        maxInitialRequests: 3, // 入口文件做代码分割最多能分成3个js文件
        automaticNameDelimiter: '~', // 文件生成时的连接符
        automaticNameMaxLength: 30, // 自动自动命名最大长度
        name: true, //让cacheGroups里设置的名字有效
        cacheGroups: {
            vendors: {
                // 建议仅包括核心框架和实用程序,并动态加载其余依赖项,作为基础库。
                test: /(react|react-dom)/,
                // 需要在htmlWebpackPlugins中的chunks属性添加依赖
                // name打包出来的值会加上hash等引入,filename不会,定义什么就是什么了
                name: 'vendors',
                chunks: 'all' // 所有引入的库进行分离(推荐)
            },
            commons: {
                // 作为公共脚本库
                name: 'commons',
                chunks: 'all',
                minChunks: 2,
                // 权重配置
                priority: -10
            }
        }
    }
}