Webpack基础(二)


PostCSS工具

什么是PostCSS

PostCSS是一个通过JavaScript来转换样式的工具,这个工具可以帮助我们进行一些CSS的转换和适配,比如自动添加浏览器前缀、css样式的重置。但是实现这些工具,我们需要借助于PostCSS对应的插件。主要用来处理浏览器兼容性问题。

安装PostCss:

npm install postcss postcss-cli -D

使用:在webpack的配置文件中编写相应的loader规则,或者直接在命令行中使用。

因为postcss是独立于webpack的,所以在webpack.config.js中配置postcss前需要安装相应loader

npm install postcss-loader -D

配置:

// webpack.config.js -> modules -> rules -> use
{
    loader: "postcss-loader",
    options: {
        postcssOptions: {
            plugins: [
                require('autoprefixer')
            ]
        }
    }
}

autoprefixer

autoprefixer可以帮助我们生成兼容各种浏览器的css代码,它的主要作用就是给css代码添加上相应的浏览器前缀。如:

/* autoprefixer处理前 */
:fullscreen {
    color: red;
}
.content {
    user-select: none;
}
/* autoprefixer处理后 */
:-ms-fullscreen {
}
:fullscreen {
}
.content {
    -webkit-user-select: none;
    	-moz-user-select: none;
    		-ms-user-select: none;
    			user-select: none;
}

安装autoprefixer

npm install autoprefixer -D

单独配置autoprefixerpostcss.config.js中配置:

// postcss.config.js
module.exports = {
    plugins: [
        require("autoprefixer")
    ]
}

postcss-preset-env

postcss-preset-env也是一个postcss的插件。它可以帮助我们将一些现代的CSS特性,转成大多数浏览器认识的CSS,并且会根据目标浏览器或者运行时环境添加所需的polyfill。也包括会自动帮助我们添加autoprefixer(所以相当于已经内置了autoprefixer)。

安装postcss-preset-env

npm install postcss-preset-env -D

配置postcss-preset-env

// postcss.config.js
module.exports = {
    plugins: [
        require("postcss-preset-env")
    ]
}

加载和处理其它资源

file-loader

file-loader的作用就是帮助我们处理import/require()方式引入的一个文件资源,并且会将它放到我们输出的文件夹中。

安装file-loader

npm install file-loader -D

配置file-loader

// webpack.config.js -> modules -> rules
{
    test: /\.(png|jpe?g|gif|svg)$/i,
    use: {
        loader: "file-loader"
    }
}

有时候我们处理后的文件名称按照一定的规则进行显示: 比如保留原来的文件名、扩展名,同时为了防止重复,包含一个hash值等。 这个时候我们可以使用PlaceHolders来完成,webpack给我们提供了大量的PlaceHolders来显示不同的内容。

常用的placeholder:

  • [ext]: 处理文件的扩展名
  • [name]:处理文件的名称
  • [hash]:文件的内容,使用MD4的散列函数处理,生成的一个128位的hash值(32个十六进制)
  • [contentHash]:在file-loader中和[hash]结果是一致的(在webpack的一些其他地方不一样,后面会讲到)
  • [hash:]:截图hash的长度,默认32个字符太长了
  • [path]:文件相对于webpack配置文件的路径

例如将图片文件输出到/img下,并且用文件原名 + hash值前8位 + 扩展名命名打包好的图片文件。

// webpack.config.js -> modules -> rules
{
    test: /\.(png|jpe?g|gif|svg)$/i,
    use: {
        loader: "file-loader",
        // 写法一
        options: {
            name: "img/[name].[hash:8].[ext]"
        }
        // 写法二
        /*
        options: {
            name: "img/[name].[hash:8].[ext]",
            outputPath: "img"
        }
        */
    }
}

url-loader

url-loaderfile-loader的工作方式是相似的,但是可以将较小的文件,转成base64的URI。

安装url-loader

npm install url-loader -D

配置url-loader

// webpack.config.js -> modules -> rules
{
    test: /\.(png|jpe?g|gif|svg)$/i,
    use: {
        loader: "url-loader",
        options: {
            limit: 100 * 1024, // 仅将100Kb一下的图片转换为base64
            name: "[name].[hash:8].[ext]",
            outputPath: "img"
        }
    }
}

asset module type

介绍

在webpack5之前,加载非javascriptjson资源我们需要使用一些loader,比如raw-loader 、url-loader、file-loader。 在webpack5之后,我们可以直接使用资源模块类型(asset module type),来替代上面的这些loader。

资源模块类型(asset module type),通过添加 4 种新的模块类型,来替换所有这些 loader:

  • passet/resource 发送一个单独的文件并导出 URL。之前通过使用 file-loader 实现
  • passet/inline 导出一个资源的 data URI。之前通过使用 url-loader 实现
  • passet/source 导出资源的源代码。之前通过使用 raw-loader 实现
  • passet 在导出一个 data URI 和发送一个单独的文件之间自动选择。之前通过使用 url-loader,并且配置资源 体积限制实现

使用

使用asset module type我们可以在rules中配置:

// webpack.config.js -> module -> rules
{
    test: /\.(png|jpe?g|svg|gif)$/i,
    type: "asset/resource"
}

自定义文件输出路径和文件名:

// webpack.config.js -> output

// 方法一
output: {
    filename: "js/bundle.js",
    path:path.resolve(__dirname,"./dist"),
    assetModuleFilename: "img/[name].[hash:6][ext]"
}
// webpack.config.js -> module -> rules

// 方法二 在rule中添加一个generator属性并设置filename
{
    test: /\.(png|jpe?g|svg|gif)$/i,
    type: "asset/resource",
    generator: {
        filename: "img/[name].[hash:6][ext]"
    }
    // 实现 limit效果
    /*
    parser: {
        dataUrlCondition: {
            maxSize: 100 * 1024
        }
    }
    */
}

处理字体文件,用webpack5中的asset/resource来替代file-loader

// // webpack.config.js -> module -> rules
{
    test: /\.(woff2?|eot|ttf)$/i,
    type: "asset/resource",
    generator: {
        filename: "font/[name].[hash:6][ext]"
    }
}