一个合格的Webpack4配置工程师素养:第二部分

发布于 2019-01-29 作者 coder 83次 浏览 版块 分享

原文: https://cnodejs.org/topic/5c4d498a595cbd1e95088cd0

webpack处理带哈希值的文件名引入问题

我们给打包的文件打上hash是为了解决缓存更新问题,常见需要打上hash的地方有。

output: {
    filename: 'bound.[hash:5].js',
    path: path.resolve(__dirname, 'dist')
}
// 提取CSS
new MiniCssExtractPlugin({
    filename: devMode ? '[name].css' : '[name].[hash:5].css', // 设置输出的文件名
    chunkFilename: devMode ? '[id].css': '[id].[hash:5].css'
})

但是打上hash我们怎么引入是一个问题。

html-webpack-plugin插件可以把js/css注入到一个模板文件, 所以不需要再手动更改引用。

npm i -D html-webpack-plugin

更改配置文件

const HtmlWebpackPlugin = require('html-webpack-plugin')

plugins: [
    // 打包模板
    new HtmlWebpackPlugin({
        inject: true,
        hash: true,
        cache: true,
        chunksSortMode: 'none',
        title: 'Webapck4-demo', // 可以由外面传入
        filename: 'index.html', // 默认index.html
        template: path.resolve(__dirname, 'index.html'),
        minify: {
            collapseWhitespace: true,
            removeComments: true,
            removeRedundantAttributes: true,
            removeScriptTypeAttributes: true,
            removeStyleLinkTypeAttributes: true
        }
    })
],

设置一个模板文件。

// index.html
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="google" value="notranslate">
    <meta http-equiv="Cache-Control" content="no-siteapp">
    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
    <meta name="format-detection" content="telephone=no">
    <title><%= htmlWebpackPlugin.options.title %></title>
</head>

<body>
    <div id="app"></div>
</body>

</html>

打包后的文件:

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="google" value="notranslate">
    <meta http-equiv="Cache-Control" content="no-siteapp">
    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
    <meta name="format-detection" content="telephone=no">
    <title></title>
    <link href="main.f37fa.css?f37fab3edd3ae8ecda6a" rel="stylesheet">
</head>

<body>
    <div id="app"></div>
    <script src="bound.f37fa.js?f37fab3edd3ae8ecda6a"></script>
</body>

</html>

webpack清理打包后的dist目录

我们会发现每次打包后dist文件夹都会不断增加文件, 显然这个方面我们需要处理, 但是某些情况下我们不需要去清理, 比如坑爹的微信公众号缓存问题。

npm i -D clean-webpack-plugin

修改配置文件

const CleanWebpackplugin = require('clean-webpack-plugin')

plugins: [
    // 清理dist目录
    new CleanWebpackplugin(['dist'])
]

webpack处理图片以及优化

我们这里只是为了测试, 在index.html模板文件添加一个dom去使用图片。

// index.html
<div class="logo"></div>

// base.scss
.logo {
    background: url('../assets/logo.png') no-repeat;
    width: 100px;
    height: 100px;
    background-size: contain;
}

使用file-loader来处理文件的导入

npm i -D file-loader

修改配置文件

rules: [
    // 处理文件
    {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        use: [
            {
                loader: 'file-loader',
                options: {
                    // 具体配置见插件官网
                    limit: 1,
                    name: '[name]-[hash:5].[ext]',
                    outputPath: 'img/', // outputPath所设置的路径,是相对于 webpack 的输出目录。
                    // publicPath 选项则被许多webpack的插件用于在生产模式下更新内嵌到css、html文件内的 url , 如CDN地址
                },
            },
        ]
    },
] 

下面继续对图片进行优化和压缩

npm i -D image-webpack-loader

修改配置文件

// 处理文件
{
    test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
    use: [
        {
            loader: 'file-loader',
            options: {
                // 具体配置见插件官网
                limit: 10000,
                name: '[name]-[hash:5].[ext]',
                outputPath: 'img/', // outputPath所设置的路径,是相对于 webpack 的输出目录。
                // publicPath 选项则被许多webpack的插件用于在生产模式下更新内嵌到css、html文件内的 url , 如CDN地址
            },
        },
        {
            loader: 'image-webpack-loader',
            options: {
              mozjpeg: {
                progressive: true,
                quality: 65
              },
              // optipng.enabled: false will disable optipng
              optipng: {
                enabled: false,
              },
              pngquant: {
                quality: '65-90',
                speed: 4
              },
              gifsicle: {
                interlaced: false,
              },
              // the webp option will enable WEBP
              webp: {
                quality: 75
              }
            }
        }
    ]
},

压缩前图片大小181.46kb.

压缩后29kb.

webpack把图片转为base64以及字体处理

通过把一些小的图片转为base65(DataURl)可以减少http请求, 提升访问效率。

npm i -D url-loader

修改配置文件

// 处理文件
{
    test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
    use: [
        {
            loader: 'url-loader',
            options: {
                // 具体配置见插件官网
                limit: 10000,
                name: '[name]-[hash:5].[ext]',
                outputPath: 'img/', // outputPath所设置的路径,是相对于 webpack 的输出目录。
                // publicPath 选项则被许多webpack的插件用于在生产模式下更新内嵌到css、html文件内的 url , 如CDN地址
            },
        },
        {
            loader: 'image-webpack-loader',
            options: {
              mozjpeg: {
                progressive: true,
                quality: 65
              },
              // optipng.enabled: false will disable optipng
              optipng: {
                enabled: false,
              },
              pngquant: {
                quality: '65-90',
                speed: 4
              },
              gifsicle: {
                interlaced: false,
              },
              // the webp option will enable WEBP
              webp: {
                quality: 75
              }
            }
        }
    ]
},

这里测试的话我们需要准备一个小的图片即可,如上述配置所述只要小于10kb就会用base64替代。

字体处理的话配置如下:

{
    test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
    loader: 'url-loader',
    options: {
        // 文件大小小于limit参数,url-loader将会把文件转为DataUR
        limit: 10000,
        name: '[name]-[hash:5].[ext]',
        output: 'fonts/',
        // publicPath: '', 多用于CDN
    }
},

收藏
暂无回复