【问题标题】:split style[hash].css into dynamically loaded chunks将 style[hash].css 拆分为动态加载的块
【发布时间】:2021-08-25 09:20:19
【问题描述】:

由于生成输出的大小,我正在尝试将样式代码拆分为更小的块。我正在使用react 进行开发,所以我使用React.lazy() 解决了javascript 加载问题。

假设有一个大型应用程序,您可以打开 50 个不同的视图。并非所有视图都可供所有用户使用。

我在路由器中所做的是:

...
const view = React.lazy(() => import("./views/view"));
...

...
<view />
...

这样做是将整个应用程序划分为 50 个独立的 js 文件,这些文件是动态加载的,这很好。

然而,它并没有以同样的方式划分样式。那么让我们看看其中一种观点:

import React, { Component } from "react";
import "../../scss/view.scss";

class view extends Component {
    ...
}

export default view;

因此,每个视图都有自己的scss 文件专用于此视图,这使得它们几乎是独立的。问题是 webpack 仍然只生成一个大的 style[hash].css 文件。

Webpack 配置:

const HtmlWebPackPlugin = require("html-webpack-plugin");
const ExtractTextPlugin = require("extract-text-webpack-plugin");

const htmlPlugin = new HtmlWebPackPlugin({
    template: "./src/index.html",
    filename: "index.html"
});

const extractTextPlugin = new ExtractTextPlugin({
    filename: "css/style.[hash:8].css",
    allChunks: true
});

module.exports = {
    output: {
        filename: "js/main.[hash:8].js"
    },
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                exclude: /node_modules/,
                use: "babel-loader"
            },
            {
                test: /\.(png|jpg|gif|ico|svg|eot|ttf|woff|woff2)$/,
                loader: "url-loader",
                options: {
                    limit: 25000,
                    outputPath: "/assets/",
                    name: "[name].[hash:8].[ext]"
                }
            },
            {
                test: /\.(scss|sass|css)$/i,
                use: ExtractTextPlugin.extract({
                    fallback: "style-loader",
                    use: [
                        { loader: "css-loader" },
                        { loader: "postcss-loader", options: { sourceMap: true } },
                        { loader: "sass-loader", options: { sourceMap: true } }
                    ]
                })
            }
        ]
    },
    resolve: {
        extensions: [".js", ".jsx", ".json"]
    },
    plugins: [htmlPlugin, extractTextPlugin],
    devServer: {
        historyApiFallback: {
            rewrites: [{ from: /^\/$/, to: "/index.html" }]
        }
    }
};

有没有什么方法可以让样式也根据它们的 js 文件动态生成和加载,例如,如果我打开视图 10,它会加载 10.main[hash].js10.style[hash].css

【问题讨论】:

    标签: javascript reactjs webpack sass lazy-loading


    【解决方案1】:

    此问题的答案是替换已弃用的 extract-text-webpack-plugin 包,该包实际上缺少此功能(将样式拆分为相应的块)。

    应该改用mini-css-extract-plugin,它会自动工作。

    更新工作 webpack 配置文件:

    const HtmlWebPackPlugin = require("html-webpack-plugin");
    const MiniCssExtractPlugin = require("mini-css-extract-plugin");
    
    const htmlPlugin = new HtmlWebPackPlugin({
        template: "./src/index.html",
        filename: "index.html",
    });
    
    const miniCssExtractPlugin = new MiniCssExtractPlugin({
        filename: "css/style.[hash:8].css",
        chunkFilename: "css/[id].style.[hash:8].css",
    });
    
    module.exports = {
        output: {
            filename: "js/main.[hash:8].js",
        },
        module: {
            rules: [
                {
                    test: /\.(js|jsx)$/,
                    exclude: /node_modules/,
                    use: "babel-loader",
                },
                {
                    test: /\.(png|jpg|jpeg|gif|ico|svg|eot|ttf|woff|woff2)$/,
                    loader: "url-loader",
                    options: {
                        limit: 25000,
                        outputPath: "/assets/",
                        name: "[name].[hash:8].[ext]",
                    },
                },
                {
                    test: /\.(scss|sass|css)$/i,
                    use: [
                        MiniCssExtractPlugin.loader,
                        "css-loader",
                        "postcss-loader",
                        "sass-loader",
                    ],
                },
            ],
        },
        resolve: {
            extensions: [".js", ".jsx", ".json"],
        },
        plugins: [htmlPlugin, miniCssExtractPlugin],
        devServer: {
            historyApiFallback: {
                rewrites: [{ from: /^\/$/, to: "/index.html" }],
            },
        },
    };
    

    【讨论】:

      猜你喜欢
      • 2018-09-21
      • 2017-07-15
      • 2020-10-09
      • 1970-01-01
      • 1970-01-01
      • 2020-03-11
      • 2015-11-10
      • 2018-02-11
      • 2011-04-14
      相关资源
      最近更新 更多