diff --git a/.eslintrc b/.eslintrc
new file mode 100644
index 0000000..e7822e5
--- /dev/null
+++ b/.eslintrc
@@ -0,0 +1,22 @@
+{
+ "env": {
+ "browser": false,
+ "amd": false,
+ "es6": true,
+ "node": true,
+ "mocha": true
+ },
+ "rules": {
+ "comma-dangle": 1,
+ "quotes": [ 1, "single" ],
+ "no-undef": 1,
+ "global-strict": 0,
+ "no-extra-semi": 1,
+ "no-underscore-dangle": 0,
+ "no-console": 0,
+ "no-unused-vars": 1,
+ "no-trailing-spaces": [1, { "skipBlankLines": true }],
+ "no-unreachable": 1,
+ "no-alert": 0
+ }
+}
diff --git a/.gitignore b/.gitignore
index 17d340a..7e8a112 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,4 +13,3 @@ $RECYCLE.BIN/
node_modules/
npm-debug.log
.idea/
-/test/temp-test
diff --git a/.jshintrc b/.jshintrc
deleted file mode 100644
index da64b6e..0000000
--- a/.jshintrc
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "node": true,
- "esnext": true,
- "bitwise": true,
- "camelcase": true,
- "curly": true,
- "eqeqeq": true,
- "immed": true,
- "indent": 2,
- "latedef": true,
- "newcap": true,
- "noarg": true,
- "quotmark": "single",
- "regexp": true,
- "undef": true,
- "unused": true,
- "strict": true,
- "trailing": true,
- "smarttabs": true,
- "white": true
-}
diff --git a/README.md b/README.md
index 88b7e58..a763b10 100644
--- a/README.md
+++ b/README.md
@@ -1,359 +1,76 @@
-# generator-react-webpack [](https://travis-ci.org/newtriks/generator-react-webpack) [](http://gruntjs.com/)
+# generator-react-webpack V2.0 [](https://travis-ci.org/newtriks/generator-react-webpack) [](http://gruntjs.com/)
> Yeoman generator for [ReactJS](http://facebook.github.io/react/) - lets you quickly set up a project including karma test runner and [Webpack](http://webpack.github.io/) module system.
+# About
+Generator-React-Webpack will help you build new Reactprojects using modern technologies.
-## Usage
+Out of the box it comes with support for:
+- Webpack
+- ES2015 via Babel-Loader
+- Different supported style languages (sass, scss, less, stylus)
+- Automatic code linting via esLint
+- Ability to unit test components via Karma and Mocha/Chai
-Install `generator-react-webpack`:
-```
-npm install -g generator-react-webpack
-```
+## Subgenerators
+This generator is also the base project for some other generators that depend on it:
+### Generator-React-Webpack-Alt
+(https://github.com/weblogixx/generator-react-webpack-alt)
+Generator based on generator-react-webpack, providing support for Alt.js.
-Make a new directory, and `cd` into it:
-```
-mkdir my-new-project && cd $_
-```
+---
-Run `yo react-webpack`, optionally passing an app name:
-```
-yo react-webpack [app-name]
-```
-
-Run `grunt build` for building and `grunt serve` for preview in the browser at [localhost](http://localhost:8000).
-
-## Generators
-
-Available generators:
-
-* [react-webpack](#app) (aka [react-webpack:app](#app))
-* [react-webpack:component](#component)
-
-and for **Flux** or **Reflux** :
-* [react-webpack:action](#action)
-* [react-webpack:store](#store)
-
-
-### App
-
-Sets up a new ReactJS app, generating all the boilerplate you need to get started. The app generator also facilitates the following:
-
-1. Configures a Gruntfile to run the app on a local server.
-2. Configures Webpack to modularise the app enabling [loading of various file formats](http://webpack.github.io/docs/loader-list.html) e.g. JSON, CSS, PNG, etc.
-3. Configures [Karma](http://karma-runner.github.io) to run all tests.
-4. Watches for changes and recompiles JS and refreshes the browser.
-
-Example:
+## Installation
```bash
+npm install -g yo
+npm install generator-react-webpack
+```
+
+## Setting up projects
+```bash
+# Create a new directory, and `cd` into it:
+mkdir my-new-project && cd my-new-project
+
+# Run the generator
yo react-webpack
```
-### Component
+Please make sure to edit your newly generated `package.json` file to set description, author information and the like.
-Generates a [JSX](http://facebook.github.io/react/docs/jsx-in-depth.html) component in `src/components`, its corresponding test in `test/spec/components` and its style in `src/styles`.
-
-Example:
+## Generating new components
```bash
-yo react-webpack:component foo //or just: yo react-webpack:c foo
+# After setup of course :)
+# cd my-new-project
+yo react-webpack:component my/namespaced/components/name
```
-Produces `src/components/Foo.js` (*javascript - JSX*):
-```js
-'use strict';
+The above command will create a new component, as well as its stylesheet and a basic testcase.
-var React = require('react/addons');
-
-require('styles/componentName.css'); //or .sass,.less etc...
-
-var Foo = React.createClass({
- render: function () {
- return (
-
-
Content for Foo
-
- )
- }
-});
-
-module.exports = Foo;
-```
-
-And `test/spec/components/Foo.js` (*javascript - jasmine, as seen on http://simonsmith.io/unit-testing-react-components-without-a-dom/*):
-```js
-'use strict';
-
-// Uncomment the following lines to use the react test utilities
-// import React from 'react/addons';
-// const TestUtils = React.addons.TestUtils;
-
-import createComponent from 'helpers/createComponent';
-import Foo from 'components/Foo.js';
-
-describe('Foo', () => {
-
- let FooComponent;
-
- beforeEach(() => {
- FooComponent = createComponent(Foo);
- });
-
- it('should have its component name as default className', () => {
- expect(FooComponent._store.props.className).toBe('Foo');
- });
-});
-```
-
-And `src/styles/Foo.css` (or .sass, .less etc...) :
-```css
-.Foo {
- border: 1px dashed #f00;
-}
-```
-
-### rich flag
-
-For all you lazy programmers out there, we've added another shortcut - `rich` flag:
+## Usage
+The following commands are available in your project:
```bash
-yo react-webpack:c foofoo --rich
+# Start for development
+npm start # or
+npm run serve
+
+# Start the dev-server with the dist version
+npm run serve:dist
+
+# Just build the dist version and copy static files
+npm run dist
+
+# Run unit tests
+npm test
+
+# Lint all files in src (also automatically done AFTER tests are run)
+npm run lint
+
+# Clean up the dist directory
+npm run clean
+
+# Just copy the static assets
+npm run copy
```
-This will give you all of react component's most common stuff :
- ```js
- var React = require('react/addons');
-
- require('styles/Foofoo.sass');
-
- var Foofoo = React.createClass({
- mixins: [],
- getInitialState: function() {
- return {};
- },
- getDefaultProps: function() {},
- componentWillMount: function() {},
- componentDidMount: function() {},
- shouldComponentUpdate: function() {},
- componentDidUpdate: function() {},
- componentWillUnmount: function() {},
-
- render: function () {
- return (
-
-
Content for Foofoo
-
- );
- }
- });
-
- module.exports = Foofoo;
- ```
-
-Just remove those you don't need, then fill and space out the rest.
-
-### Action
-
-When using Flux or Reflux architecture, it generates an actionCreator in `src/actions` and it's corresponding test in `src/spec/actions`.
-
-Example:
-```bash
-yo react-webpack:action bar //or just: yo react-webpack:a bar
-```
-Will create a file - `src/actions/BarActionCreators.js`
-
-if 'architecture' is **Flux**, it Produces :
-```js
-'use strict';
-
-var BarActionCreators = {
-
-}
-
-module.exports = BarActionCreators;
-```
-And if it's **Reflux**:
-```js
-'use strict';
-
-var Reflux = require('reflux');
-
-var BarActionCreators = Reflux.createActions([
-
-]);
-
-
-module.exports = BarActionCreators;
-```
-
-and same test for both architectures:
-```js
-'use strict';
-
-describe('BarActionCreators', () => {
- let action;
-
- beforeEach(function() {
- action = require('actions/BarActionCreators.js');
- });
-
- it('should be defined', () => {
- expect(action).toBeDefined();
- });
-});
-```
-
-### Store
-
-When using Flux or Reflux architecture, it generates a store in `src/stores` and it's corresponding test in `src/spec/stores`.
-
-Example:
-```bash
-yo react-webpack:store baz //or just: yo react-webpack:s baz
-```
-Will create a file - `src/stores/BazStore.js`
-
-if 'architecture' is **Flux**, it Produces :
-```js
-'use strict';
-
-var EventEmitter = require('events').EventEmitter;
-var assign = require('object-assign');
-var MainAppDispatcher = require('../dispatcher/MainAppDispatcher');
-
-var BazStore = assign({}, EventEmitter.prototype, {
-
-});
-
-BazStore.dispatchToken = MainAppDispatcher.register(function(action) {
-
- switch(action.type) {
- default:
- }
-
-});
-
-module.exports = BazStore;
-```
-And if it's **Reflux**:
-```js
-'use strict';
-
-var Reflux = require('reflux');
-//var Actions = require('actions/..');
-
-
-var BazStore = Reflux.createStore({
- listenables: Actions,
-
-
-});
-
-module.exports = BazStore;
-```
-
-and same test for both architectures:
-```js
-'use strict';
-
-describe('BazStore', () => {
- let store;
-
- beforeEach(() => {
- store = require('stores/BazStore.js');
- });
-
- it('should be defined', () => {
- expect(store).toBeDefined();
- });
-});
-```
-
-
-## Options
-Options are available as additional installs to the initial application generation phase.
-
-### [ReactRouter](https://github.com/rackt/react-router)
-
-A complete routing library for React. This option only adds the basic hooks to get started with [react router](https://github.com/rackt/react-router).
-
-### styles language
-
-css, sass, scss, less or stylus
-
-Sets the style file's template and extension
-
-### component suffix
-
-js or jsx
-
-Sets the file suffix for generated components. Defaults to "js". Please note that you need to require files *including* the file ending when using jsx as suffix. Example:
-
-```js
-var MyJSComponent = require('./MyJSComponent');
-var MyJSX = require('./MyJSX.jsx');
-```
-
-### architecture
-
-[flux](https://facebook.github.io/flux/) or [reflux](https://github.com/spoike/refluxjs)
-
-### es6
-
-If you are using `es6`, and want to use its export functionality (and not webpack's), just add `--es6` flag when you create a component, action or store.
-
-
-## Testing
-
-Running `grunt test` will run the unit tests with karma. Tests are written using [Jasmine](http://jasmine.github.io/) by default.
-
-## Further Information
-
-### Project Structure
-
-The react-webpack generator automates the setup of a [ReactJS](http://facebook.github.io/react/) project using the specific structure detailed below:
-
-```
-project
- - src
- -components
- MainApp.js
- Foo.js
- AnotherComponent.js
-
- //for flux/reflux
- -actions
- BarActionCreators.js
- -stores
- BazStore.js
- //for flux
- -dispatcher
- FooAppDispatcher
-
- - styles
- main.css
- index.html
- - test
- - spec
- - components
- MainApp.js
- Foo.js
- AnotherComponent.js
-
- //for flux/reflux
- -actions
- BarActionCreators.js
- -stores
- BazStore.js
-
- - helpers
- - react
- addons.js
- phantomjs-shims.js
- Gruntfile.js
- karma.conf.js
- package.json
- webpack.config.js
- webpack.dist.config.js
-```
-
-I have tried to keep the project structure as simple as possible and understand it may not suit everyone.
### Naming Components
@@ -363,27 +80,6 @@ I have opted to follow [@floydophone](https://twitter.com/floydophone) conventio
Each component is a module and can be required using the [Webpack](http://webpack.github.io/) module system. [Webpack](http://webpack.github.io/) uses [Loaders](http://webpack.github.io/docs/loaders.html) which means you can also require CSS and a host of other file types. Read the [Webpack documentation](http://webpack.github.io/docs/home.html) to find out more.
-### Grunt
-
-Out the box the [Gruntfile](http://gruntjs.com/api/grunt.file) is configured with the following:
-
-1. **webpack**: uses the [grunt-webpack](https://github.com/webpack/grunt-webpack) plugin to load all required modules and output to a single JS file `src/main.js`. This is included in the `src/index.html` file by default and will reload in the browser as and when it is recompiled.
-2. **webpack-dev-server**: uses the [webpack-dev-server](https://github.com/webpack/webpack-dev-server) to watch for file changes and also serve the webpack app in development.
-3. **connect**: uses the [grunt-connect](https://github.com/gruntjs/grunt-contrib-connect) plugin to start a webserver at [localhost](http://localhost:8000).
-4. **karma**: uses the [grunt-karma](https://github.com/karma-runner/grunt-karma) plugin to load the Karma configuration file `karma.conf.js` located in the project root. This will run all tests using [PhantomJS](http://phantomjs.org/) by default but supports many other browsers. Please note that karma-launchers other than PhantomJS must be installed separately and configured in `karma.conf.js`.
-
-### CSS
-
-Included in the project is the [normalize.css](http://necolas.github.io/normalize.css/) script. There is also a `src/styles/main.css` script that's required by the core `src/components/App.js` component using Webpack.
-
-### Linting
-
-Webpack is automatically configured to run esLint (http://eslint.org) on every file change or build. The configuration can be found in `PROJECTROOT/.eslintrc`. There are plugins for different editors that use this tool directly:
-- linter-eslint for Atom
-- Sublime-Linter-eslint for Sublime
-
-You could also use jsxhint, the corresponding rules file is located in `PROJECTROOT/.jshintrc`. However, the support for jsxhint is planned to be dropped in a later release and only available for backwards compatibility.
-
## Props
Thanks to all who contributed to [generator-angular](https://github.com/yeoman/generator-angular) as the majority of code here has been shamelessy sourced from that repos.
@@ -396,7 +92,7 @@ Contributions are welcomed. When submitting a bugfix, write a test that exposes
### Running Tests
-`node node_modules/.bin/mocha`
+`npm test` or `node node_modules/.bin/mocha`
## License
diff --git a/a/index.js b/a/index.js
deleted file mode 100644
index eeffccf..0000000
--- a/a/index.js
+++ /dev/null
@@ -1 +0,0 @@
-module.exports = require('../action');
diff --git a/action/index.js b/action/index.js
deleted file mode 100644
index 228642b..0000000
--- a/action/index.js
+++ /dev/null
@@ -1,39 +0,0 @@
-'use strict';
-var util = require('util');
-var ScriptBase = require('../script-base.js');
-
-var ActionGenerator = module.exports = function ActionGenerator(args, options, config) {
- if (!args[0]) console.log('\n Please specify a name for this action creator \n');
- else {
- args[0] += 'ActionCreators';
- ScriptBase.apply(this, arguments)
- }
-};
-
-util.inherits(ActionGenerator, ScriptBase);
-
-ActionGenerator.prototype.createActionFile = function createActionFile() {
- this.option('es6');
- this.es6 = this.options.es6;
-
- var actionTemplate;
- switch (this.architecture){
- case 'flux':
- actionTemplate = 'FluxAction';
- break;
- case 'reflux':
- actionTemplate = 'RefluxAction';
- break;
- case 'alt':
- actionTemplate = 'AltAction';
- break;
- }
-
- console.log('Creating ' + this.architecture + ' action');
-
- this.generateSourceAndTest(
- actionTemplate,
- 'spec/Action',
- 'actions'
- );
-};
diff --git a/app/index.js b/app/index.js
deleted file mode 100644
index 2fa6982..0000000
--- a/app/index.js
+++ /dev/null
@@ -1,164 +0,0 @@
-'use strict';
-var util = require('util');
-var path = require('path');
-var yeoman = require('yeoman-generator');
-var generalUtils = require('../util.js');
-
-var ReactWebpackGenerator = module.exports = function ReactWebpackGenerator(args, options, config) {
- yeoman.generators.Base.apply(this, arguments);
- this.option('es6');
-
- this.argument('appname', { type: String, required: false });
- this.appname = this.appname || path.basename(process.cwd());
- this.appname = this._.camelize(this._.slugify(this._.humanize(this.appname)));
- this.scriptAppName = this._.capitalize(this.appname) + generalUtils.appName(this);
-
- this.config.set('app-name', this.appname);
-
-
- if (typeof this.options.appPath === 'undefined') {
- this.options.appPath = this.options.appPath || 'src';
- }
-
- this.appPath = this.options.appPath;
-
- args = [this.scriptAppName];
-
- this.composeWith('react-webpack:common', {
- args: args
- });
-
- this.composeWith('react-webpack:main', {
- args: args
- });
-
- this.on('end', function () {
- this.installDependencies({ skipInstall: options['skip-install'], bower: false });
- });
-
-
- this.pkg = JSON.parse(this.readFileAsString(path.join(__dirname, '../package.json')));
-
- this.config.save();
-};
-
-util.inherits(ReactWebpackGenerator, yeoman.generators.Base);
-
-ReactWebpackGenerator.prototype.welcome = function welcome() {
- // welcome message
- if (!this.options['skip-welcome-message']) {
- console.log(this.yeoman);
- console.log(
- 'Out of the box I include Webpack and some default React components.\n'
- );
- }
-};
-
-ReactWebpackGenerator.prototype.askForReactRouter = function () {
- var done = this.async();
- this.prompt({
- type : 'confirm',
- name : 'reactRouter',
- message : 'Would you like to include react-router?',
- default : true
- }, function (props) {
- this.env.options.reactRouter = props.reactRouter;
- done();
- }.bind(this));
-};
-
-ReactWebpackGenerator.prototype.askForArchitecture = function() {
- var done = this.async();
- this.prompt({
- type : 'list',
- name : 'architecture',
- message : 'Would you like to use one of these architectures?',
- choices: [
- {name:'No need for that, thanks',value:false},
- {name:'Flux',value:'flux'},
- {name:'ReFlux',value:'reflux'},
- {name:'Alt',value:'alt'}
- ],
- default : false
- }, function(props) {
- this.env.options.architecture = props.architecture;
- this.config.set('architecture', props.architecture);
- done();
- }.bind(this));
-};
-
-ReactWebpackGenerator.prototype.askForStylesLanguage = function () {
- var done = this.async();
- this.prompt({
- type : 'list',
- name : 'stylesLanguage',
- message : 'Which styles language you want to use?',
- choices: [
- {name: 'CSS', value: 'css'},
- {name: 'SASS', value: 'sass'},
- {name: 'SCSS', value: 'scss'},
- {name: 'LESS', value: 'less'},
- {name: 'Stylus', value: 'stylus'}
- ],
- default : 'css'
- }, function (props) {
- this.env.options.stylesLanguage = props.stylesLanguage;
- this.config.set('styles-language', props.stylesLanguage);
- done();
- }.bind(this));
-};
-
-// Allow to set the generated files suffix for the project when using components
-// @see https://github.com/newtriks/generator-react-webpack/issues/99
-ReactWebpackGenerator.prototype.askForComponentSuffix = function() {
- var done = this.async();
- this.prompt({
- type: 'list',
- name: 'componentSuffix',
- message: 'Which file suffix do you want to use for components?',
- choices: [
- { name: '.js (default)', value: 'js' },
- { name: '.jsx (deprecated)', value: 'jsx' }
- ],
- default: 'js'
- }, function (props) {
- this.env.options.componentSuffix = props.componentSuffix;
- this.config.set('component-suffix', props.componentSuffix);
- done();
- }.bind(this));
-};
-
-ReactWebpackGenerator.prototype.readIndex = function readIndex() {
- this.indexFile = this.engine(this.read('../../templates/common/index.html'), this);
-};
-
-ReactWebpackGenerator.prototype.createIndexHtml = function createIndexHtml() {
- this.indexFile = this.indexFile.replace(/'/g, "'");
- this.write(path.join(this.appPath, 'index.html'), this.indexFile);
-};
-
-ReactWebpackGenerator.prototype.packageFiles = function () {
- this.es6 = this.options.es6;
- this.reactRouter = this.env.options.reactRouter;
- this.architecture = this.env.options.architecture;
- this.stylesLanguage = this.env.options.stylesLanguage;
- this.template('../../templates/common/_package.json', 'package.json');
- this.template('../../templates/common/_webpack.config.js', 'webpack.config.js');
- this.template('../../templates/common/_webpack.dist.config.js', 'webpack.dist.config.js');
- this.copy('../../templates/common/Gruntfile.js', 'Gruntfile.js');
- this.copy('../../templates/common/gitignore', '.gitignore');
-};
-
-ReactWebpackGenerator.prototype.styleFiles = function styleFiles() {
- var mainFile = 'main.css';
- this.copy('styles/' + mainFile, 'src/styles/' + mainFile);
-};
-
-ReactWebpackGenerator.prototype.imageFiles = function () {
- this.sourceRoot(path.join(__dirname, 'templates'));
- this.directory('images', 'src/images', true);
-};
-
-ReactWebpackGenerator.prototype.karmaFiles = function () {
- this.copy('../../templates/common/karma.conf.js', 'karma.conf.js');
-};
diff --git a/app/templates/images/yeoman.png b/app/templates/images/yeoman.png
deleted file mode 100644
index 92497ad..0000000
Binary files a/app/templates/images/yeoman.png and /dev/null differ
diff --git a/app/templates/styles/main.css b/app/templates/styles/main.css
deleted file mode 100644
index 321e9a1..0000000
--- a/app/templates/styles/main.css
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Stiziles */
-
-html, body {
- background: #222222;
-}
-
-/* main */
-
-.main {
- width: 100%;
- height: 100%;
- background: #222222;
- color: #fff;
-}
-
-.main img {
- width: 103px;
- height: 89px;
- margin-bottom: 10px;
- text-align: center;
-}
-
-/* transitions */
-
-.fade-enter {
- opacity: 0.01;
- transition: opacity .5s ease-in;
-}
-
-.fade-enter.fade-enter-active {
- opacity: 1;
-}
-
-.fade-leave {
- opacity: 1;
- transition: opacity .5s ease-in;
-}
-
-.fade-leave.fade-leave-active {
- opacity: 0.01;
-}
diff --git a/c/index.js b/c/index.js
deleted file mode 100644
index d61f628..0000000
--- a/c/index.js
+++ /dev/null
@@ -1 +0,0 @@
-module.exports = require('../component');
diff --git a/common/index.js b/common/index.js
deleted file mode 100644
index 0452f1a..0000000
--- a/common/index.js
+++ /dev/null
@@ -1,17 +0,0 @@
-'use strict';
-var path = require('path');
-var util = require('util');
-var yeoman = require('yeoman-generator');
-
-var CommonGenerator = module.exports = function CommonGenerator(args, options, config) {
- yeoman.generators.NamedBase.apply(this, arguments);
-};
-
-util.inherits(CommonGenerator, yeoman.generators.NamedBase);
-
-CommonGenerator.prototype.setupEnv = function setupEnv() {
- // Copies the contents of the generator `templates`
- // directory into your users new application path
- this.sourceRoot(path.join(__dirname, '../templates/common'));
- this.directory('root', '.', true);
-};
diff --git a/component/index.js b/component/index.js
deleted file mode 100644
index 28223e5..0000000
--- a/component/index.js
+++ /dev/null
@@ -1,25 +0,0 @@
-'use strict';
-var util = require('util');
-var ScriptBase = require('../script-base.js');
-
-var ComponentGenerator = module.exports = function ComponentGenerator(args, options, config) {
- ScriptBase.apply(this, arguments);
-};
-
-util.inherits(ComponentGenerator, ScriptBase);
-
-ComponentGenerator.prototype.createComponentFile = function createComponentFile() {
- this.option('es6');
- this.option('rich');
-
- this.es6 = this.options.es6;
- this.rich = this.options.rich;
-
- this.generateComponentTestAndStyle(
- 'Component',
- 'spec/Component',
- 'styles/Component',
- 'components',
- true
- );
-};
diff --git a/generators/app/index.js b/generators/app/index.js
new file mode 100644
index 0000000..54de5ab
--- /dev/null
+++ b/generators/app/index.js
@@ -0,0 +1,124 @@
+'use strict';
+let generator = require('yeoman-generator');
+let utils = require('../../utils/all');
+let prompts = require('./prompts');
+let path = require('path');
+let fs = require('fs');
+
+// Set the base root directory for our files
+let baseRootPath = path.join(__dirname, '../../node_modules/react-webpack-template');
+
+module.exports = generator.Base.extend({
+
+ constructor: function() {
+ generator.Base.apply(this, arguments);
+
+ // Make options available
+ this.option('skip-welcome-message', {
+ desc: 'Skip the welcome message',
+ type: Boolean,
+ defaults: false
+ });
+ this.option('skip-install');
+
+ // Use our plain template as source
+ this.sourceRoot(baseRootPath);
+
+ this.config.save();
+ },
+
+ initializing: function() {
+ if(!this.options['skip-welcome-message']) {
+ this.log(require('yeoman-welcome'));
+ this.log('Out of the box I include Webpack and some default React components.\n');
+ }
+ },
+
+ prompting: function() {
+ let done = this.async();
+ this.prompt(prompts, function(props) {
+
+ // Make sure to get the correct app name if it is not the default
+ if(props.appName !== utils.yeoman.getAppName()) {
+ props.appName = utils.yeoman.getAppName(props.appName);
+ }
+
+ // Set needed global vars for yo
+ this.appName = props.appName;
+ this.style = props.style;
+
+ // Set needed keys into config
+ this.config.set('appName', this.appName);
+ this.config.set('appPath', this.appPath);
+ this.config.set('style', this.style);
+
+ done();
+ }.bind(this));
+ },
+
+ configuring: function() {
+
+ // Generate our package.json. Make sure to also include the required dependencies for styles
+ let defaultSettings = this.fs.readJSON(path.join(baseRootPath, 'package.json'));
+ let packageSettings = {
+ name: this.appName,
+ private: true,
+ version: '0.0.1',
+ description: 'YOUR DESCRIPTION - Generated by generator-react-webpack',
+ main: '',
+ scripts: defaultSettings.scripts,
+ repository: '',
+ keywords: [],
+ author: 'Your name here',
+ devDependencies: defaultSettings.devDependencies,
+ dependencies: defaultSettings.dependencies
+ };
+
+ // Add needed loaders if we have special styles
+ let styleConfig = utils.config.getChoiceByKey('style', this.style);
+ if(styleConfig && styleConfig.packages) {
+
+ for(let dependency of styleConfig.packages) {
+ packageSettings.dependencies[dependency.name] = dependency.version;
+ }
+ }
+
+ this.fs.writeJSON(this.destinationPath('package.json'), packageSettings);
+ },
+
+ writing: function() {
+
+ let excludeList = [
+ 'LICENCE',
+ 'README.md',
+ 'node_modules',
+ 'package.json'
+ ];
+
+ // Get all files in our repo and copy the ones we should
+ fs.readdir(this.sourceRoot(), (err, items) => {
+
+ for(let item of items) {
+
+ // Skip the item if it is in our exclude list
+ if(excludeList.indexOf(item) !== -1) {
+ continue;
+ }
+
+ // Copy all items to our root
+ let fullPath = path.join(baseRootPath, item);
+ if(fs.lstatSync(fullPath).isDirectory()) {
+ this.bulkDirectory(item, item);
+ } else {
+ this.copy(item, item);
+ }
+ }
+ });
+ },
+
+ install: function() {
+ if(!this.options['skip-install']) {
+ this.installDependencies({ bower: false });
+ }
+ }
+});
diff --git a/generators/app/prompts.js b/generators/app/prompts.js
new file mode 100644
index 0000000..5c447ea
--- /dev/null
+++ b/generators/app/prompts.js
@@ -0,0 +1,18 @@
+'use strict';
+let utils = require('../../utils/all');
+
+module.exports = [
+ {
+ type: 'input',
+ name: 'appName',
+ message: 'Please choose your application name',
+ default: utils.yeoman.getAppName()
+ },
+ {
+ type: 'list',
+ name: 'style',
+ message: 'Which styles language you want to use?',
+ choices: utils.config.getChoices('style'),
+ default: utils.config.getDefaultChoice('style')
+ }
+];
diff --git a/generators/component/index.js b/generators/component/index.js
new file mode 100644
index 0000000..93fae40
--- /dev/null
+++ b/generators/component/index.js
@@ -0,0 +1,36 @@
+'use strict';
+let generator = require('yeoman-generator');
+let utils = require('../../utils/all');
+
+module.exports = generator.NamedBase.extend({
+
+ constructor: function() {
+ generator.NamedBase.apply(this, arguments);
+ },
+
+ writing: function() {
+
+ let settings = utils.yeoman.getAllSettingsFromComponentName(this.name, this.config.get('style'));
+
+ // Create the style template
+ this.fs.copyTpl(
+ this.templatePath(`styles/Component${settings.style.suffix}`),
+ this.destinationPath(settings.style.path + settings.style.fileName),
+ settings
+ );
+
+ // Create the component
+ this.fs.copyTpl(
+ this.templatePath('components/Base.js'),
+ this.destinationPath(settings.component.path + settings.component.fileName),
+ settings
+ );
+
+ // Create the unit test
+ this.fs.copyTpl(
+ this.templatePath('tests/Base.js'),
+ this.destinationPath(settings.test.path + settings.test.fileName),
+ settings
+ );
+ }
+});
diff --git a/generators/component/templates/components/Base.js b/generators/component/templates/components/Base.js
new file mode 100644
index 0000000..27f20e6
--- /dev/null
+++ b/generators/component/templates/components/Base.js
@@ -0,0 +1,21 @@
+'use strict';
+
+import React from 'react/addons';
+
+require('<%= style.webpackPath %>');
+
+class <%= component.className %> extends React.Component {
+ render() {
+ return (
+
+ Please edit <%= component.path %>/<%= component.fileName %> to update this component!
+