webpack入门之css处理(css预处理器和css后置处理器) | 您所在的位置:网站首页 › css预解析 › webpack入门之css处理(css预处理器和css后置处理器) |
携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情 本文 webpack 版本 ^5.73.0、webpack-cli 版本 ^4.10.0 简介说到前端构建就肯定离不开css的处理。在前端日新月异的潮流下,css也不再是单纯的css了,涌现了很多css周边技术,比如我们常听到的css预处理器(PreCss)和css后置处理器(PostCss)。那这两个东西又是啥呢?他们的区别又是什么呢?以及在webpack中又怎么去处理它呢? 带着疑问,我们今天就来一探究竟 看完本文你将学到: 知道什么是css预处理器 css预处理器都有哪些 css预处理器有哪些作用 css预处理器怎么编译成css 知道什么是css后置处理器 css后置处理器有哪些作用 css后置处理器是怎么处理css的 怎么使用webpack来处理css预处理器和css后置处理器 编译适配目标浏览器的配置 browserslist css预处理器PreCss为什么会出现CSS预编译器这个东西呢?这就要谈到CSS的不足了: 没有变量(新的规范已经支持了)。 不支持嵌套。 编程能力较弱,代码复用性差。 没有模块化。为了弥补这些不足之处,CSS预编译器应运而生。而谈到CSS预编译器,就离不开这三剑客Sass、Less、Stylus。 历史上,最先登场的是Sass,因为出现最早,所以也是最完善的,有各种丰富的功能;Less的出现伴随着Bootstrap的流行,因此也获得大量用户;最后是Stylus,由TJ大神开发(敬大神),由于其简洁的语法,更像是一门编程语言,写起来非常Cool。所以下面我们来做一个简单的对比。 scssSass3.0版本开始使用的是标准的CSS语法,基本与SCSS一样。默认Sass使用.scss扩展名。 // scss新版语法规则 .container { background: #f6f6f6; min-height: 100%; }同时,Sass也支持老的语法,这种跟常规的CSS略有不同,更为严格,任何的缩进和字符的错误都会造成样式的编译错误,Sass可以省略{}和;,而且文件使用.sass扩展名,语法如下: .container background: #f6f6f6 min-height: 100%更多特性可自行查看sass中文文档学习。 lessLess是CSS的一种扩展形式,在CSS语法基础上添加了很多额外功能。从语法规则来讲,Less和Scss一样,都是用CSS的标准语法,只是Less的源文件扩展名是.less,举个栗子🌰: .block { height: 30px; padding-bottom: 10px; color: #666; font-weight: normal; }更多特性可自行查看less中文文档学习。 stylusStylus语法多变一些,文件扩展名是.styl,Stylus既接受标准的CSS语法,也可以跟Sass老的语法规则一样,使用缩进控制,如下所示: // 类似于CSS标准语法 .head { color: #ebebeb; background-color: #666; } // 省略大括号 .head color: #ebebeb; background-color: #666; // 省略大括号和分号 .head color: #ebebeb background-color: #666更多特性可自行查看less中文文档学习。 普通构建说了这么多css预处理器,预处理器代码能在浏览器运行吗?这些语法能被浏览器直接识别吗? 当然是不能的,所以在正式上线之前我们都需要进行编译,也就是把这些.scss、.less、.styl文件转变成浏览器能识别的.css文件。 那我们怎么进行编译呢?这就需要用到对应的工具了。 sass编译sass首先需要安装sass。 npm install -g sass然后我们创建styles.scss文件 安装完后它会提供一个sass命令,使用该命令就可以将.scss文件编译成.css文件了。 sass styles.scss styles.css我们来看下编译后的效果 编译less首先需要安装less。 npm install -g less然后我们创建styles.less文件 安装完后它会提供一个lessc命令,使用该命令就可以将.less文件编译成.css文件了。 lessc styles.less styles.css我们来看下编译后的效果 编译stylus首先需要安装stylus。 npm install -g stylus然后我们创建styles.styl文件 安装完后它会提供一个stylus命令,使用该命令就可以将.styl文件编译成.css文件了。 stylus styles.styl -o styles.css我们来看下编译后的效果 上面的编译笔者都是全局安装的,当然你也可以局部安装。 我们可以看到,css预处理器虽然好用,但是每次上线都需要我们手动打包成css,然后再发布是不是有点麻烦。有没有什么更好更高效的办法呢? 当然是有的,我们可以借助webpack,在上线前统一编译即可。下面笔者就来说说使用webpack来编译这三个css预处理器。 使用webpack构建 创建项目首先我们创建一个文件夹,然后初始化package.json文件。 // 创建webpacktest文件夹 mkdir webpacktest // 进入webpacktest文件夹 cd webpacktest // 创建package.json npm init 创建scss、less、stylus源文件接下来我们创建scss、less、stylus源文件,在根目录下创建src文件夹,在里面分别创建index.scss、index.less、index.styl 然后在里面分别添加内容 index.less index.scss index.styl 并在入口文件index.js里面引入我们的样式文件 接下来我们本地安装webpack 和 webpack-cli npm i webpack webpack-cli -D 安装处理scss、less、stylus的loader因为webpack默认只能处理js,如果需要处理其他语言的话需要安装对应的loader,这里我们需要分别安装处理scss、less、stylus文件的less、less-loader、node-sass、sass-loader、stylus、stylus-loader npm i less less-loader node-sass sass-loader stylus stylus-loader -D 安装处理css的loader当然,css也是需要处理的,所以也需要对应的loader。 npm i css-loader style-loader -D 配置webpack.config.js然后我们在根目录下创建webpack.config.js文件,并做如下配置 module.exports = { mode: "development", module: { rules: [ // Less 配置 { test: /\.less$/, use: ["style-loader", "css-loader", "less-loader"], }, // Sass 配置 { test: /\.scss$/, use: ["style-loader", "css-loader", "sass-loader"], }, // stylus 配置 { test: /\.styl$/, use: ["style-loader", "css-loader", "stylus-loader"], }, ], }, };loader的配置是有顺序要求的,它的执行顺序是从右到左的。比如use: ['style-loader', 'css-loader'],它先用css-loader处理CSS的模块化,然后style-loader把css-loader解析后的样式代码内联插入到HTML中的style标签内。 配置编译脚本然后我们在package.json里面创建运行webpack的脚本 "scripts": { "webpack1": "webpack" }, 运行脚本然后我们运行npm run webpack1,webpack会读取webpack.config.js文件,进行打包。 默认会读取根目录的src文件夹,默认将打包结果放到根目录dist文件夹下。 运行打包命令后我们可以看到,在根目录下生成了dist文件夹,并输出了main.js 编译后的文件是很混乱的,不容易看懂,所以我们需要测试刚才的样式是否成功。 我们首先在根目录下创建index.html,并引入构建好的main.js文件,然后创建三个div,分别引用刚才的样式。 webpack less test scss test stylus test然后在浏览器运行,我们来看看效果 nice! 至此使用webpack构建less、scss、stylus就完成啦。 将css抽离成单独的css文件前面说到,style-loader的作用是将处理好后的CSS样式代码放到HTML的style标签中。 那么,如果我需要将处理后的CSS文件单独编译成一个.css文件,引入到HTML中,webpack需要怎么做呢? 我们可以使用mini-css-extract-plugin插件提取css代码为单独的CSS文件,然后在HTML中通过link标签引入CSS文件。 npm install mini-css-extract-plugin -D然后我们使用MiniCssExtractPlugin.loader来替换style-loader // 1.引入 const MiniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = { mode: "development", module: { rules: [ // Less 配置 { test: /\.less$/, // use: ["style-loader", "css-loader", "less-loader"], // 3. 替换style-loader use: [MiniCssExtractPlugin.loader, "css-loader", "less-loader"], }, // Sass 配置 { test: /\.scss$/, // use: ["style-loader", "css-loader", "sass-loader"], // 3. 替换style-loader use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"], }, // stylus 配置 { test: /\.styl$/, // use: ["style-loader", "css-loader", "stylus-loader"], // 3. 替换style-loader use: [MiniCssExtractPlugin.loader, "css-loader", "stylus-loader"], }, ], }, // 2. 实例化插件 plugins: [new MiniCssExtractPlugin()], };然后我们重新构建,可以发现,编译后的css会单独形成一个main.css文件。 最后我们在index.html文件中手动引入main.css就可以了。 可能有些小伙伴觉得,自己每次手动引入js和css太麻烦,有没有自动引入的方式呢?这就需要用到html-webpack-plugin插件啦 自动引入js和css文件首先安装 npm install html-webpack-plugin -D然后在webpack.config.js使用该插件。 // 1.引入 const MiniCssExtractPlugin = require("mini-css-extract-plugin"); // 1.引入 const HtmlWebpackPlugin = require("html-webpack-plugin"); module.exports = { mode: "development", // ... // 2. 实例化插件 plugins: [ new HtmlWebpackPlugin({ // 模板html文件的位置,我们这里是在根目录下 template: "./index.html", }), new MiniCssExtractPlugin(), ], };然后我们重新编译,可以看到在dist文件夹下多了index.html文件 并且该文件自动引入了我们构建后的js和css文件 每次打包的时候,打包目录都会遗留上次打包的文件,为了保持打包目录的纯净,我们需要在打包前将打包目录清空 这里我们可以使用插件 clean-webpack-plugin 来实现。 老规矩,首先安装 npm install clean-webpack-plugin -D然后在webpack.config.js使用该插件。 // 1.引入 const MiniCssExtractPlugin = require("mini-css-extract-plugin"); // 1.引入 const HtmlWebpackPlugin = require("html-webpack-plugin"); // 1.引入 const { CleanWebpackPlugin } = require("clean-webpack-plugin"); module.exports = { mode: "development", // 使用CleanWebpackPlugin需要显示定义出口,不然无效 output: { filename: "[name].js", path: path.resolve(__dirname, "./dist"), }, // ... // 2. 实例化插件 plugins: [ new HtmlWebpackPlugin({ // 模板html文件的位置,我们这里是在根目录下 template: "./index.html", }), new MiniCssExtractPlugin(), new CleanWebpackPlugin(), ], };然后我们再次打包,可以发现,它会先将dist目录删除,然后重新生成dist目录。 css的前置处理器我们大致讲完了,接下来我们再来说说css的后置处理器。 css后置处理器PostCss对于 PostCSS 官方的解释是: PostCSS 是一个允许使用 JS 插件转换样式的工具。 这些插件可以检查(lint)你的 CSS,支持 CSS Variables 和 Mixins, 编译尚未被浏览器广泛支持的先进的 CSS 语法,内联图片,以及其它很多优秀的功能。 笔者简单理解postcss 是 css 的 transpiler(转换编译器,简称转译器),它对于 css 就像 babel 对于 js 一样,能够做 css 代码的分析和转换。同时,它也提供了插件机制来做自定义的转换。 普通构建我们这里拿autoprefixer插件来做例子来讲解。 创建项目首先我们创建一个文件夹,然后初始化package.json文件。 // 创建webpacktest文件夹 mkdir postcsstest // 进入postcsstest文件夹 cd postcsstest // 创建package.json npm init 创建源文件因为我们要测试autoprefixer,所以我们需要找一个需要带浏览器前缀的样式。这个修改placeholder颜色的样式刚刚好。 单独使用postcss我们需要安装postcss、postcss-cli。这样我们就可以在命令行使用postcss命令了。 npm i postcss postcss-cli -D 安装插件 npm i autoprefixer -D 创建 postcss.config.jspostcss.config.js是postcss的配置文件,我们postcss的配置都需要在这里定义。 前面我们安装了autoprefixer插件,这里我们再来配置下。 // postcss.config.js // 引入 const autoprefixer = require("autoprefixer"); module.exports = { // 使用 plugins: [autoprefixer], }; 配置编译脚本然后我们在package.json里面创建运行postcss的脚本 "scripts": { "pc1": "postcss src/post1.css -o dist/post1.css" }, 运行脚本我们运行上面配置好的脚本来编译下,npm run pc1。当我们在命令行运行该命令时,其实真实运行的是postcss src/post1.css -o dist/post1.css,这样他会处理我们前面的post1.css。 看效果我们来看下dist/post1.css,我们可以看到,它自动生成了-moz前缀的样式。 这里我们只拿autoprefixer作了讲解,其实截止到目前,PostCSS 有 200 多个插件。你可以在 插件列表找到它们。这些插件我们可以在不同需求下选择使用。 使用postcss-cli构建虽然可以,但是不推荐这么使用。一般我们都是使用webpack进行前端统一构建,所以下面笔者来说说使用webpack来构建我们的postcss 使用webpack构建这里我们就不再单独创建项目了,我们基于前面预处理器的webpacktest项目。 创建源文件我们把前面创建好的post1.css文件复制过来,并在入口文件index.js里面引入 在webpack里面使用postcss,我们只需要安装postcss-loader就可以了。 npm i postcss-loader -D 安装插件 npm i autoprefixer -D 创建 postcss.config.jspostcss.config.js是postcss的配置文件,我们postcss的配置都需要在这里定义。 前面我们安装了autoprefixer插件,这里我们再来配置下。 // postcss.config.js // 引入 const autoprefixer = require("autoprefixer"); module.exports = { // 使用 plugins: [autoprefixer], }; 配置webpack.config.js我们在rules里面添加css的处理规则。并配置上postcss-loader。 module.exports = { mode: "development", module: { rules: [ // css 配置 { test: /\.css$/, use: ["style-loader", "css-loader", "postcss-loader"], }, // ... ], }, }; 修改index.html我们在模板index.html里面添加一个input 接下来我们编译下,npm run webpack1。webpack会读取webpack.config.js文件,进行打包。 看效果我们来看看编译后的代码,发现它也自动生成了-moz前缀的样式。 在页面上可以看到,我们input的placeholder的颜色被我们改成红色了。 为什么每次只生成了火狐浏览器的前缀-moz呢?不是还有ie浏览器前缀-ms,chrome浏览器前缀-webkit吗? 按理来说不应该是生成下面这些样式吗 这里就需要了解另外一个知识点了,那就是browserslist。 那这个browserslist到底是什么东西呢? 简单理解,browserslist 实际上就是声明了⼀段浏览器的集合,我们的⼯具可以根据这段集合描述,针对性的输出兼容性代码。 .browserslistrc文件的默认值是 > 0.5% last 2 versions Firefox ESR not dead所以,当我们不配置browserslist的话,它的配置就是上面的默认配置,所以并不会生成所有浏览器的前缀,只会针对性的输出。 如果想输出全部怎么办呢?我们可以做一个小测试,我们把not dead注释掉,再编译。 可以看到,编译后的文件里面有所有浏览器的前缀了。 我们除了定义.browserslistrc文件来配置browserslist外,我们还可以直接配置在package.json文件中,通过browserslist键来配置。 // package.json { "browserslist": [ "last 1 version", "> 1%", "IE 10" ] }现在对browserslist有了一个大概的了解了吧。 总结好啦,看了上面的例子,小伙伴们应该很清楚css预处理器(PreCss)和css后置处理器(PostCss)了吧。 总的来说,css预处理器是用来弥补css不足的,它提供了变量、嵌套、复用、模块等方案,让我们的开发效率和开发体验大大提升。缺点是浏览器不能直接识别,每次上线前需要我们单独进行编译。 css后置处理器是用来处理css的,postcss 是 css 到 css 的转译器,它分为 parse、transform、generate 3个阶段。各种转换插件都是工作在 transform 阶段,基于 AST 做分析和转换。 webpack入门之css处理(css预处理器和css后置处理器) webpack入门之图片、字体、文本、数据文件处理 webpack入门之js处理(babel、babel polyfill) webpack入门之ts处理(ts-loadr和babel-loader的选择) webpack入门之开发环境(mode、dev-server、devtool) webpack入门之提升开发效率的几个配置(ProvidePlugin、DefinePlugin、resolve、externals) webpack进阶之性能优化(webpack5最新版本) 后记感谢小伙伴们的耐心观看,本文为笔者个人学习笔记,如有谬误,还请告知,万分感谢!如果本文对你有所帮助,还请点个关注点个赞~,您的支持是笔者不断更新的动力! |
CopyRight 2018-2019 实验室设备网 版权所有 |