這幾篇都是我原來首發在 segmentfault 上的地址:https://segmentfault.com/a/1190000005040834 突然想起來我這個部落格冷落了好多年了,也該更新一下,呵呵
本專案是對使用React、Node.js、MongoDB、Socket.IO開發一個角色投票應用的學習過程。
英文原文:Create a character voting app using React, Node.js, MongoDB and Socket.IO
原專案github
學習過程
要想系統的學習些新東西,網上看了很多程式碼片段,但很少有這樣完整的一個系統來學習,基實我本來是比較偏向Vue的但是看到了這個文章,太全面了,對於想入門的人來說,方方面面都有,有前端,有後端,所以忍不住想把它提供的程式碼全敲一遍。敲程式碼的過程,雖然只是個抄的過程,但比光看要很很多,有的時候往往看人家程式碼的時候,感覺是這樣的,"哦,就是這樣的啊.so easy,不過如此嗎~",但一句一句去敲的時候,感覺就是這樣的,"WTF,這是什麼鬼,這個函式哪裡來的,這個庫是幹嘛用的,這裡這麼寫到底是為了什麼",所以當你把過程中的這些疑問都搞清楚了,才是真正的提高了,光看很多細節是注意不到的。
對原有的改動
抄程式碼是好,但是最好在原來的基礎上加點自己的相法,所以我做的改動主要有如下
- 把所有不是用ES6的程式碼全部改成ES6的
- 用資料庫從mongodb 改成了mysql
- 用waterline替換mongoose運算元據庫
改動後的程式碼,我也全釋出在github上了,還沒改完,我會不定期commit的
改寫的過程和遇到的坑
對ES6學也的也不深,改了這麼多也發現語法上也只用到了import let const 和=>,希望大家提出更多的改進意見
原文第一步的程式碼
原文第一步的改進
var express = require('express');
var path = require('path');
var logger = require('morgan');
var bodyParser = require('body-parser');
var app = express();
app.set('port', process.env.PORT || 3000);
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));
app.listen(app.get('port'), function() {
console.log('Express server listening on port ' + app.get('port'));
});
改寫後,變成
import express from 'express';
import path from 'path';
import logger from 'morgan';
import bodyParser from 'body-parser';
let app = express();
app.set('port',process.env.PORT || 3000);
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));
app.listen(app.get('port'),() => {
console.log('Express server listening on port ' + app.get('port'));
});
為了能讓它跑起來,要在原有依賴的基礎上新增
npm install --save-dev babel-cli,babel-core,babel-preset-es2015,babel-preset-react,babel-register
有幾個依賴是後面才用到的,我這裡一併安裝了
在根目錄新建一個.babelrc檔案
{
"presets": [
"es2015"
]
}
用babel-node server.js 就要以跑起來了
原文第二步分 構建系統的改寫
為了節省篇幅,有些全篇的程式碼我就不貼上,給出連線吧 gulpfile.js
gulp 從3.9.0開始支援babel,但是要把檔名改為gulpfile.babel.js
改寫後的程式碼
import gulp from 'gulp';
import gutil from 'gulp-util';
import gulpif from 'gulp-if';
import streamify from 'gulp-streamify';
import autoprefixer from 'gulp-autoprefixer';
import cssmin from 'gulp-cssmin';
import less from 'gulp-less';
import concat from 'gulp-concat';
import plumber from 'gulp-plumber';
import source from 'vinyl-source-stream';
import babelify from 'babelify';
import browserify from 'browserify';
import watchify from 'watchify';
import uglify from 'gulp-uglify';
const production = process.env.NODE_ENV === 'production';
const dependencies = [
'alt',
'react',
'react-router',
'underscore'
];
/*
|--------------------------------------------------------------------------
| Combine all JS libraries into a single file for fewer HTTP requests.
|--------------------------------------------------------------------------
*/
gulp.task('vendor',()=>
gulp.src([
'bower_components/jquery/dist/jquery.js',
'bower_components/bootstrap/dist/bootstrap.js',
'bower_components/magnific-popup/dist/jquery.magnific-popup.js',
'bower_components/toastr/toastr.js'
]).pipe(concat('vendor.js'))
.pipe(gulpif(production,uglify({ mangle:false })))
.pipe(gulp.dest('public/js'))
);
/*
|--------------------------------------------------------------------------
| Compile third-party dependencies separately for faster performance.
|--------------------------------------------------------------------------
*/
gulp.task('browserify-vendor', () =>
browserify()
.require(dependencies)
.bundle()
.pipe(source('vendor.bundle.js'))
.pipe(gulpif(production, streamify(uglify({ mangle: false }))))
.pipe(gulp.dest('public/js'))
);
/*
|--------------------------------------------------------------------------
| Compile only project files, excluding all third-party dependencies.
|--------------------------------------------------------------------------
*/
gulp.task('browserify', ['browserify-vendor'], () =>
browserify('app/main.js')
.external(dependencies)
.transform(babelify,{ presets: ["es2015", "react"]}) //注意這裡,只有加上presets配置才能正常編譯
.bundle()
.pipe(source('bundle.js'))
.pipe(gulpif(production, streamify(uglify({ mangle: false }))))
.pipe(gulp.dest('public/js'))
);
/*
|--------------------------------------------------------------------------
| Same as browserify task, but will also watch for changes and re-compile.
|--------------------------------------------------------------------------
*/
gulp.task('browserify-watch', ['browserify-vendor'], () =>{
var bundler = watchify(browserify('app/main.js', watchify.args));
bundler.external(dependencies);
bundler.transform(babelify,{ presets: ["es2015", "react"]});
bundler.on('update', rebundle);
return rebundle();
function rebundle() {
var start = Date.now();
bundler.bundle()
.on('error', function(err) {
gutil.log(gutil.colors.red(err.toString()));
})
.on('end', function() {
gutil.log(gutil.colors.green('Finished rebundling in', (Date.now() - start) + 'ms.'));
})
.pipe(source('bundle.js'))
.pipe(gulp.dest('public/js/'));
}
});
/*
|--------------------------------------------------------------------------
| Compile LESS stylesheets.
|--------------------------------------------------------------------------
*/
gulp.task('styles', () =>
gulp.src('app/stylesheets/main.less')
.pipe(plumber())
.pipe(less())
.pipe(autoprefixer())
.pipe(gulpif(production, cssmin()))
.pipe(gulp.dest('public/css'))
);
gulp.task('watch', () =>{
gulp.watch('app/stylesheets/**/*.less', ['styles']);
});
gulp.task('default', ['styles', 'vendor', 'browserify-watch', 'watch']);
gulp.task('build', ['styles', 'vendor', 'browserify']);
由於到現在為止,還沒有做其他工作,所以看不到打包的實際效果, 但是也是要控制檯下執行一下gulp 看看有沒有語法錯誤。
到這裡為止沒有遇到多大的坑,最多的往往是拼寫錯誤引起的問題,唯一由於拼寫導致,但不提示錯誤的是
app.use(bodyParser.json());
我打成了
app.use(bodyParser.json);
執行的時候伺服器一直沒有響應,找了好久才找到這個錯誤