├── app ├── templates │ ├── src │ │ ├── config │ │ │ └── config.js │ │ ├── assets.js │ │ ├── routes.js │ │ ├── styles │ │ │ └── external │ │ │ │ ├── ripples.min.css │ │ │ │ ├── roboto.min.css │ │ │ │ ├── ripples.css │ │ │ │ └── roboto.css │ │ ├── index.html │ │ ├── main.js │ │ └── components │ │ │ └── app.js │ ├── favicon.ico │ ├── mortar-logo.png │ ├── airbnb_rules_eslintrc │ ├── google_rules_eslintrc │ ├── README.md │ ├── gitignore │ ├── package.json │ ├── webpack.config.js │ └── mortar_rules_eslintrc └── index.js ├── .gitignore ├── .eslintrc ├── gulpfile.js ├── LICENSE.md ├── package.json ├── test └── app.js ├── README.md └── logo.svg /app/templates/src/config/config.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | coverage 3 | npm-debug.log 4 | -------------------------------------------------------------------------------- /app/templates/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ml-archive/generator-mortar/master/app/templates/favicon.ico -------------------------------------------------------------------------------- /app/templates/mortar-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ml-archive/generator-mortar/master/app/templates/mortar-logo.png -------------------------------------------------------------------------------- /app/templates/airbnb_rules_eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "node": true 5 | }, 6 | "extends": "airbnb" 7 | } -------------------------------------------------------------------------------- /app/templates/google_rules_eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "node": true 5 | }, 6 | "extends": "google" 7 | } -------------------------------------------------------------------------------- /app/templates/README.md: -------------------------------------------------------------------------------- 1 | ## Mortar Project Skeleton 2 | 3 | ### Development 4 | 1. Use `npm run serve` to run the development server and start building! 5 | -------------------------------------------------------------------------------- /app/templates/src/assets.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Styles 3 | * @type {exports}|string 4 | **/ 5 | require('bootstrap/dist/css/bootstrap.min.css'); 6 | require('./styles/external/material.css'); 7 | 8 | require('mortarjs/dist/styles/main.css'); -------------------------------------------------------------------------------- /app/templates/src/routes.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Route, IndexRoute} from 'react-router'; 3 | 4 | import App from './components/app'; 5 | 6 | const Routes = ( 7 | 8 | 9 | ); 10 | 11 | // 12 | // 13 | 14 | 15 | module.exports = Routes; -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "mocha": true, 4 | "es6": true, 5 | }, 6 | "ecmaFeatures": { 7 | "jsx": true, 8 | "arrowFunctions": true, 9 | "modules": true 10 | }, 11 | "plugins": [ 12 | "react" 13 | ], 14 | "rules": { 15 | "no-undef": 0, 16 | "comma-dangle": 1, 17 | "no-mixed-spaces-and-tabs": [2, "smart-tabs"], 18 | "no-console": 0, 19 | "no-unused-vars": 0, 20 | "no-extra-semi": 0, 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/templates/gitignore: -------------------------------------------------------------------------------- 1 | ### SublimeText ### 2 | *.sublime-workspace 3 | 4 | ### OSX ### 5 | .DS_Store 6 | .AppleDouble 7 | .LSOverride 8 | Icon 9 | .idea/ 10 | 11 | # Thumbnails 12 | ._* 13 | 14 | # Files that might appear on external disk 15 | .Spotlight-V100 16 | .Trashes 17 | 18 | ### Windows ### 19 | # Windows image file caches 20 | Thumbs.db 21 | ehthumbs.db 22 | 23 | # Folder config file 24 | Desktop.ini 25 | 26 | # Recycle Bin used on file shares 27 | $RECYCLE.BIN/ 28 | 29 | # Node specific 30 | node_modules/ 31 | npm-debug.log* 32 | *.npm 33 | *.log 34 | 35 | # Webpack compiled & packed javascript 36 | build.js 37 | build/.* 38 | 39 | # App specific 40 | .tmp 41 | dist 42 | src/config/base-config.js 43 | tags 44 | *-old/ 45 | -------------------------------------------------------------------------------- /app/templates/src/styles/external/ripples.min.css: -------------------------------------------------------------------------------- 1 | .withripple{position:relative}.ripple-wrapper{position:absolute;top:0;left:0;z-index:1;width:100%;height:100%;overflow:hidden;border-radius:inherit;pointer-events:none}.ripple{position:absolute;width:20px;height:20px;margin-left:-10px;margin-top:-10px;border-radius:100%;background-color:rgba(0,0,0,.05);-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);-webkit-transform-origin:50%;-ms-transform-origin:50%;transform-origin:50%;opacity:0;pointer-events:none}.ripple.ripple-on{transition:opacity .15s ease-in 0s,-webkit-transform .5s cubic-bezier(.4,0,.2,1) .1s;transition:opacity .15s ease-in 0s,transform .5s cubic-bezier(.4,0,.2,1) .1s;opacity:.1}.ripple.ripple-out{transition:opacity .1s linear 0s!important;opacity:0} 2 | /*# sourceMappingURL=ripples.min.css.map */ -------------------------------------------------------------------------------- /app/templates/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Mortar Project 11 | 12 | 13 | 14 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/templates/src/styles/external/roboto.min.css: -------------------------------------------------------------------------------- 1 | @font-face{font-family:RobotoDraft;src:local('RobotoDraft'),local('RobotoDraft-Regular'),local('Roboto-Regular'),url(../fonts/RobotoDraftRegular.woff2) format('woff2'),url(../fonts/RobotoDraftRegular.woff) format('woff')}@font-face{font-family:RobotoDraft;font-weight:500;src:local('RobotoDraft Medium'),local('RobotoDraft-Medium'),local('Roboto-Medium'),url(../fonts/RobotoDraftMedium.woff2) format('woff2'),url(../fonts/RobotoDraftMedium.woff) format('woff')}@font-face{font-family:RobotoDraft;font-weight:700;src:local('RobotoDraft Bold'),local('RobotoDraft-Bold'),local('Roboto-Bold'),url(../fonts/RobotoDraftBold.woff2) format('woff2'),url(../fonts/RobotoDraftBold.woff) format('woff')}@font-face{font-family:RobotoDraft;font-style:italic;src:local('RobotoDraft Italic'),local('RobotoDraft-Italic'),local('Roboto-Italic'),url(../fonts/RobotoDraftItalic.woff2) format('woff2'),url(../fonts/RobotoDraftItalic.woff) format('woff')} 2 | /*# sourceMappingURL=roboto.min.css.map */ -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var path = require('path'); 3 | var gulp = require('gulp'); 4 | var eslint = require('gulp-eslint'); 5 | var excludeGitignore = require('gulp-exclude-gitignore'); 6 | var mocha = require('gulp-mocha'); 7 | var istanbul = require('gulp-istanbul'); 8 | var nsp = require('gulp-nsp'); 9 | var plumber = require('gulp-plumber'); 10 | 11 | gulp.task('static', function () { 12 | return gulp.src('**/*.js') 13 | .pipe(excludeGitignore()) 14 | .pipe(eslint()) 15 | .pipe(eslint.format()) 16 | .pipe(eslint.failAfterError()); 17 | }); 18 | 19 | gulp.task('nsp', function (cb) { 20 | nsp({package: path.resolve('package.json')}, cb); 21 | }); 22 | 23 | gulp.task('test', function (cb) { 24 | var mochaErr; 25 | 26 | gulp.src('test/**/*.js') 27 | .pipe(plumber()) 28 | .pipe(mocha({reporter: 'spec'})) 29 | .on('error', function (err) { 30 | mochaErr = err; 31 | }) 32 | .pipe(istanbul.writeReports()) 33 | .on('end', function () { 34 | cb(mochaErr); 35 | }); 36 | }); 37 | 38 | gulp.task('prepublish', ['nsp']); 39 | gulp.task('default', ['static', 'test']); 40 | -------------------------------------------------------------------------------- /app/templates/src/main.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Packages 5 | * @type {exports} 6 | */ 7 | var React = require('react'); 8 | var reactDOM = require('react-dom'); 9 | // var config = require('./config/config'); 10 | 11 | import {Router, useRouterHistory} from 'react-router'; 12 | import {createHashHistory} from 'history'; 13 | 14 | const appHistory = useRouterHistory(createHashHistory)({ queryKey: false }); 15 | 16 | /** 17 | * Pull in application routes 18 | * 19 | * @type {Routes|exports} 20 | */ 21 | var Routes = require('./routes'); 22 | 23 | // Attach react router 24 | window.__app_container = document.getElementById('root'); 25 | 26 | reactDOM.render(( 27 |
28 | 29 |
30 | ), window.__app_container) 31 | 32 | /** 33 | * Pull in index.html! 34 | * 35 | * @type {exports} 36 | */ 37 | require('./index.html'); 38 | 39 | /** 40 | * Pull in css/scss/js file assets 41 | * 42 | * @type {exports} 43 | */ 44 | require('./assets'); 45 | 46 | /** 47 | * Pull in image assets 48 | * 49 | * @type {exports} 50 | */ 51 | // require('./public/favicon.ico'); 52 | -------------------------------------------------------------------------------- /app/templates/src/styles/external/ripples.css: -------------------------------------------------------------------------------- 1 | .withripple { 2 | position: relative; 3 | } 4 | .ripple-wrapper { 5 | position: absolute; 6 | top: 0; 7 | left: 0; 8 | z-index: 1; 9 | width: 100%; 10 | height: 100%; 11 | overflow: hidden; 12 | border-radius: inherit; 13 | pointer-events: none; 14 | } 15 | .ripple { 16 | position: absolute; 17 | width: 20px; 18 | height: 20px; 19 | margin-left: -10px; 20 | margin-top: -10px; 21 | border-radius: 100%; 22 | background-color: rgba(0, 0, 0, 0.05); 23 | -webkit-transform: scale(1); 24 | -ms-transform: scale(1); 25 | transform: scale(1); 26 | -webkit-transform-origin: 50%; 27 | -ms-transform-origin: 50%; 28 | transform-origin: 50%; 29 | opacity: 0; 30 | pointer-events: none; 31 | } 32 | .ripple.ripple-on { 33 | transition: opacity 0.15s ease-in 0s, -webkit-transform 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0.1s; 34 | transition: opacity 0.15s ease-in 0s, transform 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0.1s; 35 | opacity: 0.1; 36 | } 37 | .ripple.ripple-out { 38 | transition: opacity 0.1s linear 0s !important; 39 | opacity: 0; 40 | } 41 | /*# sourceMappingURL=ripples.css.map */ -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Fuzz Productions LLC 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /app/templates/src/styles/external/roboto.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'RobotoDraft'; 3 | font-style: normal; 4 | font-weight: 400; 5 | src: local('RobotoDraft'), local('RobotoDraft-Regular'), local('Roboto-Regular'), url(../fonts/RobotoDraftRegular.woff2) format('woff2'), url(../fonts/RobotoDraftRegular.woff) format('woff'); 6 | } 7 | @font-face { 8 | font-family: 'RobotoDraft'; 9 | font-style: normal; 10 | font-weight: 500; 11 | src: local('RobotoDraft Medium'), local('RobotoDraft-Medium'), local('Roboto-Medium'), url(../fonts/RobotoDraftMedium.woff2) format('woff2'), url(../fonts/RobotoDraftMedium.woff) format('woff'); 12 | } 13 | @font-face { 14 | font-family: 'RobotoDraft'; 15 | font-style: normal; 16 | font-weight: 700; 17 | src: local('RobotoDraft Bold'), local('RobotoDraft-Bold'), local('Roboto-Bold'), url(../fonts/RobotoDraftBold.woff2) format('woff2'), url(../fonts/RobotoDraftBold.woff) format('woff'); 18 | } 19 | @font-face { 20 | font-family: 'RobotoDraft'; 21 | font-style: italic; 22 | font-weight: 400; 23 | src: local('RobotoDraft Italic'), local('RobotoDraft-Italic'), local('Roboto-Italic'), url(../fonts/RobotoDraftItalic.woff2) format('woff2'), url(../fonts/RobotoDraftItalic.woff) format('woff'); 24 | } 25 | /*# sourceMappingURL=roboto.css.map */ -------------------------------------------------------------------------------- /app/templates/src/components/app.js: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | 3 | // Mortar 4 | var Mortar = require('mortarjs'); 5 | var Dispatcher = Mortar.Dispatcher; 6 | var Br = Mortar.require('components', 'Row', 'Column', 'Form'); 7 | var FormStore = Mortar.Stores.FormStore; 8 | var ResourceComponentMixin = Mortar.Mixins.ResourceComponentMixin; 9 | 10 | 11 | /** 12 | * Wrapper for the Mortar application 13 | * 14 | * @type {*|exports} 15 | */ 16 | module.exports = React.createClass({ 17 | mixins: [ResourceComponentMixin], 18 | 19 | getInitialState: function() { 20 | return { 21 | workingResource: { 22 | name: '' 23 | } 24 | }; 25 | }, 26 | 27 | formKey: 'main', 28 | 29 | componentDidMount: function() { 30 | this._componentDidMount(); 31 | }, 32 | 33 | componentWillUnmount: function() { 34 | this._componentWillUnmount(); 35 | }, 36 | 37 | pageConfig: function() { 38 | return { 39 | stores: [ 40 | { 41 | store : FormStore, 42 | changeListener : this.bindResource 43 | } 44 | ] 45 | }; 46 | }, 47 | 48 | bindResource: function() { 49 | this.setState({ 50 | workingResource: FormStore.getResource(this.formKey) 51 | }); 52 | }, 53 | 54 | render: function() { 55 | return ( 56 | 57 | 58 |
59 |

