1

我在我的应用程序中使用服务器渲染,并在使用名为react-dragula的 Dragula 库的反应扩展时遇到了一个问题

这里的问题在于

import Dragula from 'react-dragula';

由于某种原因,这种使用document会在服务器端渲染期间导致错误,因为文档不存在,因此我需要一种方法来仅包含它一次document可用,以便我可以开始使用它。

4

3 回答 3

4

没有办法有条件地import做某事,但有办法解决。我通常解决此类问题的方法是为服务器和客户端使用创建单独的构建,并使用 process.env vars 在构建过程中区分两者。它不需要对您的代码进行太多更改,但是这样可以在某种程度上模拟依赖项。

例如,您可以执行以下操作:

import Dragula from './my-dragula-wrapper'

在您的包装文件中,使用 CommonJSrequire返回正确的模块:

/* my-dragula-wrapper.js */
if(process.env.SOME_VAR === 'server'){
  module.exports = function(){}; // Or something, it's not going to be used anyway
} else {
  module.exports = require('react-dragula');
}

然后只需在构建过程中设置正确的 process.env.SOME_VAR 值即可,无论是 Gulp 或 Grunt 还是本周很酷的任何东西。

gulp.task('env:server', function(){
    return process.env.SOME_VAR = 'server';
});

gulp.task('env:client', function(){
        return process.env.SOME_VAR = 'client';
});

将其与 Browserify 或类似的 Envify 转换一起使用。你应该很好。

于 2016-03-23T13:14:34.410 回答
2

我不知道这是否是一个好习惯。但你可以这样做,

componentDidMount(){
    var Dragula = require('Dragula')
}

这只会在客户端导入dragula。组件确实安装永远不会从服务器端运行。
您必须在渲染函数中包含检查,以查看 Dragula 是否存在。但是这样的事情会起作用。我刚刚做完。
我所做的是,

var something // so that it has scope in all functions 
componentDidMount(){
    something = require('something')
    this.setState({somethingExists: true})
}
render(){
    return(
        <div> {this.state.somethingExists ? <something> : null } </div>
    )
}
于 2016-04-12T14:41:05.317 回答
0

添加到 dannyjolie 的建议。

您可以使用 try catch 而不是在 gulp/grunt 中设置

try {
  if(window) 
     module.exports = require('react-dragula');
}  
catch(ex) 
{
 module.exports = function(){};
}
于 2017-03-29T21:51:48.783 回答