React Starter Kit Main.js 未提供给客户端

React Starter Kit Main.js Not servered to Client

我正在使用最新的 React Starter Kit (Isomorphic) 构建应用程序,但我遇到了问题。该应用程序的大部分内容都是静态数据,因此我首先只使用服务器端渲染制作了一些页面。

但是,当我制作一个向按钮添加 onClick 回调的页面时,该回调从未被调用。

过了一会儿,我发现我可以通过将以下内容添加到 Html 父组件来让它工作:

<script async src="/assets/main.js"></script>

现在页面可以正常工作了。但我认为这不是正确的解决方案,因为当我使用“—release”构建应用程序时,会发出带有散列标签的 main.js(例如 main.63635afefa6a.js),并且在部署时会找不到。

我在这里错过了什么?

// 这个答案描述了 RSK 当前的工作方式,如果您修改了 RSK 的 Html 组件或服务器端路由(这也可能破坏了您的应用程序)

什么是main.js?

main.js 是 WebPack 捆绑所有 JavaScript 的地方,这就是为什么强制添加引用它的脚本标签使其适用于非发布版本的原因。

但是你应该使用 --release builds 因为...

如果您使用 --release 构建您的应用程序,文件内容的哈希值会添加到文件名中。这意味着当内容更改时,文件名也会更改。

由于旧版本的任何缓存(例如在 ISP 中)都是针对具有不同名称的文件的,因此保证请求具有更新名称的更新文件的客户端不会获得旧版本。

那么如何使用散列指定正确的 main.js 名称?

Html 组件应该在 <body> 中有一个 JSX 片段,例如:

    {script && (
      <script
        id="source"
        src={script}
        data-initial-state={JSON.stringify(state)}
      />
    )}

这在标准 RSK 中有效,因为 script 变量包含 main.js 文件名(使用 --release 构建时包含散列)。这个变量值来源于 assets.js,它是由 WebPack 构建的。然后通过从 server.js:

的注入提供给 Html 组件用于上面的片段
app.get('*', async (req, res, next) => {
  const data = { title: '', description: '', style: '', script: assets.main.js, children: '' };     
  // ...
  const html = ReactDOM.renderToStaticMarkup(<Html {...data} />);