# NTUOSC Build System 20160603 [<i class="fa fa-github"></i> Elantris](https://github.com/Elantris) Note: https://hackmd.io/s/N1ERJm5Ux ###### tags: `2016` `ntuosc` `javascript` ## Setup Install latest npm, bower, pnpm, gulp in global ``` sudo npm install -g npm bower pnpm gulp ``` Find a place to clone the [repository](https://github.com/Elantris/ntuosc-course-20160603) and install dependencies ``` git clone git@github.com:Elantris/ntuosc-course-20160603.git cd ntuosc-course-20160603 pnpm install ``` ## Front-end Tools ### Pug HTML Template Engine [Language Reference](http://jade-lang.com) `index.pug` ```jade doctype html html(lang="en") head meta(charset="UTF-8") title NTUOSC Course 20160603 body .container h1 Color Thief #color-thief ``` Use cli command to compile `.pug` file ```shell $ npm install pug-cli -g $ pug [options] [dir|file ...] ``` [Pug's CLI GitHub](https://github.com/pugjs/pug-cli) ### Sass CSS Extension Language [Official Site](http://sass-lang.com) `main.scss` ```scss body { background: #eee; } .center { text-align: center; } .row { margin-bottom: 64px; } ``` Use cli command to compile `.scss` file ```shell $ gem install sass $ sass main.scss > main.css ``` ### React JavaScript Framework [Official Site](https://facebook.github.io/react/) `main.jsx` ```jsx var React = require('react'); var ReactDOM = require('react-dom'); var colorThief = new ColorThief(); var ColorBlock = React.createClass({ render: function() { return ( <div>Color Block</div> ); } }); var ColorThiefContainer = React.createClass({ getInitialState: function() { return {}; }, handleFile: function() {}, handleLoad: function() {}, render: function() { return ( <div>Color Thief</div> ); } }); ReactDOM.render(<ColorThiefContainer />, document.getElementById('color-thief')); ``` Use cli command to compile `.jsx` file ```shell $ npm install --save react react-dom babelify babel-preset-react $ browserify -t [ babelify ] main.js -o bundle.js ``` ## Gulp Build System [Official Site](http://gulpjs.com) ### File Structure ``` . ├── bower.json ├── bower_components ├── gulpfile.js ├── index.html ├── node_modules ├── package.json └── src ├── scripts │   └── main.jsx ├── styles │   └── main.scss └── views └── index.pug ``` ### Include dependencies `gulpfile.js` ```js var fs = require('fs'); var gulp = require('gulp'); // https://github.com/gulpjs/gulp var moment = require('moment'); // https://github.com/moment/moment/ var clc = require('cli-color'); // https://github.com/medikoo/cli-color var rename = require('gulp-rename'); // https://github.com/hparra/gulp-rename var sourcemaps = require('gulp-sourcemaps'); // https://github.com/floridoo/gulp-sourcemaps var gulpif = require('gulp-if'); // https://github.com/robrich/gulp-if var production = (process.env.NODE_ENV === 'production'); ``` ### Colorful Log ```js function colorLog(color, message) { console.log('[%s] %s', clc.blackBright(moment().format('HH:mm:ss')), clc[color](message) ); } function errorLog(err) { colorLog('redBright', err.stack); } ``` ### Task: Concat Libraries ```js var cssmin = require('gulp-cssmin'); // https://github.com/chilijung/gulp-cssmin var uglify = require('gulp-uglify'); // https://github.com/terinjokes/gulp-uglify var concat = require('gulp-concat'); // https://github.com/contra/gulp-concat gulp.task('move', function() { gulp.src([ './bower_components/skeleton/css/normalize.css', './bower_components/skeleton/css/skeleton.css', ]) .pipe(concat('lib.min.css')) .pipe(cssmin()) .pipe(gulp.dest('./public/css/')); gulp.src([ './node_modules/jquery/dist/jquery.min.js', './node_modules/color-thief/js/color-thief.js', ]) .pipe(concat('lib.min.js')) .pipe(uglify({ mangle: false })) .pipe(gulp.dest('./public/js/')); }); ``` `gulp.src`: select files ### Task: Compile Pug ```js var pug = require('gulp-pug'); // https://github.com/jamen/gulp-pug gulp.task('pug', function() { gulp.src('./src/views/*.pug') .pipe(pug()) .pipe(gulp.dest('./')); }); gulp.task('pug:watch', ['pug'], function() { gulp.watch('./src/views/**/*.pug', ['pug', reload]); }); ``` `gulp.watch`: watch files changed ### Task: Compile Sass ```js 'use strict'; var sass = require('gulp-sass'); // https://github.com/dlmanning/gulp-sass gulp.task('sass', function() { gulp.src('./src/styles/*.scss') .pipe(gulpif(production, sourcemaps.init())) .pipe(sass({ outputStyle: 'compressed' }).on('error', sass.logError)) .pipe(gulpif(production, sourcemaps.write())) .pipe(rename({ suffix: '.min' })) .pipe(gulp.dest('./public/css/')); }); gulp.task('sass:watch', ['sass'], function() { gulp.watch('./src/styles/**/*.scss', ['sass', reload]); }); ``` ### Task: Compile JSX ```js var browserify = require('browserify'); // https://github.com/substack/node-browserify var watchify = require('watchify'); // https://github.com/substack/watchify var source = require('vinyl-source-stream'); // https://github.com/hughsk/vinyl-source-stream var buffer = require('vinyl-buffer'); // https://github.com/hughsk/vinyl-buffer var reactify = require('reactify'); // https://github.com/andreypopp/reactify var b = browserify('./src/scripts/main.jsx', { cache: {}, packageCache: {}, debug: !production, transform: [reactify] }); gulp.task('react', function() { bundle(); }); gulp.task('react:watch', ['react'], function() { b.plugin(watchify); b.on('log', function(msg) { colorLog('yellowBright', msg); reload(); }); b.on('update', bundle); }); function bundle() { b.bundle() .on('error', errorLog) .pipe(source('main.min.js')) .pipe(buffer()) .pipe(gulpif(production, uglify())) .on('error', errorLog) .pipe(gulp.dest('./public/js/')); } ``` ### Task: BrowserSync ```js var browserSync = require('browser-sync').create(); // https://github.com/Browsersync/browser-sync var reload = browserSync.reload; gulp.task('browser-sync', function() { browserSync.init({ server: { baseDir: "./" } }); }); gulp.task('watch', ['pug:watch', 'sass:watch', 'react:watch', 'browser-sync']); ``` ### Task: Default ```js gulp.task('default', ['move', 'pug', 'sass', 'react']); ``` ### Run scripts Run default task and specific task ``` gulp gulp react ``` Inside the package.json ```json { "scripts": { "start": "pnpm install && bower install && NODE_ENV=production gulp", "test": "NODE_ENV=production gulp watch", "build:all": "NODE_ENV=production gulp" } } ``` Run npm script ``` npm start npm test npm run build:all ```