├── assets ├── scss │ ├── _example-1.scss │ └── example.scss ├── templates │ ├── partials │ │ └── header.hbs │ ├── pages │ │ ├── index.hbs │ │ └── test │ │ │ └── index.hbs │ └── layouts │ │ └── core.hbs ├── js │ ├── example-1.js │ └── example-2.js ├── vendor │ ├── css │ │ └── example-1.css │ └── js │ │ └── example-1.js ├── images │ └── chubs.jpeg └── README.md ├── .gitignore ├── test ├── README.md └── js │ ├── example-1.test.js │ └── example-2.test.js ├── assemblefile.js ├── package.json ├── .sass-lint.yml └── README.md /assets/scss/_example-1.scss: -------------------------------------------------------------------------------- 1 | $color: blue; -------------------------------------------------------------------------------- /assets/templates/partials/header.hbs: -------------------------------------------------------------------------------- 1 |
Welcome
-------------------------------------------------------------------------------- /assets/js/example-1.js: -------------------------------------------------------------------------------- 1 | function foo() { 2 | return 'foo'; 3 | } -------------------------------------------------------------------------------- /assets/js/example-2.js: -------------------------------------------------------------------------------- 1 | function bar() { 2 | return 'bar'; 3 | } -------------------------------------------------------------------------------- /assets/vendor/css/example-1.css: -------------------------------------------------------------------------------- 1 | .vendor { 2 | content: 'vendor'; 3 | } 4 | -------------------------------------------------------------------------------- /assets/templates/pages/index.hbs: -------------------------------------------------------------------------------- 1 | --- 2 | title: Noah 3 | --- 4 | 5 |

Example

-------------------------------------------------------------------------------- /assets/vendor/js/example-1.js: -------------------------------------------------------------------------------- 1 | function vendor() { 2 | return 'vendor'; 3 | } 4 | -------------------------------------------------------------------------------- /assets/templates/pages/test/index.hbs: -------------------------------------------------------------------------------- 1 | --- 2 | title: Noah 3 | --- 4 | 5 |

Example

-------------------------------------------------------------------------------- /assets/images/chubs.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/esr360/Noah/HEAD/assets/images/chubs.jpeg -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | .settings 3 | .sass-cache 4 | debug.log 5 | npm-debug.log 6 | node_modules 7 | dist -------------------------------------------------------------------------------- /assets/scss/example.scss: -------------------------------------------------------------------------------- 1 | @import 'example-1'; 2 | 3 | .foo { 4 | .bar { 5 | content: 'Foo Bar'; 6 | color: $color; 7 | } 8 | } -------------------------------------------------------------------------------- /test/README.md: -------------------------------------------------------------------------------- 1 | All files in this directory are for demo purposes only, to provide a workable MVP. They exist to only test that the provided build scripts work. -------------------------------------------------------------------------------- /assets/README.md: -------------------------------------------------------------------------------- 1 | All files in this directory are for demo purposes only, to provide a workable MVP. They exist to only test that the provided build scripts work. -------------------------------------------------------------------------------- /assemblefile.js: -------------------------------------------------------------------------------- 1 | /** 2 | * assemblefile.js 3 | * 4 | * Compiles Handlebars templates 5 | */ 6 | var app = require('./build/tasks/assemble'); 7 | 8 | module.exports = app; -------------------------------------------------------------------------------- /test/js/example-1.test.js: -------------------------------------------------------------------------------- 1 | describe('example-1', function() { 2 | 3 | 'use strict'; 4 | 5 | beforeEach(function() { 6 | this.component = foo; 7 | }); 8 | 9 | it('should be defined', function() { 10 | expect(this.component).to.exist; 11 | }); 12 | 13 | describe('foo', function() { 14 | 15 | it('should return correct string', function() { 16 | expect(this.component()).to.equal('foo'); 17 | }); 18 | 19 | }); 20 | 21 | }); 22 | -------------------------------------------------------------------------------- /test/js/example-2.test.js: -------------------------------------------------------------------------------- 1 | describe('example-2', function() { 2 | 3 | 'use strict'; 4 | 5 | beforeEach(function() { 6 | this.component = bar; 7 | }); 8 | 9 | it('should be defined', function() { 10 | expect(this.component).to.exist; 11 | }); 12 | 13 | describe('bar', function() { 14 | 15 | it('should return correct string', function() { 16 | expect(this.component()).to.equal('bar'); 17 | }); 18 | 19 | }); 20 | 21 | }); 22 | -------------------------------------------------------------------------------- /assets/templates/layouts/core.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | {{title}} 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | {{> header}} 15 | 16 |

