2016-04-26 6 views
3

После некоторого исследования преимуществ изоморфных/универсальных приложений javascript и рендеринга на стороне сервера, я решил использовать его в проекте.Не удается найти переменную на стороне реакции на стороне клиента

Я использую Express.js и React.js для обеспечения рендеринга на стороне сервера и на стороне клиента.

Одна проблема, с которой я столкнулся недавно, - это мой браузер. Javascript не может найти переменную React, которая является компонентом React. Он дает сообщение об ошибке известного ReferenceError: Can't find variable: QuestionBox.

Этот компонент реагирует определяется в questionbox.js и этот файл используется для серверной стороне после transpiled по babel в Node.js и для стороны клиента после оказания browserify ред и rectify ред в gulp задачи.

Что может быть здесь, здесь мне не хватает? Это может быть обработанный gulp преобразованный файл, который загружается браузером тегом скрипта. The full code is in this gist.

questionbox.js:

var React = require('react'); 
var marked = require('marked'); 
/* 
    -QuestionBox 
     -QuestionList 
      -Question 
*/ 
var Question = React.createClass({//Omitted here for simplicity: https://gist.github.com/isikfsc/b19ccb5e396fd57693d2f5b876ea20a0}); 

var QuestionList = React.createClass({//Omitted here for simplicity: https://gist.github.com/isikfsc/b19ccb5e396fd57693d2f5b876ea20a0}); 

var QuestionBox = React.createClass({ 
    loadQuestionsFromServer: function() { 
     return true; 
    }, 
    getInitialState: function() { 
    return {data: []}; 
    }, 
    componentWillMount: function() { 
    this.loadQuestionsFromServer(); 
    setInterval(this.loadQuestionsFromServer, this.props.pollInterval); 
    }, 
    render: function() { 
    return (
     <div className="questionBox"> 
     <h1>Questions</h1> 
     <QuestionList data={this.state.data} /> 
     </div> 
    ); 
    } 
}); 

module.exports.QuestionBox = QuestionBox; 

gulpfile.js:

var gulp = require('gulp'); 
var browserify = require('browserify'); 
var watchify = require('watchify'); 
var source = require('vinyl-source-stream'); 
var reactify = require('reactify'); 

var production = process.env.NODE_ENV === 'production'; 

function scripts(watch) { 
    var bundler, rebundle; 
    bundler = browserify('src/components/questionbox.js', { 
    basedir: __dirname, 
    debug: !production, 
    cache: {}, // required for watchify 
    packageCache: {}, // required for watchify 
    fullPaths: watch // required to be true only for watchify 
    }); 
    if(watch) { 
    bundler = watchify(bundler) 
    } 

    bundler.transform(reactify); 

    rebundle = function() { 
    var stream = bundler.bundle(); 
    //stream.on('error', handleError('Browserify')); 
    stream = stream.pipe(source('bundle.js')); 
    return stream.pipe(gulp.dest('./dist/components')); 
    }; 

    bundler.on('update', rebundle); 
    return rebundle(); 
} 

gulp.task('watchScripts', function() { 
    gulp.watch('./src/components/*.js', ['scripts']); 
}); 

gulp.task('scripts', function() { 
    return scripts(false); 
}); 

gulp.task('watchScripts', function() { 
    return scripts(true); 
}); 
+0

Возможно, это так, как вы экспортируете? aka 'module.exports = QuestionBox;' вместо 'module.exports.QuestionBox = QuestionBox;' может стоить попробовать –

+0

Я пытаюсь это прямо сейчас. –

+0

Я пробовал это, и теперь у меня появилось долгое сообщение об ошибке: 'Invariant Violation: Тип элемента недействителен: ожидается строка (для встроенных компонентов) или класс/функция (для составных компонентов), но получила: undefined. at инвариант (/Users/isik/Dev/atelye/mt/node_modules/fbjs/lib/invariant.js:38:15) at instantiateReactComponent (/ Пользователи/isik/Dev/atelye/mt/node_modules/response/lib/instantiateReactComponent.js: 66: 134) по адресу /Users/isik/Dev/atelye/mit/node_modules/react/lib/ReactServerRendering.js:37:31 at ReactServerRenderingTransaction.Mixin.perform ... '... –

ответ

1

Я считаю, что проблема заключается в том, что компонент не является (и на самом деле не должно быть) подвергается воздействию глобального масштаба.

Весь код внутри броузера обозревателя не доступен извне. Итак, что нужно сделать дальше, это перемещение функции рендеринга в пакет.

Начнем с того, вы можете создать новый файл (скажем, entry.js) и установить его в качестве отправной точки для browserify в gulpfile.js:

bundler = browserify('src/entry.js', { 

Тогда, Вы можете переместить JavaScript из шаблона (. ejs) в эту точку входа.

var ReactDOM = require('react-dom'); 
var QuestionBox = require('./components/questionbox.js').QuestionBox; 

ReactDOM.render(QuestionBox({}), document.getElementById('mount-node')); 

Пока browserify пучок используется только клиентом, Вам не надо ничего менять на сервере.

+0

Вы может проверить [gist] (https://gist.github.com/isikfsc/b19ccb5e396fd57693d2f5b876ea20a0) –

+0

yep youre right. вы должны усилить ответ, указав, как его использовать. –

+0

@ Роман. В настоящий момент мой 'index.html' использует' components/bundle.js'а - точку входа, созданную браузером и исправляемую внутри задачи gulp. Однако у нее нет последней строки, которую вы указали, эта строка находится в 'index.html', так как тот же файл также используется на сервере, и он,' ReactDOM', не имеет смысла для сервера.Итак, я поместил его в 'index.html'. –

Смежные вопросы