【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來啟動開發環境。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM