使用 Webpack 缓存,索引源代码中的 [hash] 值,使用 React.js

IT技术 node.js caching reactjs webpack isomorphic-javascript
2021-05-08 16:13:54

我正在构建一个同构应用程序。它完全是用 react 构建的——也就是说,html 基础也在 react 中。

我有我的根 html 作为应用程序组件。

它看起来像这样:

...
var AppTemplate = React.createClass({
    displayName: 'AppTemplate',
    render: function() {
        return (
            <html>
                    <head lang="en">
                        <title>hello</title>
                        <link rel="stylesheet" href='/css/style.css' />
                    </head>
                    <body>
                        <RouteHandler {...this.props}/>
                        <script type='text/javascript' src='/js/bundle.js' />
                    </body>
                </html>
        );
    }
});
...
module.exports = AppTemplate;

当我使用 webpack 构建项目时,我需要替换 js/bundle.js 以包含哈希。

Webpack 完成后交付 stats.json。但是我需要在构建期间提供哈希值。

我正在考虑使用功能标志来执行以下操作:

...
var AppTemplate = React.createClass({
    displayName: 'AppTemplate',
    render: function() {
        return (
            <html>
                    <head lang="en">
                        <title>hello</title>
                        <link rel="stylesheet" href='/css/style.css' />
                    </head>
                    <body>
                        <RouteHandler {...this.props}/>
                        <script type='text/javascript' src='/js/bundle.{__HASH__}.js' />
                    </body>
                </html>
        );
    }
});
...
module.exports = AppTemplate;

理想情况下,这会将正确的哈希引用注入到构建的 js 中。

这有点棘手,因为它是自引用。有没有更好的方法来做到这一点?在 webpack 完成后修改构建的代码似乎适得其反。我还考虑过让客户端简单地请求 bundle.js,但让我的节点服务器提供散列文件。

这种缓存的正确解决方案是什么?

3个回答

ExtendedAPIPlugin增加了一个__webpack_hash__变量的捆绑,这可能是你在找什么。

我发现最好的解决方案是将 webpack 资产传递到应用程序中,而不是尝试在应用程序中呈现它。这可以直接通过props或通过您的通量。

这样你的代码就用一个变量呈现。您的变量的值与构建过程无关。

...
var AppTemplate = React.createClass({
    displayName: 'AppTemplate',
    render: function() {
        return (
            <html>
                    <head lang="en">
                        <title>hello</title>
                        <link rel="stylesheet" href='/css/style.css' />
                    </head>
                    <body>
                        <RouteHandler {...this.props}/>
                        <script type='text/javascript' src={this.props.jsFile} />
                    </body>
                </html>
        );
    }
});
...
module.exports = AppTemplate;

类似的东西。

您永远不应该在客户端上呈现完整的 HTML。您的头部和身体中应用程序 div 之外的所有内容都应该从服务器发送。这样您的问题就会立即得到解决,因为您的客户端 Javascript 不需要知道它所在的文件,并且在服务器上您只需等待统计信息准备好即可。