当前位置: 首页 > news >正文

使用React、Node.js、MongoDB、Socket.IO开发一个角色投票应用的学习过程(一)

这几篇都是我原来首发在 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,这是什么鬼,这个函数哪里来的,这个库是干嘛用的,这里这么写到底是为了什么",所以当你把过程中的这些疑问都搞清楚了,才是真正的提高了,光看很多细节是注意不到的。

对原有的改动

抄代码是好,但是最好在原来的基础上加点自己的相法,所以我做的改动主要有如下

  1. 把所有不是用ES6的代码全部改成ES6的
  2. 用数据库从mongodb 改成了mysql
  3. 用waterline替换mongoose操作数据库

改动后的代码,我也全发布在github上了,还没改完,我会不定期commit的

https://github.com/papersnake/newdenfaces-es6

改写的过程和遇到的坑

对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);

运行的时候服务器一直没有响应,找了好久才找到这个错误

后篇

使用React、Node.js、MongoDB、Socket.IO开发一个角色投票应用的学习过程(二)







    本文转自无心之柳.NET博客园博客,原文链接:

http://www.cnblogs.com/9527/p/6144620.html

,如需转载请自行联系原作者


相关文章:

  • pythony读取xml
  • 配置DNS支持邮件服务器域名解析,支持别名,反向查找区
  • Flash正式成为Googel Chrome浏览器内置插件
  • mysql主从切换步骤
  • GIS软件开发工具包TatukGIS Developer Kernel更新至v11.9丨附下载
  • javascript:typeof与instanceof区别
  • JS组件系列——Bootstrap Table 表格行拖拽(二:多行拖拽)
  • HTMl编写计算器
  • 使用PEAP实现802.1X
  • 超实用Mac软件分享(二)
  • JDBC获取新增记录的自增主键
  • HTTP协议中状态码的应用
  • Android笔记:触摸事件的分析与总结----MotionEvent对象
  • Ubuntu的系统安装步骤
  • VC 文件复制函数
  • [NodeJS] 关于Buffer
  • [分享]iOS开发-关于在xcode中引用文件夹右边出现问号的解决办法
  • 【Redis学习笔记】2018-06-28 redis命令源码学习1
  • C++类的相互关联
  • ES6 学习笔记(一)let,const和解构赋值
  • flask接收请求并推入栈
  • GitUp, 你不可错过的秀外慧中的git工具
  • GraphQL学习过程应该是这样的
  • IDEA 插件开发入门教程
  • iOS编译提示和导航提示
  • JavaScript设计模式系列一:工厂模式
  • oldjun 检测网站的经验
  • sublime配置文件
  • Terraform入门 - 1. 安装Terraform
  • Terraform入门 - 3. 变更基础设施
  • V4L2视频输入框架概述
  • vue-router的history模式发布配置
  • vue脚手架vue-cli
  • 对象引论
  • 深入浏览器事件循环的本质
  • 使用Swoole加速Laravel(正式环境中)
  • 微信小程序填坑清单
  • 一、python与pycharm的安装
  • 找一份好的前端工作,起点很重要
  • 阿里云IoT边缘计算助力企业零改造实现远程运维 ...
  • #HarmonyOS:Web组件的使用
  • (zt)最盛行的警世狂言(爆笑)
  • (附源码)ssm捐赠救助系统 毕业设计 060945
  • (删)Java线程同步实现一:synchronzied和wait()/notify()
  • (原創) X61用戶,小心你的上蓋!! (NB) (ThinkPad) (X61)
  • (转)自己动手搭建Nginx+memcache+xdebug+php运行环境绿色版 For windows版
  • ./indexer: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object fil
  • .NET : 在VS2008中计算代码度量值
  • .Net IOC框架入门之一 Unity
  • .NET 设计一套高性能的弱事件机制
  • .NET 应用架构指导 V2 学习笔记(一) 软件架构的关键原则
  • .net/c# memcached 获取所有缓存键(keys)
  • .NET连接MongoDB数据库实例教程
  • .Net面试题4
  • .NET文档生成工具ADB使用图文教程