引入css后执行打包命令 "build": "npx webpack --config wk.config.js"
发现报错:
webpack默认只能处理js其他的像css,图片都需要借助loader来处理
css-loader
loader可以用于对模块的源代码进行转换,可以把css看成一个模块,模块可以通过import来加载,但是在加载模块时,webpack不知道如何对其进行加载,需要特定的loader完成这个功能。
npm i css-loader -D
const path = require("path");
module.exports = {entry: "./src/main.js",output: {filename: "bundle.js",path: path.resolve(__dirname, "./build"),},module: {rules: [{test: /\.css$/,use: [{loader:"css-loader"}],},],},
};
module.rules中允许我们配置多个loader.。rules对应的值是一个数组[rule],数组中存放多个rule,rule是一个对象,有多个属性:
test:用于对资源进行匹配,通常会设置成正则表达式
use:对应的值是一个数组[useEntry] useEntry是一个数组也有一些属性
- loader:必须要一个loader属性,对应的值是一个字符串。只有一个loader时可以简写 例如use:[“css-loader”]
- options:可选的属性,只是一个字符串或对象
- query:目前已经被options给替代
loader: use:[loader]的简写, 只有一个loader时也可以简写 loader:“css-loader”
简写:
//原来写法module: {rules: [{test: /\.css$/,use: [{loader:"css-loader"}],},],
// 简写1module: {rules: [{test: /\.css$/,loader:"css-loader"},],},
// 简写2module: {rules: [{test: /\.css$/,use:["csss-loader"]},],},
style-loader
css-loader只能解决不报错的问题,但是css样式并没有生效。这是因为css-loader只负责解析css,不会将解析后的css插入到页面中,需要通过style-loader把样式插入到页面中。
npm i style-loader -D
const path = require("path");
module.exports = {entry: "./src/main.js",output: {filename: "bundle.js",path: path.resolve(__dirname, "./build"),},module: {rules: [{test: /\.css$/,use: ["style-loader", "css-loader"],},],},
};
// use: ["style-loader", "css-loader"], 也可以写成 use: [{ loader: "css-loader" }, { loader: "css-loader" }],
loader的执行顺序是从后往前执行的
在index.html中引入打包后的文件,就可以在页面中看到效果
sass-loader 解析sass
npm i sass-loader -D
编写sass并引入文件
配置sass-loader
const path = require("path");
module.exports = {entry: "./src/main.js",output: {filename: "bundle.js",path: path.resolve(__dirname, "./build"),},module: {rules: [{test: /\.css$/,use: ["style-loader", "css-loader"],},{test: /\.scss$/,use: ["style-loader", "css-loader", "sass-loader"],},],},
};
postcss-loader
PostCSS是一个用JavaScript插件转换CSS的工具。它可以帮助开发人员处理CSS,包括自动添加浏览器前缀、CSS变量、嵌套规则、函数等
npm i postcss-loader -D
以 autoprefixer (会添加一些浏览器的前缀)为例
.
由于postcss-loader有很多配置项,所以使用对象的形式:
const path = require("path");
module.exports = {entry: "./src/main.js",output: {filename: "bundle.js",path: path.resolve(__dirname, "./build"),},module: {rules: [{test: /\.css$/,use: ["style-loader","css-loader",{loader: "postcss-loader",options: {postcssOptions: {plugins: ["autoprefixer"],//也有这种写法plugins: [require("autoprefixer")],现在可以省略require()},},},],},],},
};
结果:
由于postcss配置项太多,postcss通常单独抽离出一个文件postcss.config.js:
在webpack中就可以简写了:
const path = require("path");
module.exports = {entry: "./src/main.js",output: {filename: "bundle.js",path: path.resolve(__dirname, "./build"),},module: {rules: [{test: /\.css$/,use: ["style-loader", "css-loader", "postcss-loader"],},],},
};
“autoprefixer"只能自动添加浏览器前缀,postcss还有其他功能,因此实际开发中并不会安装"autoprefixer”,而是使用 postcss-preset-env它可以将一些现代的css特性转换为浏览器所识别的特性。npm i postcss-preset-env -D
处理资源模块
在webpack5之前 加载这些资源需要使用一些loader,例如raw-loader,url-loader等。
在webpack5之后,可以直接使用资源模块类型(asset module type)来代替上面这些loader。
资源模块的类型分为 asset/resource ,asset/inline,asset/source,asset。
asset/resource:发送一个单独的文件并导出url(之前通过file-loader来),如果有两个图片,在打包后会生成两个文件,这就意味着还要发送额外的请求。
const path = require("path");
module.exports = {entry: "./src/main.js",output: {filename: "bundle.js",path: path.resolve(__dirname, "./build"),},module: {rules: [{test: /\.(png|jpe?g|gif|svg)$/,type: "asset/resource",},],},
};
这里要注意图片也要当作一个模块来导入
执行命令后可以看到打包后的结果:
asset/inline:将图片进行base64编码,并把编码后的源码打包到js文件中。会造成js文件非常大,下载和解析js文件需要的时间长。
onst path = require("path");
module.exports = {entry: "./src/main.js",output: {filename: "bundle.js",path: path.resolve(__dirname, "./build"),},module: {rules: [{test: /\.css$/,use: ["style-loader", "css-loader", "postcss-loader"],},{test: /\.scss$/,use: ["style-loader", "css-loader", "sass-loader"],},{test: /\.(png|jpe?g|gif|svg)$/,type: "asset/inline",},],},
};
打包后的js文件
这里还加了一个背景图.bgi { background-image: url(../asset/1.png); }
img和background-image的url都是base64格式的
asset/source:是将图片的源码打包到js文件中和asset/inline一样会造成js文件过大。
const path = require("path");
module.exports = {entry: "./src/main.js",output: {filename: "bundle.js",path: path.resolve(__dirname, "./build"),},module: {rules: [{test: /\.css$/,。use: ["style-loader", "css-loader", "postcss-loader"],},{test: /\.scss$/,use: ["style-loader", "css-loader", "sass-loader"],},{test: /\.(png|jpe?g|gif|svg)$/,type: "asset/source",},],},
};
asset:可以根据需要生成一个单独的文件,或打包到js中。
const path = require("path");
module.exports = {entry: "./src/main.js",output: {filename: "bundle.js",path: path.resolve(__dirname, "./build"),},module: {rules: [{test: /\.css$/,use: ["style-loader", "css-loader", "postcss-loader"],},{test: /\.scss$/,use: ["style-loader", "css-loader", "sass-loader"],},{test: /\.(png|jpe?g|gif|svg)$/,type: "asset",},],},
};
一般type会设置为asset,将较小的文件进行base64编码,较大的文件单独打包。
根据文件大小打包
const path = require("path");
module.exports = {entry: "./src/main.js",output: {filename: "bundle.js",path: path.resolve(__dirname, "./build"),},module: {rules: [{test: /\.(png|jpe?g|gif|svg)$/,type: "asset",parser: {dataUrlCondition: {maxSize: 4 * 1024,},},},],},
};//webpack官网:https://www.webpackjs.com/configuration/module/#ruleparserdataurlcondition
// 如果一个模块源码大小小于 maxSize,那么模块会被作为一个 Base64 编码的字符串注入到包中, 否则模块文件会被生成到输出的目标目录中。
//dataUrlCondition 还可以写成函数的形式
对打包后的文件名,文件目录进行操作
可以在output中对打包后生成的文件进行操作,比如修改文件名。但是在这里修改会影响所有的文件,不推荐在这里修改。
// 这里也是可以支持[hash][ext][query]的
const path = require("path");
module.exports = {entry: "./src/main.js",output: {filename: "bundle.js",path: path.resolve(__dirname, "./build"),assetModuleFilename: "aa.png",},module: {rules: [ ],},
};
应该针对对应的文件修改:
const path = require("path");
module.exports = {entry: "./src/main.js",output: {filename: "bundle.js",path: path.resolve(__dirname, "./build"),},module: {rules: [{test: /\.(png|jpe?g|gif|svg)$/,type: "asset",parser: {dataUrlCondition: {maxSize: 4 * 1024,},},generator: {filename: "img/[hash][ext]",},},],},
};
// webpack官网:https://www.webpackjs.com/configuration/module/#rulegeneratorfilename
//这里其实还可以控制生成的hash值的长度 img/[hash:8][ext]
到目前为止所有的代码
//webpack
const path = require("path");
module.exports = {entry: "./src/main.js",output: {filename: "bundle.js",path: path.resolve(__dirname, "./build"),},module: {rules: [{test: /\.css$/,use: ["style-loader", "css-loader", "postcss-loader"],},{test: /\.scss$/,use: ["style-loader", "css-loader", "sass-loader"],},{test: /\.(png|jpe?g|gif|svg)$/,type: "asset",parser: {dataUrlCondition: {maxSize: 4 * 1024,},},generator: {filename: "img/[hash][ext]",},},],},
};
//postcss.config.js
module.exports = {plugins: ["postcss-preset-env"],
};