【问题标题】:React npm package: Do I need a different webpack config to be ssr safe?React npm 包:我需要不同的 webpack 配置来保证 ssr 安全吗?
【发布时间】:2020-08-14 07:40:06
【问题描述】:

我维护了一个小型 npm 包,我目前正尝试在 Gatsby 站点中使用它。我不是 webpack 专家,我正在努力使我的 npm 包 ssr 安全。

目前,如果我尝试gatsby build,它会抛出以下错误:

failed Building static HTML for pages - 0.829s WebpackError: ReferenceError: window is not defined

componentDidMount = () => {
  window.addEventListener( 'click', this.onClickCloseMenu, false );
} 

我将以下文件添加到我的包中:

// allows us to use window server-side
const safeWindow = (typeof window === 'undefined') ? {
    addEventListener() {},
    removeEventListener() {},
  } : window;

export default safeWindow;

并在我的代码中导入对象:

import safeWindow from './safeWindow';
...
    componentDidMount = () => {
        safeWindow.addEventListener( 'click', this.onClickCloseMenu, false );
    } 

但不幸的是,这没有帮助。我已经只在 useEffect/componentDid(Un)Mount 中使用了 window 但我猜是因为这是我需要定义它的编译错误。我的下一个猜测是构建/缩小我的包以将其发布到 npm 再次破坏了这一点,但我不确定。

这是我的 webpack 配置:

var path = require('path');

module.exports = {
    mode: 'production',
    entry: './src/DataListInput.jsx',
    output: {
        path: path.resolve('lib'),
        filename: 'DataListInput.js',
        libraryTarget: 'commonjs2'
    },
    module: {
        rules: [
            {
                test: /\.jsx?$/,
                exclude: /(node_modules)/,
                use: 'babel-loader'
            },
            {
                test: /^(?!.*?\.module).*\.css$/,
                use: ['style-loader', 'css-loader']
            },
            {
                test: /\.module\.css$/,
                use: ['style-loader', {
                    loader: 'css-loader',
                    options: {
                        modules: true
                    }
                }]
            }
        ]
    }
}

非常感谢任何帮助!

找到npm包here

更新

我现在很确定它与 webpack 将 css 与 javascript 一起打包到缩小文件中有关,这需要同时调用窗口和文档。有人经历过类似的事情吗?我该如何解决这个问题?

更新 2

我通过删除 css 解决了这个问题。我创建了一个没有 css 的新 ssr 安全 npm 包。感觉更像是一种变通方法而不是一种解决方案,所以如果有一种方法可以捆绑 css + javascript 并与 ssr 兼容,我仍然很感兴趣。

【问题讨论】:

    标签: reactjs npm webpack gatsby server-side-rendering


    【解决方案1】:

    safeWindow 从常量更改为getSafeWindow 函数应该可以修复它。

    在可以导入模块之前评估一个常量。而函数版本仅在运行时调用时才会访问窗口。

    const getSafeWindow = () => (typeof window === 'undefined') ? {
        addEventListener() {},
        removeEventListener() {},
      } : window;
    

    【讨论】:

    • 感谢您的回复!我会试试看!知道为什么我的 componentDidMount 函数中的if(typeof window !== 'undefined') window.addEventListener() 失败了吗?我觉得它应该符合这个推理。
    • 我检查了 gatsby 的问题,我同意将它放入 componentDidMount 应该可以。也许您仍在导入 safeWindow,但它失败了?
    • 我认为这与我的 webpack 配置有关,即使我从代码中删除所有 setTimeouts/addEventListeners 并使用 webpack,它仍然会在构建中包含对 window 的提及。所以我想我必须为此调整配置。
    • 也许你的 webpack 配置正在捆绑 react 和 react dom。也许您可以将它们设为外部:github.com/webpack/webpack/issues/1275
    • 感谢您的支持。它抛出了未找到的反应,但使用它代替了工作:github.com/webpack/webpack/issues/1275#issuecomment-225644823 但我仍然得到 Gatsby 相同的窗口未定义错误。
    猜你喜欢
    • 1970-01-01
    • 2022-01-12
    • 2019-10-12
    • 2022-09-27
    • 1970-01-01
    • 1970-01-01
    • 2017-03-18
    • 2019-12-29
    • 2013-04-15
    相关资源
    最近更新 更多