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

  • 相关阅读:
    市场上 MLCC 226 电容现象
    什么是 PCB 的压适孔
    MLCC 电容的的 NP0 C0G 材质
    超时 CS-8610 中性笔
    压敏电阻报关相关信息
    锂电池充电的四个阶段
    FastAdmin 的 Bootstrap-Table 如何合并字段?
    从2012之殇到2013的思想极度动荡的这段人生路程….
    在页面上的输入框中即可以输入文字,又可以动态的插入图片的功能.
    由一条普通的link引用引发的无数问号,大家能回答的帮忙回答回答吧.
  • 原文地址:https://www.cnblogs.com/nianzhilian/p/10229207.html
Copyright © 2020-2023  润新知