2016-03-23 3 views
0

Я использую разъединить рендеринга с моим приложением и наткнулся на вопрос, при использовании среагировать расширение для Dragula библиотеки под названием react-dragulaИмпорт библиотеки, только если документ присутствует (не на сервере)

проблема здесь заключается в

import Dragula from 'react-dragula'; 

По какой-то причине это использует document, следовательно, вызывает ошибку во время рендеринга стороны сервера, поскольку документ отсутствует, поэтому мне нужен способ включить его только после того, как будет доступно document, чтобы я мог начать использовать его.

+0

хммм. хороший вопрос. Мы обычно используем изоморфные библиотеки, такие как «superagent» –

ответ

4

Нет никакого способа условно import что-то, но есть способ обойти. То, как я обычно сталкиваюсь с такими проблемами, заключается в создании отдельных сборок для использования сервером и клиентом и использовании process.env vars для дифференциации двух в процессе сборки. Это не требует большого изменения вашего кода, но таким образом можно несколько издеваться над зависимостью.

Вы могли бы, например, сделать что-то вроде этого:

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

В файле обертку, используйте CommonJS require вернуть правильный модуль:

/* 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'; 
}); 

Используйте это с преобразованием Envify для Browserify или аналогичного. И ты должен быть хорошим.

+0

, это интересно. –

1

Я не знаю, является ли это хорошей практикой. Но вы можете это сделать,

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

Это будет импортировать только dragula на стороне клиента. Компонент сделал mount никогда не запускается со стороны сервера.
Вам нужно будет включить проверки в вашу функцию рендеринга, чтобы увидеть, существует ли 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> 
    ) 
} 
+0

попробовал это, получил ошибки бабеля (babel - транспилятор, который я использую для es6). – Ilja

+0

Итак, вам также нужно будет изменить свой код, чтобы он только отображал ваш новый компонент после его импорта. Я добавил больше кода, чтобы показать, как именно я это сделал –

0

Добавление к dannyjolie предложение.

Вы можете использовать попробовать поймать вместо установки в Глоток/хрюкать

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