React npm包。我需要一个不同的webpack配置来保证ssr安全吗?

问题描述 投票:0回答:1

我维护了一个小的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 );
    } 

但不幸的是,这并没有帮助。我已经在useEffectcomponentDid(Un)Mount中只使用了window,但我猜测既然是编译错误,我需要定义它。我的下一个猜测是,在构建minifying我的包以将其发布到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包 此处

更新

我现在非常确定,这与webpack在minified文件中把css和javascript捆绑在一起有关,这需要调用window和document。有人遇到过类似的情况吗?我该如何解决这个问题?

更新2

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

reactjs npm webpack gatsby server-side-rendering
1个回答
1
投票

改变 safeWindow 由常数变成 getSafeWindow 函数应该可以解决这个问题。

在导入模块之前,要先评估一个常量。而函数版本只有在运行时被调用时才会访问窗口。

const getSafeWindow = () => (typeof window === 'undefined') ? {
    addEventListener() {},
    removeEventListener() {},
  } : window;
© www.soinside.com 2019 - 2024. All rights reserved.