《一》、使用gulp构建React应用 |
一、React项目结构
.gulpfile.js
./src
.index.html
/js
.App.js
.Child.js
.Parent.js
二、代码
index.html 和 js目录下的三个jsx文件如下
//index.html
<!DOCTYPE html>
<html>
<head></head>
<body>
<div id="app"></div>
<script src="../../../react/react.min.js" ></script>
<script src="../../../react-dom/react-dom.min.js" ></script>
<script src="js/Child.js"></script>
<script src="js/Parent.js"></script>
<script src="js/App.js"></script>
</body>
</html>
//Child.js
var Child = React.createClass({
render: function(){
return (
<div>
and this is the <b>{this.props.name}</b>.
</div>
)
}
});
//Parent.js
var Parent = React.createClass({
render: function(){
return (
<div>
<div> This is the parent. </div>
<Child name="child"/>
</div>
)
}
});
//App.js
ReactDOM.render(<Parent />, document.getElementById(‘app‘));
??如上,我们创建了Child和Parent两个组件,Parent组件在App.js中被渲染时,将属性child传给子组件同时渲染子组件
三、gulp在开发和生产两套环境下构建
??1、实现功能
a、开发环境
- 转换三个jsx文件成js文件并保存在dist/js下
- 复制index.html到dist目录下
- 监视jsx和html文件,一有变动执行上面转换和复制任务
b、生产环境
- 转换jsx成js,并合并然后压缩三个js文件成一个build.min.js保存在dist/build目录下
- 将html中的
<script>
标签中三个js替换成上面的build.min.js
??2、下载npm包
a、npm init
生成package.json文件— —收集应用中node包信息
b、全局安装gulp: npm install --global gulp
c、其他gulp任务必需的安装node包
npm install --save-dev gulp;
npm install --save-dev gulp-concat; //合并
npm install --save-dev gulp-uglify; //压缩
npm install --save-dev gulp-react; //jsx转js
npm install --save-dev gulp-html-replace;//更换.html文件中内容
??3、gulp任务前需准备项
在gulpfile.js顶部,需加入如下,导入用到的node_module模块
var gulp = require(‘gulp‘);
var concat = require(‘gulp-concat‘);
var uglify = require(‘gulp-uglify‘);
var react = require(‘gulp-react‘);
var htmlreplace = require(‘gulp-html-replace‘);
在深入构建不同gulp之前,需创建一个路径项,指定用到的输入文件和输出的文件路径
//指定文件输入和输出路径
var path = {
HTML: ‘src/index.html‘,
ALL: [‘src/js/*.js‘, ‘src/js/**/*.js‘, ‘src/index.html‘],
//【注意】一个个按顺序地指定js,因为默认*.js默认按abc..xyz顺序拼接成build.min.js
JS: [‘src/js/Child.js‘, ‘src/js/Parent.js‘, ‘src/js/App.js‘],
MINIFIED_OUT: ‘build.min.js‘,
DEST_SRC: ‘dist/js‘,
DEST_BUILD: ‘dist/build/‘,
DEST: ‘dist‘
};
??4、开发环境的gulp任务
a、transform转换任务;将jsx转换成js
//jsx转换成js任务
gulp.task(‘transform‘, function(){
gulp.src(path.JS)
.pipe(react())
.pipe(gulp.dest(path.DEST_SRC));
});
b、copy复制任务;将index.html复制到dist目录下
//复制index.html文件
gulp.task(‘copy‘, function(){
gulp.src(path.HTML)
.pipe(gulp.dest(path.DEST));
});
c、watch监视任务;
//监视path.ALL下所有文件,一有变动执行transform任务和copy任务
gulp.task(‘watch‘, function(){
gulp.watch(path.ALL, [‘transform‘, ‘copy‘]);
});
d、默认启动任务
//默认任务;启动监视任务并执行transform和copy任务
gulp.task(‘default‘, [‘watch‘,‘transform‘, ‘copy‘]);
??5、生产环境的gulp任务
a、build任务;该任务将三个js文件按指定顺序(path中的JS)合并成一个文件,然后压缩成build.min.js放在dist/build目录下
gulp.task(‘build‘, function(){
gulp.src(path.JS)
.pipe(react())
.pipe(concat(path.MINIFIED_OUT))
.pipe(uglify(path.MINIFIED_OUT))
.pipe(gulp.dest(path.DEST_BUILD));
});
b、更替html中的script任务;替换三个<script>
标签成<script src=”build/build.mins.js”>
并将index.html文件输入到dist目录
首先需要更替的js需包裹成如下(index.html中)
<!-- build:js -->
<script src="js/Child.js"></script>
<script src="js/Parent.js"></script>
<script src="js/App.js"></script>
<!-- endbuild -->
gulpfile文件中更替任务
gulp.task(‘replaceHTML‘, [‘build‘], function(){
gulp.src(path.HTML)
.pipe(htmlreplace({
‘js‘: ‘build/‘ + path.MINIFIED_OUT
}))
.pipe(gulp.dest(path.DEST));
});
包装启动生产任务
gulp.task(‘production‘, [‘replaceHTML‘]);
源码地址:https://github.com/mqy1023/react-basejs/tree/master/src/demo2
《二》、使用gulp + Browserify构建React应用 |
1、为什么使用Browserify?
??上面纯gulp实现React应用有一些缺点,会注意到App.js Parent.js Child.js因为加载顺序问题需要小心翼翼添加(如:Child.js必须在Parent.js前加载,因为Parent.js依赖Child.js,同样App.js要在Parent.js加载后);还有当你调试时在jsx中加入debugger,浏览器加载的是jsx转换后的js,所以调试时我们不能定位到原jsx中的具体位置,这对于我们来说很不理想。
2、理解Browserify
??Browserify能帮我们解决上述&其他更多问题。Browserify工具可以让我们类似commonjs模块化加载,即React组件中可以require进其他React组件;模块化改造的js (【注意】module.exports & require & 木有.js后缀):
//Child.js文件
var Child = React.createClass({
render: function(){
return (
<div>
and this is the <b>{this.props.name}</b>.
</div>
)
}
});
module.exports = Child;
//App.js文件
var Child = require(‘./Child‘);
var Parent = React.createClass({
render: function(){
return (
<div>
<div> This is the parent. </div>
<Child name="child"/>
</div>
)
}
});
module.exports = Parent;
//Math.js
var Parent = require(‘./Parent‘);
ReactDOM.render(<Parent />, document.getElementById(‘app‘));
一、实现功能
a、开发环境
- 连接起js文件
- 转换jsx成js
- 保存在dist目录
b、生产环境
- 转换jsx成js,并实现合并后压缩,输出到dist目录
二、Browserify + Gulp + React (Development Tasks)开发环境下的tasks
1、卸载gulp-concat
npm uninstall gulp-concat;
2、安装新的NPM包
首先npm install -g browserify
全局安装browserify
//others
npm install vinyl-source-stream --save-dev
npm install browserify --save-dev
npm install watchify --save-dev
npm install reactify --save-dev
npm install gulp-streamify --save-dev
【注意】吓尿了。–save-dev要放在后面才行,不明觉厉。。如:npm install --save-dev browserify; //报找不到文件
3、gulpfile导入模块和指定路径
var gulp = require(‘gulp‘);
var uglify = require(‘gulp-uglify‘);
var htmlreplace = require(‘gulp-html-replace‘);
var source = require(‘vinyl-source-stream‘);
var browserify = require(‘browserify‘);
var watchify = require(‘watchify‘);
var reactify = require(‘reactify‘);
var streamify = require(‘gulp-streamify‘);
var path = {
HTML: ‘src/index.html‘,
MINIFIED_OUT: ‘build.min.js‘,
OUT: ‘build.js‘,
DEST: ‘dist‘,
DEST_BUILD: ‘dist/build‘,
DEST_SRC: ‘dist/src‘,
ENTRY_POINT: ‘./src/js/App.js‘
};
4、copy任务
gulp.task(‘copy‘, function(){
gulp.src(path.HTML)
.pipe(gulp.dest(path.DEST));
});
5、watch主任务
gulp.task(‘watch‘, function() {
gulp.watch(path.HTML, [‘copy‘]);
var watcher = watchify(browserify({
entries: [path.ENTRY_POINT], //入口.js
transform: [reactify],//jsx转换成js,调试能定位显示原jsx错误具体位置
debug: true,
cache: {}, packageCache: {}, fullPaths: true //watchify官网显示此行必须
}));
return watcher.on(‘update‘, function () { //更新
watcher.bundle()
.pipe(source(path.OUT))
.pipe(gulp.dest(path.DEST_SRC))
console.log(‘Updated‘);
})
.bundle() //一执行gulp watch,需要bundle和pipe itself to the dist目录
.pipe(source(path.OUT))
.pipe(gulp.dest(path.DEST_SRC));
});
6、default任务
gulp.task(‘default‘, [‘watch‘]);
三、Browserify + Gulp + React (Production Tasks)生产环境下的tasks
任务都差不多,这里不再赘述
/***************生产版**********
gulp.task(‘build‘, function(){
browserify({
entries: [path.ENTRY_POINT],
transform: [reactify]
})
.bundle()
.pipe(source(path.MINIFIED_OUT))
.pipe(streamify(uglify(path.MINIFIED_OUT)))
.pipe(gulp.dest(path.DEST_BUILD));
});
gulp.task(‘replaceHTML‘, function(){
gulp.src(path.HTML)
.pipe(htmlreplace({
‘js‘: ‘build/‘ + path.MINIFIED_OUT
}))
.pipe(gulp.dest(path.DEST));
});
gulp.task(‘production‘, [‘replaceHTML‘, ‘build‘]);
源码地址:https://github.com/mqy1023/react-basejs/tree/master/src/demo3
参考链接:
http://tylermcginnis.com/reactjs-tutorial-pt-2-building-react-applications-with-gulp-and-browserify/
建议英文可以查看原文,老外的文章就是有很多有用的”废话”;有点遗憾的是,该文章中有些错误,可以老外原文的评论就知道,不知道为什么作者一直没改;本文已针对本人发现的错误做了改正,照着老外原文出错的地方可以回到本文找到解决方案的哈