CSS基础处理
webpack中关于css的处理用到两个loader:
- css-loader: 用于处理css文件中的@import和url(…)
- style-loader: 将css-loader的输出生成js中的函数调用将css动态添加到html文件中。
1 | yarn add css-loader style-loader -D |
1 | const path = require('path'); |
运行yarn start可以看到页面变成了粉色,运行yarn build可以看到一个html文件和一个js文件,css被打包到js文件中了
分离CSS文件
style-loader将css动态添加到html文件中,生产环境下我们希望将所有的css抽离为独立的css文件,此时可以借助mini-css-extract-plugin
1 | yarn add mini-css-extract-plugin -D |
将style-loader改为mini-css-extract-plugin的loader:
1 | ... |
另外,还需要引入MiniCssExtractPlugin插件本身:
1 | plugins: [ |
运行yarn build可以看到生成了独立的main.ec3a0b2de01cd68066ac.css,并且在index.html文件中自动引入了该css文件。
CSS Modle
所有的class的名称和动画的名称默认属于本地作用域的CSS文件。
所以CSS Modules不是一个官方的规范,也不是浏览器的一种机制,它是一种构建步骤中的一个进程。(构建通常需要webpack或者browserify的帮助)。通过构建工具的帮助,可以将class的名字或者选择器的名字作用域化。(类似命名空间化。)目的在于解决CSS中的全局作用域问题。
CSS Module只对类名和动画的名字起作用,css-loader支持CSS Module,CSS Module为每个独立的css文件处理为一个module。此时需要修改webpack.config.js文件中css-loader的配置:
1 | { |
在main.css中加入更多的css:
1 | body { |
⚠️注意:这里的:local有点多余,因为当启用了CSS Module之后,css文件中的类名默认便是:local的。
运行 yarn build 结果为:
1 | body { |
.main—red—1GVbX对应原文件中的.red,命名规则有localIdentName: ‘[name]—[local]—[hash:base64:5]’配置完成。.gold由于标记有:global,所以生成的全局的类名。
使用SASS
Sass 是一款强化 CSS 的辅助工具,它在 CSS 语法的基础上增加了变量 (variables)、嵌套 (nested rules)、混合 (mixins)、导入 (inline imports) 等高级功能,这些拓展令 CSS 更加强大与优雅。使用 Sass 以及 Sass 的样式库(如 Compass)有助于更好地组织管理样式文件,以及更高效地开发项目。
1 | yarn add sass-loader node-sass -D |
⚠️注意需要安装node-sass
修改rules,让原来处理的css的loader也能处理scss文件:
1 | ... |
然后加入sass-loader:
1 | ... |
⚠️注意:sass-loader需要是处理scss/css文件的第一个loader,需要配置在最后面。
src目录下创建base.scss
1 | body { |
global.scss
1 | $base-color: pink; |
main.scss,通过@import引入global.scss、base.scss
1 | @import './global.scss'; |
main1.scss,通过@import引入global.scss、base.scss
1 | @import './global.scss'; |
在index.js文件中引入base.scss,main.scss,main1.scss
运行 yarn build,输出css文件:
1 | body { |
可以看到base.scss中的内容出现了三次,因为SASS分别以这三个文件为编译单位进行处理,最后将他们的内容合并到一起。
因此对于SASS来说,有个原则是如果有文件作为公共css文件,那么建议它最多只引用1次,通常是在入口文件中进行引用,比如VueJS的App.vue文件。
PostCSS
1 | yarn add postcss-loader -D |
添加postcss-loader,并且添加autoprefixer插件:
1 | yarn add autoprefixer -D |
1 | { |
然后在package.json中添加:
1 | "browserslist": [ |
运行 yarn build 发现base.scss中的div添加了后缀
1 | div { |
多入口项目CSS处理
当项目中有多个入口文件时,webpack会为每个入口文件生成对应的css bundle文件。
演示一下,src目录下创建index1.html,index2.html文件,创建模块common.js,让两个入口文件都依赖于该模块:
1 | import './common.scss' |
common.scss
1 | .blue { |
创建index1.js
1 | import { log } from './common.js' |
index2.js
1 | import { log } from './common.js' |
运行 yarn build 可以看到webpack为两个入口文件分别生成了css bundle文件。
合并css文件
有时我们需要将真个项目中所有生成的css合并为一个文件,此时可以使用splitChunks:
1 | splitChunks: { |
修改HtmlWebpackPlugin配置,使每个入口文件引用自己的bundle以及公共的styles chunk文件:
1 | new HtmlWebpackPlugin({ |
可以看到只生成一个styles.a5178a5acb27551c5dde.css