我维护了一个小的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感兴趣。
改变 safeWindow
由常数变成 getSafeWindow
函数应该可以解决这个问题。
在导入模块之前,要先评估一个常量。而函数版本只有在运行时被调用时才会访问窗口。
const getSafeWindow = () => (typeof window === 'undefined') ? {
addEventListener() {},
removeEventListener() {},
} : window;