使用gulp-browserify来处理我的React.js模块时,在浏览器中出现了“require未定义”的错误。

21

我将使用gulp-browserify生成bundle.js文件,以便在客户端浏览器中包含并开始渲染React组件。

这是我的App.js文件:

/** @jsx React.DOM */
var React = require('react');

var App = React.createClass({
  render: function() {
    return <h1>Hello {this.props.name}!</h1>;
  }
});

module.exports = App;

我的 package.json 文件如下:

  "name":"hellosign-gulp",
  "version":"0.1.1",
  "dependencies": {
    "gulp": "3.5.x",
    "gulp-browserify": "0.5.0",
    "reactify": "~0.8.1",
    "react": "^0.10.0",
    "gulp-react": "0.2.x"
  }
}

和我的 gulpfile

var   gulp = require('gulp'),
  react = require('gulp-react'),
  browserify = require('gulp-browserify');


gulp.task('brow-test', function() {
    // Single entry point to browserify
    gulp.src('./src/App.js', {read: false})
        .pipe(browserify({
          insertGlobals : true,
          transform: ['reactify'],
          extensions: ['.jsx'],
          debug :false.
        }))
        .pipe(gulp.dest('.'))
});

现在当我运行“brow-test”时,我将输出文件重命名为bundle.js,并将其与HTTP响应一起包含在浏览器中。 bundle.js文件相当大,因此我不会在此处包含它,但是浏览器最终会抛出一个错误。
未捕获的引用错误:require未定义。
我使用以下命令正确地运行了常规版本的browserify,具有完全相同的设置。
browserify -t reactify -r react -r ./src/App > ../webapp/static/bundle.js

然后我就不会再出现错误了。为什么gulp-browserify没有正确创建require shim?

我不相信设置是一样的,因为你在命令行上执行了-r react -r ./src/App(对gulp不是很熟悉)。 - Brigand
1
你可以使用 vinyl-source-stream 和 gulp-buffer 在 gulp 中运行常规的 browserify。这就是我们所做的,因为 gulp-browserify 从未对我们产生足够好的效果。 - David Hellsing
我仍然无法让全局 require 被暴露出来。我简化了问题并在这里发布了一个新的问题: https://dev59.com/2IDba4cB1Zd3GeqPJNJg - asolberg
使用Browserify和Vinyl-source流改善了您的工作流程吗? - the_5imian
7个回答

12

更新: 我写了一篇关于使用不同打包工具的新文章,其中还包括了一个经过优化的 Browserify 示例:为 React JS 选择正确的打包工具

对于任何想要运行 React JS 工作流程的人:

我在实践中遇到了很多问题,最终我撰写了一篇关于此的文章:React JS 和 Browserify 工作流程。这是我的解决方案,确保您可以转换 JSX 并处理其他文件的单独监视。

var gulp = require('gulp');
var source = require('vinyl-source-stream'); // Used to stream bundle for further handling etc.
var browserify = require('browserify');
var watchify = require('watchify');
var reactify = require('reactify'); 
var concat = require('gulp-concat');

gulp.task('browserify', function() {
    var bundler = browserify({
        entries: ['./app/main.js'], // Only need initial file, browserify finds the deps
        transform: [reactify], // We want to convert JSX to normal javascript
        debug: true, // Gives us sourcemapping
        cache: {}, packageCache: {}, fullPaths: true // Requirement of watchify
    });
    var watcher  = watchify(bundler);

    return watcher
    .on('update', function () { // When any files update
        var updateStart = Date.now();
        console.log('Updating!');
        watcher.bundle() // Create new bundle that uses the cache for high performance
        .pipe(source('main.js'))
        // This is where you add uglifying etc.
        .pipe(gulp.dest('./build/'));
        console.log('Updated!', (Date.now() - updateStart) + 'ms');
    })
    .bundle() // Create the initial bundle when starting the task
    .pipe(source('main.js'))
    .pipe(gulp.dest('./build/'));
});

// I added this so that you see how to run two watch tasks
gulp.task('css', function () {
    gulp.watch('styles/**/*.css', function () {
        return gulp.src('styles/**/*.css')
        .pipe(concat('main.css'))
        .pipe(gulp.dest('build/'));
    });
});

// Just running the two tasks
gulp.task('default', ['browserify', 'css']);

要解决在Chrome中使用React JS开发工具的问题,在您的main.js文件中,您需要执行以下操作:

/** @jsx React.DOM */

var React = require('react');
// Here we put our React instance to the global scope. Make sure you do not put it 
// into production and make sure that you close and open your console if the 
// DEV-TOOLS does not display
window.React = React; 

var App = require('./App.jsx');
React.renderComponent(<App/>, document.body);

我希望这能帮助你开始!


我在我的项目中使用了你的文章,谢谢!我正在努力弄清楚如何让reactify接受harmony jsx的内容。我尝试了transform: [[reactify, {"harmony": true}]] ..但没有成功? - David Tinker
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - christianalfoni
不确定你的/app/main.jsmain.js之间有什么区别...它们是不同的文件吗? - Alexander Suraphel
提供你的 package.json 将会非常好。 - Alexander Suraphel
请查看提到的文章 :-) 它还有一个包含您所需内容的样板。 - christianalfoni
现在我们要使用babelify转换器吗? - Tjorriemorrie

8

直接在文件上运行browserify,不使用gulp-browserify插件。

参考链接:https://github.com/gulpjs/plugins/issues/47

“Browserify应该作为独立模块使用。它返回一个流并找出您的依赖关系图。如果需要vinyl对象,请使用browserify + vinyl-source-stream”

