webpack
作为前端最火的构建工具,是前端自动化工具链 最重要的局部 ,应用门槛较高。本系列是笔者本人的学习记录,比拟根底,心愿通过 问题 + 解决形式 的模式,以前端构建中遇到的具体需要为出发点,学习webpack
工具中相应的解决方法。(本篇中的参数配置及应用形式均基于webpack4.0 版本
)
一. CSS 文件根本解决需要
假如我的项目中的 CSS 文件均采纳预编译语言编写,那么在打包中须要解决的根本问题包含:
- 预编译语言转换
- 款式文件挂载形式抉择
- 代码优化(合并及压缩)
- 去除或保留指定格局的正文
- 资源定位门路的转换
- 响应式布局单位转换【可选】
- 模块化【可选】
- 解决浏览器兼容【可选】
二. 解决方案的降级
- 旧的解决方案 :
预编译语言
+命名方法论
在不应用构建工具的时代,开发者应用预编译语言来实现变量定义,选择器嵌套等一些刚需,再应用函数性能来实现一些更为简单的需要,例如编写简略的
@mixin px2rem()
函数来将开发中应用的 px 单位转换为 rem 单位,达到挪动端自适应的目标,或是编写一些解决兼容性的函数来解决浏览器兼容性。命名的方法论十分多,最为风行的当属
BEM
,也就是采纳block__Element-Modifier 这样的命名形式来进行模块划分,还有提倡碎片化款式的Aotm-CSS
及面向对象的OOCSS
等,都是一种命名方法论,也意味着没有硬性的检测和预防措施。 -
新的解决方案 :
预编译语言
+构建工具
+BEM + ACSS 全局款式
+CSSModule 组件款式
+POSTCSS
预编译语言的应用根本不变,但现代化开发中曾经不再须要通过预约义函数来解决单位转换或是兼容性的问题。首先,构建工具 能够通过自动化检测将预编译语言转换为
CSS
,基于现代化构建工具的CSS-Module
性能,能够通过特定的语法解决 CSS 模块化 的问题,而基于POSTCSS
实现的autoprefixer
插件,能够根据 CanIUse 网站提供的浏览器反对度数据实现代码的跨浏览器前缀主动补齐。新的计划波及到很多新的概念,但这并不是简略的炫技,每一个概念都有长处和实用的场合,你须要在失当的场合应用失当的技术,最愚昧的做法就是因为某种技术热门而自觉地要求开发人员在整个我的项目中应用。
三. 根本应用办法
3.1 罕用插件及性能简述
以 webpack4.0
版本为例来演示 CSS 模块的解决形式,须要用到的插件及性能如下:
style-loader
——将解决完结的 CSS 代码存储在 js 中,运行时嵌入<style>
后挂载至html
页面上css-loader
——加载器,使webpack
能够辨认css
模块postcss-loader
——加载器,下一篇将详细描述sass-loader
——加载器,使webpack
能够辨认scss/sass
文件,默认应用node-sass
进行编译mini-css-extract-plugin
——插件,4.0 版本启用的插件,代替原extract-text-webpack-plugin
插件,将解决后的 CSS 代码提取为独立的 CSS 文件optimize-css-assets-webpack-plugin
——插件,实现 CSS 代码压缩autoprefixer
——自动化增加跨浏览器兼容前缀
3.2 webpack 的配置
本篇不是 webpack
教程,在此间接给出带有正文的 webpack.config.js
的配置以供参考,示例中应用 SCSS
作为预编译语言,其余预处理语言配置形式基本一致:
const HtmlWebpackPlugin = require('html-webpack-plugin');// 用于主动生成 html 入口文件的插件
const MiniCssExtractPlugin = require("mini-css-extract-plugin");// 将 CSS 代码提取为独立文件的插件
const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");//CSS 模块资源优化插件
module.exports = {
mode:'development',
entry:'./main.js',
output:{
filename:'main.bundle.js',
path:__dirname + '/build'
},
module: {
rules: [
{
test: /\.scss$/,
exclude: /node_modules/, // 排除 node_modules 文件夹
use: [{loader: MiniCssExtractPlugin.loader// 倡议生产环境采纳此形式解耦 CSS 文件与 js 文件},{
loader: 'css-loader',//CSS 加载器
options: {importLoaders: 2}// 指定 css-loader 解决前最多能够通过的 loader 个数
},{loader: 'postcss-loader',// 承载 autoprefixer 性能},{loader: 'sass-loader'//SCSS 加载器,webpack 默认应用 node-sass 进行编译}
]
}
]
},
plugins:[new HtmlWebpackPlugin(),// 生成入口 html 文件
new MiniCssExtractPlugin({filename: "[name].css"
})// 为抽取出的独立的 CSS 文件设置配置参数
],
optimization:{
// 对生成的 CSS 文件进行代码压缩 mode='production' 时失效
minimizer:[new OptimizeCssAssetsPlugin()
]
}
}
postcss.config.js
的配置较为简单:
module.exports = {
plugins:[require('autoprefixer')
]
}
package.json
中减少新的参数指定打包须要反对的浏览器类别:
"browerslist": [
"last 2 versions",
"IE 8",
"UCAndroid"
]
编写一段待 SCSS
代码:
// 变量定义
$grey: #1e1e1d;
$yellow: #ffad15;
$offwhite: #f8f8f8;
$darkerwhite: darken($offwhite, 15);//SCSS 函数
$baseFontSize:14px;
// 循环
@for $i from 1 through 3 {.item-#{$i} {width: 2em * $i;}
}
//mixin
@mixin px2rem($name, $px){#{$name}: $px / $baseFontSize * 1rem;
}
// 嵌套
.class3{
font-weight: bold;
display:flex;
&-small{
color: $offwhite;
@include px2rem('font-size',14px);
}
}
//autoprefixer
::placeholder{width:10px;}
能够看到转换后的后果:
提醒:代码压缩等优化性能在 4.0 版本中默认当 mode : ‘production’ 时无效。
四. 应用 CSS-Modules
我的项目地址:CSS Modules 开源地址
CSS Module在 CSS 中应用类选择器,其基本原理是将 CSS 代码中的款式名替换为哈希值,并建设一个 json
对照表,在 js
文件中对于 属性名选择器 的应用均被替换为 哈希字符串,以此来解决 CSS 模块化的问题。
在 webpack 中应用 CSS Modules
性能非常简单,只须要在 css-loader
的配置参数中设置:{modules:true}即可激活模块化性能。
开启模块化性能后再进行打包,能够看到同样的 main.css
文件变成了如下样子:
而在打包文件中减少了如下片段:
当然 CSS Modules
的用法远不止如此,更多的信息能够参见下面的我的项目地址。
五. 图解 Css-Process-Chain
从上述配置中能够看出,应用预编译器编写的款式文件须要通过一系列 loader
和plugin
能力失去最终的指标文件,它之所以很形象是因为两头的解决环节对开发者来说是黑箱操作,只看失去输出和输入,笔者联合本人了解绘制了上面的示意图,心愿可能帮忙你了解 css 文件在整个 webpack
打包流程中是如何被解决的 (plugins
局部尚未进行钻研,解决链中暂不波及)。