node/express ミニマム開発環境作成


# 概要
* node/expressの開発環境をミニマムに作る
	* templateエンジンはjade
	* routeはメインと別のjsで

* frontendはgulpを使ってbrowserify&sass
	* liveReloadで自動反映
	* sourcemapに対応

# 環境構築

## npm グローバルパッケージのインストール

```
npm install -g bower browserify exoress express-generator gulp node-inspector nodemon 

```


## フォルダ・ファイル作成

```
mkdir react.tutorial
cd react.tutorial
mkdir controllers
mkdir clientsrc
mkdir clientsrc/sass
mkdir clientsrc/js
mkdir public
mkdir routes
mkdir views
touch server.js
touch gulpfile.js
touch controllers/index.js
touch routes/routes.js
touch views/index.jade
touch clientsrc/js/main.js
touch clientsrc/sass/app.scss
```

## 依存モジュール

```
npm init
# 質問は全部enterでok

npm install --save body-parser bootstrap domready express express-session font-awesome jquery path tether url noty jade


npm install --save-dev browserify cssify gulp gulp-autoprefixer gulp-concat gulp-jshint gulp-livereload gulp-nodemon gulp-plumber gulp-sass gulp-sourcemaps gulp-uglify jshint tiny-lr vinyl-buffer vinyl-source-stream

```

## frontend タスクランナー


```gulpfile.js
var gulp = require('gulp');
var sass = require('gulp-sass');
var autoprefixer = require('gulp-autoprefixer');
var uglify = require('gulp-uglify');
var plumber = require('gulp-plumber');
var browserify = require('browserify');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');
var sourcemaps = require('gulp-sourcemaps');
var nodemon = require('gulp-nodemon');
var livereload = require('gulp-livereload');
var concat = require('gulp-concat');

gulp.task("sass", function() {
  gulp.src("./clientsrc/sass/**/*scss")
    .pipe(plumber())
    .pipe(concat('style.scss'))
    .pipe(sass())
    .pipe(autoprefixer())
    .pipe(gulp.dest("./public/css"))
});

gulp.task('js', function() {
  browserify({
    entries: ["./clientsrc/js/main.js"], // ビルド対象のファイル
    debug: true, // sourcemapを出力、chromeでのdebug可能にする
    transform: ['cssify']
  })
  .bundle()
  .on('error', console.error.bind(console)) // js compileエラーでもwatchを止めない
  .pipe(source("app.js")) // ビルド後のファイル名
  .pipe(buffer())
  .pipe(sourcemaps.init({loadMaps: true}))
  .pipe(uglify())
  .pipe(sourcemaps.write("./"))
  .pipe(gulp.dest("./public/js/")); // 生成先の指定
});

gulp.task('debugserver', function() {
  livereload.listen();

  nodemon({
    exec: 'node-inspector --web-port 3002 & node --debug',
    script: './server.js',
    ext: 'js, json',
    ignore: [   // nodemon ignore directory
      'views',
      'public',
      'clientsrc'
    ],
    env: {
      'NODE_ENV': 'development'
    },
    stdout: false
  }).on('readable', function() {
    this.stdout.on('data', function(chunk) {
      if (/^application\ started/.test(chunk)) {
        livereload.reload();
      }
      process.stdout.write(chunk);
    });
    this.stderr.on('data', function(chunk) {
      process.stderr.write(chunk);
    });
  });

});

gulp.task('watch', function() {
  gulp.watch(["./clientsrc/js/**/*.js"], ["js"]);
  gulp.watch(["./clientsrc/sass/**/*.scss"], ["sass", "js"]); // jsでcssをrequireしているのでjsも実行する
  gulp.watch(["./public/**/*.*", "./views/**/*.*"], function(e) {
    livereload.changed(e);
  });
});

gulp.task("default", [
  'debugserver',
  'sass',
  'js',
  'watch'
]);

gulp.task("build", [
  'sass',
  'js'
]);

```

## nodeメイン

```server.js
// =======================
// get instance we need
// =======================
var express           = require('express');
var app               = express();
var bodyParser        = require('body-parser');
var session            = require('express-session');
var path               = require('path');
var routes             = require('./routes/routes');

// =======================
// configuration
// =======================
var port = process.env.PORT || 8080;

// request parameter parser
app.use(bodyParser.urlencoded({
  extended: true
}));

// static file folder
app.use(express.static('public'));

// html template
app.set('view engine', 'jade');
app.set('views', __dirname + '/views');

// session
app.use(session({}));

// =======================
// routes
// =======================
app.use('/', routes);

// =======================
// start the server
// =======================
app.listen(port);
console.log('application started');


```


## nodeコントローラ等

```controllers/index.js
exports.index = function(req, res) {
  res.render('index');
}
```

```routes/routes.js
var express = require('express');
var router = express.Router();

var indexController    = require('../controllers/index');

router.route('/')
  .get(indexController.index);

module.exports = router;

```


```views/index.jade
doctype html
html
  head
    title= title
    meta(charset="utf-8")
    meta(http-equiv="X-UA-Compatible", content="IE=edge")
    link(rel="stylesheet", type="text/css", href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.2/css/bootstrap.min.css")
    link(rel="stylesheet", type="text/css", href="//maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css")
  body
    .container
      h1 Works!


    <!--[if IE]><!-->
    <script src="https://www.promisejs.org/polyfills/promise-6.1.0.min.js"></script>
    <!--<![endif]-->

    script(src="/js/app.js")

```


## javascriptメイン

```clientsrc/js/main.js
// =======================
// get instance we need
// =======================
$ = jQuery = require('jquery');
window.Tether = require('tether');
var bootstrap = require('bootstrap');
var domready = require('domready');
var noty = require('noty');
$.noty.defaults.layout = 'topRight';
$.noty.defaults.timeout = 3000;

// =======================
// css
// =======================
var cssify = require('cssify');
cssify.byUrl('//maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.2/css/bootstrap.min.css');
cssify.byUrl('//maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css');
var styleNode = require('../../public/css/style.css');

// =======================
// library
// =======================

// =======================
// jQuery setting
// =======================

// =======================
// global error catch handler
// =======================

// =======================
// entry point
// =======================
domready(function() {

});


```

# node起動確認

```
gulp
```

* ブラウザよりlocalhost:8080で確認