{{{title}}}

17 | 18 | {% body %} 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "noah-npm", 3 | "version": "1.0.0", 4 | "description": "Noah is a boilerplate for building front-end web apps using NPM build scripts.", 5 | "author": "T-Mex", 6 | "contributors": [ 7 | "Edmund Reed " 8 | ], 9 | "dependencies": { 10 | "assemble": "^0.17.1", 11 | "autoprefixer": "^6.5.1", 12 | "browser-sync": "^2.18.5", 13 | "chai": "^3.5.0", 14 | "fs-extra": "^0.30.0", 15 | "gulp-extname": "^0.2.2", 16 | "handlebars": "^4.0.5", 17 | "handlebars-helper-repeat": "^0.3.1", 18 | "handlebars-helpers": "^0.7.5", 19 | "jshint": "^2.9.4", 20 | "jshint-stylish": "^2.2.1", 21 | "karma": "^1.3.0", 22 | "karma-chai-plugins": "^0.8.0", 23 | "karma-mocha": "^1.2.0", 24 | "karma-mocha-reporter": "^2.2.0", 25 | "karma-phantomjs-launcher": "^1.0.2", 26 | "mkdirp": "^0.5.1", 27 | "mocha": "^3.1.2", 28 | "mz": "^2.4.0", 29 | "node-sass": "^3.10.1", 30 | "npm-run-all": "^3.1.1", 31 | "postcss": "^5.2.5", 32 | "pre-commit": "^1.1.3", 33 | "sass-lint": "^1.9.1", 34 | "uglify-js": "^2.7.4" 35 | }, 36 | "scripts": { 37 | "assemble" : "./node_modules/assemble/bin/cli.js app", 38 | "browsersync": "node ./build/tasks/browser-sync.js", 39 | "clean" : "node ./build/tasks/clean.js", 40 | "concat" : "node ./build/tasks/concat.js", 41 | "copy" : "node ./build/tasks/copy.js", 42 | "jshint" : "./node_modules/jshint/bin/jshint assets/js/*.js --exclude assets/vendor/**/* --reporter=node_modules/jshint-stylish", 43 | "postcss" : "node ./build/tasks/postcss.js", 44 | "sass" : "node ./build/tasks/sass.js", 45 | "scsslint" : "./node_modules/sass-lint/bin/sass-lint.js -v", 46 | "test" : "node ./build/tasks/karma.js", 47 | "uglify" : "node ./build/tasks/uglify.js", 48 | 49 | "images" : "npm-run-all -s copy", 50 | "css" : "npm-run-all -s sass postcss", 51 | "js" : "npm-run-all -s concat uglify", 52 | 53 | "compile" : "npm-run-all -p scsslint jshint clean css js images", 54 | "build" : "npm-run-all -p compile assemble", 55 | "serve" : "npm-run-all -s build browsersync", 56 | 57 | "go" : "npm run browsersync", 58 | "ci" : "npm run compile" 59 | }, 60 | "pre-commit": [ 61 | "compile", "assemble", "test" 62 | ] 63 | } 64 | -------------------------------------------------------------------------------- /.sass-lint.yml: -------------------------------------------------------------------------------- 1 | files: 2 | include: 3 | - assets/**/*.scss 4 | ignore: 5 | - assets/vendor/**/*.scss 6 | 7 | options: 8 | formatter: stylish 9 | merge-default-rules: false 10 | 11 | rules: 12 | bem-depth: 13 | - 0 14 | - max-depth: 1 15 | border-zero: 16 | - 1 17 | - convention: '0' 18 | brace-style: 19 | - 1 20 | - allow-single-line: true 21 | class-name-format: 22 | - 1 23 | - convention: hyphenatedbem 24 | clean-import-paths: 25 | - 1 26 | - filename-extension: false 27 | leading-underscore: false 28 | empty-line-between-blocks: 29 | - 0 30 | - ignore-single-line-rulesets: true 31 | extends-before-declarations: 1 32 | extends-before-mixins: 1 33 | final-newline: 34 | - 1 35 | - include: false 36 | force-attribute-nesting: 1 37 | force-element-nesting: 1 38 | force-pseudo-nesting: 0 39 | function-name-format: 40 | - 1 41 | - allow-leading-underscore: true 42 | convention: hyphenatedlowercase 43 | hex-length: 44 | - 1 45 | - style: short 46 | hex-notation: 47 | - 0 48 | - style: lowercase 49 | id-name-format: 50 | - 0 51 | - convention: hyphenatedbem 52 | indentation: 53 | - 1 54 | - size: 2 55 | leading-zero: 56 | - 1 57 | - include: true 58 | mixin-name-format: 59 | - 1 60 | - allow-leading-underscore: true 61 | convention: hyphenatedlowercase 62 | mixins-before-declarations: 0 # disabled to allow declaration overrides via mixin (e.g. device-pixel-ratio()) 63 | nesting-depth: 64 | - 1 65 | - max-depth: 3 66 | no-color-keywords: 1 67 | no-color-literals: 1 68 | no-css-comments: 0 69 | no-debug: 1 70 | no-duplicate-properties: 1 71 | no-empty-rulesets: 1 72 | no-extends: 0 73 | no-ids: 0 74 | no-important: 0 75 | no-invalid-hex: 1 76 | no-mergeable-selectors: 1 77 | no-misspelled-properties: 78 | - 1 79 | - extra-properties: 80 | - interpolation-mode 81 | - touch-callout 82 | no-qualifying-elements: 83 | - 1 84 | - allow-element-with-attribute: false 85 | allow-element-with-class: false 86 | allow-element-with-id: false 87 | no-trailing-zero: 1 88 | no-transition-all: 0 89 | no-url-protocols: 1 90 | no-vendor-prefixes: 91 | - 0 92 | - additional-identifiers: [] 93 | excluded-identifiers: [] 94 | placeholder-in-extend: 0 95 | placeholder-name-format: 96 | - 1 97 | - convention: hyphenatedbem 98 | property-sort-order: 99 | - 0 100 | - ignore-custom-properties: false 101 | property-units: 102 | - 1 103 | - global: 104 | - ch 105 | - em 106 | - ex 107 | - rem 108 | - cm 109 | - in 110 | - mm 111 | - pc 112 | - pt 113 | - px 114 | - q 115 | - vh 116 | - vw 117 | - vmin 118 | - vmax 119 | - deg 120 | - grad 121 | - rad 122 | - turn 123 | - ms 124 | - s 125 | - Hz 126 | - kHz 127 | - dpi 128 | - dpcm 129 | - dppx 130 | - '%' 131 | per-property: {} 132 | quotes: 133 | - 1 134 | - style: single 135 | shorthand-values: 136 | - 1 137 | - allowed-shorthands: 138 | - 1 139 | - 2 140 | - 3 141 | - 4 142 | single-line-per-selector: 1 143 | space-after-bang: 144 | - 1 145 | - include: false 146 | space-after-colon: 147 | - 1 148 | - include: true 149 | space-after-comma: 150 | - 1 151 | - include: true 152 | space-before-bang: 153 | - 1 154 | - include: true 155 | space-before-brace: 156 | - 1 157 | - include: true 158 | space-before-colon: 0 159 | space-between-parens: 160 | - 1 161 | - include: false 162 | trailing-semicolon: 1 163 | url-quotes: 1 164 | variable-for-property: 165 | - 0 166 | - properties: [] 167 | variable-name-format: 168 | - 0 169 | - allow-leading-underscore: true 170 | convention: hyphenatedlowercase 171 | zero-unit: 1 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Noah 2 | 3 | > Noah is a boilerplate for compiling front-end web apps using NPM build scripts. 4 | 5 | - [Install](#install) 6 | - [Tasks](#tasks) 7 | - [Usage](#usage) 8 | - [Dependencies](#dependencies) 9 | 10 | ### Why NPM scripts? 11 | 12 | - Fewer dependencies (no need for Grunt/Gulp, and their respective task wrappers) 13 | - Speed (by the time you click from your text editor to your browser, your code has already been recompiled and injected into the browser) 14 | - ~~More~~ Total control over your build steps 15 | - Future proof (protect your project from time-travellers) 16 | 17 | ### Why Noah? 18 | 19 | > Compile, test and depoly code on the fly as you develop 20 | 21 | - Includes everything required to get going off the bat 22 | - Adaptable/scalable to suit your project 23 | - Built for the modern front-end developer 24 | - Favours API usage over CLI wrappers 25 | 26 | ### What's included? 27 | 28 | - CSS/Sass lint | autoprefix | compile 29 | - JS concatenate | uglify | lint | unit test 30 | - Assemble/Handlebars 31 | - Browsersync + watching & live reload 32 | - Git pre-commit hook - never commit bad code again 33 | - General tasks 34 | 35 | ### Install 36 | 37 | #### Requirements 38 | 39 | All plugins use pure Node.js bindings, so the only things required are: 40 | 41 | - Node.js 42 | - NPM 43 | 44 | > Noah is a boilerplate rather than a dependency, so you may wish to fork this repo for your starting point. Noah is still available as an npm package, however: 45 | 46 | ``` 47 | npm install noah-npm 48 | ``` 49 | 50 | ### Tasks 51 | 52 | #### Core Tasks 53 | 54 | | Task | Description | Execute | 55 | | ------------- | ----------------------------------------------- | ------------------- | 56 | | Assemble | Compile handlebars templates | npm run assemble | 57 | | Browsersync | Start a new server and watch JS/CSS files | npm run browsersync | 58 | | Clean | Clean/empty a directory | npm run clean | 59 | | Concat | Concatenate multiple files | npm run concat | 60 | | Copy | Copy files to a new location | npm run copy | 61 | | JS-lint | Lint JS files | npm run jshint | 62 | | Karma | Run JS unit tests | npm run test | 63 | | PostCSS | Run Autoprefixer | npm run postcss | 64 | | Sass | Compile Sass | npm run sass | 65 | | Sass-lint | Lint Sass files | npm run scsslint | 66 | | Uglify | Uglify JS files | npm run uglify | 67 | 68 | #### Asset Tasks 69 | 70 | | Task | Description | Execute | 71 | | ------------- | ----------------------------------------------- | ------------------- | 72 | | Images | Copy images to `dist` directory | npm run images | 73 | | CSS | Compile Sass and run Autoprefixer | npm run css | 74 | | JS | Concatenate and uglify JS files | npm run js | 75 | 76 | #### Combined Tasks 77 | 78 | Run specific tasks from above in a specific order 79 | 80 | | Task | Description | Execute | 81 | | ------------- | ---------------------------------------------------------------- | ------------------- | 82 | | Compile | Runs `scsslint`, `jshint`, `clean`, `css`, `js` & `images` tasks | npm run compile | 83 | | Build | Runs `compile` and `templates` tasks | npm run build | 84 | | Serve | Runs `build` and `browsersync` tasks | npm run serve | 85 | | Go | Short alias for `browsersync` task | npm run go | 86 | | CI | Reserved for continuous integration tools, e.g. Travis/Jenkins | npm run ci | 87 | 88 | ### Usage 89 | 90 | Most executable tasks have their own `.js` file * (found in the `/build/tasks/` directory) which is where your project specific details are passed for that task. Executing a task typically looks something like: 91 | 92 | ```js 93 | NOAH.task({ 94 | option : value 95 | }); 96 | ``` 97 | 98 | The corresponding entry in `package.json` would look something like: 99 | 100 | ```json 101 | "scripts": { 102 | "yourTask": "node ./build/tasks/task.js" 103 | } 104 | ``` 105 | 106 | And is executed from the command line by: 107 | 108 | ``` 109 | npm run yourTask 110 | ``` 111 | 112 | * Currently the `jshint` and `scsslint` tasks are executed via their CLI interface, as opposed to their API, pending future investigation. 113 | 114 | Each task has a default, basic-usage example, which will likely need to be modified for your project. Ensure you go through each task and check the options reflect your project's structure. For example, if your project requires two CSS files to be compiled, you may have something like this in your `/build/tasks/sass.js` file: 115 | 116 | ```js 117 | // Theme 118 | NOAH.sass({ 119 | src : 'assets/styles/themes/internal.scss', 120 | dest: 'public/styles/internal.css' 121 | }); 122 | 123 | // Print 124 | NOAH.sass({ 125 | src : 'assets/styles/themes/print.scss', 126 | dest: 'public/styles/print.css' 127 | }); 128 | ``` 129 | 130 | > No matter how many entries you have, they will all be executed when running `npm run sass` from the command line. 131 | 132 | ### Dependencies 133 | 134 | Noah installs the following NPM dependencies: 135 | 136 | ```json 137 | "dependencies": { 138 | "assemble" : "^0.17.1", 139 | "autoprefixer" : "^6.5.1", 140 | "browser-sync" : "^2.18.5", 141 | "chai" : "^3.5.0", 142 | "fs-extra" : "^0.30.0", 143 | "gulp-extname" : "^0.2.2", 144 | "handlebars" : "^4.0.5", 145 | "handlebars-helper-repeat": "^0.3.1", 146 | "handlebars-helpers" : "^0.7.5", 147 | "jshint" : "^2.9.4", 148 | "jshint-stylish" : "^2.2.1", 149 | "karma" : "^1.3.0", 150 | "karma-chai-plugins" : "^0.8.0", 151 | "karma-mocha" : "^1.2.0", 152 | "karma-mocha-reporter" : "^2.2.0", 153 | "karma-phantomjs-launcher": "^1.0.2", 154 | "mkdirp" : "^0.5.1", 155 | "mocha" : "^3.1.2", 156 | "mz" : "^2.4.0", 157 | "node-sass" : "^3.10.1", 158 | "npm-run-all" : "^3.1.1", 159 | "postcss" : "^5.2.5", 160 | "pre-commit" : "^1.1.3", 161 | "sass-lint" : "^1.9.1", 162 | "uglify-js" : "^2.7.4" 163 | } 164 | ``` 165 | 166 | ### Develop 167 | 168 | Whilst Noah comes with everything you might need to get going, you still may wish to expand upon the default tasks. Every new task will need its own `.js` task file configured, which, depending on the plugin, may or may not be simple to do. 169 | 170 | Noah comes with some useful additional tools to facilitate development of new tasks. 171 | 172 | ##### `file-paths.js` 173 | 174 | This helper module is used to get an array of files from a specified directory. 175 | 176 | ```js 177 | var filePaths = require('./file-paths').filePaths; 178 | var components = filePaths('assets/_js/components/'); // returns all files in this directory 179 | ``` --------------------------------------------------------------------------------