├── 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 |
--------------------------------------------------------------------------------
/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 | ```
--------------------------------------------------------------------------------