一、将css打包到单独的文件


如上图:
Css 文件目前被打包到 js 文件中,当 js 文件加载时,会创建一个 style 标签来生成样式
这样对于网站来说,如果网络比较慢的话会出现闪屏现象,用户体验不好

我们去控制台将往速调慢,然后运行打包好的index.html文件

如图:


会出现一段闪屏现象。

我们应该是单独的 Css 文件,通过 link 标签加载性能才好
想要实现link自动引入,我们需要借助webpack的miniCssExtractPlugin插件
具体配置步骤如下:

官网教程 https://webpack.docschina.org/plugins/mini-css-extract-plugin/

1. 下载依赖

npm i mini-css-extract-plugin -D

2. 配置

const MiniCssExtractPlugin = require("mini-css-extract-plugin");module.exports = {plugins: [ // 提取css成单独文件new MiniCssExtractPlugin({// 定义输出文件名和目录filename: "css/main.css",})],module: {rules: [{test: /\.css$/i,use: [MiniCssExtractPlugin.loader, "css-loader"],},],},};

在以前的章节中,我们配置过的生产环境的打包文件,webpack.prod.js
咱将上面的配置添加到生产配置中,完整代码如下:

// Node.js的核心模块,专门用来处理文件路径const path = require("path");const ESLintWebpackPlugin = require("eslint-webpack-plugin"); // 引入 ESLint 插件const HtmlWebpackPlugin = require("html-webpack-plugin"); // 引入 html-webpack-plugin 插件const MiniCssExtractPlugin = require("mini-css-extract-plugin"); // 引入 mini-css-extract-plugin 插件module.exports = {// 入口// 相对路径和绝对路径都行entry: "./src/main.js",// 输出output: {// path: 文件输出目录,必须是绝对路径// path.resolve()方法返回一个绝对路径// __dirname 当前文件的文件夹绝对路径path: path.resolve(__dirname, "../dist"),// filename: js文件输出文件名filename: "js/main.js",clean: true, // 自动将上次打包目录资源清空},// 加载器module: {rules: [{// 用来匹配 .css 结尾的文件test: /\.css$/,// use 数组里面 Loader 执行顺序是从右到左use: [MiniCssExtractPlugin.loader, "css-loader"],},{// 用来匹配.less结尾的文件test: /\.less$/,use: [MiniCssExtractPlugin.loader, "css-loader", "less-loader"],},{test: /\.s[ac]ss$/,use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],},{// 用来匹配图片文件test: /\.(png|jpe" />/,type: "asset",parser: {dataUrlCondition: {maxSize: 10 * 1024, // 小于10kb的图片会被base64处理},},generator: {// 将图片文件输出到 images 目录中// 将图片文件命名 [hash:8][ext][query]// [hash:8]: hash值取8位// [ext]: 使用之前的文件扩展名// [query]: 添加之前的query参数filename: "images/[hash:8][ext][query]",},},{test: /\.(ttf|woff2?|map4|map3|avi)$/,type: "asset/resource", // 以文件资源的形式输出generator: {filename: "media/[hash:8][ext][query]", // 输出到media目录中},},{test: /\.m?js$/, // 转译哪些文件exclude: /(node_modules|bower_components)/, // 排除哪些文件夹中的js文件不用转译// use: {loader: 'babel-loader',// options: {// presets: ['@babel/preset-env'] // 添加预设,转译js文件// }// }}],},// 插件plugins: [new ESLintWebpackPlugin({// 指定检查文件的根目录context: path.resolve(__dirname, "../src"),}),new HtmlWebpackPlugin({// 以 public/index.html 为模板创建文件// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源template: path.resolve(__dirname, "../public/index.html"),}),// 提取css成单独文件new MiniCssExtractPlugin({// 定义输出文件名和目录filename: "css/main.css",}),],// 模式mode: "production", // 生产模式};

⚠️ 注意如果你从 webpack 入口处导入CSS 或者在 初始 chunk 中引入 style, mini-css-extract-plugin 则不会将这些CSS 加载到页面中。请使用 html-webpack-plugin 自动生成 link 标签或者在创建 index.html 文件时使用 link 标签。

3. 执行打包

配置好之后运行npm run build打生产环境的包

如图,css文件已经被处理成了单独的文件了。

二、css兼容性处理

兼容性在以前一直是个比较令大家头疼的事情,尤其是那时候还得兼容IE,webpack肯定是考虑到了这些,实现样式兼容性,我们需要借助几个loader

1. 下载安装

npm i postcss-loader postcss postcss-preset-env -D

2. 配置webpack.prod.js

module: {rules: [{// 用来匹配 .css 结尾的文件test: /\.css$/,// use 数组里面 Loader 执行顺序是从右到左use: [MiniCssExtractPlugin.loader,"css-loader",{loader: "postcss-loader",options: {postcssOptions: {plugins: ["postcss-preset-env", // 能解决大多数样式兼容性问题],},},},],}, ]

由于咱的配置中多处用到了上面的loader,所以我们将其抽离成一个函数:

// 获取处理样式的Loadersconst getStyleLoaders = (preProcessor) => {return [MiniCssExtractPlugin.loader,"css-loader",{loader: "postcss-loader",options: {postcssOptions: {plugins: ["postcss-preset-env", // 能解决大多数样式兼容性问题],},},},preProcessor,].filter(Boolean);};

完整的配置代码:

  • webpack.prod.js
// Node.js的核心模块,专门用来处理文件路径const path = require("path");const ESLintWebpackPlugin = require("eslint-webpack-plugin"); // 引入 ESLint 插件const HtmlWebpackPlugin = require("html-webpack-plugin"); // 引入 html-webpack-plugin 插件const MiniCssExtractPlugin = require("mini-css-extract-plugin"); // 引入 mini-css-extract-plugin 插件// 获取处理样式的Loadersconst getStyleLoaders = (preProcessor) => {return [MiniCssExtractPlugin.loader,"css-loader",{loader: "postcss-loader",options: {postcssOptions: {plugins: ["postcss-preset-env", // 能解决大多数样式兼容性问题],},},},preProcessor,].filter(Boolean);};module.exports = {// 入口// 相对路径和绝对路径都行entry: "./src/main.js",// 输出output: {// path: 文件输出目录,必须是绝对路径// path.resolve()方法返回一个绝对路径// __dirname 当前文件的文件夹绝对路径path: path.resolve(__dirname, "../dist"),// filename: js文件输出文件名filename: "js/main.js",clean: true, // 自动将上次打包目录资源清空},// 加载器module: {rules: [{// 用来匹配 .css 结尾的文件test: /\.css$/,// use 数组里面 Loader 执行顺序是从右到左use: getStyleLoaders(),},{// 用来匹配.less结尾的文件test: /\.less$/,use: getStyleLoaders("less-loader"),},{test: /\.s[ac]ss$/,use: getStyleLoaders("sass-loader"),},{// 用来匹配图片文件test: /\.(png|jpe" />/,type: "asset",parser: {dataUrlCondition: {maxSize: 10 * 1024, // 小于10kb的图片会被base64处理},},generator: {// 将图片文件输出到 images 目录中// 将图片文件命名 [hash:8][ext][query]// [hash:8]: hash值取8位// [ext]: 使用之前的文件扩展名// [query]: 添加之前的query参数filename: "images/[hash:8][ext][query]",},},{test: /\.(ttf|woff2?|map4|map3|avi)$/,type: "asset/resource", // 以文件资源的形式输出generator: {filename: "media/[hash:8][ext][query]", // 输出到media目录中},},{test: /\.m?js$/, // 转译哪些文件exclude: /(node_modules|bower_components)/, // 排除哪些文件夹中的js文件不用转译// use: {loader: 'babel-loader',// options: {// presets: ['@babel/preset-env'] // 添加预设,转译js文件// }// }}],},// 插件plugins: [new ESLintWebpackPlugin({// 指定检查文件的根目录context: path.resolve(__dirname, "../src"),}),new HtmlWebpackPlugin({// 以 public/index.html 为模板创建文件// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源template: path.resolve(__dirname, "../public/index.html"),}),// 提取css成单独文件new MiniCssExtractPlugin({// 定义输出文件名和目录filename: "css/main.css",}),],// 模式mode: "production", // 生产模式};

3. 控制兼容性

我们可以在 package.json 文件中添加browserslist来控制样式的兼容性做到什么程度。

{// 其他省略"browserslist": ["ie >= 8"]}

想要知道更多的 browserslist 配置,查看browserslist 文档
以上为了测试兼容性所以设置兼容浏览器 ie8 以上。
实际开发中我们一般不考虑旧版本浏览器了,所以我们可以这样设置:

{// 其他省略"browserslist": ["last 2 version", "> 1%", "not dead"]}

4. 执行打包

npm run build


如上图自动为我们加上了兼容性
到这里兼容性的配置就完成了

三、 css压缩


如图,这是目前打包生成的main.css文件,并没有为我们压缩处理,想要压缩,我们需要借助css-minimizer-webpack-plugin插件,配置步骤如下:

1. 下载安装

npm i css-minimizer-webpack-plugin -D

2. 配置

用法很简单,引入,然后在plugin配置对象中添加就可以了
完整代码如下:

// Node.js的核心模块,专门用来处理文件路径const path = require("path");const ESLintWebpackPlugin = require("eslint-webpack-plugin"); // 引入 ESLint 插件const HtmlWebpackPlugin = require("html-webpack-plugin"); // 引入 html-webpack-plugin 插件const MiniCssExtractPlugin = require("mini-css-extract-plugin"); // 引入 mini-css-extract-plugin 插件const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");// 获取处理样式的Loadersconst getStyleLoaders = (preProcessor) => {return [MiniCssExtractPlugin.loader,"css-loader",{loader: "postcss-loader",options: {postcssOptions: {plugins: ["postcss-preset-env", // 能解决大多数样式兼容性问题],},},},preProcessor,].filter(Boolean);};module.exports = {// 入口// 相对路径和绝对路径都行entry: "./src/main.js",// 输出output: {// path: 文件输出目录,必须是绝对路径// path.resolve()方法返回一个绝对路径// __dirname 当前文件的文件夹绝对路径path: path.resolve(__dirname, "../dist"),// filename: js文件输出文件名filename: "js/main.js",clean: true, // 自动将上次打包目录资源清空},// 加载器module: {rules: [{// 用来匹配 .css 结尾的文件test: /\.css$/,// use 数组里面 Loader 执行顺序是从右到左use: getStyleLoaders(),},{// 用来匹配.less结尾的文件test: /\.less$/,use: getStyleLoaders("less-loader"),},{test: /\.s[ac]ss$/,use: getStyleLoaders("sass-loader"),},{// 用来匹配图片文件test: /\.(png|jpe" />/,type: "asset",parser: {dataUrlCondition: {maxSize: 10 * 1024, // 小于10kb的图片会被base64处理},},generator: {// 将图片文件输出到 images 目录中// 将图片文件命名 [hash:8][ext][query]// [hash:8]: hash值取8位// [ext]: 使用之前的文件扩展名// [query]: 添加之前的query参数filename: "images/[hash:8][ext][query]",},},{test: /\.(ttf|woff2?|map4|map3|avi)$/,type: "asset/resource", // 以文件资源的形式输出generator: {filename: "media/[hash:8][ext][query]", // 输出到media目录中},},{test: /\.m?js$/, // 转译哪些文件exclude: /(node_modules|bower_components)/, // 排除哪些文件夹中的js文件不用转译// use: {loader: 'babel-loader',// options: {// presets: ['@babel/preset-env'] // 添加预设,转译js文件// }// }}],},// 插件plugins: [new ESLintWebpackPlugin({// 指定检查文件的根目录context: path.resolve(__dirname, "../src"),}),new HtmlWebpackPlugin({// 以 public/index.html 为模板创建文件// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源template: path.resolve(__dirname, "../public/index.html"),}),// 提取css成单独文件new MiniCssExtractPlugin({// 定义输出文件名和目录filename: "css/main.css",}),// css压缩new CssMinimizerPlugin(),],// 模式mode: "production", // 生产模式};

3. 打包

npm run build

效果如图,可以看到已经帮我们压缩处理了css文件

这就是本章的内容拉,webpack处理css文件打包到单独的文件、压缩、以及兼容性处理