自己动手才发现原来写篇好文章真的是太难了,如果评个等级的话,这篇文章大概是渣渣水平,哈哈。
不过,总算是写完了,也算是最近学习的一个总结吧 :)
本文目录
<a id="prepare">
准备工作
作为一个noder,开始一切之前当然少不了npm init
关于express, babel, gulp, webpack, react本文不进行介绍,如有需要可以到其主页自行了解。
Express
Babel
Gulp
React
Webpack
<a id="toc">
项目目录结构
app
├─ lib/
├─ public/
│ ├─ dist/
│ └─ src/
│ └─ index.js
├─ src/
│ └─ app.js
├─ .babelrc
├─ index.html
├─ gulpfile.babel.js
├─ package.json
├─ README.md
└─ webpack.config.js
<a id="express">
Express
<a id="express-install">
安装
这次准备纯手写,所以不用express-generator
生成了,简单的示例尽量不使用多余的中间件。
npm install --save express body-parser
<a id="express-server">
写个server测试一下
// src/app.js
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var router = express.Router();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser());
router.get('/', function(req, res, next) {
res.end('Hello World!');
});
app.use('/', router);
app.listen(3000, function() {
console.log('server listening at port 3000...');
});
简单起见,404和error handler就不写了。
node src/app.js
跑起来,浏览器打开http://localhost:3000,可以看到页面中显示Hello World!
了。
<a id="babel">
Babel
babel升级到6.x之后,需要明确指定转换,我们使用预设的es2015。
<a id="babel-install">
安装
npm install -g babel-core
npm install --save-dev babel-core babel-preset-es2015
<a id="babelrc">
配置.babelrc
在根目录新建.babelrc文件,配置如下:
{
"presets": ["es2015"]
}
<a id="babel-es6">
使用es6语法编写代码
我们现在将之前写过的src/app.js
修改为es6语法
// src/app.js
import express, { Router } from 'express';
import bodyParser from 'body-parser';
let app = express();
let router = Router();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser());
router.get('/', (req, res, next) => {
res.end('Hello World!');
});
app.use('/', router);
app.listen(3000, () => {
console.log('server listening at port 3000...');
});
<a id="babel-transform">
使用bebel转换
将代码修改为es6语法之后,就可以使用babel进行转换了。
使用命令babel src -d lib
可以看到控制台中显示:
src/app.js -> lib/app.js
之后还是运行一下看看效果,浏览器打开http://localhost:3000,我们和熟悉的Hello World
又见面啦。
<a id="gulp">
Gulp
每次修改完代码都要重新用babel转换一次是不是很麻烦?别怕,我们有gulp。
<a id="gulp-install">
安装
npm install -g gulp-cli
npm install --save-dev gulp gulp-babel
<a id="gulpfile">
编写gulpfile
在根目录新建一个gulpfile.babel.js文件。
gulp原生并不支持es6语法,但是我们可以告诉gulp使用babel将gulpfile转换为es5,方法就是将gulpfile命名为gulpfile.babel.js
<a id="gulpfile-default">
一个简单的gulpfile
我们先写一个简单的gulpfile测试一下gulp是否能够正常工作。
import gulp from 'gulp';
import babel from 'gulp-babel';
gulp.task('default', () => {
return gulp.src('src/**/*.js')
.pipe(babel())
.pipe(gulp.dest('lib'));
});
控制台执行gulp
,可以看到:
[13:00:35] Requiring external module babel-register
[13:00:36] Using gulpfile /path/to/file/gulpfile.babel.js
[13:00:36] Starting 'default'...
[13:00:36] Finished 'default' after 191 ms
然后lib文件夹下就生成了转换后的文件了。
<a id="gulpfile-watch">
能够监听文件更改的gulpfile
虽然上面的gulpfile能够将使用了,但是还是跟之前直接用babel一样,每次都要gulp一下,下面我们就来写一个能够监听文件的gulpfile。当文件被修改之后,自动将文件转换。
这里使用gulp-watch
监听文件更改。
npm install --save-dev gulp-watch
import gulp from 'gulp';
import watch from 'gulp-watch';
import babel from 'gulp-babel';
gulp.task('transform', () => {
return gulp.src('src/**/*.js')
.pipe(babel())
.pipe(gulp.dest('lib'));
});
gulp.task('watch', () => {
return gulp.src('src/**/*.js')
.pipe(watch('src/**/*.js', {
verbose: true
}))
.pipe(babel())
.pipe(gulp.dest('lib'));
});
gulp.task('default', () => {
gulp.start('transform');
});
控制台执行gulp watch
[14:11:46] Requiring external module babel-register
[14:11:47] Using gulpfile /file/to/path/gulpfile.babel.js
[14:11:47] Starting 'watch'...
然后修改app.js并保存,可以看到控制台中多了一行信息
[14:13:20] app.js was changed
对于gulp其他的用法这里就不细说了,有兴趣的可以去看桑大i5ting
的Gulp实战和原理解析(以weui作为项目实例)
<a id="react-webpack">
React + Webpack
<a id="react-webpack-install">
安装
react
npm install --save react react-dom
webpack
npm install --save-dev webpack webpack-dev-server
为了编译jsx,我们还需要其他一些模块
npm install --save-dev babel-loader babel-preset-react
<a id="webpack-config">
编写webpack.config.js
var path = require('path');
var webpack = require('webpack');
module.exports = {
devtool: 'eval',
entry: {
public: './public/src/index'
},
output: {
path: path.join(__dirname, 'public/dist'),
filename: 'bundle.js',
publicPath: 'public/dist'
},
plugins: [],
module: {
loaders: [
{
test: /\.js$/,
include: [path.join(__dirname, 'public/src')],
loader: 'babel',
query: {
presets: ['react', 'es2015']
}
}
]
}
};
<a id="gulp-webpack">
在gulp中使用webpack
修改gulpfile.babel.js
,添加build
和webpack-dev-server
任务,分别是生成打包文件和启动开发服务器,并将default
修改为同时执行transform
和webpack-dev-server
。
import gulp from 'gulp';
import gutil from 'gulp-util';
import watch from 'gulp-watch';
import babel from 'gulp-babel';
import webpack from 'webpack';
import WebpackDevServer from 'webpack-dev-server';
import webpackConfig from './webpack.config.js';
// transform
gulp.task('transform', () => {
return gulp.src('src/**/*.js')
.pipe(babel())
.pipe(gulp.dest('lib'));
});
// watch transform
gulp.task('watch-transform', () => {
return gulp.src('src/**/*.js')
.pipe(watch('src/**/*.js', {
verbose: true
}))
.pipe(babel())
.pipe(gulp.dest('lib'));
});
gulp.task('webpack:build', (callback) => {
// modify some webpack config options
var myConfig = Object.create(webpackConfig);
myConfig.plugins = myConfig.plugins.concat(
new webpack.DefinePlugin({
'process.env': {
// This has effect on the react lib size
'NODE_ENV': JSON.stringify('production')
}
}),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin()
);
// run webpack
webpack(myConfig, (err, stats) => {
if (err)
throw new gutil.PluginError('webpack:build', err);
gutil.log('[webpack:build]', stats.toString({
colors: true
}));
callback();
});
});
gulp.task('webpack-dev-server', (callback) => {
// modify some webpack config options
var myConfig = Object.create(webpackConfig);
myConfig.devtool = 'eval';
myConfig.debug = true;
// Start a webpack-dev-server
new WebpackDevServer(webpack(myConfig), {
publicPath: '/' + myConfig.output.publicPath,
stats: {
colors: true
}
}).listen(3001, 'localhost', (err) => {
if (err) throw new gutil.PluginError('webpack-dev-server', err);
gutil.log('[webpack-dev-server]', 'http://localhost:3001/');
});
});
gulp.task('default', ['watch-transform', 'webpack-dev-server']);
<a id="react">
使用React
在根目录下创建index.html
文件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello Wrold</title>
</head>
<body>
<div id="root"></div>
<script src="http://127.0.0.1:3001/public/dist/bundle.js"></script>
</body>
</html>
之后在public/src
目录创建index.js
文件,简单的写个hello world.
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class App extends Component {
render() {
return (
<h1>Hello Wrold!!</h1>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
控制台执行gulp webpack-dev-server
,打开http://localhost:3001
我们和Hello world!
第三次见面了~
<a id="summary">
总结
到这里文章就结束了,然而这只是文章的结束,现在只是把大体的结构搭建起来了,剩下要做的还有很多,继续加油把~
PS: 我也不知道这种目录结构是否合理,如有不同意见,欢迎拍砖~