Welcome to Mortar! {this.state.workingResource.name}

60 | 61 | 62 | 63 |
64 |
65 |
66 | ); 67 | } 68 | }); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "generator-mortar", 3 | "preferGlobal": true, 4 | "version": "2.1.0", 5 | "description": "A Yeoman Generator for Mortar JS projects", 6 | "homepage": "https://github.com/fuzz-productions/generator-mortar", 7 | "author": { 8 | "name": "Fuzz Productions", 9 | "email": "web@fuzzproductions.com", 10 | "url": "https://fuzzproductions.com/" 11 | }, 12 | "contributors": [ 13 | { 14 | "name": "Kyle Mendes", 15 | "email": "kmendes@fuzzproductions.com" 16 | }, 17 | { 18 | "name": "Simon Yousoufov", 19 | "email": "syousoufov@fuzzproductions.com" 20 | }, 21 | { 22 | "name": "Lea Yousoufov", 23 | "email": "lyousoufov@fuzzproductions.com" 24 | }, 25 | { 26 | "name": "Walter Beller-Morales", 27 | "email": "wbellermorales@fuzzproductions.com" 28 | } 29 | ], 30 | "license": "MIT", 31 | "repository": "git@github.com:fuzz-productions/generator-mortar.git", 32 | "files": [ 33 | "app" 34 | ], 35 | "main": "app/index.js", 36 | "keywords": [ 37 | "yeoman-generator" 38 | ], 39 | "scripts": { 40 | "_prepublish": "gulp prepublish", 41 | "test": "gulp" 42 | }, 43 | "dependencies": { 44 | "chalk": "^1.1.1", 45 | "mkdirp": "^0.5.1", 46 | "yeoman-generator": "^0.20.2", 47 | "yosay": "^1.1.0" 48 | }, 49 | "devDependencies": { 50 | "eslint": "^1.10.3", 51 | "eslint-config-xo-space": "^0.7.0", 52 | "eslint-plugin-react": "^3.14.0", 53 | "gulp": "^3.9.0", 54 | "gulp-eslint": "^1.0.0", 55 | "gulp-exclude-gitignore": "^1.0.0", 56 | "gulp-istanbul": "^0.10.3", 57 | "gulp-mocha": "^2.0.0", 58 | "gulp-nsp": "^2.1.0", 59 | "gulp-plumber": "^1.0.0" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/templates/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= projectName %>", 3 | "description": "<%= projectDescription %>", 4 | "author": "<%= projectAuthor %>", 5 | "src": "src", 6 | "test": "test", 7 | "dist": "dist", 8 | "main": "main.js", 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1", 11 | "open": "open http://localhost:8080/webpack-dev-server/ && webpack-dev-server --progress --colors --watch --config ./webpack.config.js", 12 | "build": "webpack --progress --colors", 13 | "production": "webpack -production --progress --colors", 14 | "lint": "eslint src/", 15 | "test": "echo \"Error: no test specified\" && exit 1" 16 | }, 17 | "dependencies": { 18 | "bootstrap": "^3.3.6", 19 | "flux": "^2.1.1", 20 | "immutable": "^3.8.1", 21 | "history": "2.0.x", 22 | "mortarjs": "^2.0.0", 23 | "react": "^15.1.0", 24 | "react-dom": "^15.1.0", 25 | "react-router": "^2.2.4", 26 | "wheelbarrow": "*" 27 | }, 28 | "devDependencies": { 29 | "babel-core": "^6.10.4", 30 | "babel-loader": "^6.2.4", 31 | "babel-preset-es2015": "^6.9.0", 32 | "babel-preset-react": "^6.5.0", 33 | "clean-webpack-plugin": "^0.1.9", 34 | "css-loader": "^0.23.1", 35 | <% if (linting) { 36 | %>"eslint": "^1.10.3", 37 | "eslint-plugin-react": "^3.14.0",<% 38 | switch (lintingRules) { 39 | case "airbnb-linting": 40 | %>"eslint-config-airbnb": "*", 41 | "eslint-plugin-import": "*", 42 | "eslint-plugin-jsx-a11y": "*",<% 43 | break; 44 | case "google-linting": 45 | %>"eslint-config-google": "*",<% 46 | break; 47 | default: 48 | break; 49 | } 50 | } %> 51 | "file-loader": "^0.9.0", 52 | "node-sass": "^3.8.x", 53 | "sass-loader": "^3.1.2", 54 | "style-loader": "^0.13.1", 55 | "url-loader": "^0.5.7", 56 | "webpack": "^1.12.9", 57 | "webpack-dev-middleware": "^1.4.0", 58 | "webpack-dev-server": "^1.14.0" 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /test/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var path = require('path'); 3 | var assert = require('yeoman-assert'); 4 | var helpers = require('yeoman-generator').test; 5 | var fs = require('fs'); 6 | 7 | describe('generator-mortar with a basic scaffolding', function () { 8 | before(function (done) { 9 | helpers.run(path.join(__dirname, '../app')) 10 | .withPrompts({ projectName: 'test project' }) 11 | .withPrompts({ projectDescription: 'testing' }) 12 | .withPrompts({ projectAuthor: 'test bot' }) 13 | .withPrompts({ linting: true }) 14 | .withPrompts({ lintingRules: 'mortar-linting' }) 15 | .on('end', done); 16 | }); 17 | 18 | it('creates the basic directory structure', function () { 19 | assert.file([ 20 | 'src/', 21 | 'src/components', 22 | 'src/config/', 23 | 'src/styles', 24 | 'src/styles/external' 25 | ]); 26 | }); 27 | 28 | it('creates npm, webpack, linting, and git files', function () { 29 | assert.file([ 30 | 'package.json', 31 | 'webpack.config.js', 32 | '.gitignore', 33 | '.eslintrc' 34 | ]); 35 | }); 36 | 37 | it('uses the correct webpack.config.js content', function () { 38 | assert.fileContent( 39 | 'webpack.config.js', 40 | fs.readFileSync(path.join(__dirname, '../app/templates/webpack.config.js')).toString() 41 | ); 42 | }); 43 | 44 | it('uses the correct gitignore content', function () { 45 | assert.fileContent( 46 | '.gitignore', 47 | fs.readFileSync(path.join(__dirname, '../app/templates/gitignore')).toString() 48 | ); 49 | }); 50 | 51 | it('creates index.html', function () { 52 | assert.file([ 53 | 'src/index.html' 54 | ]); 55 | }); 56 | 57 | it('creates the basic src files', function () { 58 | assert.file([ 59 | 'src/assets.js', 60 | 'src/main.js', 61 | 'src/routes.js' 62 | ]); 63 | }); 64 | 65 | it('creates the basic components files', function () { 66 | assert.file([ 67 | 'src/components/app.js' 68 | ]); 69 | }); 70 | 71 | it('creates config files', function () { 72 | assert.file([ 73 | 'src/config/config.js' 74 | ]); 75 | }); 76 | 77 | it('uses the correct assets.js content', function () { 78 | assert.fileContent( 79 | 'src/assets.js', 80 | fs.readFileSync(path.join(__dirname, '../app/templates/src/assets.js')).toString() 81 | ); 82 | }); 83 | }); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Yeoman Generator for Mortar.js Projects [![Slack Status](https://fuzz-opensource.herokuapp.com/badge.svg)](https://fuzz-opensource.herokuapp.com/) 2 | 3 |

4 | 5 |

6 | 7 | 8 | [Mortar.js](http://mortarjs.io/) is an open source framework built with React that makes interacting and updating data quick, easy, and powerful. It can best be described as an Admin User Interface that allows developers to quickly and safely build sites to interface with an API without accessing the database directly. 9 | 10 | This generator makes it extremely easy to begin a React & Mortar project by taking care of the directory structure, installing dependencies, and the build process. The end result will allow you to build using React, JSX, ES6, and — of course — Mortar. 11 | 12 | 13 | ## Prerequisites 14 | - Yeoman and Gulp through `npm install -g yo gulp` 15 | 16 | ## Installation 17 | 1. Run `npm install -g generator-mortar` to install the generator. 18 | 2. Run `yo mortar` to start the generator. 19 | 3. Follow the command line prompts. You will have the option to include authentication if your application & API requires it. 20 | 4. Grab a cup of :coffee: and relax while the generators churns. 21 | 5. Scaffolding is done! Start the development server with `npm run open` ! 22 | 23 | ## Development 24 | 1. Clone this repository. 25 | 2. Run `npm install` to install generator dev dependencies. 26 | 3. Use `npm link` to install the mortar yeoman generator locally for testing. 27 | 4. Test suite is managed by gulp and executed with `npm test`. 28 | 29 | ## Mortar Project Directory Structure 30 | The end result of this yeoman generator will produce the following project structure: 31 | 32 | - `node_modules` Installed third party packages including [Mortar.js](http://mortarjs.io/). 33 | - `src` 34 | - `components` 35 | - `app.js` 36 | - `config` 37 | - `config.js` 38 | - `styles` 39 | - `external` 40 | - `assets.js` 41 | - `main.js` **Required entry point for Webpack** 42 | - `index.html` 43 | - `routes.js` 44 | - `.gitignore` Git ignore rules for Mortar.js projects. 45 | - `.eslintrc` Custom javascript hinting rules applied using ESLint. 46 | - `package.json` List of `npm` dependencies and commands to build / compile your application. 47 | - `README.md` 48 | - `webpack.config.js` Webpack bundler process to build and unify all javascript, css, sass, image, and font dependencies. 49 | -------------------------------------------------------------------------------- /logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 54 | 55 | -------------------------------------------------------------------------------- /app/templates/webpack.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /* 3 | * Webpack development server configuration 4 | * 5 | * This file is set up for serving the webpack-dev-server, which will watch for changes and recompile as required if 6 | * the subfolder /webpack-dev-server/ is visited. Visiting the root will not automatically reload. 7 | */ 8 | 9 | const webpack = require('webpack'); 10 | // path module used to resolve absolute paths 11 | const path = require('path'); 12 | // cleans the bundled directory between build 13 | const CleanWebpackPlugin = require('clean-webpack-plugin'); 14 | 15 | const PATHS = { 16 | app : path.join(__dirname, '/src'), 17 | main : path.join(__dirname, '/src/main.js'), 18 | output: path.join(__dirname, '/build') 19 | }; 20 | 21 | module.exports = { 22 | context: PATHS.app, 23 | entry : PATHS.main, 24 | output : { 25 | path : PATHS.output, 26 | filename: 'main.js' 27 | }, 28 | 29 | cache: true, 30 | stats: { 31 | colors : true, 32 | reasons: true 33 | }, 34 | 35 | resolve: { 36 | extensions: ['', '.js'], 37 | alias : { 38 | 'styles' : __dirname + '/src/styles', 39 | 'mixins' : __dirname + '/src/mixins', 40 | 'components': __dirname + '/src/components/' 41 | } 42 | }, 43 | 44 | module: { 45 | loaders: [ 46 | // compile all javascript files using the babel-loader module 47 | { 48 | test : /\.js$/, 49 | exclude: /node_modules/, 50 | loader : 'babel', 51 | query : { 52 | presets : ['es2015', 'react'], 53 | cacheDirectory: true 54 | } 55 | }, 56 | { 57 | test : /\.html$/, 58 | loader: 'file', 59 | query : { 60 | name: '[name].[ext]' 61 | } 62 | }, 63 | // compile sass files using the sass-loader module 64 | // stored in the compiled javascript file 65 | { 66 | test : /\.scss$/, 67 | loaders: ['style', 'css', 'sass'] 68 | }, 69 | // compile css files using the css-loader module 70 | // stored in the compiled javascript file 71 | { 72 | test : /\.css$/, 73 | loaders: ['style', 'css'] 74 | }, 75 | // compile local images 76 | // hash file names to prevent cacheing 77 | // copy into 'assets/img' sub-directory 78 | { 79 | test : /\.(png|jpg|gif|svg)$/, 80 | exclude: /node_modules/, 81 | loader : 'file', 82 | query : { 83 | name: 'assets/img/img-[hash:6].[ext]' 84 | } 85 | }, 86 | { 87 | test : /\.ico$/, 88 | exclude: /node_modules/, 89 | loader : 'file', 90 | query : { 91 | name: '[name].[ext]' 92 | } 93 | }, 94 | { 95 | test : /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, 96 | loader: 'url', 97 | query : { 98 | limit : 10000, 99 | minetype: 'application/font-woff', 100 | name : 'assets/fonts/[name].[ext]' 101 | } 102 | }, 103 | { 104 | test : /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, 105 | loader: 'url', 106 | query : { 107 | limit: 8192, 108 | name : 'assets/fonts/[name].[ext]' 109 | } 110 | } 111 | ] 112 | }, 113 | 114 | plugins: [ 115 | new CleanWebpackPlugin(['build'], { 116 | root : __dirname + '/', 117 | verbose: true 118 | }) 119 | ] 120 | 121 | }; -------------------------------------------------------------------------------- /app/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var yeoman = require('yeoman-generator'); 3 | var chalk = require('chalk'); 4 | var yosay = require('yosay'); 5 | var mkdirp = require('mkdirp'); 6 | 7 | module.exports = yeoman.generators.Base.extend({ 8 | prompting: function () { 9 | var done = this.async(); 10 | 11 | // Greeting 12 | this.log(yosay( 13 | 'Welcome to the the ' + chalk.red('Mortar.js') + ' generator!' 14 | )); 15 | 16 | // Information requested from CLI 17 | var prompts = [ 18 | // Application name 19 | { 20 | type : 'input', 21 | name : 'projectName', 22 | message : 'Name of this project:', 23 | default : 'My Mortar Project' 24 | }, 25 | 26 | // Application description 27 | { 28 | type : 'input', 29 | name : 'projectDescription', 30 | message : 'Short description:', 31 | default : 'My CMS' 32 | }, 33 | 34 | // Application author 35 | { 36 | type : 'input', 37 | name : 'projectAuthor', 38 | message : 'Author or creator:', 39 | default : 'Mordecai Rigby' 40 | }, 41 | // Linting 42 | { 43 | type : 'confirm', 44 | name : 'linting', 45 | message : 'Would you like to use ESLint in your project?', 46 | default : true 47 | }, 48 | { 49 | type : 'list', 50 | name : 'lintingRules', 51 | message : 'Which ESLint rules would you like to use?', 52 | when: function (answers) { 53 | return answers.linting; 54 | }, 55 | choices: [ 56 | { 57 | name: "Mortar .eslintrc", 58 | value: "mortar-linting" 59 | }, 60 | { 61 | name: "Airbnb .eslintrc", 62 | value: "airbnb-linting" 63 | }, 64 | { 65 | name: "Google .eslintrc", 66 | value: "google-linting" 67 | } 68 | ] 69 | } 70 | ]; 71 | 72 | // Collect information through the command promp 73 | // input can be retrived through `this.props.{prompName}` 74 | this.prompt(prompts, function (props) { 75 | this.props = props; 76 | done(); 77 | }.bind(this)); 78 | }, 79 | writing: { 80 | // Copy the configuration files to app root directory 81 | copyProjectConfig: function () { 82 | // Copy package.json 83 | this.fs.copyTpl( 84 | this.templatePath('package.json'), 85 | this.destinationPath('package.json'), { 86 | projectName: this.props.projectName.toLowerCase() 87 | .replace(/[^\w ]+/g, '') 88 | .replace(/ +/g, '-'), 89 | 90 | projectDescription: this.props.projectDescription, 91 | projectAuthor: this.props.projectAuthor, 92 | linting: this.props.linting, 93 | lintingRules: this.props.lintingRules 94 | } 95 | ); 96 | 97 | // Copy webpack.config.js 98 | this.fs.copy( this.templatePath('webpack.config.js'), this.destinationPath('webpack.config.js') ); 99 | 100 | // Copy .gitignore 101 | this.fs.copy( this.templatePath('gitignore'), this.destinationPath('.gitignore') ); 102 | 103 | // Copy .eslintrc 104 | if (this.props.linting) { 105 | switch (this.props.lintingRules) { 106 | case "mortar-linting": 107 | this.fs.copy( this.templatePath('mortar_rules_eslintrc'), this.destinationPath('.eslintrc') ); 108 | break; 109 | case "airbnb-linting": 110 | this.fs.copy( this.templatePath('airbnb_rules_eslintrc'), this.destinationPath('.eslintrc') ); 111 | break; 112 | case "google-linting": 113 | this.fs.copy( this.templatePath('google_rules_eslintrc'), this.destinationPath('.eslintrc') ); 114 | break; 115 | default: 116 | this.fs.copy( this.templatePath('mortar_rules_eslintrc'), this.destinationPath('.eslintrc') ); 117 | } 118 | 119 | } 120 | 121 | // Copy README 122 | this.fs.copy( this.templatePath('README.md'), this.destinationPath('README.md') ); 123 | 124 | // Copy favicon 125 | this.fs.copy( this.templatePath('favicon.ico'), this.destinationPath('favicon.ico') ); 126 | 127 | // Copy Mortar logo 128 | this.fs.copy( this.templatePath('mortar-logo.png'), this.destinationPath('mortar-logo.png') ); 129 | 130 | }, 131 | // Create app directory structure 132 | scaffoldFolders: function () { 133 | mkdirp.sync('src'); 134 | mkdirp.sync('src/components'); 135 | mkdirp.sync('src/config'); 136 | mkdirp.sync('src/styles/external'); 137 | }, 138 | // Copy scaffolding files 139 | copyMain: function () { 140 | // Copy files to /src directory 141 | this.fs.copyTpl( 142 | this.templatePath('src/index.html'), 143 | this.destinationPath('src/index.html') 144 | ); 145 | this.fs.copyTpl( 146 | this.templatePath('src/assets.js'), 147 | this.destinationPath('src/assets.js') 148 | ); 149 | this.fs.copyTpl( 150 | this.templatePath('src/main.js'), 151 | this.destinationPath('src/main.js') 152 | ); 153 | this.fs.copyTpl( 154 | this.templatePath('src/routes.js'), 155 | this.destinationPath('src/routes.js') 156 | ); 157 | }, 158 | copyComponents: function() { 159 | this.fs.copy( 160 | this.templatePath('src/components/app.js'), 161 | this.destinationPath('src/components/app.js') 162 | ); 163 | }, 164 | copyAppConfig: function() { 165 | this.fs.copy( 166 | this.templatePath('src/config/config.js'), 167 | this.destinationPath('src/config/config.js') 168 | ); 169 | }, 170 | copyStyles: function() { 171 | // Copy files to /src/styles directory 172 | this.fs.copyTpl( 173 | this.templatePath('src/styles/external/material-fullpalette.css'), 174 | this.destinationPath('src/styles/external/material-fullpalette.css') 175 | ); 176 | this.fs.copyTpl( 177 | this.templatePath('src/styles/external/material-fullpalette.min.css'), 178 | this.destinationPath('src/styles/external/material-fullpalette.min.css') 179 | ); 180 | this.fs.copyTpl( 181 | this.templatePath('src/styles/external/material.css'), 182 | this.destinationPath('src/styles/external/material.css') 183 | ); 184 | this.fs.copyTpl( 185 | this.templatePath('src/styles/external/material.min.css'), 186 | this.destinationPath('src/styles/external/material.min.css') 187 | ); 188 | this.fs.copyTpl( 189 | this.templatePath('src/styles/external/ripples.css'), 190 | this.destinationPath('src/styles/external/ripples.css') 191 | ); 192 | this.fs.copyTpl( 193 | this.templatePath('src/styles/external/ripples.min.css'), 194 | this.destinationPath('src/styles/external/ripples.min.css') 195 | ); 196 | this.fs.copyTpl( 197 | this.templatePath('src/styles/external/roboto.css'), 198 | this.destinationPath('src/styles/external/roboto.css') 199 | ); 200 | this.fs.copyTpl( 201 | this.templatePath('src/styles/external/roboto.min.css'), 202 | this.destinationPath('src/styles/external/roboto.min.css') 203 | ); 204 | } 205 | }, 206 | // Install app dependencies 207 | install: function () { 208 | this.installDependencies({ 209 | bower: false, 210 | npm: true 211 | }); 212 | } 213 | }); 214 | -------------------------------------------------------------------------------- /app/templates/mortar_rules_eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, // browser global variables. 4 | "es6": true, // enable all ES6 features 5 | "node": true, // Node.js global variables and Node.js-specific rules. 6 | "amd": true, // defines require() and define() as global variables as per the amd spec. 7 | "mocha": true, // adds all of the Mocha testing global variables. 8 | "jasmine": false, // adds all of the Jasmine testing global variables for version 1.3 and 2.0. 9 | "phantomjs": false, // phantomjs global variables. 10 | "jquery": false, // jquery global variables. 11 | "prototypejs": false, // prototypejs global variables. 12 | "shelljs": false, // shelljs global variables. 13 | }, 14 | 15 | "globals": { 16 | 17 | }, 18 | 19 | "plugins": [ 20 | "react" 21 | ], 22 | "extends": ["eslint:recommended", "plugin:react/recommended"], 23 | 24 | "rules": { 25 | "comma-dangle": [2, "never"], // disallow trailing commas in object literals 26 | "no-cond-assign": 1, // disallow assignment in conditional expressions 27 | "no-constant-condition": 0, // disallow use of constant expressions in conditions 28 | "no-control-regex": 0, // disallow control characters in regular expressions 29 | "no-debugger": 1, // disallow use of debugger 30 | "no-dupe-args": 2, // disallow duplicate arguments with the same name 31 | "no-dupe-keys": 2, // disallow duplicate keys when creating object literals 32 | "no-duplicate-case": 2, // disallow duplicate caste labels in switch statements 33 | "no-empty": 1, // disallow empty statements 34 | "no-ex-assign": 2, // disallow assigning to the exception in a catch block 35 | "no-extra-boolean-cast": 0, // disallow double-negation boolean casts in a boolean context 36 | "no-extra-parens": 1, // disallow unnecessary parentheses (off by default) 37 | "no-extra-semi": 2, // disallow unnecessary semicolons 38 | "no-func-assign": 1, // disallow overwriting functions written as function declarations 39 | "no-inner-declarations": 1, // disallow function or variable declarations in nested blocks 40 | "no-invalid-regexp": 1, // disallow invalid regular expression strings in the RegExp constructor 41 | "no-irregular-whitespace": 2, // disallow irregular whitespace outside of strings and comments 42 | "no-negated-in-lhs": 1, // disallow negation of the left operand of an in expression 43 | "no-obj-calls": 1, // disallow the use of object properties of the global object (Math and JSON) as functions 44 | "no-regex-spaces": 1, // disallow multiple spaces in a regular expression literal 45 | "no-sparse-arrays": 1, // disallow sparse arrays 46 | "no-unreachable": 2, // disallow unreachable statements after a return, throw, continue, or break statement 47 | "use-isnan": 2, // disallow comparisons with the value NaN 48 | "valid-typeof": 2, // Ensure that the results of typeof are compared against a valid string 49 | 50 | "array-callback-return": 1, // Ensure array functions return where expected 51 | "block-scoped-var": 1, // treat var statements as if they were block scoped (off by default) 52 | "complexity": 1, // specify the maximum cyclomatic complexity allowed in a program (default of 20, off by default) 53 | "consistent-return": 1, // require return statements to either always or never specify values 54 | "curly": 1, // specify curly brace conventions for all control statements 55 | "default-case": 2, // require default case in switch statements (off by default) 56 | "dot-location": 2, // when seperating dot member expressions with newlines, dot should be on the newline 57 | "dot-notation": 1, // encourages use of dot notation whenever possible 58 | "eqeqeq": 1, // require the use of === and !== 59 | "guard-for-in": 1, // make sure for-in loops have an if statement (off by default) 60 | "no-alert": 2, // disallow the use of alert, confirm, and prompt 61 | "no-caller": 1, // disallow use of arguments.caller or arguments.callee 62 | "no-div-regex": 0, // disallow division operators explicitly at beginning of regular expression (off by default) 63 | "no-else-return": 1, // disallow else after a return in an if (off by default) 64 | "no-eq-null": 1, // disallow comparisons to null without a type-checking operator (off by default) 65 | "no-eval": 1, // disallow use of eval() 66 | "no-extend-native": 2, // disallow adding to native types 67 | "no-extra-bind": 2, // disallow unnecessary function binding 68 | "no-fallthrough": 2, // disallow fallthrough of case statements 69 | "no-floating-decimal": 0, // disallow the use of leading or trailing decimal points in numeric literals (off by default) 70 | "no-implied-eval": 0, // disallow use of eval()-like methods 71 | "no-iterator": 2, // disallow usage of __iterator__ property 72 | "no-labels": 2, // disallow use of labeled statements 73 | "no-lone-blocks": 1, // disallow unnecessary nested blocks 74 | "no-loop-func": 2, // disallow creation of functions within loops 75 | "no-multi-spaces": 0, // disallow use of multiple spaces 76 | "no-multi-str": 0, // disallow use of multiline strings 77 | "no-native-reassign": 2, // disallow reassignments of native objects 78 | "no-new": 0, // disallow use of new operator when not part of the assignment or comparison 79 | "no-new-func": 0, // disallow use of new operator for Function object 80 | "no-new-wrappers": 0, // disallows creating new instances of String, Number, and Boolean 81 | "no-octal": 0, // disallow use of octal literals 82 | "no-octal-escape": 0, // disallow use of octal escape sequences in string literals, such as var foo = "Copyright \251"; 83 | "no-process-env": 0, // disallow use of process.env (off by default) 84 | "no-proto": 1, // disallow usage of __proto__ property 85 | "no-redeclare": 1, // disallow declaring the same variable more then once 86 | "no-return-assign": 1, // disallow use of assignment in return statement 87 | "no-script-url": 0, // disallow use of javascript: urls. 88 | "no-self-compare": 1, // disallow comparisons where both sides are exactly the same (off by default) 89 | "no-sequences": 0, // disallow use of comma operator 90 | "no-unused-expressions": 0, // disallow usage of expressions in statement position 91 | "no-void": 0, // disallow use of void operator (off by default) 92 | "no-warning-comments": 0, // disallow usage of configurable warning terms in comments, e.g. TODO or FIXME (off by default) 93 | "no-with": 0, // disallow use of the with statement 94 | "radix": 0, // require use of the second argument for parseInt() (off by default) 95 | "require-jsdoc": [1, { 96 | "require": { 97 | "FunctionDeclaration": true, 98 | "MethodDefinition": true, 99 | "ClassDeclaration": false 100 | } 101 | }], // require JSDoc comments for all function declarations 102 | "valid-jsdoc": [1, { 103 | "requireReturnDescription": false, 104 | "requireParamDescription": true, 105 | "prefer": { 106 | "return": "return" 107 | } 108 | }], // Ensure JSDoc comments are valid (off by default) 109 | "vars-on-top": 0, // requires to declare all vars on top of their containing scope (off by default) 110 | "wrap-iife": 0, // require immediate function invocation to be wrapped in parentheses (off by default) 111 | "yoda": 1, // require or disallow Yoda conditions 112 | 113 | ////////// Variables ////////// 114 | 115 | "no-catch-shadow": 0, // disallow the catch clause parameter name being the same as a variable in the outer scope (off by default in the node environment) 116 | "no-delete-var": 0, // disallow deletion of variables 117 | "no-label-var": 0, // disallow labels that share a name with a variable 118 | "no-shadow": 1, // disallow declaration of variables already declared in the outer scope 119 | "no-shadow-restricted-names": 1, // disallow shadowing of names such as arguments 120 | "no-undef": 1, // disallow use of undeclared variables unless mentioned in a /*global */ block 121 | "no-undef-init": 1, // disallow use of undefined when initializing variables 122 | "no-undefined": 1, // disallow use of undefined variable (off by default) 123 | "no-unused-vars": 1, // disallow declaration of variables that are not used in the code 124 | "no-use-before-define": 2, // disallow use of variables before they are defined 125 | 126 | 127 | ////////// Node.js ////////// 128 | 129 | "handle-callback-err": 0, // enforces error handling in callbacks (off by default) (on by default in the node environment) 130 | "no-mixed-requires": 1, // disallow mixing regular variable and require declarations (off by default) (on by default in the node environment) 131 | "no-new-require": 0, // disallow use of new operator with the require function (off by default) (on by default in the node environment) 132 | "no-path-concat": 0, // disallow string concatenation with __dirname and __filename (off by default) (on by default in the node environment) 133 | "no-process-exit": 0, // disallow process.exit() (on by default in the node environment) 134 | "no-restricted-modules": 0, // restrict usage of specified node modules (off by default) 135 | "no-sync": 0, // disallow use of synchronous methods (off by default) 136 | 137 | 138 | ////////// Stylistic Issues ////////// 139 | 140 | "brace-style": 1, // enforce one true brace style (off by default) 141 | "camelcase": 1, // require camel case names 142 | "comma-spacing": 1, // enforce spacing before and after comma 143 | "comma-style": [1, "last"], // enforce one true comma style (off by default) 144 | "consistent-this": [2, "self"], // enforces consistent naming when capturing the current execution context (off by default) 145 | "eol-last": 1, // enforce newline at the end of file, with no multiple empty lines 146 | "func-names": 0, // require function expressions to have a name (off by default) 147 | "func-style": 0, // enforces use of function declarations or expressions (off by default) 148 | "indent": [2, "tab", { // newlines should be indented with tabs 149 | "SwitchCase": 1 150 | }], 151 | "key-spacing": [1, { // enforces spacing between keys and values in object literal properties, keys align on colon 152 | "singleLine": { 153 | "beforeColon": false, 154 | "afterColon": true 155 | }, 156 | "multiLine": { 157 | "align": "colon", // Enforces that objects align on the colon. Breaks for the longest object. 158 | "mode": "minimum" 159 | } 160 | }], 161 | "keyword-spacing": 2, // require a space after keywords 162 | "max-nested-callbacks": 1, // specify the maximum depth callbacks can be nested (off by default) 163 | "new-cap": 1, // require a capital letter for constructors 164 | "new-parens": 0, // disallow the omission of parentheses when invoking a constructor with no arguments 165 | "no-array-constructor": 0, // disallow use of the Array constructor 166 | "no-inline-comments": 0, // disallow comments inline after code (off by default) 167 | "no-lonely-if": 1, // disallow if as the only statement in an else block (off by default) 168 | "no-mixed-spaces-and-tabs": [1, "smart-tabs"], // disallow mixed spaces and tabs for indentation 169 | "no-multiple-empty-lines": 1, // disallow multiple empty lines (off by default) 170 | "no-nested-ternary": 1, // disallow nested ternary expressions (off by default) 171 | "no-new-object": 0, // disallow use of the Object constructor 172 | "semi-spacing": 1, // disallow space before semicolon 173 | "no-spaced-func": 1, // disallow space between function identifier and application 174 | "no-ternary": 0, // disallow the use of ternary operators (off by default) 175 | "no-trailing-spaces": 2, // disallow trailing whitespace at the end of lines 176 | "no-underscore-dangle": 0, // disallow dangling underscores in identifiers 177 | "no-wrap-func": 0, // disallow wrapping of non-IIFE statements in parens 178 | "one-var": 0, // allow just one var statement per function (off by default) 179 | "operator-assignment": 0, // require assignment operator shorthand where possible or prohibit it entirely (off by default) 180 | "padded-blocks": 0, // enforce padding within blocks (off by default) 181 | "quote-props": 0, // require quotes around object literal property names (off by default) 182 | "quotes": 0, // specify whether double or single quotes should be used 183 | "semi": 1, // require or disallow use of semicolons instead of ASI 184 | "sort-vars": 0, // sort variables within the same declaration block (off by default) 185 | "space-before-blocks": 1, // require or disallow space before blocks (off by default) 186 | "space-in-parens": 1, // require or disallow spaces inside parentheses (off by default) 187 | "space-infix-ops": 1, // require spaces around operators 188 | "space-unary-ops": [0, // Require or disallow spaces before/after unary operators (words on by default, nonwords off by default) 189 | { 190 | words: true, 191 | nonwords: false, 192 | /* { overrides: { */ 193 | /* "!", true */ 194 | /* }} */ 195 | } 196 | ], 197 | "spaced-line-comment": 0, // require or disallow a space immediately following the // in a line comment (off by default) 198 | "wrap-regex": 0, // require regex literals to be wrapped in parentheses (off by default) 199 | 200 | 201 | ////////// Legacy ////////// 202 | 203 | "max-depth": 0, // specify the maximum depth that blocks can be nested (off by default) 204 | "max-len": 0, // specify the maximum length of a line in your program (off by default) 205 | "max-params": 0, // limits the number of parameters that can be used in the function declaration. (off by default) 206 | "max-statements": 0, // specify the maximum number of statement allowed in a function (off by default) 207 | "no-bitwise": 0, // disallow use of bitwise operators (off by default) 208 | "no-plusplus": 0 // disallow use of unary operators, ++ and -- (off by default) 209 | }, 210 | 211 | ////////// ECMAScript 6 ////////// 212 | "parserOptions": { 213 | "ecmaVersion": 6, 214 | "sourceType": "module", 215 | "ecmaFeatures": { 216 | "modules": true, 217 | "jsx": true 218 | }, 219 | }, 220 | } --------------------------------------------------------------------------------