1. 提取 Css 成单独文件(MiniCssExtractPlugin)

  • Css 文件目前被打包到 js 文件中,当 js 文件加载时,会创建一个 style 标签来生成样式

  • 这样对于网站来说,会出现闪屏现象,用户体验不好

  • 我们应该是单独的 Css 文件,通过 link 标签加载性能才好

闪屏现象如下:

image

这时我们就用到一个插件MiniCssExtractPlugin该插件会将 CSS 提取到单独的文件中,为每个包含 CSSJS 文件创建一个 CSS 文件,并且支持 CSSSourceMaps 的按需加载。

使用方法:

1.下载包

npm i mini-css-extract-plugin -D

2.配置webpack.prod.js(将所有的style-loder改成MiniCssExtractPlugin.loader)

// 使用的是commonjs 的语法格式[node.js]
const path = require("path");//node.js中的核心模块,专门用于处理路径问题
// 引入eslint
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
// 引入HtmlWebpackPlugin插件
const HtmlWebpackPlugin = require("html-webpack-plugin");
// 引入MiniCssExtractPlugin插件
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
// 入口
// 相对路径和绝对路径都行
entry:"./src/main.js",//相对路径
// 输出
output:{
// 所有文件的输出目录,必须是绝对路径
// path.resolve()方法返回一个绝对路径
// __dirname为node.js中的变量,代表当前文件的文件夹名(就是这个文件夹的webpack_code)
path: path.resolve(__dirname , "../dist"),//相较于开发模式,生产模式需要输出
// js文件(入口文件)输出的文件名(打包后在输出路径当中生成的文件夹名)
filename:"static/js/main.js",//所以我们这里改成js资源就输出到一个js文件夹当中
clean: true,//需要输出就需要clean(自动清空上次打包内容) 原理:在打包前,将path整个目录内容清空,在进行打包
},
// 加载器
module:{
rules:[
// loder的配置
// 1.处理css资源
{
// 用来匹配 .css 结尾的文件
test: /\.css$/,
// use 数组里面 Loader 执行顺序是从右到左
use: [
// *************************************************************************
MiniCssExtractPlugin.loader, //将style-loder改成MiniCssExtractPlugin.loader
// ************************************************************************
"css-loader"//将css资源编译成common.js的模块到js当中
],
},
// 2.处理less资源
{
test: /\.less$/,
// loader:xxx => 自能使用一个loader
use: [
// *************************************************************************
MiniCssExtractPlugin.loader, //将style-loder改成MiniCssExtractPlugin.loader
// ************************************************************************
"css-loader",
"less-loader"//将less编译成css文件
], // use能够使用多个loader
},
// 3.处理图片资源
{
test: /\.(png|jpe?g|gif|webp)$/,//正则判断图片后缀
type: "asset",
parser:{
dataUrlCondition:{
// 将小于10kb的图片转化为base64
// 优点:减小请求数量 缺点:原图片的体积会变大(故大体积突变不会使用这种方法)
maxSize: 10*1024//10kb(大体积图片不会使用这种方法)
}
},
generator: {
// 将图片文件输出到 static/imgs 目录中
// 将图片文件命名 [hash:8][ext][query]
// [hash:8]: hash值取8位
// [ext]: 使用之前的文件扩展名
// [query]: 添加之前的query参数
filename: 'static/imgs/[hash:8][ext][query]'
}
},
// 4.处理字体资源
{
test: /\.(ttf|woff2?)$/,
type: "asset/resource",//这里的是改成"asset/resource"
generator: {
filename: "static/media/[hash:8][ext][query]",
},
},
// 配置babel**********************************************************
{
test: /\.js$/,//检查匹配以js结尾的文件
exclude: /node_modules/, // 排除node_modules代码不编译
loader: "babel-loader",
},
// *******************************************************************
],
},
// 插件
plugins:[
// plugin的配置

// eslint配置
new ESLintWebpackPlugin({
// 指定检查文件的根目录(src目录下的所有文件的语法)
context: path.resolve(__dirname, "../src"),
}),

// HtmlWebpackPlugin配置*******************************************************
new HtmlWebpackPlugin({
// 以 public/index.html 为模板创建文件
// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源
template: path.resolve(__dirname, "../public/index.html"),
}),
// ****************************************************************************

// 提取css成单独文件
new MiniCssExtractPlugin({
// 定义输出文件名和输出路径
filename: "static/css/main.css",
}),
],
/*
生产模式不需要开发服务器(devServer)
*/
// 模式
mode:"production"//生产模式
};

3. 运行指令

npm run build

npx webpack --config ./config/webpack.prod.js

结果展示:

image

2.Css 兼容性处理

  • 之前我们使用babel来处理js的样式兼容性问题,但是css样式同样是存在兼容性问题的,这里我们选择postcss-loader来处理

  • 官方文档

使用方法:

1. 下载包

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

2. 配置webpack.prod.js(封装loader函数)

