【问题标题】:Using materialize-css in express/react SSR app在 express/react SSR 应用程序中使用 materialize-css
【发布时间】:2020-03-15 21:12:26
【问题描述】:

我有一个使用服务器端渲染 (SSR) 来渲染 React 应用程序的快速服务器。

我想将 materialize-css 包与我的 react 应用程序一起使用。

我已将materialize-css/dist/css/materialize.min.cssmaterialize-css/dist/js/materialize.min 导入我的App.js。

在我使用 express 渲染我的应用服务器端之前,它工作正常,来自 materialize 的样式和模态已正确加载。

现在,当我尝试使用 express 渲染我的应用时,出现以下错误:

[0] ReferenceError: window is not defined
[0]     at Object.<anonymous> (/Users/user/Sites/task_keeper/node_modules/materialize-css/dist/js/materialize.min.js:6:1135)
[0]     at Module._compile (internal/modules/cjs/loader.js:778:30)
[0]     at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
[0]     at Module.load (internal/modules/cjs/loader.js:653:32)
[0]     at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
[0]     at Function.Module._load (internal/modules/cjs/loader.js:585:3)
[0]     at Module.require (internal/modules/cjs/loader.js:692:17)
[0]     at require (internal/modules/cjs/helpers.js:25:18)
[0]     at eval (webpack:///external_%22materialize-css/dist/js/materialize.min%22?:1:18)

这是我的渲染中间件:

const renderMiddleware = () => (req, res) => {
  let html = req.html;
  const htmlContent = ReactDOMServer.renderToString(<App />);
  const htmlReplacements = {
    HTML_CONTENT: htmlContent,
  };

  Object.keys(htmlReplacements).forEach(key => {
    const value = htmlReplacements[key];
    html = html.replace(
      new RegExp('__' + escapeStringRegexp(key) + '__', 'g'),
      value
    );
  });

  res.send(html);
};

然后我在index.js 中使用水合物,

ReactDOM.hydrate(<App />, document.getElementById('root'));.

在这样的设置中使用materialize-css 的正确方法是什么?

【问题讨论】:

  • window 应该是文档的父对象,在服务器端它不存在,因为它与浏览器相关并且可能是一个虚拟容器。如果您使用 (I) 框架,您可能会注意到类似的问题。
  • @David 感谢您的回复。我知道窗口和文档在服务器端不可用,所以我正在考虑在应用程序呈现服务器端后加载 js。你认为这可能吗?
  • windowdocument 并没有太大变化,但这可能使您能够首先无错误地进行渲染。所以是的,听起来是一个合理且好的解决方案。
  • 另一个问题是您是否可以模拟窗口和文档服务器端,但如果不需要,那可能会更好
  • 我发现这篇文章看起来很有趣,stackoverflow.com/questions/32126003/…

标签: javascript reactjs express materialize server-side-rendering


【解决方案1】:

您可以通过使用 CDN 加载脚本来解决此问题,如下所示:

<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>

这样脚本被注入到window变量中,所以你可以使用window.M.AutoInit(),例如。

所以在你使用模态框的组件中,在 useEffect 回调中自动初始化它们:

useEffect(() => {
  window.M.AutoInit();
}, []);

【讨论】:

  • &lt;script src="..."&gt; 不能在那种服务器端工作。
  • 是的,如果我将它包含在我的 app.html 中。
  • 啊,好吧,我从来没有这样考虑过;-)
猜你喜欢
  • 1970-01-01
  • 2016-05-31
  • 2018-05-24
  • 1970-01-01
  • 1970-01-01
  • 2018-02-21
  • 2017-11-09
  • 2019-06-13
  • 1970-01-01
相关资源
最近更新 更多