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

Webpack-React with server-side-rendering: linking to css file in server template with hash name

提问人: 提问时间:4/23/2018 更新时间:3/9/2019 访问量:1322

问:

我正在从头开始准备一个 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文件。现在在我有的模板中,但css文件在.href="assets/index.css/dist/assets/d47e.css

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

谢谢!

CSS ReactJS Webpack 服务器端

评论

0赞 amdev 3/3/2019
有什么解决方案吗?

答:

-1赞 jpdelatorre 4/23/2018 #1

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

评论

0赞 4/23/2018
不明白你为什么建议用 Webpack 这样做,如果你阅读了这个问题,你会注意到 HTMLWebpackPlugin 不是一个可行的解决方案。
0赞 amdev 3/6/2019
HTML webpack 插件对于这个用例来说不是一个好的解决方案,我们通过一个函数生成我们的模板并返回它的结果,并用它来将 React 最顶级组件渲染到字符串的结果注入到它来创建我们的文件,所以在这种情况下它应该不是一个好的解决方案, 如果您知道任何更好的解决方案来实现 HTML webpack 插件,请不要犹豫与我们分享......
3赞 pintxo 3/9/2019 #2

这要视情况而定。

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

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

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

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

// 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)

  });

});