带有服务器端渲染的 Webpack-React:使用哈希名称链接到服务器模板中的 css 文件

Posted

技术标签:

【中文标题】带有服务器端渲染的 Webpack-React:使用哈希名称链接到服务器模板中的 css 文件【英文标题】:Webpack-React with server-side-rendering: linking to css file in server template with hash name 【发布时间】:2018-10-02 18:27:24 【问题描述】:

我正在准备一个从头开始的 react,代码如下:https://github.com/antondc/react-starter

我设法为客户端和服务器设置捆绑,使用 css 模块和更少,现在我使用服务器端渲染。我正在使用 js 模板进行操作:

// src/server/views/index.ejs
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>INDEX.EJS</title>
    <link rel="stylesheet" type="text/css" href="assets/index.css">
</head>
<body>
    <div id="app"></div>
    <script src="/assets/bundle.js"></script>
</body>
</html>

如您所见,指向 css 文件的链接在此处被硬编码。但是在我的 Webpack 配置中,我对这个文件名进行了哈希处理,因为我想在更新开发代码时防止浏览器缓存。

我想知道如何在此处链接 css 文件。现在在模板中我有href="assets/index.css,但css文件在/dist/assets/d47e.css中。

如果可以做href="assets/*.css 之类的事情,那就太好了,但不可能,那么解决此类问题的常用方法是什么?

谢谢!

【问题讨论】:

任何解决方案了吗? 【参考方案1】:

您可以使用HTMLWebpackPlugin 生成一个 HTML 文件,其中将插入您的 JS 和 CSS 输出。

【讨论】:

不明白你为什么建议用 Webpack 做这个,如果你读了这个问题你会发现 HTMLWebpackPlugin 不是一个可行的解决方案。 html webpack 插件对于这个用例不是一个好的解决方案,我们通过一个函数生成我们的模板并返回它的结果并使用它来注入 react 的最顶层组件渲染的结果字符串来创建我们的文件,所以在这种情况下它不应该是一个好的解决方案,如果你知道使用 html webpack 插件实现更好的解决方案,请不要犹豫与我们分享......【参考方案2】:

视情况而定。

第一步:获取当前资产名称

要获取生成的 webpack css/js 文件的当前名称,可以使用assets-webpack-plugin。这将(使用默认配置)在您的输出文件夹中生成一个 assets.json 文件,其结构基本如下:


    "bundle_name": 
        "asset_kind": "/public/path/to/asset"
    

第 2a 步:从模板(pug/jade/whatever)呈现您的 html

// in your render code

const assets = require('<webpack-output-folder>/assets.json');

// ...

res.render('template', 
 scripts: [src: `$WEBPACK_PUBLIC_PATH/$assets.myEntryPointName.js` ],
 links: [href: `$WEBPACK_PUBLIC_PATH/$assets.myEntryPointName.css` rel: 'stylesheet' ],
);

// in your template (example for pug)

// ...

each link in links
  link(rel=link.rel href=link.href)

// ...

each script in scripts
  script(src=script.src)

// ...

第 2b 步:您的 html 是静态的

您需要使用asset.json 文件中的信息更新html(使用脚本)。这个脚本需要在 webpack 之后运行。类似的东西

const assets = require('<webpack-output-folder>/assets.json');
const fs = require('fs');

const css = /assets\/[a-z0-9]*\.css/i;
const js = /assets\/[a-z0-9]*\.js/i;

fs.readFile('<yourhtml>.html', (err, data) => 

  // ... (error handling)

  const updatedCss = data.replace(css, assets.myEntryPointName.css);
  const updatedJs = updatedCss.replace(js, assets.myEntryPointName.js);

  fs.writeFile('<yourhtml>.html', updated, (err) => 

    // ... (error handling)

  );

);

【讨论】:

以上是关于带有服务器端渲染的 Webpack-React:使用哈希名称链接到服务器模板中的 css 文件的主要内容,如果未能解决你的问题,请参考以下文章

带有热重载的 ReactJS 服务器端渲染 (webpack-dev-server)

使用带有 NextJS 的 Apollo Client 时服务器端渲染数据?

带有服务器端渲染的 React 应用程序因负载而崩溃

Gatsby:在使用带有 JavaScript 的 Bootstrap 组件构建项目时,服务器端渲染期间“文档”不可用

react服务端渲染框架

如何在 React/redux 中进行服务器端渲染?