用Gulp,Browserify和Babel构建React组件 [英] Build React components with Gulp, Browserify and Babel

查看:182
本文介绍了用Gulp,Browserify和Babel构建React组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  var gulp = require('gulp'); 
var browserify = require('browserify');
var babelify = require('babelify');
var source = require('vinyl-source-stream');
$ b $ 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

 依赖关系:{
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应用程序时引发错误:

 从'my-组件 - 在节点模块; 

我缺少什么?

Edit



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

  var React = require('react'); 
//或从'react'导入React;

class Foo扩展React.Component {
static propTypes = {...};
static defaultProps = {...};
render(){...}
}
导出默认Foo;

如果我删除 var React = require('react'); code>那些需要(emptyFunction,camelize)消失,显然错误是 React未定义



Edit2:

正如@JMM所示,我应该拥有依赖关系(对我来说,在 dist 文件夹中,但我应该如何实现它?如果我的组件具有更多的依赖性呢?我认为我只需要在 package.json 中定义依赖项。



Edit3:



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

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

gulp.task('bundle',bundle);

函数bundle(){
gulp.src('./ src / *。js')
.pipe(babel())
.pipe(gulp .dest( './ DIST'));
}

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

就是这样。完整的例子在这里: react-svg-components

$ b $根据你最近的解释,你可能需要在浏览你的组件时做这样的事情:



browserify('./ src / Foo.js')
//注意这个调用:
.external(react )
.transform(babelify)
.bundle()

问题与吞咽无关。我也不知道如何/何时获得您在评论中描述的运行时错误。根据您的最新信息,问题在于您使用browserify创建bundle A ,然后创建bundle B 与在它的依赖图中使用 A ,并且browserify试图解析已经存在的相对 require()的s捆绑在 A 中。从此答案引用以解决这个问题:



以下是几个选项:


  • 在消费/消费者之前在包 A 上运行取决发布。

  • 尝试浏览你的应用程序是这样的:

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

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


  • 缩小包 A

  • a href =https://github.com / substack / node-browserify / pull / 1151rel =nofollow noreferrer> substack / node-browserify#1151 。

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


    I've created a React component and I want to distribute a built-in version (built with gulp) of this component, so in gulpfile.js I have:

    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']);
    

    In .babelrc:

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

    And these are the dependencies in 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"
    }
    

    When I run gulp build (after npm install) build.js file is created under /dist, but when I try to use this component from other React app I get the error:

    Error: Cannot find module ' ./emptyFunction'.

    If I dig into this file (build.js), I can see these lines:

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

    These files does not exist under ./dist, so the error is thrown when I try to build the new React app calling the component:

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

    What am I missing?

    Edit:

    As I can see, the weird requires come from requiring React within the component file:

    var React = require('react');
    // or import React from 'react';
    
    class Foo extends React.Component {
        static propTypes = {...};
        static defaultProps = {...};
        render() {...}
    }
    export default Foo; 
    

    If I remove var React = require('react'); those requires (emptyFunction, camelize) disappear, and the error is React is not defined, obviously.

    Edit2:

    As @JMM suggests, I should have the dependencies (React in my case) in the dist folder, but how should I achieve it? What if my component has more dependencies? I thought that I just had to have the dependencies defined in package.json.

    Edit3:

    I finally realized that I don't need browserify, just 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']);
    

    And that's all. The full example is here: react-svg-components.

    解决方案

    Based on your most recent explanation, you probably need to do something like this when browserifying your component:

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

    The problem has nothing to do with gulp. I also don't know how / when you were getting the run time error you described in the comments. Based on your latest information, the problem is that you're creating bundle A with browserify, then creating bundle B with browserify, with A in its dependency graph, and browserify is trying to resolve relative require()'s that are already bundled in A. Quoting from this answer for how to deal with that:

    Here are a few options:

    • Run derequire on bundle A before consuming / publishing.

    • Try browserifying your app like so:

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

      If it doesn't work, try an absolute path (require.resolve('my-components-in-node-modules')).

    • Minify bundle A before consuming it.

    A more detailed explanation of that issue can be found in substack/node-browserify#1151.

    I'm not sure bundling React with your component is the way to go. I'm not sure, but I think in that case people must peer depend on React (implicitly or explicitly). Including React in the bundle means different components would be trying to use different instances of React, which may cause you problems, and would definitely bloat the node_modules directory for each component that does it.

    这篇关于用Gulp,Browserify和Babel构建React组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