使用Gulp,Browserify和Babel构建React组件

时间:2016-03-21 16:54:04

标签: reactjs gulp browserify babeljs

我已经创建了一个React组件,我想分发这个组件的内置版本(用gulp构建),所以在gulpfile.js我有:

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

gulp.task('build-js', function() {
    return browserify('./src/Foo.js')
        .transform(babelify)
        .bundle()
        .pipe(source('bundle.js'))
        .pipe(gulp.dest('./dist'));
});

gulp.task('build', ['build-js']);

.babelrc

{
  "presets": ["es2015", "react", "stage-0"],
}

这些是package.json

中的依赖项
"dependencies": {
    "react": "^0.14.7"
}
"devDependencies": {
  "babel-polyfill": "^6.3.14",
  "babel-preset-es2015": "^6.3.13",
  "babel-preset-react": "^6.3.13",
  "babel-preset-stage-0": "^6.3.13",
  "babelify": "^7.2.0",
  "browserify": "^13.0.0",
  "gulp": "^3.9.1",
  "react": "^0.14.7",
  "react-dom": "^0.14.7",
  "vinyl-source-stream": "^1.1.0"
}

当我在gulp build下创建npm install build.js之后/dist文件时,但当我尝试从其他React应用程序使用此组件时,我收到错误:

  

错误:找不到模块'./emptyFunction'。

如果我深入研究这个文件(build.js),我可以看到以下几行:

var emptyFunction = require('./emptyFunction');
...
var camelize = require('./camelize');

./dist下不存在这些文件,因此当我尝试构建调用该组件的新React应用程序时会引发错误:

import Foo from 'my-components-in-node-modules';

我错过了什么?

修改

正如我所看到的,奇怪的需要来自组件文件中的React:

var React = require('react');
// or import React from 'react';

class Foo extends React.Component {
    static propTypes = {...};
    static defaultProps = {...};
    render() {...}
}
export default Foo; 

如果我删除var React = require('react');那些需要(emptyFunction,camelize)消失,错误为React is not defined,显然。

EDIT2:

正如@JMM建议的那样,我应该在dist文件夹中拥有依赖项(在我的情况下为React),但我该如何实现呢?如果我的组件有更多依赖项怎么办?我认为我必须在package.json中定义依赖关系。

EDIT3:

我终于意识到我不需要browserify,只需要gulp-babel

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

gulp.task('bundle', bundle);

function bundle () {
  gulp.src('./src/*.js')
    .pipe(babel())
    .pipe(gulp.dest('./dist'));
}

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

就是这样。完整的示例如下:react-svg-components

1 个答案:

答案 0 :(得分:2)

根据您最近的解释,您可能需要在浏览组件时执行以下操作:

browserify('./src/Foo.js')
// Note this call:
.external("react")
.transform(babelify)
.bundle()

这个问题与gulp无关。我也不知道你是如何/何时得到你在评论中描述的运行时错误。根据您的最新信息,问题是您正在使用browserify创建捆绑A,然后使用browserify创建捆绑B,其依赖关系图中包含A,并且浏览器正在尝试解析require()中已捆绑的相对A。引自this answer以了解如何处理:

以下是一些选项:

  • 在使用/发布之前在包A上运行derequire

  • 尝试按以下方式浏览您的应用:

    browserify({
      entries: ['./entry'],
      noParse: ['my-components-in-node-modules'],
    })
    

    如果不起作用,请尝试绝对路径(require.resolve('my-components-in-node-modules'))。

  • 在使用之前缩小捆绑A

有关该问题的更详细说明,请参阅substack/node-browserify#1151

我不确定将React与您的组件捆绑是可行的方法。我不确定,但我认为在这种情况下,人们必须依赖于React(隐式或显式)。在包中包含React意味着不同的组件会尝试使用不同的React实例,这可能会导致问题,并且肯定会使每个组件的node_modules目录膨胀。