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

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

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:html

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中。node

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

npm run build

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

 

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中引入web

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看起来是这样npm

    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来启动开发环境。

相关文章
相关标签/搜索