From 82dc5f0d22a5f3e7657b63a773b12e417857e06e Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Mon, 26 Jan 2015 16:51:10 +0200 Subject: [PATCH 01/49] add MIT license --- LICENSE.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE.md diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..3a8ee75 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Riku Rouvila + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. From 9820ad1d00fde4e93444b9d8641bfa93c73f120a Mon Sep 17 00:00:00 2001 From: Chang Wang Date: Thu, 5 Feb 2015 11:03:57 -0500 Subject: [PATCH 02/49] stylus sourcemaps --- gulpfile.coffee | 6 +++++- package.json | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/gulpfile.coffee b/gulpfile.coffee index 9c18108..e126b99 100644 --- a/gulpfile.coffee +++ b/gulpfile.coffee @@ -10,6 +10,7 @@ path = require 'path' prefix = require 'gulp-autoprefixer' prettyTime = require 'pretty-hrtime' source = require 'vinyl-source-stream' +sourcemaps = require 'gulp-sourcemaps' streamify = require 'gulp-streamify' stylus = require 'gulp-stylus' uglify = require 'gulp-uglify' @@ -71,6 +72,7 @@ gulp.task 'templates', -> gulp.task 'styles', -> styles = gulp .src config.styles.source + .pipe sourcemaps.init() .pipe stylus 'include css': true @@ -78,7 +80,9 @@ gulp.task 'styles', -> .pipe prefix 'last 2 versions', 'Chrome 34', 'Firefox 28', 'iOS 7' styles = styles.pipe(CSSmin()) if production - styles = styles.pipe gulp.dest config.styles.destination + styles = styles + .pipe sourcemaps.write('.') + .pipe gulp.dest config.styles.destination styles = styles.pipe livereload(auto: false) unless production styles diff --git a/package.json b/package.json index 88bffea..bf14988 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,8 @@ "gulp-livereload": "~2.1.0", "gulp-minify-css": "~0.3.5", "gulp-streamify": "0.0.5", - "gulp-stylus": "1.3.3", + "gulp-sourcemaps": "^1.3.0", + "gulp-stylus": "~2.0.0", "gulp-uglify": "~1.0.1", "gulp-util": "~3.0.1", "karma": "~0.12.21", From 17d64a0b1daad8ecb4f35165d3be9faef91bbda9 Mon Sep 17 00:00:00 2001 From: Chang Wang Date: Fri, 6 Feb 2015 15:00:42 -0500 Subject: [PATCH 03/49] disable css sourcemaps for production --- gulpfile.coffee | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/gulpfile.coffee b/gulpfile.coffee index e126b99..51a6232 100644 --- a/gulpfile.coffee +++ b/gulpfile.coffee @@ -70,19 +70,17 @@ gulp.task 'templates', -> pipeline gulp.task 'styles', -> - styles = gulp - .src config.styles.source - .pipe sourcemaps.init() - .pipe stylus + styles = gulp.src config.styles.source + styles = styles.pipe(sourcemaps.init()) unless production + styles = styles.pipe stylus 'include css': true .on 'error', handleError .pipe prefix 'last 2 versions', 'Chrome 34', 'Firefox 28', 'iOS 7' styles = styles.pipe(CSSmin()) if production - styles = styles - .pipe sourcemaps.write('.') - .pipe gulp.dest config.styles.destination + styles = styles.pipe(sourcemaps.write '.') unless production + styles = styles.pipe gulp.dest config.styles.destination styles = styles.pipe livereload(auto: false) unless production styles From 0cb804439a960ef36c53086fd516e48c5ab2dcf5 Mon Sep 17 00:00:00 2001 From: Lauri Hahne Date: Tue, 10 Feb 2015 17:12:20 +0200 Subject: [PATCH 04/49] upgrade watchify to support node 0.12 & io.js --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bf14988..aa3d591 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "karma-jasmine": "~0.2.2", "pretty-hrtime": "~0.2.2", "vinyl-source-stream": "~1.0.0", - "watchify": "~2.0.0" + "watchify": "~2.3.0" }, "browserify": { "transform": [ From 045428adcfe7e49100d2face45fc3aba00d619e0 Mon Sep 17 00:00:00 2001 From: Hannu Pousi Date: Thu, 5 Mar 2015 10:27:01 +0200 Subject: [PATCH 05/49] use browser-sync instead of livereload --- gulpfile.coffee | 53 ++++++++++++++++++++++++------------------------- package.json | 4 ++-- 2 files changed, 28 insertions(+), 29 deletions(-) diff --git a/gulpfile.coffee b/gulpfile.coffee index 51a6232..2c9546b 100644 --- a/gulpfile.coffee +++ b/gulpfile.coffee @@ -1,22 +1,22 @@ -browserify = require 'browserify' -chalk = require 'chalk' -CSSmin = require 'gulp-minify-css' -ecstatic = require 'ecstatic' -gulp = require 'gulp' -gutil = require 'gulp-util' -jade = require 'gulp-jade' -livereload = require 'gulp-livereload' -path = require 'path' -prefix = require 'gulp-autoprefixer' -prettyTime = require 'pretty-hrtime' -source = require 'vinyl-source-stream' -sourcemaps = require 'gulp-sourcemaps' -streamify = require 'gulp-streamify' -stylus = require 'gulp-stylus' -uglify = require 'gulp-uglify' -watchify = require 'watchify' +browserify = require 'browserify' +chalk = require 'chalk' +CSSmin = require 'gulp-minify-css' +ecstatic = require 'ecstatic' +gulp = require 'gulp' +gutil = require 'gulp-util' +jade = require 'gulp-jade' +browserSync = require 'browser-sync' +path = require 'path' +prefix = require 'gulp-autoprefixer' +prettyTime = require 'pretty-hrtime' +source = require 'vinyl-source-stream' +sourcemaps = require 'gulp-sourcemaps' +streamify = require 'gulp-streamify' +stylus = require 'gulp-stylus' +uglify = require 'gulp-uglify' +watchify = require 'watchify' -production = process.env.NODE_ENV is 'production' +production = process.env.NODE_ENV is 'production' config = scripts: @@ -65,7 +65,7 @@ gulp.task 'templates', -> .on 'error', handleError .pipe gulp.dest config.templates.destination - pipeline = pipeline.pipe livereload(auto: false) unless production + pipeline = pipeline.pipe browserSync.reload(stream: true) unless production pipeline @@ -81,7 +81,7 @@ gulp.task 'styles', -> styles = styles.pipe(CSSmin()) if production styles = styles.pipe(sourcemaps.write '.') unless production styles = styles.pipe gulp.dest config.styles.destination - styles = styles.pipe livereload(auto: false) unless production + styles = styles.pipe browserSync.reload(stream: true) unless production styles gulp.task 'assets', -> @@ -90,13 +90,12 @@ gulp.task 'assets', -> .pipe gulp.dest config.assets.destination gulp.task 'server', -> - require('http') - .createServer ecstatic root: path.join(__dirname, 'public') - .listen 9001 + browserSync + port: 9001 + server: + baseDir: './public' gulp.task 'watch', -> - livereload.listen() - gulp.watch config.templates.watch, ['templates'] gulp.watch config.styles.watch, ['styles'] gulp.watch config.assets.watch, ['assets'] @@ -114,12 +113,12 @@ gulp.task 'watch', -> start = process.hrtime() build = bundle.bundle() .on 'error', handleError - .pipe source config.scripts.filename build .pipe gulp.dest config.scripts.destination - .pipe(livereload()) + .pipe(browserSync.reload(stream: true)) + gutil.log "Finished '#{chalk.cyan 'rebundle'}' after #{chalk.magenta prettyTime process.hrtime start}" .emit 'update' diff --git a/package.json b/package.json index aa3d591..60fd4e0 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ }, "devDependencies": { "bower": "~1.3.5", + "browser-sync": "~2.2.2", "browserify": "~6.1.0", "chalk": "~0.5.1", "coffeeify": "~0.7.0", @@ -29,10 +30,9 @@ "gulp": "~3.8.1", "gulp-autoprefixer": "1.0.1", "gulp-jade": "~0.9.0", - "gulp-livereload": "~2.1.0", "gulp-minify-css": "~0.3.5", - "gulp-streamify": "0.0.5", "gulp-sourcemaps": "^1.3.0", + "gulp-streamify": "0.0.5", "gulp-stylus": "~2.0.0", "gulp-uglify": "~1.0.1", "gulp-util": "~3.0.1", From 0fe3a4d837a7b1a41ef3e73fc99619c85fdb2c7f Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Thu, 5 Mar 2015 10:49:44 +0200 Subject: [PATCH 06/49] trim trailing whitespace reorganize require calls alphabetically --- gulpfile.coffee | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gulpfile.coffee b/gulpfile.coffee index 2c9546b..a8f1d37 100644 --- a/gulpfile.coffee +++ b/gulpfile.coffee @@ -1,11 +1,11 @@ browserify = require 'browserify' +browserSync = require 'browser-sync' chalk = require 'chalk' CSSmin = require 'gulp-minify-css' ecstatic = require 'ecstatic' gulp = require 'gulp' gutil = require 'gulp-util' jade = require 'gulp-jade' -browserSync = require 'browser-sync' path = require 'path' prefix = require 'gulp-autoprefixer' prettyTime = require 'pretty-hrtime' @@ -92,8 +92,8 @@ gulp.task 'assets', -> gulp.task 'server', -> browserSync port: 9001 - server: - baseDir: './public' + server: + baseDir: './public' gulp.task 'watch', -> gulp.watch config.templates.watch, ['templates'] From dc053974ab8ce312459eb9dedb81b3f687abe685 Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Thu, 5 Mar 2015 10:57:54 +0200 Subject: [PATCH 07/49] filter style files before calling browsersync to refresh so that .map files don't initialize full reload --- gulpfile.coffee | 8 +++++++- package.json | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/gulpfile.coffee b/gulpfile.coffee index a8f1d37..e3b3339 100644 --- a/gulpfile.coffee +++ b/gulpfile.coffee @@ -3,6 +3,7 @@ browserSync = require 'browser-sync' chalk = require 'chalk' CSSmin = require 'gulp-minify-css' ecstatic = require 'ecstatic' +filter = require 'gulp-filter' gulp = require 'gulp' gutil = require 'gulp-util' jade = require 'gulp-jade' @@ -81,7 +82,12 @@ gulp.task 'styles', -> styles = styles.pipe(CSSmin()) if production styles = styles.pipe(sourcemaps.write '.') unless production styles = styles.pipe gulp.dest config.styles.destination - styles = styles.pipe browserSync.reload(stream: true) unless production + + unless production + styles = styles + .pipe filter '**/*.css' + .pipe browserSync.reload(stream: true) + styles gulp.task 'assets', -> diff --git a/package.json b/package.json index 60fd4e0..05d9bbc 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "ecstatic": "~0.5.3", "gulp": "~3.8.1", "gulp-autoprefixer": "1.0.1", + "gulp-filter": "^2.0.2", "gulp-jade": "~0.9.0", "gulp-minify-css": "~0.3.5", "gulp-sourcemaps": "^1.3.0", From 6ae6792319cab9ced33d7a5e3b8bac7a87fd568c Mon Sep 17 00:00:00 2001 From: Chang Wang Date: Mon, 20 Apr 2015 02:29:48 -0400 Subject: [PATCH 08/49] Update README.md Remove section on livereload since it's been replaced with BrowserSync --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index d8ac91c..653db61 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,6 @@ npm start open http://localhost:9001 in your browser ```` -### Enable LiveReload -Install [LiveReload for Chrome](https://chrome.google.com/webstore/detail/livereload/jnihajbhpnppcggbcgedagnkighmdlei?hl=en) ## CLI Commands * npm install From c0d2cec9557ed322854d10eec94b90c9d8322d83 Mon Sep 17 00:00:00 2001 From: Chang Wang Date: Mon, 20 Apr 2015 23:44:38 -0400 Subject: [PATCH 09/49] add gulp notify --- gulpfile.coffee | 4 ++++ package.json | 1 + 2 files changed, 5 insertions(+) diff --git a/gulpfile.coffee b/gulpfile.coffee index e3b3339..830f493 100644 --- a/gulpfile.coffee +++ b/gulpfile.coffee @@ -7,6 +7,7 @@ filter = require 'gulp-filter' gulp = require 'gulp' gutil = require 'gulp-util' jade = require 'gulp-jade' +notify = require 'gulp-notify' path = require 'path' prefix = require 'gulp-autoprefixer' prettyTime = require 'pretty-hrtime' @@ -41,6 +42,9 @@ config = handleError = (err) -> gutil.log err gutil.beep() + notify + .onError title: 'Compile Error', message: '<%= error.message %>' + .apply this, Array::slice.call(arguments) this.emit 'end' gulp.task 'scripts', -> diff --git a/package.json b/package.json index 05d9bbc..31a7460 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "gulp-filter": "^2.0.2", "gulp-jade": "~0.9.0", "gulp-minify-css": "~0.3.5", + "gulp-notify": "^2.2.0", "gulp-sourcemaps": "^1.3.0", "gulp-streamify": "0.0.5", "gulp-stylus": "~2.0.0", From aecb07fe8755954942baddc35a09e37820587554 Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Fri, 1 May 2015 16:17:44 +0300 Subject: [PATCH 10/49] do not open browser automatically when gulp is started --- gulpfile.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gulpfile.coffee b/gulpfile.coffee index 830f493..d7e2128 100644 --- a/gulpfile.coffee +++ b/gulpfile.coffee @@ -101,7 +101,8 @@ gulp.task 'assets', -> gulp.task 'server', -> browserSync - port: 9001 + open: false + port: 9001 server: baseDir: './public' From 71af2bbb28f3135e53c92379b8058aa41c64d1d6 Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Fri, 1 May 2015 16:42:27 +0300 Subject: [PATCH 11/49] add npm-debug.log to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index b51fa0c..7580c79 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +npm-debug.log node_modules bower_components public From 6eaa314e825713aff7dfdf90a4d7652295c07bda Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Wed, 20 May 2015 23:13:01 +0300 Subject: [PATCH 12/49] Refactoring * Removed needless dependencies * All functionality should be like earlier --- gulpfile.coffee | 86 ++++++++++++++++++++----------------------------- package.json | 11 +++---- 2 files changed, 39 insertions(+), 58 deletions(-) diff --git a/gulpfile.coffee b/gulpfile.coffee index d7e2128..3e293e3 100644 --- a/gulpfile.coffee +++ b/gulpfile.coffee @@ -1,16 +1,13 @@ browserify = require 'browserify' browserSync = require 'browser-sync' -chalk = require 'chalk' -CSSmin = require 'gulp-minify-css' +duration = require 'gulp-duration' ecstatic = require 'ecstatic' -filter = require 'gulp-filter' gulp = require 'gulp' gutil = require 'gulp-util' jade = require 'gulp-jade' notify = require 'gulp-notify' path = require 'path' prefix = require 'gulp-autoprefixer' -prettyTime = require 'pretty-hrtime' source = require 'vinyl-source-stream' sourcemaps = require 'gulp-sourcemaps' streamify = require 'gulp-streamify' @@ -18,7 +15,7 @@ stylus = require 'gulp-stylus' uglify = require 'gulp-uglify' watchify = require 'watchify' -production = process.env.NODE_ENV is 'production' +production = process.env.NODE_ENV is 'production' config = scripts: @@ -39,60 +36,57 @@ config = watch: './src/assets/**/*.*' destination: './public/' +browserifyConfig = + entries: [config.scripts.source] + extensions: config.scripts.extensions + debug: not production + cache: {} + packageCache: {} + handleError = (err) -> gutil.log err gutil.beep() + notify - .onError title: 'Compile Error', message: '<%= error.message %>' - .apply this, Array::slice.call(arguments) + title: 'Compile Error' + message: err.message + this.emit 'end' gulp.task 'scripts', -> - - bundle = browserify - entries: [config.scripts.source] - extensions: config.scripts.extensions - debug: not production - - build = bundle.bundle() + pipeline = browserify(browserifyConfig) + .bundle() .on 'error', handleError .pipe source config.scripts.filename - build.pipe(streamify(uglify())) if production + pipeline = build.pipe(streamify(uglify())) if production - build - .pipe gulp.dest config.scripts.destination + pipeline.pipe gulp.dest config.scripts.destination gulp.task 'templates', -> pipeline = gulp .src config.templates.source - .pipe(jade(pretty: not production)) + .pipe jade pretty: not production .on 'error', handleError .pipe gulp.dest config.templates.destination - pipeline = pipeline.pipe browserSync.reload(stream: true) unless production - - pipeline + if production then pipeline else pipeline.pipe browserSync.reload(stream: true) gulp.task 'styles', -> - styles = gulp.src config.styles.source - styles = styles.pipe(sourcemaps.init()) unless production - styles = styles.pipe stylus - 'include css': true + pipeline = gulp.src config.styles.source - .on 'error', handleError - .pipe prefix 'last 2 versions', 'Chrome 34', 'Firefox 28', 'iOS 7' + pipeline = pipeline.pipe(sourcemaps.init()) unless production - styles = styles.pipe(CSSmin()) if production - styles = styles.pipe(sourcemaps.write '.') unless production - styles = styles.pipe gulp.dest config.styles.destination + pipeline = pipeline.pipe stylus + 'include css': true + compress: production + .on 'error', handleError + .pipe prefix 'last 2 versions', 'Chrome 34', 'Firefox 28', 'iOS 7' - unless production - styles = styles - .pipe filter '**/*.css' - .pipe browserSync.reload(stream: true) + pipeline = pipeline.pipe(sourcemaps.write '.') unless production + pipeline = pipeline.pipe gulp.dest config.styles.destination - styles + if production then pipeline else pipeline.pipe browserSync.stream match: '**/*.css' gulp.task 'assets', -> gulp @@ -111,31 +105,21 @@ gulp.task 'watch', -> gulp.watch config.styles.watch, ['styles'] gulp.watch config.assets.watch, ['assets'] - bundle = watchify browserify - entries: [config.scripts.source] - extensions: config.scripts.extensions - debug: not production - cache: {} - packageCache: {} - fullPaths: true + bundle = watchify browserify browserifyConfig bundle.on 'update', -> - gutil.log "Starting '#{chalk.cyan 'rebundle'}'..." - start = process.hrtime() build = bundle.bundle() .on 'error', handleError .pipe source config.scripts.filename build .pipe gulp.dest config.scripts.destination + .pipe(duration('Rebundling browserify bundle')) .pipe(browserSync.reload(stream: true)) - gutil.log "Finished '#{chalk.cyan 'rebundle'}' after #{chalk.magenta prettyTime process.hrtime start}" - .emit 'update' -gulp.task 'no-js', ['templates', 'styles', 'assets'] -gulp.task 'build', ['scripts', 'no-js'] -# scripts and watch conflict and will produce invalid js upon first run -# which is why the no-js task exists. -gulp.task 'default', ['watch', 'no-js', 'server'] +buildTasks = ['templates', 'styles', 'assets'] + +gulp.task 'build', buildTasks.concat ['scripts'] +gulp.task 'default', buildTasks.concat ['watch', 'server'] diff --git a/package.json b/package.json index 31a7460..975caa2 100644 --- a/package.json +++ b/package.json @@ -20,18 +20,16 @@ }, "devDependencies": { "bower": "~1.3.5", - "browser-sync": "~2.2.2", - "browserify": "~6.1.0", - "chalk": "~0.5.1", + "browser-sync": "^2.7.2", + "browserify": "^10.2.1", "coffeeify": "~0.7.0", "deamdify": "^0.1.1", "debowerify": "~0.9.1", "ecstatic": "~0.5.3", "gulp": "~3.8.1", "gulp-autoprefixer": "1.0.1", - "gulp-filter": "^2.0.2", + "gulp-duration": "0.0.0", "gulp-jade": "~0.9.0", - "gulp-minify-css": "~0.3.5", "gulp-notify": "^2.2.0", "gulp-sourcemaps": "^1.3.0", "gulp-streamify": "0.0.5", @@ -43,9 +41,8 @@ "karma-cli": "0.0.4", "karma-coffee-preprocessor": "~0.2.1", "karma-jasmine": "~0.2.2", - "pretty-hrtime": "~0.2.2", "vinyl-source-stream": "~1.0.0", - "watchify": "~2.3.0" + "watchify": "^3.2.1" }, "browserify": { "transform": [ From 74de7b9bddd36802d6429f5eef76a984ff88a9a8 Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Wed, 20 May 2015 23:28:37 +0300 Subject: [PATCH 13/49] convert gulpfile.coffee to gulpfile.js --- gulpfile.coffee | 125 -------------------------------------- gulpfile.js | 157 ++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 4 +- 3 files changed, 158 insertions(+), 128 deletions(-) delete mode 100644 gulpfile.coffee create mode 100644 gulpfile.js diff --git a/gulpfile.coffee b/gulpfile.coffee deleted file mode 100644 index 3e293e3..0000000 --- a/gulpfile.coffee +++ /dev/null @@ -1,125 +0,0 @@ -browserify = require 'browserify' -browserSync = require 'browser-sync' -duration = require 'gulp-duration' -ecstatic = require 'ecstatic' -gulp = require 'gulp' -gutil = require 'gulp-util' -jade = require 'gulp-jade' -notify = require 'gulp-notify' -path = require 'path' -prefix = require 'gulp-autoprefixer' -source = require 'vinyl-source-stream' -sourcemaps = require 'gulp-sourcemaps' -streamify = require 'gulp-streamify' -stylus = require 'gulp-stylus' -uglify = require 'gulp-uglify' -watchify = require 'watchify' - -production = process.env.NODE_ENV is 'production' - -config = - scripts: - source: './src/coffee/main.coffee' - extensions: ['.coffee'] - destination: './public/js/' - filename: 'bundle.js' - templates: - source: './src/jade/*.jade' - watch: './src/jade/*.jade' - destination: './public/' - styles: - source: './src/stylus/style.styl' - watch: './src/stylus/*.styl' - destination: './public/css/' - assets: - source: './src/assets/**/*.*' - watch: './src/assets/**/*.*' - destination: './public/' - -browserifyConfig = - entries: [config.scripts.source] - extensions: config.scripts.extensions - debug: not production - cache: {} - packageCache: {} - -handleError = (err) -> - gutil.log err - gutil.beep() - - notify - title: 'Compile Error' - message: err.message - - this.emit 'end' - -gulp.task 'scripts', -> - pipeline = browserify(browserifyConfig) - .bundle() - .on 'error', handleError - .pipe source config.scripts.filename - - pipeline = build.pipe(streamify(uglify())) if production - - pipeline.pipe gulp.dest config.scripts.destination - -gulp.task 'templates', -> - pipeline = gulp - .src config.templates.source - .pipe jade pretty: not production - .on 'error', handleError - .pipe gulp.dest config.templates.destination - - if production then pipeline else pipeline.pipe browserSync.reload(stream: true) - -gulp.task 'styles', -> - pipeline = gulp.src config.styles.source - - pipeline = pipeline.pipe(sourcemaps.init()) unless production - - pipeline = pipeline.pipe stylus - 'include css': true - compress: production - .on 'error', handleError - .pipe prefix 'last 2 versions', 'Chrome 34', 'Firefox 28', 'iOS 7' - - pipeline = pipeline.pipe(sourcemaps.write '.') unless production - pipeline = pipeline.pipe gulp.dest config.styles.destination - - if production then pipeline else pipeline.pipe browserSync.stream match: '**/*.css' - -gulp.task 'assets', -> - gulp - .src config.assets.source - .pipe gulp.dest config.assets.destination - -gulp.task 'server', -> - browserSync - open: false - port: 9001 - server: - baseDir: './public' - -gulp.task 'watch', -> - gulp.watch config.templates.watch, ['templates'] - gulp.watch config.styles.watch, ['styles'] - gulp.watch config.assets.watch, ['assets'] - - bundle = watchify browserify browserifyConfig - - bundle.on 'update', -> - build = bundle.bundle() - .on 'error', handleError - .pipe source config.scripts.filename - - build - .pipe gulp.dest config.scripts.destination - .pipe(duration('Rebundling browserify bundle')) - .pipe(browserSync.reload(stream: true)) - - .emit 'update' - -buildTasks = ['templates', 'styles', 'assets'] - -gulp.task 'build', buildTasks.concat ['scripts'] -gulp.task 'default', buildTasks.concat ['watch', 'server'] diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000..deb0d50 --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,157 @@ +'use strict'; + +var browserify = require('browserify'); +var browserSync = require('browser-sync'); +var duration = require('gulp-duration'); +var ecstatic = require('ecstatic'); +var gulp = require('gulp'); +var gutil = require('gulp-util'); +var jade = require('gulp-jade'); +var notify = require('gulp-notify'); +var prefix = require('gulp-autoprefixer'); +var source = require('vinyl-source-stream'); +var sourcemaps = require('gulp-sourcemaps'); +var streamify = require('gulp-streamify'); +var stylus = require('gulp-stylus'); +var uglify = require('gulp-uglify'); +var watchify = require('watchify'); + +var production = process.env.NODE_ENV === 'production'; + +var config = { + scripts: { + source: './src/coffee/main.coffee', + extensions: ['.coffee'], + destination: './public/js/', + filename: 'bundle.js' + }, + templates: { + source: './src/jade/*.jade', + watch: './src/jade/*.jade', + destination: './public/' + }, + styles: { + source: './src/stylus/style.styl', + watch: './src/stylus/*.styl', + destination: './public/css/' + }, + assets: { + source: './src/assets/**/*.*', + watch: './src/assets/**/*.*', + destination: './public/' + } +}; + +var browserifyConfig = { + entries: [config.scripts.source], + extensions: config.scripts.extensions, + debug: !production, + cache: {}, + packageCache: {} +}; + +function handleError(err) { + gutil.log(err); + gutil.beep(); + notify({ + title: 'Compile Error', + message: err.message + }); + return this.emit('end'); +} + +gulp.task('scripts', function() { + var pipeline = browserify(browserifyConfig) + .bundle() + .on('error', handleError) + .pipe(source(config.scripts.filename)); + + if (production) { + pipeline = pipeline.pipe(streamify(uglify())); + } + return pipeline.pipe(gulp.dest(config.scripts.destination)); +}); + +gulp.task('templates', function() { + var pipeline = gulp.src(config.templates.source) + .pipe(jade({ + pretty: !production + })) + .on('error', handleError) + .pipe(gulp.dest(config.templates.destination)); + + if(production) { + return pipeline; + } + + return pipeline.pipe(browserSync.reload({ + stream: true + })); +}); + +gulp.task('styles', function() { + var pipeline = gulp.src(config.styles.source); + + if (!production) { + pipeline = pipeline.pipe(sourcemaps.init()); + } + + pipeline = pipeline.pipe(stylus({ + 'include css': true, + compress: production + })) + .on('error', handleError) + .pipe(prefix('last 2 versions', 'Chrome 34', 'Firefox 28', 'iOS 7')); + + if (!production) { + pipeline = pipeline.pipe(sourcemaps.write('.')); + } + + pipeline = pipeline.pipe(gulp.dest(config.styles.destination)); + + if (production) { + return pipeline; + } + + return pipeline.pipe(browserSync.stream({ + match: '**/*.css' + })); +}); + +gulp.task('assets', function() { + return gulp.src(config.assets.source) + .pipe(gulp.dest(config.assets.destination)); +}); + +gulp.task('server', function() { + return browserSync({ + open: false, + port: 9001, + server: { + baseDir: './public' + } + }); +}); + +gulp.task('watch', function() { + gulp.watch(config.templates.watch, ['templates']); + gulp.watch(config.styles.watch, ['styles']); + gulp.watch(config.assets.watch, ['assets']); + + var bundle = watchify(browserify(browserifyConfig)); + + bundle.on('update', function() { + var build = bundle.bundle() + .on('error', handleError) + .pipe(source(config.scripts.filename)); + + build.pipe(gulp.dest(config.scripts.destination)) + .pipe(duration('Rebundling browserify bundle')) + .pipe(browserSync.reload({stream: true})); + }).emit('update'); +}); + +var buildTasks = ['templates', 'styles', 'assets']; + +gulp.task('build', buildTasks.concat(['scripts'])); +gulp.task('default', buildTasks.concat(['watch', 'server'])); diff --git a/package.json b/package.json index 975caa2..3379a50 100644 --- a/package.json +++ b/package.json @@ -15,9 +15,7 @@ "gulp", "template" ], - "dependencies": { - "coffee-script": "~1.8.0" - }, + "dependencies": {}, "devDependencies": { "bower": "~1.3.5", "browser-sync": "^2.7.2", From f716e5fe73d1683916df111174efb6a899984422 Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Wed, 20 May 2015 23:29:18 +0300 Subject: [PATCH 14/49] remove ecstatic --- gulpfile.js | 1 - package.json | 1 - 2 files changed, 2 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index deb0d50..f670084 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -3,7 +3,6 @@ var browserify = require('browserify'); var browserSync = require('browser-sync'); var duration = require('gulp-duration'); -var ecstatic = require('ecstatic'); var gulp = require('gulp'); var gutil = require('gulp-util'); var jade = require('gulp-jade'); diff --git a/package.json b/package.json index 3379a50..b18059a 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,6 @@ "coffeeify": "~0.7.0", "deamdify": "^0.1.1", "debowerify": "~0.9.1", - "ecstatic": "~0.5.3", "gulp": "~3.8.1", "gulp-autoprefixer": "1.0.1", "gulp-duration": "0.0.0", From 7ff4d2a88712446ff0ee84d58435735f15e208e0 Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Thu, 21 May 2015 00:32:25 +0300 Subject: [PATCH 15/49] turn code examples into javascript and update readme --- README.md | 28 ++++++---------------------- gulpfile.js | 8 ++++---- package.json | 11 ++++++----- src/coffee/main.coffee | 1 - src/js/main.js | 33 +++++++++++++++++++++++++++++++++ src/stylus/style.styl | 21 +++++++++++++++++++++ 6 files changed, 70 insertions(+), 32 deletions(-) delete mode 100644 src/coffee/main.coffee create mode 100644 src/js/main.js diff --git a/README.md b/README.md index 653db61..3688099 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ### What it does * [Jade](http://jade-lang.com) files to HTML * [Stylus](http://learnboost.github.io/stylus) files to CSS -* [CoffeeScript](http://coffeescript.org/) files to Javascript through [browserify](http://browserify.org/) +* [ES6+ JavaScript](babeljs.io) files to ES5 Javascript through [browserify](http://browserify.org/) * You are able to use 'require' in your client-side code * Serves your static files to localhost:9001 * Reloads your browser with LiveReload when files change @@ -18,7 +18,7 @@ npm install npm start open http://localhost:9001 in your browser -```` +``` ## CLI Commands * npm install @@ -28,6 +28,7 @@ * npm run build * Builds everything +# Production build Minification, uglification and other tasks you're expected to run before deploying your product can be made by running the build command with env variable NODE_ENV set to "production" NODE_ENV=production npm run build @@ -37,23 +38,6 @@ Minification, uglification and other tasks you're expected to run before deployi It should be possible to delete directory completely and after **npm start** or **npm run build** everything should be as they were before the deletion. * All backend dependencies should be installed with **npm**. Browser dependencies should be installed with **bower** or with **npm**. -### Using JavaScript instead of CoffeeScript -Remove coffeeify transform from package.json file (browserify.transform field) -```diff - "transform": [ -- "coffeeify", - "debowerify", - "deamdify" - ] -``` - -and change the ".coffee" extension to ".js" from gulpfile.coffee -```diff -config = - scripts: -- source: './src/coffee/main.coffee' -- extensions: ['.coffee'] -+ source: './src/js/main.js' -+ extensions: ['.js'] -``` -You also can change the directory name to scripts or what ever. +# FAQ +### I want to use CoffeeScript instead of JavaScript +Check out the [coffee branch](https://github.com/leonidas/gulp-project-template/tree/coffee) diff --git a/gulpfile.js b/gulpfile.js index f670084..67de18f 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -6,7 +6,7 @@ var duration = require('gulp-duration'); var gulp = require('gulp'); var gutil = require('gulp-util'); var jade = require('gulp-jade'); -var notify = require('gulp-notify'); +var notifier = require('node-notifier'); var prefix = require('gulp-autoprefixer'); var source = require('vinyl-source-stream'); var sourcemaps = require('gulp-sourcemaps'); @@ -19,9 +19,9 @@ var production = process.env.NODE_ENV === 'production'; var config = { scripts: { - source: './src/coffee/main.coffee', - extensions: ['.coffee'], + source: './src/js/main.js', destination: './public/js/', + extensions: ['.jsx'], filename: 'bundle.js' }, templates: { @@ -52,7 +52,7 @@ var browserifyConfig = { function handleError(err) { gutil.log(err); gutil.beep(); - notify({ + notifier.notify({ title: 'Compile Error', message: err.message }); diff --git a/package.json b/package.json index b18059a..ba421de 100644 --- a/package.json +++ b/package.json @@ -15,19 +15,20 @@ "gulp", "template" ], - "dependencies": {}, + "dependencies": { + "lodash": "^3.9.1" + }, "devDependencies": { + "babelify": "^6.1.1", "bower": "~1.3.5", "browser-sync": "^2.7.2", "browserify": "^10.2.1", - "coffeeify": "~0.7.0", "deamdify": "^0.1.1", "debowerify": "~0.9.1", "gulp": "~3.8.1", "gulp-autoprefixer": "1.0.1", "gulp-duration": "0.0.0", "gulp-jade": "~0.9.0", - "gulp-notify": "^2.2.0", "gulp-sourcemaps": "^1.3.0", "gulp-streamify": "0.0.5", "gulp-stylus": "~2.0.0", @@ -36,14 +37,14 @@ "karma": "~0.12.21", "karma-chrome-launcher": "~0.1.4", "karma-cli": "0.0.4", - "karma-coffee-preprocessor": "~0.2.1", "karma-jasmine": "~0.2.2", + "node-notifier": "^4.2.1", "vinyl-source-stream": "~1.0.0", "watchify": "^3.2.1" }, "browserify": { "transform": [ - "coffeeify", + "babelify", "debowerify", "deamdify" ] diff --git a/src/coffee/main.coffee b/src/coffee/main.coffee deleted file mode 100644 index 14d7b64..0000000 --- a/src/coffee/main.coffee +++ /dev/null @@ -1 +0,0 @@ -console.log 'foobar' diff --git a/src/js/main.js b/src/js/main.js new file mode 100644 index 0000000..e679bcc --- /dev/null +++ b/src/js/main.js @@ -0,0 +1,33 @@ +'use strict'; + +import {partialRight, invoke} from 'lodash'; + +Promise.all([ + fetch('https://api.github.com/repos/leonidas/gulp-project-template'), + fetch('https://api.github.com/repos/leonidas/gulp-project-template/commits') +]) +.then(partialRight(invoke, 'json')) +.then(Promise.all.bind(Promise)) +.then(data => { + + const [repository, commits] = data; + const {html_url, description, full_name} = repository; + + const commitItems = commits.map(item => { + const {commit} = item; + + return ` +
  • + ${commit.message.replace(/\n/g, '
    ')} +

    + ${commit.committer.name} +
  • `; + }); + + document.body.innerHTML = ` +

    ${description}

    +

    ${full_name}

    +
      ${commitItems.join('')}
    + `; +}); + diff --git a/src/stylus/style.styl b/src/stylus/style.styl index e09ddc3..a389d9d 100644 --- a/src/stylus/style.styl +++ b/src/stylus/style.styl @@ -1,2 +1,23 @@ body, html margin 0 + padding 1em + font 14px/1.4 'Helvetica Neue', Helvetica, Arial + color #333 + +li + margin 1em 0 + padding 1em 0 + border-bottom 1px solid #eee + +h1 + margin-bottom 0 + +h2 + margin-top 0 + +ul + margin-top 2em + +li + small + color #777 From 008ee37e9463ef7cd657372436d10ffbd8eed5d8 Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Thu, 21 May 2015 00:50:33 +0300 Subject: [PATCH 16/49] Add .jscsrc file http://jscs.info/ * Sublime text plugin is recommended --- .jscsrc | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .jscsrc diff --git a/.jscsrc b/.jscsrc new file mode 100644 index 0000000..796ffa0 --- /dev/null +++ b/.jscsrc @@ -0,0 +1,4 @@ +{ + "preset": "airbnb", + "esnext": true +} From 78fc56bf7fc7e1c189fd78ba188b4137f40dfedc Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Thu, 21 May 2015 22:59:33 +0300 Subject: [PATCH 17/49] replace jshint + jscs with eslint --- .eslintrc | 219 ++++++++++++++++++++++++++++++++++++++++++++++++++++ .jscsrc | 4 - .jshintrc | 3 - gulpfile.js | 9 ++- 4 files changed, 224 insertions(+), 11 deletions(-) create mode 100644 .eslintrc delete mode 100644 .jscsrc delete mode 100644 .jshintrc diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..39afb57 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,219 @@ +{ + "env": { + "browser": true, + "node": true, + "es6": true + }, + "ecmaFeatures": { + "arrowFunctions": true, + "binaryLiterals": true, + "blockBindings": true, + "classes": true, + "defaultParams": true, + "destructuring": true, + "forOf": true, + "generators": true, + "modules": true, + "objectLiteralComputedProperties": true, + "objectLiteralDuplicateProperties": true, + "objectLiteralShorthandMethods": true, + "objectLiteralShorthandProperties": true, + "octalLiterals": true, + "regexUFlag": true, + "regexYFlag": true, + "spread": true, + "superInFunctions": true, + "templateStrings": true, + "unicodeCodePointEscapes": true, + "globalReturn": true, + "jsx": true + }, + + "rules": { + + // + //Possible Errors + // + // The following rules point out areas where you might have made mistakes. + // + "comma-dangle": 2, // disallow or enforce trailing commas + "no-cond-assign": 2, // disallow assignment in conditional expressions + "no-console": 1, // disallow use of console (off by default in the node environment) + "no-constant-condition": 2, // disallow use of constant expressions in conditions + "no-control-regex": 2, // disallow control characters in regular expressions + "no-debugger": 2, // disallow use of debugger + "no-dupe-args": 2, // disallow duplicate arguments in functions + "no-dupe-keys": 2, // disallow duplicate keys when creating object literals + "no-duplicate-case": 2, // disallow a duplicate case label. + "no-empty": 2, // disallow empty statements + "no-empty-class": 2, // disallow the use of empty character classes in regular expressions + "no-ex-assign": 2, // disallow assigning to the exception in a catch block + "no-extra-boolean-cast": 2, // disallow double-negation boolean casts in a boolean context + "no-extra-parens": 0, // disallow unnecessary parentheses (off by default) + "no-extra-semi": 2, // disallow unnecessary semicolons + "no-func-assign": 2, // disallow overwriting functions written as function declarations + "no-inner-declarations": 2, // disallow function or variable declarations in nested blocks + "no-invalid-regexp": 2, // disallow invalid regular expression strings in the RegExp constructor + "no-irregular-whitespace": 2, // disallow irregular whitespace outside of strings and comments + "no-negated-in-lhs": 2, // disallow negation of the left operand of an in expression + "no-obj-calls": 2, // disallow the use of object properties of the global object (Math and JSON) as functions + "no-regex-spaces": 2, // disallow multiple spaces in a regular expression literal + "no-reserved-keys": 2, // disallow reserved words being used as object literal keys (off by default) + "no-sparse-arrays": 2, // disallow sparse arrays + "no-unreachable": 2, // disallow unreachable statements after a return, throw, continue, or break statement + "use-isnan": 2, // disallow comparisons with the value NaN + "valid-jsdoc": 2, // Ensure JSDoc comments are valid (off by default) + "valid-typeof": 2, // Ensure that the results of typeof are compared against a valid string + + // + // Best Practices + // + // These are rules designed to prevent you from making mistakes. + // They either prescribe a better way of doing something or help you avoid footguns. + // + "block-scoped-var": 0, // treat var statements as if they were block scoped (off by default). 0: deep destructuring is not compatible https://github.com/eslint/eslint/issues/1863 + "complexity": 0, // specify the maximum cyclomatic complexity allowed in a program (off by default) + "consistent-return": 2, // require return statements to either always or never specify values + "curly": 2, // specify curly brace conventions for all control statements + "default-case": 2, // require default case in switch statements (off by default) + "dot-notation": 2, // encourages use of dot notation whenever possible + "eqeqeq": 2, // require the use of === and !== + "guard-for-in": 2, // make sure for-in loops have an if statement (off by default) + "no-alert": 2, // disallow the use of alert, confirm, and prompt + "no-caller": 2, // disallow use of arguments.caller or arguments.callee + "no-div-regex": 2, // disallow division operators explicitly at beginning of regular expression (off by default) + "no-else-return": 2, // disallow else after a return in an if (off by default) + "no-empty-label": 2, // disallow use of labels for anything other then loops and switches + "no-eq-null": 2, // disallow comparisons to null without a type-checking operator (off by default) + "no-eval": 2, // disallow use of eval() + "no-extend-native": 2, // disallow adding to native types + "no-extra-bind": 2, // disallow unnecessary function binding + "no-fallthrough": 2, // disallow fallthrough of case statements + "no-floating-decimal": 2, // disallow the use of leading or trailing decimal points in numeric literals (off by default) + "no-implied-eval": 2, // disallow use of eval()-like methods + "no-iterator": 2, // disallow usage of __iterator__ property + "no-labels": 2, // disallow use of labeled statements + "no-lone-blocks": 2, // disallow unnecessary nested blocks + "no-loop-func": 2, // disallow creation of functions within loops + "no-multi-spaces": 2, // disallow use of multiple spaces + "no-multi-str": 2, // disallow use of multiline strings + "no-native-reassign": 2, // disallow reassignments of native objects + "no-new": 2, // disallow use of new operator when not part of the assignment or comparison + "no-new-func": 2, // disallow use of new operator for Function object + "no-new-wrappers": 2, // disallows creating new instances of String,Number, and Boolean + "no-octal": 2, // disallow use of octal literals + "no-octal-escape": 2, // disallow use of octal escape sequences in string literals, such as var foo = "Copyright \251"; + "no-param-reassign": 2, // disallow reassignment of function parameters (off by default) + "no-process-env": 2, // disallow use of process.env (off by default) + "no-proto": 2, // disallow usage of __proto__ property + "no-redeclare": 2, // disallow declaring the same variable more then once + "no-return-assign": 2, // disallow use of assignment in return statement + "no-script-url": 2, // disallow use of javascript: urls. + "no-self-compare": 2, // disallow comparisons where both sides are exactly the same (off by default) + "no-sequences": 2, // disallow use of comma operator + "no-throw-literal": 2, // restrict what can be thrown as an exception (off by default) + "no-unused-expressions": 2, // disallow usage of expressions in statement position + "no-void": 2, // disallow use of void operator (off by default) + "no-warning-comments": [0, {"terms": ["todo", "fixme"], "location": "start"}], // disallow usage of configurable warning terms in comments": 2, // e.g. TODO or FIXME (off by default) + "no-with": 2, // disallow use of the with statement + "radix": 2, // require use of the second argument for parseInt() (off by default) + "vars-on-top": 2, // requires to declare all vars on top of their containing scope (off by default) + "wrap-iife": 2, // require immediate function invocation to be wrapped in parentheses (off by default) + "yoda": 2, // require or disallow Yoda conditions + + // + // Strict Mode + // + // These rules relate to using strict mode. + // + "strict": 0, // controls location of Use Strict Directives. 0: required by `babel-eslint` + + // + // Variables + // + // These rules have to do with variable declarations. + // + "no-catch-shadow": 2, // disallow the catch clause parameter name being the same as a variable in the outer scope (off by default in the node environment) + "no-delete-var": 2, // disallow deletion of variables + "no-label-var": 2, // disallow labels that share a name with a variable + "no-shadow": 2, // disallow declaration of variables already declared in the outer scope + "no-shadow-restricted-names": 2, // disallow shadowing of names such as arguments + "no-undef": 2, // disallow use of undeclared variables unless mentioned in a /*global */ block + "no-undef-init": 2, // disallow use of undefined when initializing variables + "no-undefined": 2, // disallow use of undefined variable (off by default) + "no-unused-vars": 2, // disallow declaration of variables that are not used in the code + "no-use-before-define": 2, // disallow use of variables before they are defined + + // + //Stylistic Issues + // + // These rules are purely matters of style and are quite subjective. + // + "indent": [1, 2], // this option sets a specific tab width for your code (off by default) + "brace-style": 1, // enforce one true brace style (off by default) + "camelcase": 1, // require camel case names + "comma-spacing": [1, {"before": false, "after": true}], // enforce spacing before and after comma + "comma-style": [1, "last"], // enforce one true comma style (off by default) + "consistent-this": [1, "_this"], // enforces consistent naming when capturing the current execution context (off by default) + "eol-last": 1, // enforce newline at the end of file, with no multiple empty lines + "func-names": 0, // require function expressions to have a name (off by default) + "func-style": 0, // enforces use of function declarations or expressions (off by default) + "key-spacing": [1, {"beforeColon": false, "afterColon": true}], // enforces spacing between keys and values in object literal properties + "max-nested-callbacks": [1, 3], // specify the maximum depth callbacks can be nested (off by default) + "new-cap": [1, {newIsCap: true, capIsNew: false}], // require a capital letter for constructors + "new-parens": 1, // disallow the omission of parentheses when invoking a constructor with no arguments + "newline-after-var": 0, // allow/disallow an empty newline after var statement (off by default) + "no-array-constructor": 1, // disallow use of the Array constructor + "no-inline-comments": 1, // disallow comments inline after code (off by default) + "no-lonely-if": 1, // disallow if as the only statement in an else block (off by default) + "no-mixed-spaces-and-tabs": 1, // disallow mixed spaces and tabs for indentation + "no-multiple-empty-lines": [1, {"max": 2}], // disallow multiple empty lines (off by default) + "no-nested-ternary": 1, // disallow nested ternary expressions (off by default) + "no-new-object": 1, // disallow use of the Object constructor + "no-spaced-func": 1, // disallow space between function identifier and application + "no-ternary": 0, // disallow the use of ternary operators (off by default) + "no-trailing-spaces": 1, // disallow trailing whitespace at the end of lines + "no-underscore-dangle": 1, // disallow dangling underscores in identifiers + "no-wrap-func": 1, // disallow wrapping of non-IIFE statements in parens + "one-var": [1, "never"], // allow just one var statement per function (off by default) + "operator-assignment": [1, "never"], // require assignment operator shorthand where possible or prohibit it entirely (off by default) + "padded-blocks": [1, "never"], // enforce padding within blocks (off by default) + "quote-props": [1, "as-needed"], // require quotes around object literal property names (off by default) + "quotes": [1, "single"], // specify whether double or single quotes should be used + "semi": [1, "always"], // require or disallow use of semicolons instead of ASI + "semi-spacing": [1, {"before": false, "after": true}], // enforce spacing before and after semicolons + "sort-vars": 0, // sort variables within the same declaration block (off by default) + "space-after-keywords": [1, "always"], // require a space after certain keywords (off by default) + "space-before-blocks": [1, "always"], // require or disallow space before blocks (off by default) + "space-before-function-paren": [1, {"anonymous": "never", "named": "never"}], // require or disallow space before function opening parenthesis (off by default) + "space-in-brackets": [1, "never"], // require or disallow spaces inside brackets (off by default) + "space-in-parens": [1, "never"], // require or disallow spaces inside parentheses (off by default) + "space-infix-ops": [1, "always"], // require spaces around operators + "space-return-throw-case": [1, "always"], // require a space after return, throw, and case + "space-unary-ops": [1, {"words": true, "nonwords": false}], // Require or disallow spaces before/after unary operators (words on by default, nonwords off by default) + "spaced-line-comment": [1, "always"], // require or disallow a space immediately following the // in a line comment (off by default) + "wrap-regex": 0, // require regex literals to be wrapped in parentheses (off by default) + + // + // ECMAScript 6 + // + // These rules are only relevant to ES6 environments and are off by default. + // + "no-var": 2, // require let or const instead of var (off by default) + "generator-star-spacing": [2, "before"], // enforce the spacing around the * in generator functions (off by default) + + // + // Legacy + // + // The following rules are included for compatibility with JSHint and JSLint. + // While the names of the rules may not match up with the JSHint/JSLint counterpart, + // the functionality is the same. + // + "max-depth": [2, 3], // specify the maximum depth that blocks can be nested (off by default) + "max-len": [2, 100, 2], // specify the maximum length of a line in your program (off by default) + "max-params": [2, 5], // limits the number of parameters that can be used in the function declaration. (off by default) + "max-statements": 0, // specify the maximum number of statement allowed in a function (off by default) + "no-bitwise": 0, // disallow use of bitwise operators (off by default) + "no-plusplus": 2 // disallow use of unary operators, ++ and -- (off by default) + } +} diff --git a/.jscsrc b/.jscsrc deleted file mode 100644 index 796ffa0..0000000 --- a/.jscsrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "preset": "airbnb", - "esnext": true -} diff --git a/.jshintrc b/.jshintrc deleted file mode 100644 index a08e606..0000000 --- a/.jshintrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "browserify": true -} diff --git a/gulpfile.js b/gulpfile.js index 67de18f..1314c56 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -65,9 +65,10 @@ gulp.task('scripts', function() { .on('error', handleError) .pipe(source(config.scripts.filename)); - if (production) { + if(production) { pipeline = pipeline.pipe(streamify(uglify())); } + return pipeline.pipe(gulp.dest(config.scripts.destination)); }); @@ -91,7 +92,7 @@ gulp.task('templates', function() { gulp.task('styles', function() { var pipeline = gulp.src(config.styles.source); - if (!production) { + if(!production) { pipeline = pipeline.pipe(sourcemaps.init()); } @@ -102,13 +103,13 @@ gulp.task('styles', function() { .on('error', handleError) .pipe(prefix('last 2 versions', 'Chrome 34', 'Firefox 28', 'iOS 7')); - if (!production) { + if(!production) { pipeline = pipeline.pipe(sourcemaps.write('.')); } pipeline = pipeline.pipe(gulp.dest(config.styles.destination)); - if (production) { + if(production) { return pipeline; } From 2ac09dba69144417838ae86b948132065d5dfd3a Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Thu, 21 May 2015 22:59:40 +0300 Subject: [PATCH 18/49] update readme --- README.md | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3688099..9e8ee9d 100644 --- a/README.md +++ b/README.md @@ -34,10 +34,24 @@ Minification, uglification and other tasks you're expected to run before deployi NODE_ENV=production npm run build ## Development guidelines -* **public** - directory should be dedicated only to compiled/copied files from **src** - directory. - It should be possible to delete directory completely and after **npm start** or **npm run build** everything should be as they were before the deletion. -* All backend dependencies should be installed with **npm**. Browser dependencies should be installed with **bower** or with **npm**. +#### Directory structure + +**public** - directory should be dedicated only to compiled/copied files from **src** - directory. + It should be possible to delete directory completely and after **npm start** or **npm run build** everything should be as they were before the deletion. + +#### Dependencies +All dependencies are meant to be installed with **bower** or with **npm**. +* JavaScript-files from both **bower_components** and **node_modules** can be *require()*'d in client-side modules. +* CSS files can be [imported](https://learnboost.github.io/stylus/docs/import.html) from **bower_components** and **node_modules** using relative path from the stylus file to the css file e.g `@import '../../bower_components/bootstrap/dist/css/bootstrap.css'` +* You can either create a new gulp task for copying other assets from directories mentioned above or use an array as a value for [assets sources](https://github.com/leonidas/gulp-project-template/blob/master/gulpfile.js#L38) e.g `source: ['./src/assets/**/*.*', 'bower_components/bootstrap/fonts*/*.*']` *(notice the asterisk after 'fonts'? It makes gulp copy the whole directory instead of just the files inside of it)* + +## Suggested development tools + +* [eslint](http://eslint.org/) + * When used as an editor plugin (for example. [SublimeLinter](http://sublimelinter.readthedocs.org/en/latest/) + [SublimeLinter-eslint](https://github.com/roadhump/SublimeLinter-eslint)), gives you immediate feedback about your code and can find bugs, potential problem areas, poor coding styles and stylistic issues. + + +## FAQ -# FAQ ### I want to use CoffeeScript instead of JavaScript Check out the [coffee branch](https://github.com/leonidas/gulp-project-template/tree/coffee) From 83e7e65d589d887202dd63cc0592d885e70c8704 Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Thu, 21 May 2015 23:14:58 +0300 Subject: [PATCH 19/49] fix gulpfile's linting errors and modify rules --- .eslintrc | 4 ++-- gulpfile.js | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.eslintrc b/.eslintrc index 39afb57..54cf9d4 100644 --- a/.eslintrc +++ b/.eslintrc @@ -117,7 +117,7 @@ "no-warning-comments": [0, {"terms": ["todo", "fixme"], "location": "start"}], // disallow usage of configurable warning terms in comments": 2, // e.g. TODO or FIXME (off by default) "no-with": 2, // disallow use of the with statement "radix": 2, // require use of the second argument for parseInt() (off by default) - "vars-on-top": 2, // requires to declare all vars on top of their containing scope (off by default) + "vars-on-top": 0, // requires to declare all vars on top of their containing scope (off by default) "wrap-iife": 2, // require immediate function invocation to be wrapped in parentheses (off by default) "yoda": 2, // require or disallow Yoda conditions @@ -183,7 +183,7 @@ "semi": [1, "always"], // require or disallow use of semicolons instead of ASI "semi-spacing": [1, {"before": false, "after": true}], // enforce spacing before and after semicolons "sort-vars": 0, // sort variables within the same declaration block (off by default) - "space-after-keywords": [1, "always"], // require a space after certain keywords (off by default) + "space-after-keywords": [0, "never"], // require a space after certain keywords (off by default) "space-before-blocks": [1, "always"], // require or disallow space before blocks (off by default) "space-before-function-paren": [1, {"anonymous": "never", "named": "never"}], // require or disallow space before function opening parenthesis (off by default) "space-in-brackets": [1, "never"], // require or disallow spaces inside brackets (off by default) diff --git a/gulpfile.js b/gulpfile.js index 1314c56..736aa82 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,3 +1,4 @@ +/*eslint "no-var":0 */ 'use strict'; var browserify = require('browserify'); @@ -15,6 +16,7 @@ var stylus = require('gulp-stylus'); var uglify = require('gulp-uglify'); var watchify = require('watchify'); +/*eslint "no-process-env":0 */ var production = process.env.NODE_ENV === 'production'; var config = { From 83fb7c31d5f5fd64f23011fe1e7ac16c717b64d6 Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Sat, 23 May 2015 16:37:13 +0300 Subject: [PATCH 20/49] fix readme link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9e8ee9d..1ce1804 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ### What it does * [Jade](http://jade-lang.com) files to HTML * [Stylus](http://learnboost.github.io/stylus) files to CSS -* [ES6+ JavaScript](babeljs.io) files to ES5 Javascript through [browserify](http://browserify.org/) +* [ES6+ JavaScript](https://babeljs.io) files to ES5 Javascript through [browserify](http://browserify.org/) * You are able to use 'require' in your client-side code * Serves your static files to localhost:9001 * Reloads your browser with LiveReload when files change From e56a628c95137bdca34b4a46446e0409c83e8902 Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Sun, 24 May 2015 18:58:15 +0300 Subject: [PATCH 21/49] add revisioning task to gulp build * 'public' directory is now removed on gulp build * Copies built .css and .js files to -. * Replaces references from built .html files to match the revisioned files * Keeps the original built files intact, but this is most likely going to change in the future --- .gitignore | 1 + gulpfile.js | 41 ++++++++++++++++++++++++++++++++++++++--- package.json | 3 +++ 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 7580c79..4979fbc 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ node_modules bower_components public .DS_Store +rev-manifest.json diff --git a/gulpfile.js b/gulpfile.js index 736aa82..ee16be2 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -8,7 +8,11 @@ var gulp = require('gulp'); var gutil = require('gulp-util'); var jade = require('gulp-jade'); var notifier = require('node-notifier'); +var path = require('path'); var prefix = require('gulp-autoprefixer'); +var replace = require('gulp-replace'); +var rev = require('gulp-rev'); +var rimraf = require('rimraf'); var source = require('vinyl-source-stream'); var sourcemaps = require('gulp-sourcemaps'); var streamify = require('gulp-streamify'); @@ -20,6 +24,7 @@ var watchify = require('watchify'); var production = process.env.NODE_ENV === 'production'; var config = { + destination: './public', scripts: { source: './src/js/main.js', destination: './public/js/', @@ -29,7 +34,8 @@ var config = { templates: { source: './src/jade/*.jade', watch: './src/jade/*.jade', - destination: './public/' + destination: './public/', + revision: './public/**/*.html' }, styles: { source: './src/stylus/style.styl', @@ -40,6 +46,11 @@ var config = { source: './src/assets/**/*.*', watch: './src/assets/**/*.*', destination: './public/' + }, + revision: { + source: ['./public/**/*.css', './public/**/*.js'], + base: path.join(__dirname, 'public'), + destination: './public/' } }; @@ -130,7 +141,7 @@ gulp.task('server', function() { open: false, port: 9001, server: { - baseDir: './public' + baseDir: config.destination } }); }); @@ -155,5 +166,29 @@ gulp.task('watch', function() { var buildTasks = ['templates', 'styles', 'assets']; -gulp.task('build', buildTasks.concat(['scripts'])); +gulp.task('revision', buildTasks.concat(['scripts']), function() { + return gulp.src(config.revision.source, {base: config.revision.base}) + .pipe(rev()) + .pipe(gulp.dest(config.revision.destination)) + .pipe(rev.manifest()) + .pipe(gulp.dest('./')); +}); + +gulp.task('replace-revision-references', ['revision', 'templates'], function() { + var revisions = require('./rev-manifest.json'); + + var pipeline = gulp.src(config.templates.revision); + + pipeline = Object.keys(revisions).reduce(function(stream, key) { + return stream.pipe(replace(key, revisions[key])); + }, pipeline); + + return pipeline.pipe(gulp.dest(config.templates.destination)); +}); + +gulp.task('build', function() { + rimraf.sync(config.destination); + gulp.start(buildTasks.concat(['scripts', 'revision', 'replace-revision-references'])); +}); + gulp.task('default', buildTasks.concat(['watch', 'server'])); diff --git a/package.json b/package.json index ba421de..d4b6193 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,8 @@ "gulp-autoprefixer": "1.0.1", "gulp-duration": "0.0.0", "gulp-jade": "~0.9.0", + "gulp-replace": "^0.5.3", + "gulp-rev": "^4.0.0", "gulp-sourcemaps": "^1.3.0", "gulp-streamify": "0.0.5", "gulp-stylus": "~2.0.0", @@ -39,6 +41,7 @@ "karma-cli": "0.0.4", "karma-jasmine": "~0.2.2", "node-notifier": "^4.2.1", + "rimraf": "^2.3.4", "vinyl-source-stream": "~1.0.0", "watchify": "^3.2.1" }, From 7c3c3a517f2ee64345ce1ed8592d00c106db4f8e Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Sun, 24 May 2015 19:12:52 +0300 Subject: [PATCH 22/49] add codeship badge --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 1ce1804..688f610 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # Project template for [gulp.js](http://gulpjs.com/) +[ ![Codeship Status for leonidas/gulp-project-template](https://codeship.com/projects/07620890-e45d-0132-b176-5e88bc3b0df8/status?branch=master)](https://codeship.com/projects/81833) + ### What it does * [Jade](http://jade-lang.com) files to HTML * [Stylus](http://learnboost.github.io/stylus) files to CSS From 4c9efe58ff2880b500a94caf9a45bc2fe7ce65e1 Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Sun, 24 May 2015 19:20:08 +0300 Subject: [PATCH 23/49] update readme --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 688f610..5059eee 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,7 @@ * [Stylus](http://learnboost.github.io/stylus) files to CSS * [ES6+ JavaScript](https://babeljs.io) files to ES5 Javascript through [browserify](http://browserify.org/) * You are able to use 'require' in your client-side code -* Serves your static files to localhost:9001 -* Reloads your browser with LiveReload when files change +* Uses [BrowserSync](http://www.browsersync.io/) to serves your static files to localhost:9001 and to automatically reload your browser when files change. ## Getting things up and running - Install [Node.js](http://nodejs.org) From 361f18115bbd677aa1897ee6934308fe7f73ff74 Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Wed, 8 Jul 2015 16:19:56 +0300 Subject: [PATCH 24/49] fix typo in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5059eee..a89ac47 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ * [Stylus](http://learnboost.github.io/stylus) files to CSS * [ES6+ JavaScript](https://babeljs.io) files to ES5 Javascript through [browserify](http://browserify.org/) * You are able to use 'require' in your client-side code -* Uses [BrowserSync](http://www.browsersync.io/) to serves your static files to localhost:9001 and to automatically reload your browser when files change. +* Uses [BrowserSync](http://www.browsersync.io/) to serve your static files to localhost:9001 and to automatically reload your browser when files change. ## Getting things up and running - Install [Node.js](http://nodejs.org) From 8ed68ff60dce7578f7e67684761020905f9731c9 Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Wed, 8 Jul 2015 20:23:48 +0300 Subject: [PATCH 25/49] Replace karma with jsdom + mocha + chai * Also a bit refactoring for better testability --- package.json | 10 ++--- src/js/main.js | 33 +++------------ src/js/services/github.js | 13 ++++++ src/js/utils/__tests__/renderer.js | 37 ++++++++++++++++ src/js/utils/renderer.js | 20 +++++++++ test/karma.conf.js | 68 ------------------------------ test/test-helper.js | 7 +++ test/unit/exampleSpec.coffee | 3 -- 8 files changed, 87 insertions(+), 104 deletions(-) create mode 100644 src/js/services/github.js create mode 100644 src/js/utils/__tests__/renderer.js create mode 100644 src/js/utils/renderer.js delete mode 100644 test/karma.conf.js create mode 100644 test/test-helper.js delete mode 100644 test/unit/exampleSpec.coffee diff --git a/package.json b/package.json index d4b6193..e4cce79 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "prepublish": "bower install", "start": "gulp", "build": "gulp build", - "test": "karma start test/karma.conf.js" + "test": "mocha src/**/__tests__/*.js --compilers js:babel/register --require test/test-helper" }, "keywords": [ "gulp", @@ -19,10 +19,12 @@ "lodash": "^3.9.1" }, "devDependencies": { + "babel": "^5.6.14", "babelify": "^6.1.1", "bower": "~1.3.5", "browser-sync": "^2.7.2", "browserify": "^10.2.1", + "chai": "^3.0.0", "deamdify": "^0.1.1", "debowerify": "~0.9.1", "gulp": "~3.8.1", @@ -36,10 +38,8 @@ "gulp-stylus": "~2.0.0", "gulp-uglify": "~1.0.1", "gulp-util": "~3.0.1", - "karma": "~0.12.21", - "karma-chrome-launcher": "~0.1.4", - "karma-cli": "0.0.4", - "karma-jasmine": "~0.2.2", + "jsdom": "^5.6.0", + "mocha": "^2.2.5", "node-notifier": "^4.2.1", "rimraf": "^2.3.4", "vinyl-source-stream": "~1.0.0", diff --git a/src/js/main.js b/src/js/main.js index e679bcc..41e9918 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -1,33 +1,10 @@ 'use strict'; -import {partialRight, invoke} from 'lodash'; +import {getCommits, getRepo} from './services/github'; +import {render} from './utils/renderer'; -Promise.all([ - fetch('https://api.github.com/repos/leonidas/gulp-project-template'), - fetch('https://api.github.com/repos/leonidas/gulp-project-template/commits') -]) -.then(partialRight(invoke, 'json')) -.then(Promise.all.bind(Promise)) -.then(data => { - - const [repository, commits] = data; - const {html_url, description, full_name} = repository; - - const commitItems = commits.map(item => { - const {commit} = item; - - return ` -
  • - ${commit.message.replace(/\n/g, '
    ')} -

    - ${commit.committer.name} -
  • `; - }); - - document.body.innerHTML = ` -

    ${description}

    -

    ${full_name}

    -
      ${commitItems.join('')}
    - `; +Promise.all([getRepo(), getCommits()]) +.then(([repository, commits]) => { + document.body.innerHTML = render(repository, commits); }); diff --git a/src/js/services/github.js b/src/js/services/github.js new file mode 100644 index 0000000..8da54c2 --- /dev/null +++ b/src/js/services/github.js @@ -0,0 +1,13 @@ +const REPO_URL = 'https://api.github.com/repos/leonidas/gulp-project-template'; + +export function getRepo() { + return fetch(REPO_URL).then(res => res.json()); +} + +export function getCommits() { + return fetch(`${REPO_URL}/commits`) + .then(res => res.json()) + .then(commits => { + return commits.map(({commit}) => commit); + }); +} diff --git a/src/js/utils/__tests__/renderer.js b/src/js/utils/__tests__/renderer.js new file mode 100644 index 0000000..3f69cee --- /dev/null +++ b/src/js/utils/__tests__/renderer.js @@ -0,0 +1,37 @@ +/* globals beforeEach, describe, it */ +import {render} from '../renderer'; +import {expect} from 'chai'; + +const REPO_DATA = { + html_url: 'http://example.com', + full_name: 'Gulp project template', + description: 'Hello world!' +}; + +const COMMITS = [{ + message: 'initial commit', + committer: { + name: 'Riku' + } +}, { + message: 'final commit', + committer: { + name: 'L.H.Ahne' + } +}]; + +describe('View renderer', function() { + beforeEach(function() { + document.body.innerHTML = render(REPO_DATA, COMMITS); + }); + + it('should render a title with the string "Hello world!"', function() { + const $title = document.getElementsByTagName('h1')[0]; + expect($title.innerHTML).to.equal('Hello world!'); + }); + + it('should render 2 list items', function() { + const $listItems = document.querySelectorAll('li'); + expect($listItems.length).to.equal(2); + }); +}); diff --git a/src/js/utils/renderer.js b/src/js/utils/renderer.js new file mode 100644 index 0000000..52dc665 --- /dev/null +++ b/src/js/utils/renderer.js @@ -0,0 +1,20 @@ + +export function render(repository, commits) { + const $commits = commits.map(commit => { + return ` +
  • + ${commit.message.replace(/\n/g, '
    ')} +

    + ${commit.committer.name} +
  • `; + }); + + return ` +

    ${repository.description}

    +

    + ${repository.full_name} +

    +
      ${$commits.join('')}
    + `; +} + diff --git a/test/karma.conf.js b/test/karma.conf.js deleted file mode 100644 index 718dbc6..0000000 --- a/test/karma.conf.js +++ /dev/null @@ -1,68 +0,0 @@ -// Karma configuration -// Generated on Mon Aug 11 2014 13:43:38 GMT+0300 (EEST) - -'use strict'; - -module.exports = function(config) { - config.set({ - - // base path that will be used to resolve all patterns (eg. files, exclude) - basePath: '../', - - - // frameworks to use - // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ['jasmine'], - - - // list of files / patterns to load in the browser - files: [ - 'test/unit/**/*.coffee' - ], - - - // list of files to exclude - exclude: [ - ], - - - // preprocess matching files before serving them to the browser - // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor - preprocessors: { - '**/*.coffee': ['coffee'] - }, - - - // test results reporter to use - // possible values: 'dots', 'progress' - // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ['progress'], - - - // web server port - port: 9876, - - - // enable / disable colors in the output (reporters and logs) - colors: true, - - - // level of logging - // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG - logLevel: config.LOG_INFO, - - - // enable / disable watching file and executing tests whenever any file changes - autoWatch: false, - - - // start these browsers - // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher - browsers: ['Chrome'], - - - // Continuous Integration mode - // if true, Karma captures browsers, runs the tests and exits - singleRun: true - }); -}; diff --git a/test/test-helper.js b/test/test-helper.js new file mode 100644 index 0000000..a14c8f6 --- /dev/null +++ b/test/test-helper.js @@ -0,0 +1,7 @@ +'use strict'; + +import {jsdom} from 'jsdom'; + +const document = global.document = jsdom(''); +const window = global.window = document.defaultView; +global.navigator = window.navigator = {}; diff --git a/test/unit/exampleSpec.coffee b/test/unit/exampleSpec.coffee deleted file mode 100644 index df38553..0000000 --- a/test/unit/exampleSpec.coffee +++ /dev/null @@ -1,3 +0,0 @@ -describe 'Example spec', -> - it 'should ...', -> - expect(true).toBe(true) From f86ab3be90452a6b5ec4738dfa318cd3c5baeef9 Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Wed, 8 Jul 2015 20:42:34 +0300 Subject: [PATCH 26/49] resource links to readme --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index a89ac47..84a9b22 100644 --- a/README.md +++ b/README.md @@ -51,8 +51,14 @@ All dependencies are meant to be installed with **bower** or with **npm**. * [eslint](http://eslint.org/) * When used as an editor plugin (for example. [SublimeLinter](http://sublimelinter.readthedocs.org/en/latest/) + [SublimeLinter-eslint](https://github.com/roadhump/SublimeLinter-eslint)), gives you immediate feedback about your code and can find bugs, potential problem areas, poor coding styles and stylistic issues. +--- ## FAQ ### I want to use CoffeeScript instead of JavaScript Check out the [coffee branch](https://github.com/leonidas/gulp-project-template/tree/coffee) + +## Useful resources +* [Browserify handbook](https://github.com/substack/browserify-handbook) + * [avoiding ../../../../../../..](https://github.com/substack/browserify-handbook#avoiding-) +* [MindBEMding – getting your head ’round BEM syntax](http://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/) From f883fc2626069acb7ae186abee35bef0587c9340 Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Wed, 8 Jul 2015 21:05:08 +0300 Subject: [PATCH 27/49] component based directory structure --- gulpfile.js | 10 +++---- .../repository}/__tests__/renderer.js | 2 +- src/components/repository/index.js | 28 +++++++++++++++++++ .../repository/index.styl} | 26 +++++++---------- src/{jade => }/index.jade | 0 src/js/utils/renderer.js | 20 ------------- src/{js => }/main.js | 2 +- src/{js => }/services/github.js | 0 src/style.styl | 7 +++++ 9 files changed, 52 insertions(+), 43 deletions(-) rename src/{js/utils => components/repository}/__tests__/renderer.js (95%) create mode 100644 src/components/repository/index.js rename src/{stylus/style.styl => components/repository/index.styl} (54%) rename src/{jade => }/index.jade (100%) delete mode 100644 src/js/utils/renderer.js rename src/{js => }/main.js (81%) rename src/{js => }/services/github.js (100%) create mode 100644 src/style.styl diff --git a/gulpfile.js b/gulpfile.js index ee16be2..bc7c33d 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -26,20 +26,20 @@ var production = process.env.NODE_ENV === 'production'; var config = { destination: './public', scripts: { - source: './src/js/main.js', + source: './src/main.js', destination: './public/js/', extensions: ['.jsx'], filename: 'bundle.js' }, templates: { - source: './src/jade/*.jade', - watch: './src/jade/*.jade', + source: './src/*.jade', + watch: './src/*.jade', destination: './public/', revision: './public/**/*.html' }, styles: { - source: './src/stylus/style.styl', - watch: './src/stylus/*.styl', + source: './src/style.styl', + watch: './src/**/*.styl', destination: './public/css/' }, assets: { diff --git a/src/js/utils/__tests__/renderer.js b/src/components/repository/__tests__/renderer.js similarity index 95% rename from src/js/utils/__tests__/renderer.js rename to src/components/repository/__tests__/renderer.js index 3f69cee..c46aca3 100644 --- a/src/js/utils/__tests__/renderer.js +++ b/src/components/repository/__tests__/renderer.js @@ -1,5 +1,5 @@ /* globals beforeEach, describe, it */ -import {render} from '../renderer'; +import {render} from '../'; import {expect} from 'chai'; const REPO_DATA = { diff --git a/src/components/repository/index.js b/src/components/repository/index.js new file mode 100644 index 0000000..9317029 --- /dev/null +++ b/src/components/repository/index.js @@ -0,0 +1,28 @@ + +export function render(repository, commits) { + const $commits = commits.map(commit => { + return ` +
  • + + ${commit.message.replace(/\n/g, '
    ')} + +

    + + ${commit.committer.name} + +
  • `; + }); + + return ` +
    +

    ${repository.description}

    +

    + ${repository.full_name} +

    +
      + ${$commits.join('')} +
    +
    + `; +} + diff --git a/src/stylus/style.styl b/src/components/repository/index.styl similarity index 54% rename from src/stylus/style.styl rename to src/components/repository/index.styl index a389d9d..e733b92 100644 --- a/src/stylus/style.styl +++ b/src/components/repository/index.styl @@ -1,23 +1,17 @@ -body, html - margin 0 - padding 1em - font 14px/1.4 'Helvetica Neue', Helvetica, Arial - color #333 +.repository__title + margin-bottom 0 -li +.repository__description + margin-top 0 + +.repository__commits + margin-top 2em + +.commit margin 1em 0 padding 1em 0 border-bottom 1px solid #eee -h1 - margin-bottom 0 - -h2 - margin-top 0 - -ul - margin-top 2em - -li small color #777 + diff --git a/src/jade/index.jade b/src/index.jade similarity index 100% rename from src/jade/index.jade rename to src/index.jade diff --git a/src/js/utils/renderer.js b/src/js/utils/renderer.js deleted file mode 100644 index 52dc665..0000000 --- a/src/js/utils/renderer.js +++ /dev/null @@ -1,20 +0,0 @@ - -export function render(repository, commits) { - const $commits = commits.map(commit => { - return ` -
  • - ${commit.message.replace(/\n/g, '
    ')} -

    - ${commit.committer.name} -
  • `; - }); - - return ` -

    ${repository.description}

    -

    - ${repository.full_name} -

    -
      ${$commits.join('')}
    - `; -} - diff --git a/src/js/main.js b/src/main.js similarity index 81% rename from src/js/main.js rename to src/main.js index 41e9918..a2c72f4 100644 --- a/src/js/main.js +++ b/src/main.js @@ -1,7 +1,7 @@ 'use strict'; import {getCommits, getRepo} from './services/github'; -import {render} from './utils/renderer'; +import {render} from './components/repository'; Promise.all([getRepo(), getCommits()]) .then(([repository, commits]) => { diff --git a/src/js/services/github.js b/src/services/github.js similarity index 100% rename from src/js/services/github.js rename to src/services/github.js diff --git a/src/style.styl b/src/style.styl new file mode 100644 index 0000000..32ba096 --- /dev/null +++ b/src/style.styl @@ -0,0 +1,7 @@ +body, html + margin 0 + padding 1em + font 14px/1.4 'Helvetica Neue', Helvetica, Arial + color #333 + +@import './components/repository' From 57cc7be36731b0246c7b0ecb9879ea59a3db0678 Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Wed, 8 Jul 2015 20:33:01 +0300 Subject: [PATCH 28/49] remove bower --- .gitignore | 1 - README.md | 10 +++++----- bower.json | 17 ----------------- package.json | 4 ---- 4 files changed, 5 insertions(+), 27 deletions(-) delete mode 100644 bower.json diff --git a/.gitignore b/.gitignore index 4979fbc..ce30f25 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ npm-debug.log node_modules -bower_components public .DS_Store rev-manifest.json diff --git a/README.md b/README.md index 84a9b22..19dc495 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ ## CLI Commands * npm install - * Installs server-side dependencies from NPM and client-side dependencies from Bower + * Installs server-side dependencies from npm * npm start * Compiles your files, starts watching files for changes, serves static files to port 9001 * npm run build @@ -41,10 +41,10 @@ Minification, uglification and other tasks you're expected to run before deployi It should be possible to delete directory completely and after **npm start** or **npm run build** everything should be as they were before the deletion. #### Dependencies -All dependencies are meant to be installed with **bower** or with **npm**. -* JavaScript-files from both **bower_components** and **node_modules** can be *require()*'d in client-side modules. -* CSS files can be [imported](https://learnboost.github.io/stylus/docs/import.html) from **bower_components** and **node_modules** using relative path from the stylus file to the css file e.g `@import '../../bower_components/bootstrap/dist/css/bootstrap.css'` -* You can either create a new gulp task for copying other assets from directories mentioned above or use an array as a value for [assets sources](https://github.com/leonidas/gulp-project-template/blob/master/gulpfile.js#L38) e.g `source: ['./src/assets/**/*.*', 'bower_components/bootstrap/fonts*/*.*']` *(notice the asterisk after 'fonts'? It makes gulp copy the whole directory instead of just the files inside of it)* +All dependencies are meant to be installed with **npm**. +* JavaScript-files from **node_modules** can be *require()*'d in client-side modules. +* CSS files can be [imported](https://learnboost.github.io/stylus/docs/import.html) from **node_modules** using relative path from the stylus file to the css file e.g `@import '../../node_modules/bootstrap/dist/css/bootstrap.css'` +* You can either create a new gulp task for copying other assets from directories mentioned above or use an array as a value for [assets sources](https://github.com/leonidas/gulp-project-template/blob/master/gulpfile.js#L38) e.g `source: ['./src/assets/**/*.*', 'node_modules/bootstrap/fonts*/*.*']` *(notice the asterisk after 'fonts'? It makes gulp copy the whole directory instead of just the files inside of it)* ## Suggested development tools diff --git a/bower.json b/bower.json deleted file mode 100644 index ca2fc99..0000000 --- a/bower.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "gulp-template", - "version": "0.0.0", - "authors": [ - "Riku Rouvila " - ], - "license": "MIT", - "ignore": [ - "**/.*", - "node_modules", - "bower_components", - "test", - "tests" - ], - "dependencies": { - } -} diff --git a/package.json b/package.json index e4cce79..8e7c4eb 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,6 @@ "license": "MIT", "main": "gulpfile.js", "scripts": { - "prepublish": "bower install", "start": "gulp", "build": "gulp build", "test": "mocha src/**/__tests__/*.js --compilers js:babel/register --require test/test-helper" @@ -21,12 +20,10 @@ "devDependencies": { "babel": "^5.6.14", "babelify": "^6.1.1", - "bower": "~1.3.5", "browser-sync": "^2.7.2", "browserify": "^10.2.1", "chai": "^3.0.0", "deamdify": "^0.1.1", - "debowerify": "~0.9.1", "gulp": "~3.8.1", "gulp-autoprefixer": "1.0.1", "gulp-duration": "0.0.0", @@ -48,7 +45,6 @@ "browserify": { "transform": [ "babelify", - "debowerify", "deamdify" ] } From 4efe6800d1bb140d0cbea69e8e6c0f0724b909f8 Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Wed, 8 Jul 2015 21:08:55 +0300 Subject: [PATCH 29/49] remove deamdify --- package.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/package.json b/package.json index 8e7c4eb..fb59f2d 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,6 @@ "browser-sync": "^2.7.2", "browserify": "^10.2.1", "chai": "^3.0.0", - "deamdify": "^0.1.1", "gulp": "~3.8.1", "gulp-autoprefixer": "1.0.1", "gulp-duration": "0.0.0", @@ -44,8 +43,7 @@ }, "browserify": { "transform": [ - "babelify", - "deamdify" + "babelify" ] } } From 5615c019d0284f37f8ec3d9f8dffd5a7942b5f56 Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Wed, 15 Jul 2015 14:48:46 +0300 Subject: [PATCH 30/49] disable browsersync notifications and ghosting Notifications are pretty much useless and annoying when you are developing something that happens to be on the top right corner of your screen. --- gulpfile.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gulpfile.js b/gulpfile.js index bc7c33d..5e4c791 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -140,6 +140,8 @@ gulp.task('server', function() { return browserSync({ open: false, port: 9001, + notify: false, + ghostMode: false, server: { baseDir: config.destination } From 107428ca97a3567456fcb5410d62f4dc15d575d3 Mon Sep 17 00:00:00 2001 From: Santtu Pajukanta Date: Thu, 16 Jul 2015 23:10:27 +0300 Subject: [PATCH 31/49] README: import instead of require --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 19dc495..90b25cb 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ * [Jade](http://jade-lang.com) files to HTML * [Stylus](http://learnboost.github.io/stylus) files to CSS * [ES6+ JavaScript](https://babeljs.io) files to ES5 Javascript through [browserify](http://browserify.org/) - * You are able to use 'require' in your client-side code + * You are able to use `import` in your client-side code * Uses [BrowserSync](http://www.browsersync.io/) to serve your static files to localhost:9001 and to automatically reload your browser when files change. ## Getting things up and running From 103299516f4e4cfcf3e9b39a47b93537d74fcef3 Mon Sep 17 00:00:00 2001 From: Juuso Tapaninen Date: Sun, 19 Jul 2015 19:09:37 +0300 Subject: [PATCH 32/49] Fixed ESLint rulesets to work on the most recent release Changed consistent-this rule to enforce 'that' instead of '_that' due to a rule conflict with no-underscore-dangle --- .eslintrc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.eslintrc b/.eslintrc index 54cf9d4..127c2b8 100644 --- a/.eslintrc +++ b/.eslintrc @@ -46,7 +46,7 @@ "no-dupe-keys": 2, // disallow duplicate keys when creating object literals "no-duplicate-case": 2, // disallow a duplicate case label. "no-empty": 2, // disallow empty statements - "no-empty-class": 2, // disallow the use of empty character classes in regular expressions + "no-empty-character-class": 2, // disallow the use of empty character classes in regular expressions "no-ex-assign": 2, // disallow assigning to the exception in a catch block "no-extra-boolean-cast": 2, // disallow double-negation boolean casts in a boolean context "no-extra-parens": 0, // disallow unnecessary parentheses (off by default) @@ -154,7 +154,7 @@ "camelcase": 1, // require camel case names "comma-spacing": [1, {"before": false, "after": true}], // enforce spacing before and after comma "comma-style": [1, "last"], // enforce one true comma style (off by default) - "consistent-this": [1, "_this"], // enforces consistent naming when capturing the current execution context (off by default) + "consistent-this": [1, "that"], // enforces consistent naming when capturing the current execution context (off by default) "eol-last": 1, // enforce newline at the end of file, with no multiple empty lines "func-names": 0, // require function expressions to have a name (off by default) "func-style": 0, // enforces use of function declarations or expressions (off by default) @@ -174,7 +174,7 @@ "no-ternary": 0, // disallow the use of ternary operators (off by default) "no-trailing-spaces": 1, // disallow trailing whitespace at the end of lines "no-underscore-dangle": 1, // disallow dangling underscores in identifiers - "no-wrap-func": 1, // disallow wrapping of non-IIFE statements in parens + "no-extra-parens": [1, "functions"], // disallow wrapping of non-IIFE statements in parens "one-var": [1, "never"], // allow just one var statement per function (off by default) "operator-assignment": [1, "never"], // require assignment operator shorthand where possible or prohibit it entirely (off by default) "padded-blocks": [1, "never"], // enforce padding within blocks (off by default) @@ -186,12 +186,13 @@ "space-after-keywords": [0, "never"], // require a space after certain keywords (off by default) "space-before-blocks": [1, "always"], // require or disallow space before blocks (off by default) "space-before-function-paren": [1, {"anonymous": "never", "named": "never"}], // require or disallow space before function opening parenthesis (off by default) - "space-in-brackets": [1, "never"], // require or disallow spaces inside brackets (off by default) + "object-curly-spacing": [1, "never"], // require or disallow spaces inside curly braces in objects + "array-bracket-spacing": [1, "never"], // require or disallow spaces inside of brackets "space-in-parens": [1, "never"], // require or disallow spaces inside parentheses (off by default) - "space-infix-ops": [1, "always"], // require spaces around operators - "space-return-throw-case": [1, "always"], // require a space after return, throw, and case + "space-infix-ops": 1, // require spaces around operators + "space-return-throw-case": 1, // require a space after return, throw, and case "space-unary-ops": [1, {"words": true, "nonwords": false}], // Require or disallow spaces before/after unary operators (words on by default, nonwords off by default) - "spaced-line-comment": [1, "always"], // require or disallow a space immediately following the // in a line comment (off by default) + "spaced-comment": [1, "always"], // require or disallow a space immediately following the // in a line comment (off by default) "wrap-regex": 0, // require regex literals to be wrapped in parentheses (off by default) // From 907cf1a15270f64a280afee55bb6d5173c5a638b Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Sun, 26 Jul 2015 20:13:34 +0300 Subject: [PATCH 33/49] enable babel's experimental features http://babeljs.io/docs/usage/experimental/ --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fb59f2d..bb7492f 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ }, "browserify": { "transform": [ - "babelify" + ["babelify", {"stage": 0}] ] } } From 54f261e1b76bf68823a33330f1b9df9d544e9dbb Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Wed, 12 Aug 2015 22:02:20 +0300 Subject: [PATCH 34/49] replace gulp's built-in watch with gulp-watch https://github.com/leonidas/gulp-project-template/issues/24 --- gulpfile.js | 10 +++++++--- package.json | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 5e4c791..f5de596 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -19,6 +19,7 @@ var streamify = require('gulp-streamify'); var stylus = require('gulp-stylus'); var uglify = require('gulp-uglify'); var watchify = require('watchify'); +var watch = require('gulp-watch'); /*eslint "no-process-env":0 */ var production = process.env.NODE_ENV === 'production'; @@ -149,9 +150,12 @@ gulp.task('server', function() { }); gulp.task('watch', function() { - gulp.watch(config.templates.watch, ['templates']); - gulp.watch(config.styles.watch, ['styles']); - gulp.watch(config.assets.watch, ['assets']); + + ['templates', 'styles', 'assets'].forEach(function(watched) { + watch(config[watched].watch, function() { + gulp.start(watched); + }); + }); var bundle = watchify(browserify(browserifyConfig)); diff --git a/package.json b/package.json index bb7492f..f5068a5 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "gulp-stylus": "~2.0.0", "gulp-uglify": "~1.0.1", "gulp-util": "~3.0.1", + "gulp-watch": "^4.3.4", "jsdom": "^5.6.0", "mocha": "^2.2.5", "node-notifier": "^4.2.1", From 611c310a476b8d42b62bfaec5fd2716e9264e0fa Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Mon, 17 Aug 2015 17:36:56 +0300 Subject: [PATCH 35/49] Add node_modules and src directories to Stylus paths. Third party CSS files can now be imported with absolute path --- README.md | 2 +- gulpfile.js | 2 ++ src/style.styl | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 90b25cb..cc419fd 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ Minification, uglification and other tasks you're expected to run before deployi #### Dependencies All dependencies are meant to be installed with **npm**. * JavaScript-files from **node_modules** can be *require()*'d in client-side modules. -* CSS files can be [imported](https://learnboost.github.io/stylus/docs/import.html) from **node_modules** using relative path from the stylus file to the css file e.g `@import '../../node_modules/bootstrap/dist/css/bootstrap.css'` +* Third party CSS files should be [imported](https://learnboost.github.io/stylus/docs/import.html). Stylus has been configured to use **node_modules** as one of the base directories so you can import file like this: `@import 'bootstrap/dist/css/bootstrap.css'` * You can either create a new gulp task for copying other assets from directories mentioned above or use an array as a value for [assets sources](https://github.com/leonidas/gulp-project-template/blob/master/gulpfile.js#L38) e.g `source: ['./src/assets/**/*.*', 'node_modules/bootstrap/fonts*/*.*']` *(notice the asterisk after 'fonts'? It makes gulp copy the whole directory instead of just the files inside of it)* ## Suggested development tools diff --git a/gulpfile.js b/gulpfile.js index f5de596..76bbb17 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -25,6 +25,7 @@ var watch = require('gulp-watch'); var production = process.env.NODE_ENV === 'production'; var config = { + source: './src', destination: './public', scripts: { source: './src/main.js', @@ -112,6 +113,7 @@ gulp.task('styles', function() { pipeline = pipeline.pipe(stylus({ 'include css': true, + paths: ['node_modules', path.join(__dirname, config.source)], compress: production })) .on('error', handleError) diff --git a/src/style.styl b/src/style.styl index 32ba096..3226077 100644 --- a/src/style.styl +++ b/src/style.styl @@ -4,4 +4,5 @@ body, html font 14px/1.4 'Helvetica Neue', Helvetica, Arial color #333 -@import './components/repository' +@import 'components/repository' +// @import 'bootstrap/dist/css/bootstrap.css' From 84ed329d81db8b33e27177f4cfbe29b1c6698350 Mon Sep 17 00:00:00 2001 From: Chang Wang Date: Thu, 20 Aug 2015 16:26:46 -0400 Subject: [PATCH 36/49] extract js sourcemap into separate .map file --- gulpfile.js | 12 +++++++++++- package.json | 2 ++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/gulpfile.js b/gulpfile.js index 76bbb17..bb03478 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -14,6 +14,8 @@ var replace = require('gulp-replace'); var rev = require('gulp-rev'); var rimraf = require('rimraf'); var source = require('vinyl-source-stream'); +var exorcist = require('exorcist'); +var transform = require('vinyl-transform'); var sourcemaps = require('gulp-sourcemaps'); var streamify = require('gulp-streamify'); var stylus = require('gulp-stylus'); @@ -82,6 +84,10 @@ gulp.task('scripts', function() { if(production) { pipeline = pipeline.pipe(streamify(uglify())); + } else { + pipeline = pipeline.pipe(transform(function() { + return exorcist(config.scripts.destination + config.scripts.filename + '.map'); + })) } return pipeline.pipe(gulp.dest(config.scripts.destination)); @@ -166,7 +172,11 @@ gulp.task('watch', function() { .on('error', handleError) .pipe(source(config.scripts.filename)); - build.pipe(gulp.dest(config.scripts.destination)) + build + .pipe(transform(function() { + return exorcist(config.scripts.destination + config.scripts.filename + '.map'); + })) + .pipe(gulp.dest(config.scripts.destination)) .pipe(duration('Rebundling browserify bundle')) .pipe(browserSync.reload({stream: true})); }).emit('update'); diff --git a/package.json b/package.json index f5068a5..2957600 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "browser-sync": "^2.7.2", "browserify": "^10.2.1", "chai": "^3.0.0", + "exorcist": "^0.4.0", "gulp": "~3.8.1", "gulp-autoprefixer": "1.0.1", "gulp-duration": "0.0.0", @@ -40,6 +41,7 @@ "node-notifier": "^4.2.1", "rimraf": "^2.3.4", "vinyl-source-stream": "~1.0.0", + "vinyl-transform": "^1.0.0", "watchify": "^3.2.1" }, "browserify": { From 1b62bce932ff0e902a6d7a5c51fcb038a36bdb6b Mon Sep 17 00:00:00 2001 From: Lauri Hahne Date: Tue, 22 Sep 2015 10:13:29 +0300 Subject: [PATCH 37/49] update browsersync for node 4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2957600..7b6ba93 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "devDependencies": { "babel": "^5.6.14", "babelify": "^6.1.1", - "browser-sync": "^2.7.2", + "browser-sync": "^2.9.4", "browserify": "^10.2.1", "chai": "^3.0.0", "exorcist": "^0.4.0", From 8ee20f35f889ce5a9335aa298a3d2d29da7479d3 Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Tue, 29 Sep 2015 19:23:42 +0300 Subject: [PATCH 38/49] use airbnb's eslint configuration as a base to extend from. update eslint-related dependencies --- .eslintrc | 241 ++++++--------------------------------------------- package.json | 12 ++- src/main.js | 2 - 3 files changed, 38 insertions(+), 217 deletions(-) diff --git a/.eslintrc b/.eslintrc index 127c2b8..95898b2 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,220 +1,33 @@ { + "extends": "airbnb", + "ecmaFeatures": { + "jsx": true, + "modules": true + }, "env": { "browser": true, - "node": true, - "es6": true + "node": true }, - "ecmaFeatures": { - "arrowFunctions": true, - "binaryLiterals": true, - "blockBindings": true, - "classes": true, - "defaultParams": true, - "destructuring": true, - "forOf": true, - "generators": true, - "modules": true, - "objectLiteralComputedProperties": true, - "objectLiteralDuplicateProperties": true, - "objectLiteralShorthandMethods": true, - "objectLiteralShorthandProperties": true, - "octalLiterals": true, - "regexUFlag": true, - "regexYFlag": true, - "spread": true, - "superInFunctions": true, - "templateStrings": true, - "unicodeCodePointEscapes": true, - "globalReturn": true, - "jsx": true - }, - + "parser": "babel-eslint", "rules": { - - // - //Possible Errors - // - // The following rules point out areas where you might have made mistakes. - // - "comma-dangle": 2, // disallow or enforce trailing commas - "no-cond-assign": 2, // disallow assignment in conditional expressions - "no-console": 1, // disallow use of console (off by default in the node environment) - "no-constant-condition": 2, // disallow use of constant expressions in conditions - "no-control-regex": 2, // disallow control characters in regular expressions - "no-debugger": 2, // disallow use of debugger - "no-dupe-args": 2, // disallow duplicate arguments in functions - "no-dupe-keys": 2, // disallow duplicate keys when creating object literals - "no-duplicate-case": 2, // disallow a duplicate case label. - "no-empty": 2, // disallow empty statements - "no-empty-character-class": 2, // disallow the use of empty character classes in regular expressions - "no-ex-assign": 2, // disallow assigning to the exception in a catch block - "no-extra-boolean-cast": 2, // disallow double-negation boolean casts in a boolean context - "no-extra-parens": 0, // disallow unnecessary parentheses (off by default) - "no-extra-semi": 2, // disallow unnecessary semicolons - "no-func-assign": 2, // disallow overwriting functions written as function declarations - "no-inner-declarations": 2, // disallow function or variable declarations in nested blocks - "no-invalid-regexp": 2, // disallow invalid regular expression strings in the RegExp constructor - "no-irregular-whitespace": 2, // disallow irregular whitespace outside of strings and comments - "no-negated-in-lhs": 2, // disallow negation of the left operand of an in expression - "no-obj-calls": 2, // disallow the use of object properties of the global object (Math and JSON) as functions - "no-regex-spaces": 2, // disallow multiple spaces in a regular expression literal - "no-reserved-keys": 2, // disallow reserved words being used as object literal keys (off by default) - "no-sparse-arrays": 2, // disallow sparse arrays - "no-unreachable": 2, // disallow unreachable statements after a return, throw, continue, or break statement - "use-isnan": 2, // disallow comparisons with the value NaN - "valid-jsdoc": 2, // Ensure JSDoc comments are valid (off by default) - "valid-typeof": 2, // Ensure that the results of typeof are compared against a valid string - - // - // Best Practices - // - // These are rules designed to prevent you from making mistakes. - // They either prescribe a better way of doing something or help you avoid footguns. - // - "block-scoped-var": 0, // treat var statements as if they were block scoped (off by default). 0: deep destructuring is not compatible https://github.com/eslint/eslint/issues/1863 - "complexity": 0, // specify the maximum cyclomatic complexity allowed in a program (off by default) - "consistent-return": 2, // require return statements to either always or never specify values - "curly": 2, // specify curly brace conventions for all control statements - "default-case": 2, // require default case in switch statements (off by default) - "dot-notation": 2, // encourages use of dot notation whenever possible - "eqeqeq": 2, // require the use of === and !== - "guard-for-in": 2, // make sure for-in loops have an if statement (off by default) - "no-alert": 2, // disallow the use of alert, confirm, and prompt - "no-caller": 2, // disallow use of arguments.caller or arguments.callee - "no-div-regex": 2, // disallow division operators explicitly at beginning of regular expression (off by default) - "no-else-return": 2, // disallow else after a return in an if (off by default) - "no-empty-label": 2, // disallow use of labels for anything other then loops and switches - "no-eq-null": 2, // disallow comparisons to null without a type-checking operator (off by default) - "no-eval": 2, // disallow use of eval() - "no-extend-native": 2, // disallow adding to native types - "no-extra-bind": 2, // disallow unnecessary function binding - "no-fallthrough": 2, // disallow fallthrough of case statements - "no-floating-decimal": 2, // disallow the use of leading or trailing decimal points in numeric literals (off by default) - "no-implied-eval": 2, // disallow use of eval()-like methods - "no-iterator": 2, // disallow usage of __iterator__ property - "no-labels": 2, // disallow use of labeled statements - "no-lone-blocks": 2, // disallow unnecessary nested blocks - "no-loop-func": 2, // disallow creation of functions within loops - "no-multi-spaces": 2, // disallow use of multiple spaces - "no-multi-str": 2, // disallow use of multiline strings - "no-native-reassign": 2, // disallow reassignments of native objects - "no-new": 2, // disallow use of new operator when not part of the assignment or comparison - "no-new-func": 2, // disallow use of new operator for Function object - "no-new-wrappers": 2, // disallows creating new instances of String,Number, and Boolean - "no-octal": 2, // disallow use of octal literals - "no-octal-escape": 2, // disallow use of octal escape sequences in string literals, such as var foo = "Copyright \251"; - "no-param-reassign": 2, // disallow reassignment of function parameters (off by default) - "no-process-env": 2, // disallow use of process.env (off by default) - "no-proto": 2, // disallow usage of __proto__ property - "no-redeclare": 2, // disallow declaring the same variable more then once - "no-return-assign": 2, // disallow use of assignment in return statement - "no-script-url": 2, // disallow use of javascript: urls. - "no-self-compare": 2, // disallow comparisons where both sides are exactly the same (off by default) - "no-sequences": 2, // disallow use of comma operator - "no-throw-literal": 2, // restrict what can be thrown as an exception (off by default) - "no-unused-expressions": 2, // disallow usage of expressions in statement position - "no-void": 2, // disallow use of void operator (off by default) - "no-warning-comments": [0, {"terms": ["todo", "fixme"], "location": "start"}], // disallow usage of configurable warning terms in comments": 2, // e.g. TODO or FIXME (off by default) - "no-with": 2, // disallow use of the with statement - "radix": 2, // require use of the second argument for parseInt() (off by default) - "vars-on-top": 0, // requires to declare all vars on top of their containing scope (off by default) - "wrap-iife": 2, // require immediate function invocation to be wrapped in parentheses (off by default) - "yoda": 2, // require or disallow Yoda conditions - - // - // Strict Mode - // - // These rules relate to using strict mode. - // - "strict": 0, // controls location of Use Strict Directives. 0: required by `babel-eslint` - - // - // Variables - // - // These rules have to do with variable declarations. - // - "no-catch-shadow": 2, // disallow the catch clause parameter name being the same as a variable in the outer scope (off by default in the node environment) - "no-delete-var": 2, // disallow deletion of variables - "no-label-var": 2, // disallow labels that share a name with a variable - "no-shadow": 2, // disallow declaration of variables already declared in the outer scope - "no-shadow-restricted-names": 2, // disallow shadowing of names such as arguments - "no-undef": 2, // disallow use of undeclared variables unless mentioned in a /*global */ block - "no-undef-init": 2, // disallow use of undefined when initializing variables - "no-undefined": 2, // disallow use of undefined variable (off by default) - "no-unused-vars": 2, // disallow declaration of variables that are not used in the code - "no-use-before-define": 2, // disallow use of variables before they are defined - - // - //Stylistic Issues - // - // These rules are purely matters of style and are quite subjective. - // - "indent": [1, 2], // this option sets a specific tab width for your code (off by default) - "brace-style": 1, // enforce one true brace style (off by default) - "camelcase": 1, // require camel case names - "comma-spacing": [1, {"before": false, "after": true}], // enforce spacing before and after comma - "comma-style": [1, "last"], // enforce one true comma style (off by default) - "consistent-this": [1, "that"], // enforces consistent naming when capturing the current execution context (off by default) - "eol-last": 1, // enforce newline at the end of file, with no multiple empty lines - "func-names": 0, // require function expressions to have a name (off by default) - "func-style": 0, // enforces use of function declarations or expressions (off by default) - "key-spacing": [1, {"beforeColon": false, "afterColon": true}], // enforces spacing between keys and values in object literal properties - "max-nested-callbacks": [1, 3], // specify the maximum depth callbacks can be nested (off by default) - "new-cap": [1, {newIsCap: true, capIsNew: false}], // require a capital letter for constructors - "new-parens": 1, // disallow the omission of parentheses when invoking a constructor with no arguments - "newline-after-var": 0, // allow/disallow an empty newline after var statement (off by default) - "no-array-constructor": 1, // disallow use of the Array constructor - "no-inline-comments": 1, // disallow comments inline after code (off by default) - "no-lonely-if": 1, // disallow if as the only statement in an else block (off by default) - "no-mixed-spaces-and-tabs": 1, // disallow mixed spaces and tabs for indentation - "no-multiple-empty-lines": [1, {"max": 2}], // disallow multiple empty lines (off by default) - "no-nested-ternary": 1, // disallow nested ternary expressions (off by default) - "no-new-object": 1, // disallow use of the Object constructor - "no-spaced-func": 1, // disallow space between function identifier and application - "no-ternary": 0, // disallow the use of ternary operators (off by default) - "no-trailing-spaces": 1, // disallow trailing whitespace at the end of lines - "no-underscore-dangle": 1, // disallow dangling underscores in identifiers - "no-extra-parens": [1, "functions"], // disallow wrapping of non-IIFE statements in parens - "one-var": [1, "never"], // allow just one var statement per function (off by default) - "operator-assignment": [1, "never"], // require assignment operator shorthand where possible or prohibit it entirely (off by default) - "padded-blocks": [1, "never"], // enforce padding within blocks (off by default) - "quote-props": [1, "as-needed"], // require quotes around object literal property names (off by default) - "quotes": [1, "single"], // specify whether double or single quotes should be used - "semi": [1, "always"], // require or disallow use of semicolons instead of ASI - "semi-spacing": [1, {"before": false, "after": true}], // enforce spacing before and after semicolons - "sort-vars": 0, // sort variables within the same declaration block (off by default) - "space-after-keywords": [0, "never"], // require a space after certain keywords (off by default) - "space-before-blocks": [1, "always"], // require or disallow space before blocks (off by default) - "space-before-function-paren": [1, {"anonymous": "never", "named": "never"}], // require or disallow space before function opening parenthesis (off by default) - "object-curly-spacing": [1, "never"], // require or disallow spaces inside curly braces in objects - "array-bracket-spacing": [1, "never"], // require or disallow spaces inside of brackets - "space-in-parens": [1, "never"], // require or disallow spaces inside parentheses (off by default) - "space-infix-ops": 1, // require spaces around operators - "space-return-throw-case": 1, // require a space after return, throw, and case - "space-unary-ops": [1, {"words": true, "nonwords": false}], // Require or disallow spaces before/after unary operators (words on by default, nonwords off by default) - "spaced-comment": [1, "always"], // require or disallow a space immediately following the // in a line comment (off by default) - "wrap-regex": 0, // require regex literals to be wrapped in parentheses (off by default) - - // - // ECMAScript 6 - // - // These rules are only relevant to ES6 environments and are off by default. - // - "no-var": 2, // require let or const instead of var (off by default) - "generator-star-spacing": [2, "before"], // enforce the spacing around the * in generator functions (off by default) - - // - // Legacy - // - // The following rules are included for compatibility with JSHint and JSLint. - // While the names of the rules may not match up with the JSHint/JSLint counterpart, - // the functionality is the same. - // - "max-depth": [2, 3], // specify the maximum depth that blocks can be nested (off by default) - "max-len": [2, 100, 2], // specify the maximum length of a line in your program (off by default) - "max-params": [2, 5], // limits the number of parameters that can be used in the function declaration. (off by default) - "max-statements": 0, // specify the maximum number of statement allowed in a function (off by default) - "no-bitwise": 0, // disallow use of bitwise operators (off by default) - "no-plusplus": 2 // disallow use of unary operators, ++ and -- (off by default) - } + "quotes": [2, "single"], + "react/jsx-uses-react": 2, + "react/jsx-uses-vars": 2, + "react/react-in-jsx-scope": 2, + "comma-dangle": [2, "never"], + "space-after-keywords": [2, "never"], + "react/jsx-quotes": [2, "single"], + "react/prop-types": 0, + "no-use-before-define": 0, + "padded-blocks": 0, + "id-length": [2, { + "min": 3, + "max": 20, + "properties": "never", + "exceptions": ["x", "y", "vx", "vy", "id", "i"] + }] + }, + "plugins": [ + "react" + ] } diff --git a/package.json b/package.json index 7b6ba93..0f0c240 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "scripts": { "start": "gulp", "build": "gulp build", + "lint": "eslint src", "test": "mocha src/**/__tests__/*.js --compilers js:babel/register --require test/test-helper" }, "keywords": [ @@ -19,10 +20,14 @@ }, "devDependencies": { "babel": "^5.6.14", + "babel-eslint": "^4.1.3", "babelify": "^6.1.1", "browser-sync": "^2.9.4", "browserify": "^10.2.1", "chai": "^3.0.0", + "eslint": "^1.5.1", + "eslint-config-airbnb": "0.0.9", + "eslint-plugin-react": "^3.4.2", "exorcist": "^0.4.0", "gulp": "~3.8.1", "gulp-autoprefixer": "1.0.1", @@ -46,7 +51,12 @@ }, "browserify": { "transform": [ - ["babelify", {"stage": 0}] + [ + "babelify", + { + "stage": 0 + } + ] ] } } diff --git a/src/main.js b/src/main.js index a2c72f4..a8af948 100644 --- a/src/main.js +++ b/src/main.js @@ -1,5 +1,3 @@ -'use strict'; - import {getCommits, getRepo} from './services/github'; import {render} from './components/repository'; From 3820ee461da6ad05754115ffea74c1ff616b4b75 Mon Sep 17 00:00:00 2001 From: Chang Wang Date: Mon, 28 Sep 2015 23:58:53 -0400 Subject: [PATCH 39/49] inject resources from build directory. obviates rev-manifest. --- gulpfile.js | 50 +++++++++++++++----------------------------------- package.json | 1 + src/index.jade | 6 ++++-- 3 files changed, 20 insertions(+), 37 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index bb03478..06a3e63 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -22,6 +22,7 @@ var stylus = require('gulp-stylus'); var uglify = require('gulp-uglify'); var watchify = require('watchify'); var watch = require('gulp-watch'); +var inject = require('gulp-inject'); /*eslint "no-process-env":0 */ var production = process.env.NODE_ENV === 'production'; @@ -51,10 +52,8 @@ var config = { watch: './src/assets/**/*.*', destination: './public/' }, - revision: { - source: ['./public/**/*.css', './public/**/*.js'], - base: path.join(__dirname, 'public'), - destination: './public/' + inject: { + resources: ['./public/**/*.css', './public/**/*.js'] } }; @@ -83,7 +82,9 @@ gulp.task('scripts', function() { .pipe(source(config.scripts.filename)); if(production) { - pipeline = pipeline.pipe(streamify(uglify())); + pipeline = pipeline + .pipe(streamify(uglify())) + .pipe(streamify(rev())); } else { pipeline = pipeline.pipe(transform(function() { return exorcist(config.scripts.destination + config.scripts.filename + '.map'); @@ -93,12 +94,15 @@ gulp.task('scripts', function() { return pipeline.pipe(gulp.dest(config.scripts.destination)); }); -gulp.task('templates', function() { +gulp.task('templates', production ? ['styles', 'scripts'] : [], function() { + var resources = gulp.src(config.inject.resources, {read: false}); + var pipeline = gulp.src(config.templates.source) .pipe(jade({ pretty: !production })) .on('error', handleError) + .pipe(inject(resources, {ignorePath: 'public', removeTags: true})) .pipe(gulp.dest(config.templates.destination)); if(production) { @@ -125,7 +129,9 @@ gulp.task('styles', function() { .on('error', handleError) .pipe(prefix('last 2 versions', 'Chrome 34', 'Firefox 28', 'iOS 7')); - if(!production) { + if(production) { + pipeline = pipeline.pipe(rev()); + } else { pipeline = pipeline.pipe(sourcemaps.write('.')); } @@ -182,31 +188,5 @@ gulp.task('watch', function() { }).emit('update'); }); -var buildTasks = ['templates', 'styles', 'assets']; - -gulp.task('revision', buildTasks.concat(['scripts']), function() { - return gulp.src(config.revision.source, {base: config.revision.base}) - .pipe(rev()) - .pipe(gulp.dest(config.revision.destination)) - .pipe(rev.manifest()) - .pipe(gulp.dest('./')); -}); - -gulp.task('replace-revision-references', ['revision', 'templates'], function() { - var revisions = require('./rev-manifest.json'); - - var pipeline = gulp.src(config.templates.revision); - - pipeline = Object.keys(revisions).reduce(function(stream, key) { - return stream.pipe(replace(key, revisions[key])); - }, pipeline); - - return pipeline.pipe(gulp.dest(config.templates.destination)); -}); - -gulp.task('build', function() { - rimraf.sync(config.destination); - gulp.start(buildTasks.concat(['scripts', 'revision', 'replace-revision-references'])); -}); - -gulp.task('default', buildTasks.concat(['watch', 'server'])); +gulp.task('build', ['styles', 'assets', 'scripts', 'templates']); +gulp.task('default', ['styles', 'assets', 'templates', 'watch', 'server']); diff --git a/package.json b/package.json index 7b6ba93..744a693 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "gulp": "~3.8.1", "gulp-autoprefixer": "1.0.1", "gulp-duration": "0.0.0", + "gulp-inject": "^3.0.0", "gulp-jade": "~0.9.0", "gulp-replace": "^0.5.3", "gulp-rev": "^4.0.0", diff --git a/src/index.jade b/src/index.jade index 76a4bf6..c5ab11f 100644 --- a/src/index.jade +++ b/src/index.jade @@ -2,7 +2,9 @@ doctype html html head title Gulp template - link(rel='stylesheet', href='css/style.css') + // inject:css + // endinject body h1 Hello world! - script(src='js/bundle.js') + // inject:js + // endinject From 69063d4d807e43434773cb3025a890bc3ba49f94 Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Wed, 30 Sep 2015 21:17:05 +0300 Subject: [PATCH 40/49] convert gulpfile into ES6+ --- gulpfile.js => gulpfile.babel.js | 89 +++++++++++++++----------------- package.json | 5 +- 2 files changed, 45 insertions(+), 49 deletions(-) rename gulpfile.js => gulpfile.babel.js (63%) diff --git a/gulpfile.js b/gulpfile.babel.js similarity index 63% rename from gulpfile.js rename to gulpfile.babel.js index 06a3e63..6819da4 100644 --- a/gulpfile.js +++ b/gulpfile.babel.js @@ -1,33 +1,28 @@ -/*eslint "no-var":0 */ -'use strict'; - -var browserify = require('browserify'); -var browserSync = require('browser-sync'); -var duration = require('gulp-duration'); -var gulp = require('gulp'); -var gutil = require('gulp-util'); -var jade = require('gulp-jade'); -var notifier = require('node-notifier'); -var path = require('path'); -var prefix = require('gulp-autoprefixer'); -var replace = require('gulp-replace'); -var rev = require('gulp-rev'); -var rimraf = require('rimraf'); -var source = require('vinyl-source-stream'); -var exorcist = require('exorcist'); -var transform = require('vinyl-transform'); -var sourcemaps = require('gulp-sourcemaps'); -var streamify = require('gulp-streamify'); -var stylus = require('gulp-stylus'); -var uglify = require('gulp-uglify'); -var watchify = require('watchify'); -var watch = require('gulp-watch'); -var inject = require('gulp-inject'); +import browserify from 'browserify'; +import browserSync from 'browser-sync'; +import duration from 'gulp-duration'; +import gulp from 'gulp'; +import gutil from 'gulp-util'; +import jade from 'gulp-jade'; +import notifier from 'node-notifier'; +import path from 'path'; +import prefix from 'gulp-autoprefixer'; +import rev from 'gulp-rev'; +import source from 'vinyl-source-stream'; +import exorcist from 'exorcist'; +import transform from 'vinyl-transform'; +import sourcemaps from 'gulp-sourcemaps'; +import streamify from 'gulp-streamify'; +import stylus from 'gulp-stylus'; +import uglify from 'gulp-uglify'; +import watchify from 'watchify'; +import watch from 'gulp-watch'; +import inject from 'gulp-inject'; /*eslint "no-process-env":0 */ -var production = process.env.NODE_ENV === 'production'; +const production = process.env.NODE_ENV === 'production'; -var config = { +const config = { source: './src', destination: './public', scripts: { @@ -57,7 +52,7 @@ var config = { } }; -var browserifyConfig = { +const browserifyConfig = { entries: [config.scripts.source], extensions: config.scripts.extensions, debug: !production, @@ -75,8 +70,8 @@ function handleError(err) { return this.emit('end'); } -gulp.task('scripts', function() { - var pipeline = browserify(browserifyConfig) +gulp.task('scripts', () => { + let pipeline = browserify(browserifyConfig) .bundle() .on('error', handleError) .pipe(source(config.scripts.filename)); @@ -86,18 +81,18 @@ gulp.task('scripts', function() { .pipe(streamify(uglify())) .pipe(streamify(rev())); } else { - pipeline = pipeline.pipe(transform(function() { - return exorcist(config.scripts.destination + config.scripts.filename + '.map'); - })) + pipeline = pipeline.pipe(transform(() => { + return exorcist(path.join(config.scripts.destination, config.scripts.filename) + '.map'); + })); } return pipeline.pipe(gulp.dest(config.scripts.destination)); }); -gulp.task('templates', production ? ['styles', 'scripts'] : [], function() { - var resources = gulp.src(config.inject.resources, {read: false}); +gulp.task('templates', production ? ['styles', 'scripts'] : [], () => { + const resources = gulp.src(config.inject.resources, {read: false}); - var pipeline = gulp.src(config.templates.source) + const pipeline = gulp.src(config.templates.source) .pipe(jade({ pretty: !production })) @@ -114,8 +109,8 @@ gulp.task('templates', production ? ['styles', 'scripts'] : [], function() { })); }); -gulp.task('styles', function() { - var pipeline = gulp.src(config.styles.source); +gulp.task('styles', () => { + let pipeline = gulp.src(config.styles.source); if(!production) { pipeline = pipeline.pipe(sourcemaps.init()); @@ -146,12 +141,12 @@ gulp.task('styles', function() { })); }); -gulp.task('assets', function() { +gulp.task('assets', () => { return gulp.src(config.assets.source) .pipe(gulp.dest(config.assets.destination)); }); -gulp.task('server', function() { +gulp.task('server', () => { return browserSync({ open: false, port: 9001, @@ -163,23 +158,23 @@ gulp.task('server', function() { }); }); -gulp.task('watch', function() { +gulp.task('watch', () => { - ['templates', 'styles', 'assets'].forEach(function(watched) { - watch(config[watched].watch, function() { + ['templates', 'styles', 'assets'].forEach((watched) => { + watch(config[watched].watch, () => { gulp.start(watched); }); }); - var bundle = watchify(browserify(browserifyConfig)); + const bundle = watchify(browserify(browserifyConfig)); - bundle.on('update', function() { - var build = bundle.bundle() + bundle.on('update', () => { + const build = bundle.bundle() .on('error', handleError) .pipe(source(config.scripts.filename)); build - .pipe(transform(function() { + .pipe(transform(() => { return exorcist(config.scripts.destination + config.scripts.filename + '.map'); })) .pipe(gulp.dest(config.scripts.destination)) diff --git a/package.json b/package.json index c61da43..4db7cc3 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,8 @@ "lodash": "^3.9.1" }, "devDependencies": { - "babel": "^5.6.14", + "babel": "^5.8.23", + "babel-core": "^5.8.25", "babel-eslint": "^4.1.3", "babelify": "^6.1.1", "browser-sync": "^2.9.4", @@ -29,7 +30,7 @@ "eslint-config-airbnb": "0.0.9", "eslint-plugin-react": "^3.4.2", "exorcist": "^0.4.0", - "gulp": "~3.8.1", + "gulp": "3.9.0", "gulp-autoprefixer": "1.0.1", "gulp-duration": "0.0.0", "gulp-inject": "^3.0.0", From 8b3b5c5e1938460101736c9b051990eabadb1df9 Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Fri, 2 Oct 2015 10:53:11 +0300 Subject: [PATCH 41/49] fix task running order Style and script files should be created before templates task so gulp-inject can find the built files and inject them. --- gulpfile.babel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gulpfile.babel.js b/gulpfile.babel.js index 6819da4..dedc6d5 100644 --- a/gulpfile.babel.js +++ b/gulpfile.babel.js @@ -89,7 +89,7 @@ gulp.task('scripts', () => { return pipeline.pipe(gulp.dest(config.scripts.destination)); }); -gulp.task('templates', production ? ['styles', 'scripts'] : [], () => { +gulp.task('templates', ['styles', 'scripts'], () => { const resources = gulp.src(config.inject.resources, {read: false}); const pipeline = gulp.src(config.templates.source) From f6a918d8396efd2be6aea72fd975f4e4d6c6d812 Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Sun, 4 Oct 2015 14:43:09 +0300 Subject: [PATCH 42/49] inline environment variables to built code --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 4db7cc3..5858f0f 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,8 @@ [ "babelify", { - "stage": 0 + "stage": 0, + "optional": ["utility.inlineEnvironmentVariables"] } ] ] From 0117ae6ec652dc18ae6a353141093d01c0f67efd Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Sun, 4 Oct 2015 14:59:27 +0300 Subject: [PATCH 43/49] update readme add list of know forks and stuff about if you should keep the version history or not --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cc419fd..b7a3629 100644 --- a/README.md +++ b/README.md @@ -54,9 +54,17 @@ All dependencies are meant to be installed with **npm**. --- ## FAQ +### Should I clear the version history after I clone this repository? +I would advice against it. Keeping the version history makes it easier to receive updates from this project. ### I want to use CoffeeScript instead of JavaScript -Check out the [coffee branch](https://github.com/leonidas/gulp-project-template/tree/coffee) +Fork this repository and customize it based on your preferences . Please leave an issue about your fork and we'll add it to the list below. + +**Known forks** + +* [CoffeeScript + Knockout.js](https://github.com/tjyrkinen/gulp-knockout-project-template) + + ## Useful resources * [Browserify handbook](https://github.com/substack/browserify-handbook) From f271572234df9d51afc1137e97def72dac3ce3a7 Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Mon, 19 Oct 2015 21:38:58 +0300 Subject: [PATCH 44/49] eslintrc tuning --- .eslintrc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.eslintrc b/.eslintrc index 95898b2..a493496 100644 --- a/.eslintrc +++ b/.eslintrc @@ -22,9 +22,9 @@ "padded-blocks": 0, "id-length": [2, { "min": 3, - "max": 20, + "max": 30, "properties": "never", - "exceptions": ["x", "y", "vx", "vy", "id", "i"] + "exceptions": ["x", "y", "vx", "vy", "id", "i", "e", "fn"] }] }, "plugins": [ From 711b98caa79d4e52e23b4ddcc707913c3a4a1130 Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Sat, 10 Oct 2015 13:10:38 +0200 Subject: [PATCH 45/49] remove dist directory on start and on build --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 5858f0f..8119e37 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,8 @@ "license": "MIT", "main": "gulpfile.js", "scripts": { - "start": "gulp", - "build": "gulp build", + "start": "rm -rf public && gulp", + "build": "rm -rf public && gulp build", "lint": "eslint src", "test": "mocha src/**/__tests__/*.js --compilers js:babel/register --require test/test-helper" }, From a8dfa7164ad16914d5c189a7e959ef67ab3fd6da Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Thu, 22 Oct 2015 20:24:45 +0300 Subject: [PATCH 46/49] only log error messages https://github.com/leonidas/gulp-project-template/issues/32 --- gulpfile.babel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gulpfile.babel.js b/gulpfile.babel.js index dedc6d5..dda3d1c 100644 --- a/gulpfile.babel.js +++ b/gulpfile.babel.js @@ -61,7 +61,7 @@ const browserifyConfig = { }; function handleError(err) { - gutil.log(err); + gutil.log(err.message); gutil.beep(); notifier.notify({ title: 'Compile Error', From 631ded2aafafca1fd485d7348f03bc6b1bad312d Mon Sep 17 00:00:00 2001 From: Chang Wang Date: Mon, 23 Nov 2015 16:09:13 -0500 Subject: [PATCH 47/49] upgrade babel. add .babelrc --- .babelrc | 3 +++ package.json | 15 ++++++--------- 2 files changed, 9 insertions(+), 9 deletions(-) create mode 100644 .babelrc diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..af0f0c3 --- /dev/null +++ b/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["es2015"] +} \ No newline at end of file diff --git a/package.json b/package.json index 8119e37..485e40d 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "start": "rm -rf public && gulp", "build": "rm -rf public && gulp build", "lint": "eslint src", - "test": "mocha src/**/__tests__/*.js --compilers js:babel/register --require test/test-helper" + "test": "mocha src/**/__tests__/*.js --compilers js:babel-core/register --require test/test-helper" }, "keywords": [ "gulp", @@ -19,10 +19,11 @@ "lodash": "^3.9.1" }, "devDependencies": { - "babel": "^5.8.23", - "babel-core": "^5.8.25", + "babel": "^6.1.18", + "babel-core": "^6.2.1", "babel-eslint": "^4.1.3", - "babelify": "^6.1.1", + "babel-preset-es2015": "^6.1.18", + "babelify": "^7.2.0", "browser-sync": "^2.9.4", "browserify": "^10.2.1", "chai": "^3.0.0", @@ -54,11 +55,7 @@ "browserify": { "transform": [ [ - "babelify", - { - "stage": 0, - "optional": ["utility.inlineEnvironmentVariables"] - } + "babelify" ] ] } From cb3d9193c1dbe6f7ec1b8537b125ce3361321274 Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Tue, 24 Nov 2015 13:32:55 +0200 Subject: [PATCH 48/49] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b7a3629..130dc4b 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,7 @@ Fork this repository and customize it based on your preferences . Please leave a **Known forks** +* [React + Redux](https://github.com/eetu/gulp-redux-project-template) * [CoffeeScript + Knockout.js](https://github.com/tjyrkinen/gulp-knockout-project-template) From aa4cbee8a05bcf09a8e7f90854cf1d1a26442256 Mon Sep 17 00:00:00 2001 From: Chang Wang Date: Wed, 25 Nov 2015 02:33:54 -0500 Subject: [PATCH 49/49] add envify transform to inline environment variables --- package.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/package.json b/package.json index 485e40d..aff1126 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "browser-sync": "^2.9.4", "browserify": "^10.2.1", "chai": "^3.0.0", + "envify": "^3.4.0", "eslint": "^1.5.1", "eslint-config-airbnb": "0.0.9", "eslint-plugin-react": "^3.4.2", @@ -56,6 +57,9 @@ "transform": [ [ "babelify" + ], + [ + "envify" ] ] }