【webpack系列】从零搭建 webpack4+react 脚手架(三)

本章节,我们对如何在脚手架中引入CSS,如何压缩CSS,如何使用CSS Modules,如何使用less,如何使用postcss等问题进行展开学习。

1 支持css

(1)在app目录,新建一个css,命名为index.css,输入样式:
 h1{ display: flex; height: 200px; align-items: center; justify-content: center; color: #8FBC8F; }
(2)在index.js中引入css
import ./index.css
(3)配置loader

在第一节,我们知道,webpack只能编译js文件,不能编译css,它不认识css文件,所以需要配置loader加载器来预处理。
首先安装style-loader和css-loader:

npm install --save-dev style-loader css-loader
(4)配置module.rules:

在webpack.prod.conf.js中配置:

 module: { rules: [ { test: /\.(css)$/, use: [ style-loader, css-loader, ] } ] },

loader的加载顺序是从右边到左边,css-loader是加载通过import引入的css文件,而style-loader的作用是把样式插入到DOM中。

最后,执行npm run build试试看样式是否生效。

npm run build

打开页面,发现样式已经生效了。打开控制台查看,你会发现css的确是通过style在页面上方插入的。

 

2 导出CSS文件   如果我们希望把样式导出到css文件,并且在页面引用该css文件,又要怎么做呢?

这里先提在webpack4版本以前一个插件,叫extract-text-webpack-plugin,熟悉webpack3的同学,可能知道,这个插件主要是为了抽离css样式,防止将样式打包在js中引起页面样式加载错乱的现象。然而,在webpack4版本下,该插件已经不再兼容,官方提示我们去下载使用另外一个插件,叫mini-css-extract-plugin。

(1)安装mini-css-extract-plugin
npm install mini-css-extract-plugin --save-dev
(2)引入mini-css-extract-plugin

在webpack.prod.conf.js中引入

const MiniCssExtractPlugin = require("mini-css-extract-plugin");
(3)修改配置loader
 module: { rules: [ { test: /\.(css)$/, use: [ MiniCssExtractPlugin.loader, { loader: css-loader, } ] } ] },
(4)配置plugin
 //导出css  new MiniCssExtractPlugin({ filename: css/[name].[hash].css, chunkFilename: css/[id].[hash].css, }),

最后你的webpack.prod.conf.js看起来是这样

 const merge = require(webpack-merge); const baseWebpackConfig = require(./webpack.base.conf); const HtmlWebpackPlugin = require(html-webpack-plugin); const CleanWebpackPlugin = require(clean-webpack-plugin); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const UglifyJSPlugin = require(uglifyjs-webpack-plugin); module.exports = merge(baseWebpackConfig, { mode: production, output: { filename: "js/[name].[chunkhash:16].js", }, module: { rules: [ { test: /\.(css)$/, use: [ MiniCssExtractPlugin.loader, { loader: css-loader, } ] } ] }, plugins: [ new HtmlWebpackPlugin({ template: public/index.html, inject: body, minify: { removeComments: true, collapseWhitespace: true, removeAttributeQuotes: true }, }), new CleanWebpackPlugin([../dist], { allowExternal: true }), //导出css  new MiniCssExtractPlugin({ filename: css/[name].[hash].css, chunkFilename: css/[id].[hash].css, }), ], optimization: { minimizer: [ new UglifyJSPlugin() ], splitChunks: { chunks: "all", minChunks: 1, cacheGroups: { framework: { priority: 200, test: "framework", name: "framework", enforce: true, reuseExistingChunk: true }, vendor: { priority: 10, test: /node_modules/, name: "vendor", enforce: true, reuseExistingChunk: true } } } } });
(5)编译build命令
npm run build

查看下dist目录,你会看到css已经被编译到css文件夹中,并且在html文件中成功引入。

 

3 压缩css   打开编译后的css文件,你会发现css没有压缩处理。在webpack4版本中,只要定义了mode为production,那么webpack是默认会调用UglifyJsPlugin对js文件进行代码压缩的,无需我们手动引入。但是css还是需要我们手动引入插件。在webpack4版本中,使用optimize-css-assets-webpack-plugin这个插件处理压缩css文件。

(1)安装optimize-css-assets-webpack-plugin
npm install optimize-css-assets-webpack-plugin --save-dev
(2)引入optimize-css-assets-webpack-plugin

在webpack.prod.conf.js中引入optimize-css-assets-webpack-plugin :

const OptimizeCSSAssetsPlugin = require(optimize-css-assets-webpack-plugin);
(3)配置minimizer参数

minimizer参数是配置在optimization参数内,和splitChunks同级。

 minimizer: [ new UglifyJSPlugin(), new OptimizeCSSAssetsPlugin({ cssProcessorOptions: true ? { map: { inline: false } } : {} }) ],
(4)编译build命令
npm run build

再次查看dist/css目录下的css文件,你会发现已经是压缩后的了。

 

4 支持 css modules   css modules是react官方提倡的一种css解决方案,把import后的对象赋值给一个变量。在jsx中直接使用这个变量下的class名称来设置css。编译后,会在css属性加上唯一的hash编码,防止css全局污染。它的好处和坏处这里不再作更多的阐述。

(1)配置css-loader参数

配置loader,传入的是数组,它的子项,可以是字符串,比如‘css-loader‘,也可以是一个对象,支持其他参数的设置,设置loader为:

 { loader: css-loader, options: { modules: true, localIdentName: [local]__[hash:7] } }

modules参数,定义是否开启css modules,默认是否。localIdentName定义生成class的名称格式,这样设置后,如果你定义了一个叫main的class,最后生成的是main__i72tywq这样的格式。

(2)试试看

修改index.js

 import React from "react"; import ReactDom from "react-dom"; import indexStyle from ./index.css; ReactDom.render( <h1 className={indexStyle.main}>hello, world!</h1>, document.getElementById("root") );

定义一个main的class

 .main{ display: flex; height: 200px; align-items: center; justify-content: center; color: #8FBC8F; }
(3)编译build命令
npm run build

在dist目录打开编译后的index.css文件,查看css,发现 class名称后都加了hash后缀,而且html中的引用也是加了后缀。

 

5 Less or Sass   作为一个前端,你肯定不满足于现有的css方案,less或者sass是一个不错的选择。

如何让它支持less,或者sass?webpack不认识less,需要配置loader。

(1)安装less-loader
npm install less less-loader --save-dev
(2)配置loader

在webpack.prod.conf.js中的module.rules内增加一个对象:

 { test: /\.(less)$/, use: [ MiniCssExtractPlugin.loader, { loader: css-loader, options: { modules: true, localIdentName: [local]__[hash:7] } }, { loader: less-loader } ] }
(3)编译build命令
npm run build

在dist目录打开编译后的index.css文件,查看css,less文件成功被编译。引入sass也是类似。这里不再阐述。

 

6 使用postcss   PostCSS是什么?或许,你会认为它是预处理器、或者后处理器等等。其实,它什么都不是。它可以理解为一种插件系统。

你可以在使用预处理器的情况下使用它,也可以在原生的css中使用它。它都是支持的,并且它具备着一个庞大的生态系统,例如你可能常用的Autoprefixer,就是PostCSS的一个非常受欢迎的插件。

(1)安装postcss
npm install postcss postcss-loader --save-dev
(2)安装postcss某个插件,这里我用Autoprefixer举例
npm install autoprefixer --save-dev
(3)配置postcss.config.js

在根目录新建postcss.config.js

 module.exports = () => ({ plugins: { autoprefixer: { browsers: [last 5 version, >1%, ie >=8] }, } });
(4)设置loader

修改webpack.prod.conf.js中的中的module.rules

 module: { rules: [ { test: /\.(css)$/, use: [ MiniCssExtractPlugin.loader, { loader: css-loader, options: { importLoaders: 1, modules: true, localIdentName: [local]__[hash:7] } }, { loader: postcss-loader } ] }, { test: /\.(less)$/, use: [ MiniCssExtractPlugin.loader, { loader: css-loader, options: { importLoaders: 1, modules: true, localIdentName: [local]__[hash:7] } }, { loader: postcss-loader }, { loader: less-loader } ] } ] },
(4)编译build命令
npm run build

看下编译生成的css文件,查看代码,已经自动加了浏览器前缀。
最后你可以把webpack.prod.conf.js内关于module rules的设置拷贝到webpack.dev.conf.js,修改第一个为style-loader

 module: { rules: [ { test: /\.(css)$/, use: [ style-loader, { loader: css-loader, options: { importLoaders: 1, modules: true, localIdentName: [local]__[hash:7] } }, { loader: postcss-loader } ] }, { test: /\.(less)$/, use: [ style-loader, { loader: css-loader, options: { importLoaders: 1, modules: true, localIdentName: [local]__[hash:7] } }, { loader: postcss-loader }, { loader: less-loader } ] } ] },

你可以执行 npm run dev来启动开发环境。

相关文章