// 使用的是commonjs 的语法格式[node.js]
const path = require("path");//node.js中的核心模块,专门用于处理路径问题
// 引入eslint
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
// 引入HtmlWebpackPlugin插件
const HtmlWebpackPlugin = require("html-webpack-plugin");
// 引入MiniCssExtractPlugin插件
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

/* 封装loader函数 */
// 设置一个函数用来获取样式处理的loader(提高代码复用率)
function getStyleLoader(pre){//pre为其他的loader,如less-loader
return [
// *************************************************************************
MiniCssExtractPlugin.loader, //将style-loder改成MiniCssExtractPlugin.loader
// ************************************************************************
"css-loader",//将css资源编译成common.js的模块到js当中

// postcss-loader处理css样式的兼容性问题(放在cssloder后面,lessloder前面)*****
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
"postcss-preset-env", // 能解决大多数样式兼容性问题
],
},
},
},
// ************************************************************************
pre,
].filter(Boolean)//设置一个布尔值的filter来过滤掉undefined(存css样式不需要pre[即其他的loader])
}

module.exports = {
// 入口
// 相对路径和绝对路径都行
entry:"./src/main.js",//相对路径
// 输出
output:{
// 所有文件的输出目录,必须是绝对路径
// path.resolve()方法返回一个绝对路径
// __dirname为node.js中的变量,代表当前文件的文件夹名(就是这个文件夹的webpack_code)
path: path.resolve(__dirname , "../dist"),//相较于开发模式,生产模式需要输出
// js文件(入口文件)输出的文件名(打包后在输出路径当中生成的文件夹名)
filename:"static/js/main.js",//所以我们这里改成js资源就输出到一个js文件夹当中
clean: true,//需要输出就需要clean(自动清空上次打包内容) 原理:在打包前,将path整个目录内容清空,在进行打包
},
// 加载器
module:{
rules:[
// loder的配置
// 1.处理css资源
{
// 用来匹配 .css 结尾的文件
test: /\.css$/,
// use 数组里面 Loader 执行顺序是从右到左
use: getStyleLoader()
},
// 2.处理less资源
{
test: /\.less$/,
// loader:xxx => 自能使用一个loader
use: getStyleLoader("less-loader")
},
// 3.处理图片资源
{
test: /\.(png|jpe?g|gif|webp)$/,//正则判断图片后缀
type: "asset",
parser:{
dataUrlCondition:{
// 将小于10kb的图片转化为base64
// 优点:减小请求数量 缺点:原图片的体积会变大(故大体积突变不会使用这种方法)
maxSize: 10*1024//10kb(大体积图片不会使用这种方法)
}
},
generator: {
// 将图片文件输出到 static/imgs 目录中
// 将图片文件命名 [hash:8][ext][query]
// [hash:8]: hash值取8位
// [ext]: 使用之前的文件扩展名
// [query]: 添加之前的query参数
filename: 'static/imgs/[hash:8][ext][query]'
}
},
// 4.处理字体资源
{
test: /\.(ttf|woff2?)$/,
type: "asset/resource",//这里的是改成"asset/resource"
generator: {
filename: "static/media/[hash:8][ext][query]",
},
},
// 配置babel**********************************************************
{
test: /\.js$/,//检查匹配以js结尾的文件
exclude: /node_modules/, // 排除node_modules代码不编译
loader: "babel-loader",
},
// *******************************************************************
],
},
// 插件
plugins:[
// plugin的配置

// eslint配置
new ESLintWebpackPlugin({
// 指定检查文件的根目录(src目录下的所有文件的语法)
context: path.resolve(__dirname, "../src"),
}),

// HtmlWebpackPlugin配置*******************************************************
new HtmlWebpackPlugin({
// 以 public/index.html 为模板创建文件
// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源
template: path.resolve(__dirname, "../public/index.html"),
}),
// ****************************************************************************

// 提取css成单独文件
new MiniCssExtractPlugin({
// 定义输出文件名和输出路径
filename: "static/css/main.css",
}),
],
/*
生产模式不需要开发服务器(devServer)
*/
// 模式
mode:"production"//生产模式
};

3. 控制兼容性

  • 我们可以在 package.json 文件中添加 browserslist 来控制样式的兼容性做到什么程度。
{
// 其他省略
"browserslist": ["ie >= 8"]
}
  • 想要知道更多的 browserslist 配置,查看browserslist 文档

  • 以上为了测试兼容性所以设置兼容浏览器 ie8 以上。

  • 实际开发中我们一般不考虑旧版本浏览器了,所以我们可以这样设置:

{
// 其他省略
"browserslist": [//(以下三者取的是交集)
"last 2 version", //只需要浏览器最近的两个版本
"> 1%", //覆盖市面上99%的浏览器
"not dead"//浏览器发展过程中遗弃的版本不要
]
}

3.Css 压缩

使用方法:

  1. 下载包
npm i css-minimizer-webpack-plugin -D
  1. 配置webpack.prod.js
