仅当文档存在时才导入库(不在服务器上)

Import library only if document is present (not on server)

我在我的应用程序中使用服务器渲染,在使用名为 react-dragula

的 dragula 库的反应扩展时遇到问题

这里的问题在

import Dragula from 'react-dragula';

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

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

例如,您可以这样做:

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

在你的包装文件中,使用 CommonJS require 到 return 正确的模块:

/* 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 转换一起使用。你应该很好。

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

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>
    )
}

加入 dannyjolie 的建议。

您可以使用 try catch 代替 gulp/grunt

中的设置
try {
  if(window) 
     module.exports = require('react-dragula');
}  
catch(ex) 
{
 module.exports = function(){};
}