【问题标题】:Cannot find variable on client side react code在客户端反应代码上找不到变量
【发布时间】:2016-08-20 18:31:36
【问题描述】:

在研究了同构/通用 javascript 应用程序和服务器端渲染的好处后,我决定在项目中使用它。

我正在使用 Express.js 和 React.js 来实现服务端和客户端的渲染。

我最近遇到的一个问题是我的浏览器 javascript 找不到作为 React 组件的 React 变量。它给出了众所周知的ReferenceError: Can't find variable: QuestionBox的错误信息。

这个react组件在questionbox.js中定义,这个文件在由node.js中的babel转译后用于服务器端,在browserifyed和rectifyed在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);
});

【问题讨论】:

  • 这可能是您导出的方式吗?又名 module.exports = QuestionBox; 而不是 module.exports.QuestionBox = QuestionBox; 可能值得一试
  • 我现在正在尝试。
  • 我已经尝试过了,现在我有很长的错误消息说:Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. at invariant (/Users/isik/Dev/atelye/mt/node_modules/fbjs/lib/invariant.js:38:15) at instantiateReactComponent (/Users/isik/Dev/atelye/mt/node_modules/react/lib/instantiateReactComponent.js:66:134) at /Users/isik/Dev/atelye/mt/node_modules/react/lib/ReactServerRendering.js:37:31 at ReactServerRenderingTransaction.Mixin.perform... ...

标签: javascript reactjs gulp browserify react-jsx


【解决方案1】:

我认为问题在于组件没有(而且确实不应该)暴露在全局范围内。

browserify 包中的所有代码都无法从外部访问。所以接下来应该做的就是将渲染函数移到包中。

首先,您可以创建新文件(例如,entry.js)并将其设置为 gulpfile.js 中 browserify 的入口点:

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 包只被客户端使用,你不需要在服务器上做任何改变。

【讨论】:

  • 您可以查看gist
  • 是的,你说得对。您应该通过提供如何使用它来加强答案
  • @Роман,目前我的index.html 使用components/bundle.js 作为browserify 构建的入口点,并在gulp 任务中进行纠正。但是它没有您给出的最后一行,该行在index.html 中,因为服务器中也使用了相同的文件,而且ReactDOM 对服务器没有意义。所以,我把它放在了index.html
  • @ışık 您所做的所有更改都不会影响服务器。我已经用分步说明更新了答案。
  • 谢谢@Роман,我明白了。在router.js 中,服务器需要来自文件questionbox.js 的React 组件,因此不需要ReactDOM 文件,它是src/index.js 作为browserify 包的入口点以生成dist/bundle.js
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-22
  • 2016-12-05
  • 1970-01-01
  • 1970-01-01
  • 2012-07-28
  • 2016-05-27
  • 1970-01-01
相关资源
最近更新 更多