提取 css 文件及处理
大约 3 分钟
提取 css 文件及处理
在 js 中提取 css
css 文件目前被打包到 js 文件中,当 js 文件加载时,会动态创建一个 style 标签来生成样式
这样对于网站来说,会出现闪屏现象,用户体验不好
我们应该是单独的 css 文件通过 link 标签加载性能才好
1. 下载包
npm install mini-css-extract-plugin -D
2. 配置
- webpack.prod.js
const path = require("path") const ESlintPlugin = require('eslint-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin') const MiniCssExtractPlugin = require('mini-css-extract-plugin') module.exports = { entry: "./src/main.js", output: { path: path.resolve(__dirname, "../dist"), filename: "static/js/main.js", }, module: { rules: [ /** * 将所有的 style-loader 改为 MiniCssExtractPlugin.loader * MiniCssExtractPlugin.loader 可以提取 css 成单独文件 */ { test: /\.css$/i, use: [MiniCssExtractPlugin.loader, "css-loader"] }, { test: /\.less$/i, use: [MiniCssExtractPlugin.loader, "css-loader", "less-loader"] }, { test: /\.s[ac]ss$/i, use: [MiniCssExtractPlugin.loader, "css-loader", "less-loader"] }, { test: /\.styl$/i, use: [MiniCssExtractPlugin.loader, "css-loader", "stylus-loader"] }, { test: /\.(png|jpe?g|gif|webp|svg)$/, type: "asset", parser: { dataUrlCondition: { maxSize: 600 * 1024, // 600kb } }, generator: { filename: "static/images/[hash:10][ext][query]", } }, { test: /\.(ttf|woff2|map3|map4|avi)$/, type: "asset/resource", generator: { filename: "static/media/[hash:10][ext][query]", } }, { test: /\.js$/, exclude: /node_modules/, / use: { loader: "babel-loader", } } ] }, plugins: [ new ESlintPlugin({ context: path.resolve(__dirname, "../src") }), new HtmlWebpackPlugin({ template: path.resolve(__dirname, "../public/index.html") }), new MiniCssExtractPlugin({ /** 指定输出文件路径和文件名 */ filename: "static/css/main.css" }) ], mode: "production", }
css 兼容性处理
1. 下载包
npm i postcss-loader postcss postcss-preset-env -D
2. 配置
- webpack.prod.js
const path = require("path") const ESlintPlugin = require('eslint-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin') const MiniCssExtractPlugin = require('mini-css-extract-plugin') module.exports = { entry: "./src/main.js", output: { path: path.resolve(__dirname, "../dist"), filename: "static/js/main.js", }, module: { rules: [ { test: /\.css$/i, use: [ MiniCssExtractPlugin.loader, "css-loader", { loader: "postcss-loader", options: { postcssOptions: { plugins: ["postcss-preset-env"] // 能解决大多数样式兼容性问题 } } } ] }, /** 这里注意顺序,less-loader 在后面 */ { test: /\.less$/i, use: [MiniCssExtractPlugin.loader, "css-loader", { loader: "postcss-loader", options: { postcssOptions: { plugins: ["postcss-preset-env"] // 能解决大多数样式兼容性问题 } } }, "less-loader", ] }, /** 这里注意顺序,sass-loader 在后面 */ { test: /\.s[ac]ss$/i, use: [MiniCssExtractPlugin.loader, "css-loader", { loader: "postcss-loader", options: { postcssOptions: { plugins: ["postcss-preset-env"] // 能解决大多数样式兼容性问题 } } }, "sass-loader" ] }, /** 这里注意顺序,stylus-loader 在后面 */ { test: /\.styl$/i, use: [MiniCssExtractPlugin.loader, "css-loader", { loader: "postcss-loader", options: { postcssOptions: { plugins: ["postcss-preset-env"] // 能解决大多数样式兼容性问题 } } }, "stylus-loader" ] }, { test: /\.(png|jpe?g|gif|webp|svg)$/, type: "asset", parser: { dataUrlCondition: { maxSize: 600 * 1024, // 600kb } }, generator: { filename: "static/images/[hash:10][ext][query]", } }, { test: /\.(ttf|woff2|map3|map4|avi)$/, type: "asset/resource", generator: { filename: "static/media/[hash:10][ext][query]", } }, { test: /\.js$/, exclude: /node_modules/, use: { loader: "babel-loader", } } ] }, plugins: [ new ESlintPlugin({ context: path.resolve(__dirname, "../src") }), new HtmlWebpackPlugin({ template: path.resolve(__dirname, "../public/index.html") }), new MiniCssExtractPlugin({ filename: "static/css/main.css" }) ], /** 生产模式 */ mode: "production", }
3. 控制兼容性
我们可以在
package.json
文件中添加browserslist
来控制样式的兼容性做到什么程度。
{
"browserslist": [
"ie >= 8"
]
}
了解更多的
browserslist
配置
以上为了测试兼容性所以设置兼容浏览器 ie8 以上。实际开发中我们一般不考虑旧版本浏览器了,所以我们可以这样设置
{
"browserslist": [
"last 2 version",
"> 1%",
"not dead"
]
}
4. 合并配置
const path = require("path")
const ESlintPlugin = require('eslint-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
/** 提取公共配置 */
function getStyleLoader(pre) {
return [
MiniCssExtractPlugin.loader, "css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: ["postcss-preset-env"] // 能解决大多数样式兼容性问题
}
}
},
pre
].filter(Boolean) // .filter(Boolean) 会将 pre 的值为 undefined 过滤掉
}
module.exports = {
entry: "./src/main.js",
output: {
path: path.resolve(__dirname, "../dist"),
filename: "static/js/main.js",
},
module: {
rules: [
{
test: /\.css$/i,
use: getStyleLoader()
},
{
test: /\.less$/i,
use: getStyleLoader("less-loader")
},
{
test: /\.s[ac]ss$/i,
use: getStyleLoader("sass-loader")
},
{
test: /\.styl$/i,
use: getStyleLoader("stylus-loader")
},
{
test: /\.(png|jpe?g|gif|webp|svg)$/,
type: "asset",
parser: {
dataUrlCondition: {
maxSize: 600 * 1024, // 600kb
}
},
generator: {
filename: "static/images/[hash:10][ext][query]",
}
},
{
test: /\.(ttf|woff2|map3|map4|avi)$/,
type: "asset/resource",
generator: {
filename: "static/media/[hash:10][ext][query]",
}
},
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
}
}
]
},
plugins: [
new ESlintPlugin({
context: path.resolve(__dirname, "../src")
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "../public/index.html")
}),
new MiniCssExtractPlugin({
filename: "static/css/main.css"
})
],
/** 生产模式 */
mode: "production",
}
css 压缩
1. 下载包
npm install css-minimizer-webpack-plugin -D
2. 配置
const CssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin')
module.exports = {
plugins: [
new CssMinimizerWebpackPlugin()
],
/** 生产模式 */
mode: "production",
}
html 压缩
默认生产模式已经开启了 html 压缩和 js 压缩
不需要额外进行配置