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

从上述配置中能够看出,应用预编译器编写的款式文件须要通过一系列loaderplugin能力失去最终的指标文件,它之所以很形象是因为两头的解决环节对开发者来说是黑箱操作,只看失去输出和输入,笔者联合本人了解绘制了上面的示意图,心愿可能帮忙你了解css文件在整个webpack打包流程中是如何被解决的(plugins局部尚未进行钻研,解决链中暂不波及)。