// 使用的是commonjs 的语法格式[node.js]
const path = require("path");//node.js中的核心模块,专门用于处理路径问题
// 引入eslint
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
// 引入HtmlWebpackPlugin插件
const HtmlWebpackPlugin = require("html-webpack-plugin");
// 引入MiniCssExtractPlugin插件
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
// 引入CssMinimizerPlugin插件
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");

// 设置一个函数用来获取样式处理的loader(提高代码复用率)
function getStyleLoader(pre){//pre为其他的loader,如less-loader
return [
// *************************************************************************
MiniCssExtractPlugin.loader, //将style-loder改成MiniCssExtractPlugin.loader
// ************************************************************************
"css-loader",//将css资源编译成common.js的模块到js当中

// postcss-loader处理css样式的兼容性问题(放在cssloder后面,lessloder前面)*****
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
"postcss-preset-env", // 能解决大多数样式兼容性问题
],
},
},
},
// ************************************************************************
pre,
].filter(Boolean)//设置一个布尔值的filter来过滤掉undefined(存css样式不需要pre[即其他的loader])
}

module.exports = {
// 入口
// 相对路径和绝对路径都行
entry:"./src/main.js",//相对路径
// 输出
output:{
// 所有文件的输出目录,必须是绝对路径
// path.resolve()方法返回一个绝对路径
// __dirname为node.js中的变量,代表当前文件的文件夹名(就是这个文件夹的webpack_code)
path: path.resolve(__dirname , "../dist"),//相较于开发模式,生产模式需要输出
// js文件(入口文件)输出的文件名(打包后在输出路径当中生成的文件夹名)
filename:"static/js/main.js",//所以我们这里改成js资源就输出到一个js文件夹当中
clean: true,//需要输出就需要clean(自动清空上次打包内容) 原理:在打包前,将path整个目录内容清空,在进行打包
},
// 加载器
module:{
rules:[
// loder的配置
// 1.处理css资源
{
// 用来匹配 .css 结尾的文件
test: /\.css$/,
// use 数组里面 Loader 执行顺序是从右到左
use: getStyleLoader()
},
// 2.处理less资源
{
test: /\.less$/,
// loader:xxx => 自能使用一个loader
use: getStyleLoader("less-loader")
},
// 3.处理图片资源
{
test: /\.(png|jpe?g|gif|webp)$/,//正则判断图片后缀
type: "asset",
parser:{
dataUrlCondition:{
// 将小于10kb的图片转化为base64
// 优点:减小请求数量 缺点:原图片的体积会变大(故大体积突变不会使用这种方法)
maxSize: 10*1024//10kb(大体积图片不会使用这种方法)
}
},
generator: {
// 将图片文件输出到 static/imgs 目录中
// 将图片文件命名 [hash:8][ext][query]
// [hash:8]: hash值取8位
// [ext]: 使用之前的文件扩展名
// [query]: 添加之前的query参数
filename: 'static/imgs/[hash:8][ext][query]'
}
},
// 4.处理字体资源
{
test: /\.(ttf|woff2?)$/,
type: "asset/resource",//这里的是改成"asset/resource"
generator: {
filename: "static/media/[hash:8][ext][query]",
},
},
// 配置babel**********************************************************
{
test: /\.js$/,//检查匹配以js结尾的文件
exclude: /node_modules/, // 排除node_modules代码不编译
loader: "babel-loader",
},
// *******************************************************************
],
},
// 插件
plugins:[
// plugin的配置

// eslint配置
new ESLintWebpackPlugin({
// 指定检查文件的根目录(src目录下的所有文件的语法)
context: path.resolve(__dirname, "../src"),
}),

// HtmlWebpackPlugin配置*******************************************************
new HtmlWebpackPlugin({
// 以 public/index.html 为模板创建文件
// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源
template: path.resolve(__dirname, "../public/index.html"),
}),
// ****************************************************************************

// 提取css成单独文件
new MiniCssExtractPlugin({
// 定义输出文件名和输出路径
filename: "static/css/main.css",
}),
// css压缩************************************************************************
new CssMinimizerPlugin(),
// ******************************************************************************
],
/*
生产模式不需要开发服务器(devServer)
*/
// 模式
mode:"production"//生产模式
};
  1. 运行指令
npm run build

npx webpack --config ./config/webpack.prod.js

4. html 压缩

  • 默认生产模式已经开启了:html 压缩和 js 压缩, 不需要额外进行配置

5. webpack的基础总结:

  1. 两种开发模式
  • 开发模式:代码能编译自动化运行
  • 生产模式:代码编译优化输出
  1. Webpack 基本功能
  • 开发模式:可以编译 ES Module 语法
  • 生产模式:可以编译 ES Module 语法,压缩 js 代码
  1. Webpack 配置文件
  • 5 个核心概念
    • entry
    • output
    • loader
    • plugins
    • mode
  • devServer 配置
  1. Webpack 脚本指令用法
  • webpack 直接打包输出
  • webpack serve 启动开发服务器,内存编译打包没有输出