您可以像这样实现所需的结果:

var source = require('vinyl-source-stream'), //<--this is the key
    browserify = require('browserify');

    function buildEverything(){
        return browserify({
               //do your config here
                entries: './src/js/index.js',
            })
            .bundle()
            .pipe(source('index.js')) //this converts to stream
             //do all processing here.
             //like uglification and so on.
            .pipe(gulp.dest('bundle.js'));
        }
    }

    gulp.task('buildTask', buildEverything);

现在,在您的包 Json 中,您已经有了 - require react, browserify 等等。您还可以在此处 shim browserify,使用 transforms 或其他任何内容。

  "dependencies": {
    "react": "^0.10.0",  
  },
  "devDependencies": {
     "browserify": "3.46.0",
    "browserify-shim": "3.x.x",
   }
  "browserify": {
    "transform": [
      "browserify-shim"
    ]
  },
  "browserify-shim": {
     "react": "React", 
  }

或者像你现在这样做,将React包含在你使用它的页面中。
var React = require('react');

如果您需要一些方便的助手工具,可以使用以下内容:
var React = require('react/addons');

但归根结底,是要直接在gulp中使用browserify,并使用vinyl-source-stream将其纳入gulp管道。


2

我在我的React工作中使用这个。

var gulp = require('gulp');
var source = require('vinyl-source-stream'); 
var browserify = require('browserify');
var watchify = require('watchify');
var reactify = require('reactify'); 
var concat = require('gulp-concat');
 
gulp.task('browserify', function() {
    var bundler = browserify({
        entries: ['./assets/react/main.js'], 
        transform: [reactify],
        debug: true, 
        cache: {}, packageCache: {}, fullPaths: true 
    });
    var watcher  = watchify(bundler);

    return watcher
    .on('update', function () { 
        var updateStart = Date.now();
        console.log('Updating!');
        watcher.bundle() 
        .pipe(source('main.js'))
    
        .pipe(gulp.dest('./assets/js/'));
        console.log('Updated!', (Date.now() - updateStart) + 'ms');
    })
    .bundle() 
    .pipe(source('main.js'))
    .pipe(gulp.dest('./assets/js/'));
});



gulp.task('default', ['browserify']);


1
这是使用browserify(配合vinyl-transform等工具)实现与以下内容完全相同的gulp配方:

browserify -t reactify -r react -r ./src/App > ../webapp/static/bundle.js`

src/App.js 中。
/** @jsx React.DOM */
var React = require('react');

var App = React.createClass({
  render: function() {
    return <h1>Hello {this.props.name}!</h1>;
  }
});

module.exports = App;

gulpfile.js 中。
var gulp = require('gulp');
var browserify = require('browserify');
var transform = require('vinyl-transform');
var reactify = require('reactify');
var rename = require("gulp-rename");

gulp.task('build', function () {

  // browserify -t reactify -r react -r ./src/App > ../webapp/static/bundle.js

  var browserified = transform(function(filename) {
    return browserify()

      // -t reactify
      .transform(reactify)

      // -r react
      // update below with the correct path to react/react.js node_module
      .require('./node_modules/react/react.js', { expose: 'react'})

      // -r ./src/App
      // filename = <full_path_to>/src/App.js
      .require(filename, {expose: 'src/App'})
      .bundle();
  });
  return gulp.src('./src/App.js')
    .pipe(browserified)
    .pipe(rename('bundle.js'))
    .pipe(gulp.dest('../webapp/static/'));
});

gulp.task('default', ['build']);

0

package.json:

{
  "devDependencies": {
    "gulp": "^3.8.11",
    "gulp-browserify": "^0.5.1",
    "reactify": "^1.1.0"
  },
  "browserify": {
    "transform": [["reactify", { "es6": true }]],
    "insertGlobals": true,
    "debug": true
  }
}

gulpfile.js:

var gulp = require('gulp');
var browserify = require('gulp-browserify');

gulp.task('browserify', function() {
    return gulp.src("./assets/index.js")
        .pipe(browserify())
        .pipe(gulp.dest("./www/assets"));
});

不建议使用 gulp-browserify,因为它目前被列入黑名单。最好使用 browserify 包代替。 - Con Antonakos

0

定义

React=require('react');
ReactDOM = require('react-dom');

将那些全局 JavaScript 变量放在 App.js 中,然后加入这个

var stream = require('vinyl-source-stream');
var browserify = require('browserify');
    browserify(source + '/app/app.js')
        // bundles it and creates a file called main.js
        .bundle()
        .pipe(stream('main.js'))
        // saves it the dest directory
        .pipe(gulp.dest(destination +'/assets/js'));

在 Gulpfile.js 中。

最后,在 HTML 中放置 main.js,它应该可以工作。

问题是如果我们使用 var React=require('react'),那么对象 React 在其他脚本中不可见,但 React=require('react') 定义了一个全局值。


0

我没有直接看出你的代码有什么问题,但是我正在使用这个:

gulp.src('./src/js/index.js') .pipe(browserify()) .on('prebundle', function(bundle) { // React Dev Tools tab won't appear unless we expose the react bundle bundle.require('react'); }) .pipe(concat('bundle.js'))

我曾经使用https://www.npmjs.org/package/gulp-react来转换.jsx文件,但现在我更喜欢使用普通的JavaScript。

如果这对你有用,请告诉我,如果不行,我可以提供一个示例模板...


此代码运行失败并出现错误:TypeError: Object #<Browserify> 没有 'pipe' 方法。 - asolberg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接