é¡åã®éãããã£ã¨æ¸ãåºãã
ãã®ãããã®ãã¨ãç¸è«ãããæã«ãæå ã®ãªãã¸ããªãæ¼ã£ã¦ããããªæãã§ãã£ã¦ã¾ããã¨ãã£ã¦ããã©ã ã¨ãããããã®URL渡ãã¦åèã«ãã¦ãããã¿ãããªãã¨ãã§ããã°...
ã注æ
- Xubuntu 14.04ã§ãã£ã¦ãã®ã§WindowsãOSXã¯æªç¢ºèªã
- ãããã¾ãããè¦æ¨¡ã®éçºã§ä½¿ã£ã¦ããæ§æãªã®ã§ãè¦æ¨¡ã«ãã£ã¦ã¯åãã¦ããªãããã
- ãµã¼ãã¨ã¯JSONã¨ãã®APIã§ã話ããã ãã®ãSPAãªããã³ãã¨ã³ãç¨ï¼ã«ã¼ãã£ã³ã°ã¯ããã·ã¥ãã§ã³ã¸ç³»åãï¼ã
ãããªãã
- å ±éç¨
- ããã¸ã§ã¯ãç¨
- ããã¸ã§ã¯ããã£ã¬ã¯ããªã®ä¸æºå
- ã¿ã¹ã¯ã©ã³ãã¼
- HTMLã¨éçºç¨Webãµã¼ã
- CSSãç»åãã¡ã¤ã«ãªã©ã®ã¹ã¿ã¤ã«ã¾ãã
- JavaScriptã¾ããï¼ã¢ã¸ã¥ã¼ã«ãã³ãã©ï¼
- ãããã¯ã·ã§ã³ç¨ã®ãã«ã
- ãã¹ãç°å¢
- APIãµã¼ãã¨ã¤ãªããªããéçº
- fetchãã¢ãã¯ãã¦ãã¹ã
- ãã©ã¦ã¶ã§ãã¹ã
- ã¾ã¨ã
å ±éç¨
nodeã®ç®¡ç
ã¨ããããnodeããªãã¨å§ã¾ããªãã®ã§nodeããã
nodeã®ç®¡çã¯nodebrewã使ã£ã¦ããã å¤ãªãããæ¹ãããªãããã«ãv4.2.xç³»ã使ã£ã¦ããã
JavaScriptã®Lint
eslintã使ã£ã¦ããã Vimãã©ã°ã¤ã³ã®syntasticã使ã£ã¦ããã¡ã¤ã«ã®ä¿åæã«ãã§ãã¯ãã¦ãã
ã¤ã³ã¹ãã¼ã«
$ npm install -g eslint
次ã®ããã«Vimã«è¨å®ãã¦æå¹ã«ããã
let g:syntastic_javascript_checkers=['eslint']
ããã¸ã§ã¯ãç¨
ããã¸ã§ã¯ããã£ã¬ã¯ããªã®ä¸æºå
npm initã§package.jsonãä½ããgiboã使ã£ã¦nodeç¨ã®.gitignoreè¨å®ãä½ã£ã¦ããã
$ mkdir project $ cd project $ npm init $ gibo Node | tee .gitignore
ã¿ã¹ã¯ã©ã³ãã¼
ã¿ã¹ã¯ã©ã³ãã¼ã¯gulpã®3.9ç³»ã使ã£ã¦ããã
gulpã³ãã³ãã¯ããã¸ã§ã¯ãé ä¸ã«ã¤ã³ã¹ãã¼ã«ãããã®ãnpmã®ã³ãã³ãçµç±ã§ä½¿ãã å¾ã 追å ãããã¨ã«ãªãgulpã®ãã©ã°ã¤ã³ã¯gulp-load-pluginsã§ã¾ã¨ãã¦ãã¼ãã§ããããã«ãã¦ããã
HTMLãCSSãJavaScriptãªã©ã®ãã¡ã¤ã«ã¯appãã£ã¬ã¯ããªé ä¸ã«ç½®ãã¦è¡ãã å種ãã¼ã«ãéãã¦ãã«ãæ¸ã¿ãã£ã¬ã¯ããªï¼distï¼ã«é åãããããã«ããã
ãã«ãæ¸ã¿ãã£ã¬ã¯ããªã¯package.jsonã«è¨å®ã¨ãã¦æ¸ãã¦ãããgulpfile.jsãªã©ããåç §ãã¦ä½¿ã£ã¦ããã
ãã£ã¬ã¯ããªæ§æã¯æ¬¡ã®ãããªæãã
. âââ app âââ dist âââ gulpfile.js âââ node_modules âââ package.json
ã¤ã³ã¹ãã¼ã«
$ npm install --save-dev gulp gulp-load-plugins del
éçºæã«ä½¿ãå ±éçãªgulpã®ã¿ã¹ã¯ã¯æ¬¡ã®éãã
ã¿ã¹ã¯å | ç¨é |
---|---|
clean | ãã«ãæ¸ã¿ãã£ã¬ã¯ããªãåé¤ãã |
dev | éçºç°å¢ãèµ·åãã |
default | ããã©ã«ãï¼cleanãã¦devãå®è¡ããï¼ |
gulpfile.js
var path = require('path'); var pkg = require('./package.json'); var distDir = path.join(__dirname, pkg.dist); var gulp = require('gulp'); var $ = require('gulp-load-plugins')(); var del = require('del'); gulp.task('clean', del.bind(null, [distDir])); gulp.task('dev', [], () => { }); gulp.task('default', ['clean'], () => { gulp.start('dev'); });
package.jsonã«gulpã³ãã³ãã¨ãã«ãæ¸ã¿ãã£ã¬ã¯ããªã®è¨å®ã次ã®ããã«è¿½å ãã¦ããã
package.json
-- ä¸ç¥ -- "dist": "dist", "scripts": { "gulp": "gulp" }, -- ä¸ç¥ --
ãã«ãæ¸ã¿ãã£ã¬ã¯ããªã¯gitignore対象ã
.gitignore
dist -- ä¸ç¥ --
ããã§gulpã¯ãããªæãã«ä½¿ãã
$ npm run gulp
HTMLã¨éçºç¨Webãµã¼ã
éçºæã«ãã©ã¦ã¶ã§ç¢ºèªããããã®Webãµã¼ãã¯connectã使ã£ã¦ããã
Webãµã¼ãã¯ãã«ãæ¸ã¿ãã£ã¬ã¯ããªãããã¥ã¡ã³ãã«ã¼ãã¨ãã¦åä½ãããã gulpã®watchã§ãã¡ã¤ã«ç£è¦ãã¦ãå¤æ´ããã£ããå¿ è¦ãªãã«ãããã¦LiveReloadã§ãã©ã¦ã¶ãæ´æ°ãããã
BrowserSyncããã°ãã使ã£ã¦ãããã©ã connectã§ååãªæ©è½ãã使ã£ã¦ãªãã£ãã®ã§connectã«æ»ããã
ã¤ã³ã¹ãã¼ã«
$ npm install --save-dev connect connect-livereload serve-static gulp-livereload
HTMLãã¡ã¤ã«ãappãã£ã¬ã¯ããªã«è¿½å ããã
app/index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Hello World!</title> </head> <body> <h1>Hello World!</h1> </body> </html>
HTMLã¨éçºç¨Webãµã¼ãã®ããã®gulpã¿ã¹ã¯ã¯æ¬¡ã®éãã
ã¿ã¹ã¯å | ç¨é |
---|---|
html | HTMLãã¡ã¤ã«ããã«ãæ¸ã¿ãã£ã¬ã¯ããªã¸é åãã |
serve | éçºç¨Webãµã¼ããèµ·åãã |
dev | éçºç°å¢ãèµ·åããHTMLãã¡ã¤ã«ãç£è¦ãã |
gulpfile.js
-- ä¸ç¥ -- var connect = require('connect'); var connectLivereload = require('connect-livereload'); var serveStatic = require('serve-static'); -- ä¸ç¥ -- gulp.task('html', () => { return gulp.src('app/**/*.html') .pipe(gulp.dest(distDir)) .pipe($.livereload()); }); gulp.task('serve', () => { $.livereload.listen(); connect() .use(connectLivereload()) .use(serveStatic(distDir)) .listen(3100); }); gulp.task('dev', ['html', 'serve'], () => { gulp.watch('app/**/*.html', ['html']); }); -- ä¸ç¥ --
ããã§gulpãèµ·åãã¦ãéçºç¨Webãµã¼ããç«ã¡ä¸ãã¦ãã©ã¦ã¶ã§ç¢ºèªã§ããã
$ npm run gulp
CSSãç»åãã¡ã¤ã«ãªã©ã®ã¹ã¿ã¤ã«ã¾ãã
CSSã¯Bootstrapããã¼ã¹ã«lessã§æ¸ãã¦ã gulp-lessã§ãã«ããã¦ããã
ã¤ã³ã¹ãã¼ã«
$ npm install --save bootstrap $ npm install --save-dev gulp-less
ã¢ããªç¨ã«app.lessãã¡ã¤ã«ãä½ããimportã§bootstrapã®lessãèªã¾ãã¦å¿ è¦ãªã¹ã¿ã¤ã«ãæ¸ãã¦ããã
Reactã¿ãããªã³ã³ãã¼ãã³ãä½ã£ã¦è¡ãç³»ã®ã使ã£ã¦ãã¨ã ã³ã³ãã¼ãã³ããã¨ã«lessãã¡ã¤ã«ä½ã£ã¦ç®¡çã¨ãããã»ããããã®ããªã¼ã¨æããã©ã Bootstrapã«æ¯ã®çããç¨åº¦ã«ããã¹ã¿ã¤ã«è¿½å ãã¦ãªãã®ã§app.lessã ãã§ä»ã®ã¨ããã¯æ¸ãã§ããã
ã¢ã¤ã³ã³å¢ããããã¿ãããªã¨ãã ãfont awesomeã¨ã足ãã¦ãã
app/styles/app.less
@import '../../node_modules/bootstrap/less/bootstrap.less'; body { background-color: #efffef; }
HTMLã«CSSã®èªã¿è¾¼ã¿ã追å ã
app/index.html
-- ä¸ç¥ -- <head> <meta charset="UTF-8"> <title>Hello World!</title> <link rel="stylesheet" href="./styles/app.css" /> </head> -- ä¸ç¥ --
ã¹ã¿ã¤ã«å¨ãã®gulpã¿ã¹ã¯ã¯æ¬¡ã®éãã
ã¿ã¹ã¯å | ç¨é |
---|---|
styles:dev | éçºç°å¢ç¨ã¹ã¿ã¤ã«ãã«ãï¼less:devãfontsãimagesãå®è¡ããï¼ |
less:dev | lessãã¡ã¤ã«ããã«ããã |
fonts | ãã©ã³ããªã½ã¼ã¹ããã«ãæ¸ã¿ãã£ã¬ã¯ããªã¸é åãã |
images | ç»åãªã½ã¼ã¹ããã«ãæ¸ã¿ãã£ã¬ã¯ããªã¸é åãã |
dev | éçºç°å¢ãèµ·åããHTMLãã¡ã¤ã«ãlessãã¡ã¤ã«ãç£è¦ãã |
gulpfile.js
-- ä¸ç¥ -- gulp.task('styles:dev', ['less:dev', 'fonts', 'images']); gulp.task('less:dev', () => { return gulp.src('app/styles/**/*.less') .pipe($.less({ paths: [ 'node_modules/bootstrap/less' ] })) .pipe(gulp.dest(path.join(distDir, 'styles'))) .pipe($.livereload()); }); gulp.task('fonts', () => { return gulp.src([ 'node_modules/bootstrap/fonts/*' ]) .pipe(gulp.dest(path.join(distDir, 'fonts'))); }); gulp.task('images', () => { return gulp.src([ 'app/images/**/*' ]) .pipe(gulp.dest(path.join(distDir, 'images'))); }); -- ä¸ç¥ -- gulp.task('dev', ['html', 'styles:dev', 'serve'], () => { gulp.watch('app/**/*.html', ['html']); gulp.watch('app/styles/**/*.less', ['less:dev']); }); -- ä¸ç¥ --
JavaScriptã¾ããï¼ã¢ã¸ã¥ã¼ã«ãã³ãã©ï¼
Babelã使ã£ã¦ES6ã§æ¸ããã³ã¼ããES5ã«ãã©ã³ã¹ãã¤ã«ãã¦ããã ã¢ã¸ã¥ã¼ã«ãã³ãã©ã«ã¯webpackã使ã£ã¦ããã
webpackã¯å¤æ©è½ã ãã©ãããã¾ã§JavaScriptã®ã¢ã¸ã¥ã¼ã«ãã³ãã©ã¨ãã¦ä½¿ã£ã¦ããã®ã§ã å¿ è¦ã«å¿ãã¦browserifyã«å·®ãæ¿ããããã¦ããã
ã¤ã³ã¹ãã¼ã«
$ npm install --save-dev webpack babel-loader babel-preset-es2015 gulp-util
Babelã®è¨å®ã¯.babelrcã«æ¸ãã
.babelrc
{ "presets": ["es2015"] }
éçºç°å¢ç¨ã®webpackè¨å®ãä½ãã
ã¨ã³ããªãã¤ã³ãã®app.jsãèªã¿è¾¼ãã§ãBabelãéãã¦ã½ã¼ã¹ãããä»ãã§ãã«ãæ¸ã¿ãã£ã¬ã¯ããªã«é åãã¦ããã
webpack.config.js
var path = require('path'); var pkg = require('./package.json'); var distDir = path.join(__dirname, pkg.dist); module.exports = { entry: { app: './app/scripts/app.js' }, output: { path: path.join(distDir, 'scripts'), filename: '[name].js' }, devtool: 'inline-source-map', module: { loaders: [ { test: /\.js$/, exclude: /node_modules/, loader: 'babel' } ] } };
JavaScriptç¨ã®gulpã¿ã¹ã¯ã¯æ¬¡ã®éãã
ã¿ã¹ã¯å | ç¨é |
---|---|
bundle:dev | JavaScriptã®éçºç¨ãã«ããè¡ã |
dev | éçºç°å¢ãèµ·åããHTMLãã¡ã¤ã«ãlessãã¡ã¤ã«ãJavaScriptãã¡ã¤ã«ãç£è¦ãã |
gulpfile.js
-- ä¸ç¥ -- var webpack = require('webpack'); var bundler = webpack(require('./webpack.config.js')); -- ä¸ç¥ -- gulp.task('bundle:dev', cb => { bundler.run((err, stats) => { if (err) { throw new $.util.PluginError('webpack:build', err); } $.util.log('[webpack:build]', stats.toString({ colors: true, chunkModules: false })); cb(); $.livereload.reload(); }); }); -- ä¸ç¥ -- gulp.task('dev', ['html', 'styles:dev', 'bundle:dev', 'serve'], () => { gulp.watch('app/**/*.html', ['html']); gulp.watch('app/styles/**/*.less', ['less:dev']); gulp.watch('app/scripts/**/*.js', ['bundle:dev']); }); -- ä¸ç¥ --
JavaScriptã½ã¼ã¹ã³ã¼ãã¯app/scriptsé ä¸ã«ç½®ãã¦è¡ãã
app/scripts/Hoge.js
export default class Hoge { constructor(name) { this._name = name; } greet() { return `Hello! ${this._name}`; } }
app.jsãã¨ã³ããªãã¤ã³ãã¨ãã¦ãHTMLãã¡ã¤ã«ã«èªã¿è¾¼ã¾ããã
app/scripts/app.js
import Hoge from './Hoge'; const hoge = new Hoge('test'); console.log(hoge.greet());
app/index.html
-- ä¸ç¥ -- <body> <h1>Hello World!</h1> <script src="./scripts/app.js"></script> </body> </html>
ãããã¯ã·ã§ã³ç¨ã®ãã«ã
éçºç¨ã®ãã«ãè¨å®ã¨ã¯å¥ã«ãããã¯ã·ã§ã³ç¨ãã«ãè¨å®ï¼ã½ã¼ã¹ããããªãããããã¡ã¤åï¼ãç¨æãã¦ããã ãã«ãæ¸ã¿ãªã½ã¼ã¹ã¯zipã§åºãã¦ãç´æ¥ããã³ãã¨ã³ãã®éçºãããªãã¡ã³ãã¼ã«é ããããã«ããã
ã¤ã³ã¹ãã¼ã«
$ npm install --save-dev gulp-zip gulp-minify-css
gulpã®ãããã¯ã·ã§ã³ç¨ãã«ãã¿ã¹ã¯ã¯æ¬¡ã®éãã
ã¿ã¹ã¯å | ç¨é |
---|---|
styles:prod | ãããã¯ã·ã§ã³ç°å¢ç¨ã®styleãã«ãï¼less:prodãfontsãimagesãå®è¡ããï¼ |
less:prod | lessãã¡ã¤ã«ã®ãããã¯ã·ã§ã³ç¨ãã«ããè¡ã |
bundle:prod | JavaScriptã®ãããã¯ã·ã§ã³ç¨ãã«ããè¡ã |
prod | ãããã¯ã·ã§ã³ãã«ããèµ·åãã |
build | ãããã¯ã·ã§ã³ãã«ãï¼cleanãã¦prodããï¼ |
less:devã¨less:prodã®å ±éé¨åãlessé¢æ°ã¨ãã¦åãåºãã¦ãããããã®ã¿ã¹ã¯ã«å©ç¨ããã webpackã®ãããã¯ã·ã§ã³ãã«ãç¨è¨å®ã追å ãã¦bundle:prodã§ã¯ãã¡ãã使ãããã«ããã
gulpfile.js
-- ä¸ç¥ -- function less() { return gulp.src('app/styles/**/*.less') .pipe($.less({ paths: [ 'node_modules/bootstrap/less' ] })); } -- ä¸ç¥ -- gulp.task('styles:prod', ['less:prod', 'fonts', 'images']); gulp.task('less:dev', () => { return less() .pipe(gulp.dest(path.join(distDir, 'styles'))) .pipe($.livereload()); }); gulp.task('less:prod', () => { return less() .pipe($.minifyCss()) .pipe(gulp.dest(path.join(distDir, 'styles'))) }); -- ä¸ç¥ -- gulp.task('bundle:prod', cb => { webpack(require('./webpack.production.config.js'), cb); }); -- ä¸ç¥ -- gulp.task('prod', ['html', 'styles:prod', 'bundle:prod'], () => { return gulp.src(path.join(distDir, '**/*')) .pipe($.zip(pkg.name + '.zip')) .pipe(gulp.dest('build')); }); gulp.task('build', ['clean'], () => { gulp.start('prod'); }); -- ä¸ç¥ --
webpackã®è¨å®ãéçºç¨ã¨ãããã¯ã·ã§ã³ç¨ã§åé¢ããã両æ¹ã®å ±éé¨åãcommonè¨å®ãã¡ã¤ã«ã¨ãã¦åãåºãã
webpack.common.js
var path = require('path'); var pkg = require('./package.json'); var distDir = path.join(__dirname, pkg.dist); module.exports = function() { return { entry: { app: './app/scripts/app.js' }, output: { path: path.join(distDir, 'scripts'), filename: '[name].js' }, module: { loaders: [ { test: /\.js$/, exclude: /node_modules/, loader: 'babel' } ] } }; };
éçºç¨ã®webpackè¨å®ã¯ãå ±éè¨å®ãèªã¿è¾¼ãã§ã½ã¼ã¹ãããã追å ããè¨å®ã«ããã
webpack.config.js
var config = require('./webpack.common.js')(); config.devtool = 'inline-source-map'; module.exports = config;
ãããã¯ã·ã§ã³ç¨ã®webpackè¨å®ã¯ãå ±éè¨å®ãèªã¿è¾¼ãã§Uglifyãã©ã°ã¤ã³ã追å ããè¨å®ã«ããã
webpack.production.config.js
var config = require('./webpack.common.js')(); var webpack = require('webpack'); config.plugins = [ new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false } }) ]; module.exports = config;
buildãã£ã¬ã¯ããªã¯gitignore対象ã
.gitignore
dist build -- ä¸ç¥ --
ãã«ãç¨ã³ãã³ããpackage.jsonã«è¿½å ããã
package.json
-- ä¸ç¥ -- "scripts": { "gulp": "gulp", "build": "gulp build" }, -- ä¸ç¥ --
ãããã¯ã·ã§ã³ç¨ãã«ãã¯ã³ãã³ããå©ãã¦è¡ãã
$ npm run build
ãã¹ãç°å¢
ãã¹ãã¯mochaã¨power-assertã§æ¸ãã¦ããã ãã¹ãã³ã¼ããES6ã§æ¸ãããã®ã§espower-babelã使ã£ã¦ããã
ã¤ã³ã¹ãã¼ã«
$ npm install --save-dev mocha power-assert espower-babel
mochaã®è¨å®ãå ¥ãã¦ããã
test/mocha.opts
--compilers js:espower-babel/guess
ãã¹ãã³ã¼ãã¯ãããªæãã
test/Hoge-test.js
import Hoge from '../app/scripts/Hoge'; import assert from 'power-assert'; describe('Hoge', () => { const name = 'Test'; let hoge; beforeEach(() => { hoge = new Hoge(name); }); describe('#greet', () => { it('returns greet message', () => { assert(hoge.greet() === `Hello! ${name}`); }); }); });
ãã¹ããå©ãããã®npmã³ãã³ããpackage.jsonã«è¿½å ããã
package.json
-- ä¸ç¥ -- "scripts": { "gulp": "gulp", "build": "gulp build", "mocha": "mocha", "test": "mocha test/*-test.js" }, -- ä¸ç¥ --
ãã¹ãå©ãã¨ãã¯ãããªæãã§ä¸æ°ã«ãVimã§ç·¨éã®ãã¡ã¤ã«ã¨ãåå¥ã«å©ãã¨ãã¯npm run mocha ã§ã
$ npm test
APIãµã¼ãã¨ã¤ãªããªããéçº
Ajaxã§ããã¯ã¨ã³ãã®APIã使ãå ´åãå¯è½ã§ããã°ããã¯ã¨ã³ãã®ãµã¼ããèµ·åãã¦ããã¦ã http-proxy-middlewareã使ã£ã¦APIã¸ã®ãªã¯ã¨ã¹ãã ããªãã¼ã¹ãããã·ãã¦ããã
ã¤ã³ã¹ãã¼ã«
$ npm install --save-dev http-proxy-middleware
ãã®å ´åãgulpã®serveã¿ã¹ã¯ã«æ¬¡ã®ãããªä¿®æ£ãå ããã ä¸ã®è¨å®ä¾ã ã¨/apiãªãã¹ã¸ã®ãªã¯ã¨ã¹ãã¯localhostã®3000ãã¼ãã®æ¹ã¸ãããã·ãããã
gulefile.js
-- ä¸ç¥ -- var proxyMiddleware = require('http-proxy-middleware'); -- ä¸ç¥ -- gulp.task('serve', () => { var port = process.env.API_PORT || 3000; $.livereload.listen(); connect() .use(connectLivereload()) .use(serveStatic(distDir)) .use(proxyMiddleware([ '/api' ], { target: 'http://localhost:' + port, changeOrigin: true })) .listen(3100); }); -- ä¸ç¥ --
fetchã使ã£ã¦APIãå©ããµã³ãã«ã次ã®ãããªæãã
app/scripts/Hoge.js
export default class Hoge { constructor(name) { this._name = name; } greet() { return `Hello! ${this._name}`; } fetchGreet() { return fetch('/api/greeting') .then(res => res.json()) .then(json => { return `${json.message} ${this._name}`; }); } }
app/scripts/app.js
import Hoge from './Hoge'; const hoge = new Hoge('test'); console.log(hoge.greet()); hoge.fetchGreet() .then(message => { console.log(message); });
ä½è«ï¼ããã¯ã¨ã³ããµã¼ãã®APIãã¢ãã¯
ããã¯ã¨ã³ããµã¼ãã®APIä»æ§ãJSON Hyper-Schemaã§å®ç¾©ããã¦ããå ´å ï¼ä¸ã®fixture/api.jsonã¿ãããªæãï¼ãéã«ã¢ãã¯ãµã¼ããèµ·åãã¦ä»£æ¿ã«ãã¦ããã
{ "$schema": "http://interagent.github.io/interagent-hyper-schema", "type": [ "object" ], "definitions": { "greeting": { "$schema": "http://json-schema.org/draft-04/hyper-schema", "title": "Greeting", "description": "ãæ¨æ¶API", "stability": "prototype", "strictProperties": true, "type": [ "object" ], "definitions": { "message": { "description": "ãæ¨æ¶ã¡ãã»ã¼ã¸", "example": "ããã«ã¡ã¯", "type": [ "string" ] } }, "links": [ { "description": "ãæ¨æ¶ã¡ãã»ã¼ã¸ãåå¾ãã", "href": "/api/greeting", "method": "GET", "rel": "self", "title": "Info" } ], "properties": { "message": { "$ref": "#/definitions/greeting/definitions/message" } } } }, "properties": { "greeting": { "$ref": "#/definitions/greeting" } } }
ã¤ã³ã¹ãã¼ã«
$ npm install --save-dev json-schema-mockserve
ãã®å ´åãgulpã®serveã¿ã¹ã¯ã次ã®ããã«ä¿®æ£ããã ç°å¢å¤æ°MOCKã«å¤ãè¨å®ãããå ´åãã¢ãã¯ãµã¼ããèµ·åããããã«ãã¦ããã
gulpfile.js
-- ä¸ç¥ -- var MockServe = require('json-schema-mockserve').MockServe; -- ä¸ç¥ -- gulp.task('serve', () => { var port = process.env.API_PORT || 3000; if (process.env.MOCK) { new MockServe({ port: port, path: path.join(__dirname, 'fixture', 'api.json') }).start(); } $.livereload.listen(); connect() .use(connectLivereload()) .use(serveStatic(distDir)) .use(proxyMiddleware([ '/api' ], { target: 'http://localhost:' + port, changeOrigin: true })) .listen(3100); }); -- ä¸ç¥ --
ã¢ãã¯ãµã¼ãã§èµ·åããã³ãã³ããpackage.jsonã«è¿½å ããã
package.json
-- ä¸ç¥ -- "scripts": { "gulp": "gulp", "gulp:mock": "MOCK=ON gulp", "build": "gulp build", "mocha": "mocha", "test": "mocha test/*-test.js" }, -- ä¸ç¥ --
ã³ãã³ãããèµ·åããã
$ npm run gulp:mock
fetchãã¢ãã¯ãã¦ãã¹ã
Ajaxãªãã¨ã¯ãPromiseãã¼ã¹ã®ã¤ã³ã¿ã¼ãã§ã¤ã¹ã«ãªã£ã¦ãããã¨ããã XMLHttpRequestãããfetchã使ãããã«ãªã£ãã fetchã使ãAPIããã¹ãããå ´åãfetch-mockã使ã£ã¦ããã
ã¤ã³ã¹ãã¼ã«
$ npm install --save-dev fetch-mock
ãã¹ãã³ã¼ãã¯æ¬¡ã®ãããªæãã«ã fetchMockã®mockã§ã¢ãã¯è¨å®ãã¦ãafterEachã§restoreãã¦ã¢ãã¯è§£é¤ãã¦ããã
test/Hoge-test.js
import Hoge from '../app/scripts/Hoge'; import assert from 'power-assert'; import fetchMock from 'fetch-mock'; describe('Hoge', () => { const name = 'Test'; let hoge; beforeEach(() => { hoge = new Hoge(name); }); afterEach(() => { fetchMock.restore(); }); describe('#greet', () => { it('returns greet message', () => { assert(hoge.greet() === `Hello! ${name}`); }); }); describe('#fetchGreet', () => { beforeEach(() => { fetchMock.mock('/api/greeting', 'GET', { status: 200, body: '{"message":"Hello Hello Hello..."}' }); }); it('returns greet message promise', () => { return hoge.fetchGreet() .then(message => { assert(message === `Hello Hello Hello... ${name}`); }); }); }); });
ãã©ã¦ã¶ã§ãã¹ã
nodeã®ç°å¢ã ãã§ãªããã©ã¦ã¶ç°å¢ã§ããã¹ãããå ´åã¯testemã使ã£ã¦ããã
webpackã§JavaScriptã³ã¼ãããã©ã¦ã¶ç¨ã«ãã«ããã¦testemã«èªã¾ãã¦ãã ãã®ã¨ããpower-assertã¨webpackã§jsonã®èªã¿è¾¼ã¿ãå¯è½ã«ãã¦ãããªãã¨ã ãã«ãå¾ã®ã³ã¼ããåããªãã®ã§json-loaderã追å ãã¦ããã
ã¤ã³ã¹ãã¼ã«
$ npm install --save-dev testem glob json-loader
ãã¹ãç¨ã®webpackè¨å®ã追å ããã testãã£ã¬ã¯ããªé ä¸ã®ãã¹ãç¨ã³ã¼ããglobã§ããã£ã¨éãã¦å¤æããã
webpack.test.config.js
var path = require('path'); var glob = require('glob'); module.exports = { entry: { test: glob.sync(path.join(__dirname, 'test/**/*-test.js')) }, output: { path: path.join(__dirname, '.powered-assert'), filename: '[name].js' }, devtool: 'inline-source-map', module: { loaders: [ { test: /\.js$/, exclude: /node_modules/, loader: 'babel' }, { test: /\.json$/, loader: 'json' } ] } };
testemã®è¨å®ãtestem.jsonã«è¡ãã å®è¡åã«webpackã§ãã¹ãç¨ãã«ããè¡ããå®è¡å¾ã«ãã¹ãç¨ãã«ããã£ã¬ã¯ããªï¼.powered-assertï¼ãã¨ç ´æ£ããã
testem.json
{ "framework": "mocha", "before_tests": "webpack --config webpack.test.config.js", "on_exit": "rm -rf .powered-assert/", "src_files": [ ".powered-assert/**/*.js" ] }
ãã¹ãç¨ãã«ããã£ã¬ã¯ããªãgitignore対象ã«ããã
.gitignore
dist build .powered-assert/ -- ä¸ç¥ --
testemã®å®è¡ãã³ãã³ãã¨ãã¦è¿½å ãã¦ããã
package.json
-- ä¸ç¥ -- "scripts": { "gulp": "gulp", "gulp:mock": "MOCK=ON gulp", "build": "gulp build", "mocha": "mocha", "testem": "testem", "test": "mocha test/*-test.js" }, -- ä¸ç¥ --
testemãèµ·åããå ´åã¯æ¬¡ã®ããã«ãã¦è¡ããèµ·åããããã©ã¦ã¶ã§ã¢ã¯ã»ã¹ããã
$ npm run testem
ä¸æ°ã«è¡ãå ´åã¯ciãªãã·ã§ã³ã§å®è¡ããã
$ npm run testem ci
ã¾ã¨ã
ä¸éããã£ããªãã¸ããªã¯ãã¡ãã
å¿ è¦ãªãã®ãå¿ è¦ãªã¨ãã«å¿ è¦ãªã ãåãå ¥ãã¤ã¤ãå ¨ä½çã«èãã«åãæ¿ããå¹ãããã«ã·ã³ãã«ãªæ§æã§...ã¨ããã®ãä»ã®ã¨ããã®èªåã®æ¹éã