├── .editorconfig ├── .gitattributes ├── .gitignore ├── .jshintrc ├── .travis.yml ├── .yo-rc.json ├── README.md ├── app ├── index.js └── templates │ ├── _package.json │ ├── editorconfig │ ├── gitignore │ ├── index.html │ ├── jscsrc │ ├── jshintrc │ ├── src │ ├── css │ │ └── main.css │ └── js │ │ └── app.js │ └── webpack.config.js ├── package.json └── test └── test-app.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "esnext": true, 4 | "bitwise": true, 5 | "camelcase": true, 6 | "curly": true, 7 | "eqeqeq": true, 8 | "immed": true, 9 | "indent": 2, 10 | "latedef": true, 11 | "newcap": true, 12 | "noarg": true, 13 | "quotmark": "single", 14 | "undef": true, 15 | "unused": true, 16 | "strict": true 17 | } 18 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - '6' 5 | - '5' 6 | - '4' 7 | -------------------------------------------------------------------------------- /.yo-rc.json: -------------------------------------------------------------------------------- 1 | { 2 | "generator-generator": {} 3 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # generator-webpack-es6-cssnext [![Build Status](https://secure.travis-ci.org/ilkka/generator-webpack-es6-cssnext.png?branch=master)](https://travis-ci.org/ilkka/generator-webpack-es6-cssnext) [![Requirements Status](https://requires.io/github/ilkka/generator-webpack-es6-cssnext/requirements.svg?branch=master)](https://requires.io/github/ilkka/generator-webpack-es6-cssnext/requirements/?branch=master) 2 | 3 | > [Yeoman](http://yeoman.io) generator 4 | 5 | This generator gives you a project scaffold where [webpack](http://webpack.github.io/) is used for bundling. You can write next generation [CSS](https://cssnext.github.io/) and [JS](https://babeljs.io/) with impunity and it is all transpiled for you so that browser support doesn't suffer. 6 | 7 | ## Getting Started 8 | 9 | ### What is Yeoman? 10 | 11 | Trick question. It's not a thing. It's this guy: 12 | 13 | ![](http://i.imgur.com/JHaAlBJ.png) 14 | 15 | Basically, he wears a top hat, lives in your computer, and waits for you to tell him what kind of application you wish to create. 16 | 17 | Not every new computer comes with a Yeoman pre-installed. He lives in the [npm](https://npmjs.org) package repository. You only have to ask for him once, then he packs up and moves into your hard drive. *Make sure you clean up, he likes new and shiny things.* 18 | 19 | ```bash 20 | npm install -g yo 21 | ``` 22 | 23 | ### Yeoman Generators 24 | 25 | Yeoman travels light. He didn't pack any generators when he moved in. You can think of a generator like a plug-in. You get to choose what type of application you wish to create, such as a Backbone application or even a Chrome extension. 26 | 27 | To install generator-webpack-es6-cssnext from npm, run: 28 | 29 | ```bash 30 | npm install -g generator-webpack-es6-cssnext 31 | ``` 32 | 33 | Finally, initiate the generator: 34 | 35 | ```bash 36 | yo webpack-es6-cssnext 37 | ``` 38 | 39 | ### Getting To Know Yeoman 40 | 41 | Yeoman has a heart of gold. He's a person with feelings and opinions, but he's very easy to work with. If you think he's too opinionated, he can be easily convinced. 42 | 43 | If you'd like to get to know Yeoman better and meet some of his friends, [Grunt](http://gruntjs.com) and [Bower](http://bower.io), check out the complete [Getting Started Guide](https://github.com/yeoman/yeoman/wiki/Getting-Started). 44 | 45 | 46 | ## License 47 | 48 | MIT 49 | -------------------------------------------------------------------------------- /app/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var generators = require('yeoman-generator'); 3 | var chalk = require('chalk'); 4 | var yosay = require('yosay'); 5 | 6 | module.exports = generators.Base.extend({ 7 | constructor: function () { 8 | generators.Base.apply(this, arguments); 9 | }, 10 | 11 | prompting: function () { 12 | // Have Yeoman greet the user. 13 | this.log(yosay( 14 | 'Welcome to the ' + chalk.red('webpack-ws6-cssnext') + ' generator!' 15 | )); 16 | 17 | var prompts = [{ 18 | type : 'input', 19 | name : 'projectName', 20 | message : 'Project name', 21 | default : this.appname // Default to current folder name 22 | }, 23 | { 24 | type : 'input', 25 | name : 'projectDescription', 26 | message : 'Project description' 27 | }, 28 | { 29 | type : 'input', 30 | name : 'authorName', 31 | message : 'Author name' 32 | }, 33 | { 34 | type : 'input', 35 | name : 'authorEmail', 36 | message : 'Author email' 37 | }, 38 | { 39 | type : 'input', 40 | name : 'license', 41 | message : 'License' 42 | }]; 43 | 44 | return this.prompt(prompts) 45 | .then(function (answers) { 46 | this.props = answers; 47 | }.bind(this)); 48 | }, 49 | 50 | writing: function () { 51 | var projectFiles = [ 52 | {src: '_package.json', dst: 'package.json'}, 53 | {src: 'webpack.config.js', dst: 'webpack.config.js'}, 54 | {src: 'index.html', dst: 'index.html'}, 55 | {src: 'src/css/main.css', dst: 'src/css/main.css'}, 56 | {src: 'src/js/app.js', dst: 'src/js/app.js'} 57 | ]; 58 | var dotfiles = ['editorconfig', 'jshintrc', 'jscsrc', 'gitignore']; 59 | 60 | projectFiles.forEach(function (f) { 61 | this.fs.copyTpl(this.templatePath(f.src), this.destinationPath(f.dst), this.props); 62 | }.bind(this)); 63 | 64 | dotfiles.forEach(function (dotfile) { 65 | this.fs.copy(this.templatePath(dotfile), this.destinationPath('.' + dotfile)); 66 | }.bind(this)); 67 | }, 68 | 69 | install: function () { 70 | this.installDependencies(); 71 | }, 72 | 73 | end: function () { 74 | } 75 | }); 76 | -------------------------------------------------------------------------------- /app/templates/_package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= projectName %>", 3 | "version": "0.0.0", 4 | "description": "<%= projectDescription %>", 5 | "scripts": { 6 | "start": "webpack-dev-server", 7 | "build": "webpack", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "author": "<%= authorName %> <<%= authorEmail %>>", 11 | "license": "<%= license %>", 12 | "devDependencies": { 13 | "autoprefixer": "^6.3.6", 14 | "babel-core": "^6.7.7", 15 | "babel-loader": "^6.2.4", 16 | "colors": "^1.1.0", 17 | "css-loader": "^0.23.1", 18 | "csswring": "^4.2.2", 19 | "doiuse": "^2.3.0", 20 | "extract-text-webpack-plugin": "^1.0.1", 21 | "postcss-cssnext": "^2.5.2", 22 | "postcss-loader": "^0.8.2", 23 | "postcss-nested": "^1.0.0", 24 | "style-loader": "^0.13.1", 25 | "webpack": "^1.8.11", 26 | "webpack-dev-server": "^1.8.2", 27 | "wordwrap": "1.0.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/templates/editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /app/templates/gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git 27 | node_modules 28 | -------------------------------------------------------------------------------- /app/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <%= projectName %> 5 | 6 | 7 | 8 | 9 |
10 |

Welcome to <%= projectName %>!

11 |
12 |
13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/templates/jscsrc: -------------------------------------------------------------------------------- 1 | { 2 | "esnext": true, 3 | "preset": "airbnb", 4 | "validateIndentation": 2, 5 | "excludeFiles": ["node_modules/**"] 6 | } 7 | -------------------------------------------------------------------------------- /app/templates/jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "esnext": true, 4 | "bitwise": true, 5 | "camelcase": true, 6 | "curly": true, 7 | "eqeqeq": true, 8 | "immed": true, 9 | "indent": 2, 10 | "latedef": true, 11 | "newcap": true, 12 | "noarg": true, 13 | "quotmark": "single", 14 | "undef": true, 15 | "unused": true, 16 | "strict": true 17 | } 18 | -------------------------------------------------------------------------------- /app/templates/src/css/main.css: -------------------------------------------------------------------------------- 1 | /* cssnext: CSS variables */ 2 | :root { 3 | --mainColor: #ffbbaaff; 4 | } 5 | 6 | /* cssnext: custom media queries */ 7 | @custom-media --mobile (width <= 640px); 8 | 9 | /* cssnext: custom selectors */ 10 | @custom-selector :--heading h1, h2, h3, h4, h5, h6; 11 | 12 | /* Nesting via postcss-nested */ 13 | main { 14 | :--heading { 15 | text-rendering: optimizeLegibility; 16 | color: color( var(--mainColor) blackness(+20%) ); 17 | } 18 | } 19 | 20 | @media (--mobile) { 21 | :--heading { 22 | margin-top: 0; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/templates/src/js/app.js: -------------------------------------------------------------------------------- 1 | require('../css/main.css'); 2 | 3 | const WHO = 'JS'; 4 | let greeter = (who) => 'Hello from ' + who + '!'; 5 | 6 | document.getElementById('app').appendChild( 7 | document.createTextNode(greeter(WHO)) 8 | ); 9 | -------------------------------------------------------------------------------- /app/templates/webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var webpack = require('webpack'); 3 | var ExtractTextPlugin = require("extract-text-webpack-plugin"); 4 | 5 | var cssnext = require('postcss-cssnext'); 6 | var nested = require('postcss-nested'); 7 | var doiuse = require('doiuse'); 8 | var wordwrap = require('wordwrap'); 9 | 10 | var colors = require('colors'); 11 | 12 | var postCSSConfig = function(webpack) { 13 | return [ 14 | nested, 15 | cssnext(), 16 | doiuse({ 17 | onFeatureUsage: function(info) { 18 | var source = info.usage.source; 19 | // file is whole require path, joined with !'s.. we want the last part 20 | var sourceFile = path.relative('.', source.input.file.split('!').pop()) 21 | var sourceLine = sourceFile + ':' + source.start.line; 22 | // take out location info in message itself 23 | var message = info.message.split(': ').slice(1).join(': ') 24 | console.log('[doiuse]'.red + ' ' + sourceLine + ': ' + info.featureData.title + '\n'); 25 | console.log(wordwrap(4, process.stdout.columns - 1)(message) + '\n'); 26 | } 27 | }), 28 | ]; 29 | }; 30 | 31 | module.exports = { 32 | entry: { 33 | app: ['./src/js/app.js'] 34 | }, 35 | output: { 36 | path: require('path').resolve('build'), 37 | publicPath: '/', 38 | filename: 'bundle.js' 39 | }, 40 | module: { 41 | loaders: [ 42 | { 43 | test: /\.css$/, 44 | loader: ExtractTextPlugin.extract('css!postcss'), 45 | }, 46 | { 47 | test: /\.js$/, 48 | exclude: /node_modules/, 49 | loader: 'babel' 50 | } 51 | ] 52 | }, 53 | postcss: postCSSConfig, 54 | plugins: [ 55 | new ExtractTextPlugin('styles.css'), 56 | ], 57 | }; 58 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "generator-webpack-es6-cssnext", 3 | "version": "1.0.3", 4 | "description": "Yeoman generator", 5 | "license": "MIT", 6 | "main": "app/index.js", 7 | "repository": "https://github.com/ilkka/generator-webpack-es6-cssnext", 8 | "author": { 9 | "name": "Ilkka Laukkanen", 10 | "email": "ilkka@ilkka.io", 11 | "url": "https://github.com/ilkka" 12 | }, 13 | "scripts": { 14 | "test": "mocha" 15 | }, 16 | "files": [ 17 | "app" 18 | ], 19 | "keywords": [ 20 | "yeoman-generator" 21 | ], 22 | "dependencies": { 23 | "yeoman-generator": "0.24.1", 24 | "chalk": "1.1.3", 25 | "yosay": "1.1.1" 26 | }, 27 | "devDependencies": { 28 | "mocha": "3.0.2", 29 | "yeoman-assert": "^2.2.1", 30 | "yeoman-test": "^1.4.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /test/test-app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var path = require('path'); 4 | var assert = require('yeoman-assert'); 5 | var helpers = require('yeoman-test'); 6 | var os = require('os'); 7 | 8 | describe('webpack-es6-cssnext:app', function () { 9 | before(function () { 10 | return helpers.run(path.join(__dirname, '../app')) 11 | .withOptions({ skipInstall: true }) 12 | .withPrompts({ 13 | projectName: 'my-project', 14 | projectDescription: 'my project description', 15 | authorName: 'Ahto Simakuutio', 16 | authorEmail: 'ahto@example.com', 17 | license: 'Apache 2.0' 18 | }) 19 | .toPromise(); 20 | }); 21 | 22 | it('creates files', function () { 23 | assert.file([ 24 | 'package.json', 25 | '.editorconfig', 26 | '.jshintrc', 27 | '.jscsrc', 28 | '.gitignore', 29 | 'index.html', 30 | 'webpack.config.js', 31 | 'src/js/app.js', 32 | 'src/css/main.css' 33 | ]); 34 | }); 35 | 36 | it('templates metadata in package.json', function () { 37 | assert.fileContent([ 38 | ['package.json', /"name": "my-project",/], 39 | ['package.json', /"description": "my project description",/], 40 | ['package.json', /"author": "Ahto Simakuutio ",/], 41 | ['package.json', /"license": "Apache 2.0",/] 42 | ]); 43 | }) 44 | }); 45 | --------------------------------------------------------------------------------