【问题标题】:Webpack localIdentName mismatch on server and client in a React SSR applicationReact SSR 应用程序中服务器和客户端上的 Webpack localIdentName 不匹配
【发布时间】:2019-07-15 08:17:32
【问题描述】:

我正在尝试将 Css 模块与 React SSR 一起使用,并且我添加了以下 webpack 配置。

module: {
        rules: [
            {
                test: /\.jsx?$/,
                exclude: /(node_modules|bower_components)/,
                loader: "babel-loader",
            },{
                test:/\.(s*)css$/,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader,
                    },
                    {
                        loader: 'css-loader',
                        options: {
                            modules: {
                                mode: 'local',
                                localIdentName: "[name]__[local]___[hash:base64:5]"
                            },
                            import: true,
                            importLoaders: true,
                        }
                    },
                    {
                        loader: "sass-loader",
                    }
                ],
            },
        ]
    },

这会在 dist 包中生成以下 css 文件

.Home\.module__Container___3B08 {
  display: flex;
  width: 600px;
  height: 300px;
  border: 2px solid red; }

在我的 DOM 中,div 具有以下样式

<div class="Home-module__Container___14QBF">

我怎样才能做到这一点?以及为什么 webpack 配置与浏览器中的配置不同

【问题讨论】:

  • 通读 - javascriptplayground.com/css-modules-webpack-react 并检查您的设置是否正确。另外,您如何在 DOM 中填充 css 文件名?
  • @MonikaMangal 我已经查看了您共享的链接,问题是使用已弃用的ExtractTextPlugin 链接已过时,并且我已正确配置它,因为它生成的哈希不正确根据浏览器

标签: css webpack css-modules


【解决方案1】:

您必须在插件下的 .babelrc 文件中添加 CSS 模块配置。然后只有生成的 CSS 会与您的 html 中的相匹配。

.babelrc

"plugins": [
   ["react-css-modules", {
     "generateScopedName": "[name]__[local]___[hash:base64:5]"
    }]
 ],

更新:

必须使用 css-modules-require-hook 进行服务器端 CSS 渲染,并使用 generic-names 在客户端和服务器中生成哈希。

index.js

const hook = require( "css-modules-require-hook" );
const genericNames = require( "generic-names" );

const generate = genericNames( "[name]__[local]___[hash:base64:5]", {
   context: process.cwd(),
});

// Scope Generator function.
hook( {
    generateScopedName: ( c, path ) => {
        return generate( c, path );
    },
} ); 

webpack.config.js

const genericNames = require( "generic-names" );
const generate = genericNames( "[name]__[local]___[hash:base64:5]", {
  context: process.cwd(),
});

const getLocalIdent = ( loaderContext, localIdentName, localName ) =>
    generate( localName, loaderContext.resourcePath );

.....
{
    loader: "css-loader",
    options: {
        modules: {
           getLocalIdent,
        },
     },
 },

有关更多信息,请查看此存储库:https://github.com/ajayvarghese/react-ssr/tree/css-modules。 注意:repo 使用更新版本的 babel 包。

【讨论】:

  • 我试过了,但它不起作用,我还添加了库 react css 模块,它已被弃用,还添加了新的 babel 没有任何运气
  • 服务器端和客户端的哈希生成有些不匹配。如果您避免使用 hash:base64:5 部分,它可能会起作用。不过,这不是一个合适的解决方案。否则,您可以使用自定义函数生成 scopeName。
  • `服务器端和客户端的哈希生成有些不匹配。这就是我想知道的原因?
  • 可能 css-loader(客户端)和 css-modules-transform(服务器)使用不同的方法来生成哈希。 css-loader git 中提出了一个问题,说的一样。这是由于他们所遵循的依赖关系。这是问题github.com/webpack-contrib/css-loader/issues/877
  • 这就是为什么我建议使用自定义范围生成器,或者不使用散列。喜欢[name]__[local]
猜你喜欢
  • 2021-10-18
  • 2019-12-20
  • 2019-11-01
  • 2018-12-28
  • 2016-09-19
  • 1970-01-01
  • 2016-07-16
  • 2022-12-06
  • 1970-01-01
相关资源
最近更新 更多