webpack处理CSS文件,打包到单独的文件、压缩、以及兼容性处理

一、将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?g|gif|webp)$/,
        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,所以我们将其抽离成一个函数:

// 获取处理样式的Loaders
const 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 插件

// 获取处理样式的Loaders
const 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?g|gif|webp)$/,
        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");

// 获取处理样式的Loaders
const 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?g|gif|webp)$/,
        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文件打包到单独的文件、压缩、以及兼容性处理

猜你喜欢

转载自blog.csdn.net/jieyucx/article/details/131204328