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

IT技术 reactjs gulp browserify babeljs
2021-05-18 21:32:21

我创建了一个 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 installbuild.js文件是在 下创建的/dist,但是当我尝试从其他 React 应用程序使用此组件时,我收到错误消息:

错误:找不到module“./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明显。

编辑2:

正如@JMM 所建议的那样,我应该在dist文件夹中拥有依赖项(在我的情况下是 React) ,但是我应该如何实现它?如果我的组件有更多的依赖怎么办?我以为我只需要在package.json.

编辑3:

我终于意识到我不需要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个回答

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

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

问题与 gulp 无关。我也不知道您是如何/何时收到您在评论中描述的运行时错误的。根据您的最新信息,问题在于您正在A使用 browserify创建捆绑包,然后B使用 browserifyA在其依赖关系图中创建捆绑包,而 browserify 正在尝试解析require()已经捆绑在A. 这个答案中引用如何处理:

这里有几个选项:

  • 在使用/发布之前在 bundle 上运行derequireA

  • 尝试像这样浏览您的应用程序:

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

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

  • A在消费之前缩小捆绑包

可以在substack/node-browserify#1151 中找到对该问题的更详细解释

我不确定将 React 与您的组件捆绑在一起是否可行。我不确定,但我认为在那种情况下人们必须对等依赖于 React(隐式或显式)。在 bundle 中包含 React 意味着不同的组件会尝试使用不同的 React 实例,这可能会给你带来问题,并且肯定会node_modules为每个执行它的组件增加目录。