问题
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.
回答1:
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.
来源:https://stackoverflow.com/questions/36137169/build-react-components-with-gulp-browserify-and-babel