前言
前面完成了webpack5配置中的基本配置,包括html的渲染,运行和打包命令,开发环境的基本配置,接下来就是css加载的配置了。
css加载
webpack运行环境是在node,而node环境下打包只能处理js文件间的依赖,对于.css这类后缀的文件,由于不是一个js模块,那就需要特殊的工具进行处理,也就是loader。
而传统引入css文件的方式,都是通过在 html 写上对应的标签进行加载资源,如:<style>
。
css加载方式介绍
style标签方式
使用这种方式需要使用到css-loader和style-loader,那么就下载一下依赖吧
npm i -D css-loader style-loader
- css-loader的作用,是用来识别并加载css
- style-loader的作用,是用来将css转化为html的style节点。
下载好依赖之后,在webpack.config.js文件中增加module属性,配置如下:
module.exports = {
...
module: {
rules: [
{
test: /\.css$/,
// use: ["style-loader", "css-loader"]
use: [
{ loader: "style-loader" },
{
loader: "css-loader",
options: {
modules: true // 启用/禁用 CSS 模块及其配置
}
}
]
}
]
}
}
顺便提醒一下,loader的加载顺序是从右到左(从下到上)
在src下创建css文件夹,并创建一个css文件---index.css,内容如下
// src/css/index.css
body {
background: pink;
}
执行编译之后,页面控制台内容如下图:
页面展示如下图:
那么,再执行一下打包命令看看:
发现,在html中,并没有出现style标签,然后,在打包好的js文件中,发现了这么一句:
...
s.push([e.id,"body {\r\n background-color: pink;\r\n}\r\n",""]),
不难发现,这就是我们在css文件中写下的样式代码,这就说明,<style>
标签实际上是js动态插入的。
独立css文件方式
除了传统的style标签引入,我们还可以使用独立css文件的方式,这样的好处就是,css的文件是独立,做到了样式文件分离的目的。使用这种方式,则不需要下载style-loader依赖,需要用到的插件则是mini-css-extract-plugin,这个插件的作用,便是提取css到单独的文件中了。
webpack.config.js文件配置修改如下:
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
plugins: [
...
new MiniCssExtractPlugin()
],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"]
}
]
}
};
运行打包命令后,会生成一个css文件在指定的打包文件夹下。
然,此时的css文件是没有压缩的,那么,在打包时候,也要对css文件进行压缩打包,不过,开发环境不需要,所以压缩css的配置,便不用在公共config配置中。
css压缩
插件:css-minimizer-webpack-plugin。
// webpack.config.prod.js
module.exports = merge(config, {
mode: "production",
...
optimization: {
minimizer: [new CssMinimizerPlugin()]
}, // 优化
devServer: {
compress: true
}
});
再次运行打包命令,会发现,css文件被压缩了。然后,此时又会发现,js文件没有被压缩了,因为,我们覆盖了默认压缩行为。查看官方文档会发现这么一句话:在
optimization.minimizer中可以使用
'...' 来访问默认值
,那么,我们也加上,再次运行打包命令,此时,js文件和css文件均压缩了。
// webpack.config.prod.js
module.exports = merge(config, {
mode: "production",
...
optimization: {
minimizer: [new CssMinimizerPlugin(), "..."]
}, // 优化
devServer: {
compress: true
}
});
在日常开发中,在写css的时候,相信大部分人都是使用sass或者less,而webpack自身也是无法解析这两类文件的,此时,我们需要新的方法来解决这个问题(以sass为例)。
加载scss,sass
安装 sass sass-loader
修改webpack.config.js配置
module.exports = {
plugins: [
...
new MiniCssExtractPlugin()
],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"]
},
{
test: /\.s[ac]ss$/i,
use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"]
}
]
}
};
运行打包命令后,会发现,在css文件中,出现了新的css样式
后续如果使用像less之类的,配置方式差不多是一样的啦。
指定打包文件夹
至此,基本的配置就完成了。但是,css并没有像js那样有独立的文件夹,这个可以配置吗?答案当然是可以的啦。
// webpack.config.js
new MiniCssExtractPlugin({
filename: "css/[name].[fullhash].css"
})
// webpack.config.prod.js
output: {
filename: "js/[name].[hash].js",
path: path.resolve(__dirname, "../dist_prod"), // 指定打包文件夹
clean: true // 磁盘空间会存有打包后的资源,在再次打包的时候,我们需要先把本地已有的打包后的资源清空,来减少它们对磁盘空间的占用
},
像这样,在filename前加上文件夹名,可以实现文件分类到不同的文件夹。
展示完整代码
目录
main.js文件
import "./index.js";
import "./css/index.css";
import "./scss/index.scss";
console.log(process.env.NODE_ENV);
webpack.config.js
// webpack.config.js
const webpack = require("webpack");
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
entry: path.resolve(__dirname, "../src/main.js"), // path.resolve 方法用于生成绝对路径
plugins: [
new webpack.LoaderOptionsPlugin({
// test: /\.xxx$/, // may apply this only for some modules
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "../public/index.html"), // 指定要编译的文件,不指定的话会按照默认的模板创建一个html
title: "webpack练习",
filename: "index.html" // 编译完成输出的文件名
}),
new MiniCssExtractPlugin({
filename: "css/[name].[fullhash].css"
})
],
module: {
rules: [
// {
// test: /\.css$/,
// // use: ["style-loader", "css-loader"]
// use: [
// { loader: "style-loader" },
// {
// loader: "css-loader",
// options: {
// modules: true // 启用/禁用 CSS 模块及其配置
// }
// }
// ]
// }
// loader,源码预处理器
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"]
},
{
test: /\.s[ac]ss$/i,
use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"]
}
]
}
};
webpack.config.prod.js
const { merge } = require("webpack-merge");
const config = require("./webpack.config");
const path = require("path");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
module.exports = merge(config, {
mode: "production",
output: {
filename: "js/[name].[hash].js",
path: path.resolve(__dirname, "../dist_prod"), // 指定打包文件夹
clean: true // 磁盘空间会存有打包后的资源,在再次打包的时候,我们需要先把本地已有的打包后的资源清空,来减少它们对磁盘空间的占用
},
optimization: {
minimizer: [new CssMinimizerPlugin(), "..."]
}, // 优化
devServer: {
compress: true
}
});
webpack.config.dev.js
const { merge } = require("webpack-merge");
const config = require("./webpack.config");
const path = require("path");
module.exports = merge(config, {
mode: "development",
devServer: {
port: 8080, // 端口号
hot: true //文件修改自动刷新
}
});