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" ]