【问题标题】:Build React components with Gulp, Browserify and Babel使用 Gulp、Browserify 和 Babel 构建 React 组件
【发布时间】:2016-03-21 16:54:03
【问题描述】:

我已经创建了一个 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';

我错过了什么?

编辑

正如我所见,奇怪的 requires 来自于在组件文件中要求 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');,那些 requires (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

【问题讨论】:

  • 你有什么问题?
  • @JMM 当我尝试使用 react 应用程序中的组件时,gulp 会抛出错误 Error: Cannot find module ' ./emptyFunction'
  • 错误是在编译时还是在运行时?你得到一个文件dist/bundle.js,对吧?所有依赖项都应该在该包中。因此,您突出显示的 require() 调用应解析为捆绑包中的某些内容。
  • @JMM 在运行时。是的,我得到一个文件dist/bundle.js。好的,所以如果所有依赖项都应该在那个包中,如何处理呢?我只需要 React 作为依赖项。
  • 好的,所以这不是 gulp 抛出错误。我不知道 - 从示例中不清楚您为什么会收到该错误。

标签: reactjs gulp browserify babeljs


【解决方案1】:

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

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

问题与 gulp 无关。我也不知道您是如何/何时收到您在 cmets 中描述的运行时错误。根据您的最新信息,问题是您正在使用 browserify 创建 bundle A,然后使用 browserify 创建 bundle B,在其依赖关系图中使用 A,并且 browserify 正在尝试解决相对 require()'已经捆绑在 A 中的 s。引用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 目录膨胀。

【讨论】:

  • 感谢您的回答,但我不确定这对我的情况是否有意义。我的组件就像第一个问题的版本(更多...)。只需要 React 来定义我的组件。每个想要安装和使用此组件的人都必须安装 React,因此该组件将使用与使用该组件的应用程序相同的 React 实例。我很难让我说清楚:P 我已经尝试过你所说的,但没有用,derequire 没有改变任何东西,第二个选项也没有,最后一个给我一个错误(使用 uglify): TypeError: file.isNull is not a function.
  • 我用新建议更新了答案。但是很难完全理解你在做什么。
  • 嗯,我已经实现了让它工作的一个小技巧。我已经将我的更改推送到 Github,因为它已经可以使用了。这是回购:github.com/msalsas/react-svg。我还想从src/react-svg.js 导出所有组件,但这是另一回事。 hack 包括运行 gulp 而不需要方法,然后手动将它们添加到 build.js。同时删除第一行和最后一行(在gulpfile.js 中有解释)。感谢您的大力帮助:)
  • 我看了你的回购。你试过.external("react") 电话吗?这可能会奏效,而且会更干净,并且可以避免您不得不手动处理事情。
  • 工作了一半。我仍然需要分别删除build.js:(function e(t,n,r){function s(o,u)...},{"react":"react"}]},{},[1]); 的第一行和最后一行。否则我会得到这个运行时错误:bundle.js:88399 Uncaught Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
猜你喜欢
  • 1970-01-01
  • 2016-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多