├── .editorconfig ├── .gitattributes ├── .gitignore ├── .yo-rc.json ├── LICENSE ├── README.md ├── app ├── index.js └── templates │ ├── _bower.json │ ├── _gulpfile.js │ ├── _package.json │ ├── _readme.md │ ├── editorconfig │ ├── eslintignore │ ├── eslintrc │ ├── example │ ├── _example.js │ ├── _index.html │ ├── example.less │ └── gitignore │ ├── gitignore │ └── src │ └── _Component.js ├── package.json ├── test └── test-app.js └── travis.yml /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | # This file is for unifying the coding style for different editors and IDEs 5 | # editorconfig.org 6 | root = true 7 | 8 | [*] 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = false 12 | insert_final_newline = true 13 | indent_style = tab 14 | 15 | [*.json] 16 | indent_style = space 17 | indent_size = 2 18 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.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 | # Compiled binary addons (http://nodejs.org/api/addons.html) 20 | build/Release 21 | 22 | # Dependency directory 23 | # Commenting this out is preferred by some people, see 24 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- 25 | node_modules 26 | 27 | # Users Environment Variables 28 | .lock-wscript 29 | -------------------------------------------------------------------------------- /.yo-rc.json: -------------------------------------------------------------------------------- 1 | { 2 | "generator-generator": {} 3 | } 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Jed Watson 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 all 13 | 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 THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # generator-react-component 2 | 3 | > [Yeoman](http://yeoman.io) generator for [React](http://facebook.github.io/react/) Components 4 | 5 | Builds a React Component project with useful gulp tasks for development, build and publishing. 6 | 7 | See [react-component-gulp-tasks](https://github.com/JedWatson/react-component-gulp-tasks) for documentation on how to use the gulp tasks. 8 | 9 | 10 | ## Getting Started 11 | 12 | Install the generator: 13 | 14 | ```bash 15 | npm install -g generator-react-component 16 | ``` 17 | 18 | Then run the generator: 19 | 20 | ```bash 21 | yo react-component 22 | ``` 23 | 24 | ... and follow the prompts. 25 | 26 | 27 | ## How to develop your component 28 | 29 | ### Source 30 | 31 | Your component source code is in `src`. You can use JSX and ES6 syntax freely in your component source; it will be transpiled to `lib` with Babel before being published to npm so that your users will simply be able to include it. 32 | 33 | It's a great idea to add a description, documentation and other information to your `README.md` file, to help people who are interested in using your component. 34 | 35 | ### Example & Preview 36 | 37 | Preview your component with LiveReload: 38 | 39 | ```bash 40 | npm start 41 | ``` 42 | 43 | A webserver will be started on [localhost:8000](http://localhost:8000) running the examples in `example/src`. 44 | 45 | You can use this playpen to test your component, and then publish it as live examples to GitHub Pages, which is a great way to let potential users try out your component and see what it can do. 46 | 47 | ### Lint your code! 48 | 49 | ```bash 50 | npm run lint 51 | ``` 52 | 53 | Your code will be linted with ESLint, using the Babel parser and the React plugin. You can customise the settings by editing the `.eslintrc` file. 54 | 55 | ### Build and Publish 56 | 57 | ```bash 58 | npm run build 59 | ``` 60 | 61 | This will build your `lib`, `dist` and `example/dist` folders ready for release. 62 | 63 | You can then publish your component to npm and GitHub Pages by running: 64 | 65 | ```bash 66 | npm run release 67 | ``` 68 | 69 | ### Other npm scripts 70 | 71 | #### `examples` 72 | 73 | Just run the examples server; no code will be built or watched, everything in `example/dist` will be served on [localhost:8000](http://localhost:8000). 74 | 75 | #### `publish:site` 76 | 77 | Usually run as part of the `release` script, this will copy the contents of `example/dist` to your `gh-pages` branch and push it. 78 | 79 | #### `watch` 80 | 81 | This task watches the `src` folder for changes, and builds automatically into `lib`. This is useful if you are developing your component in another project using `npm link`. 82 | 83 | 84 | ## Feedback? 85 | 86 | I'd love to hear it. Open an issue or submit a PR. 87 | 88 | 89 | ## License 90 | 91 | [MIT License](http://en.wikipedia.org/wiki/MIT_License). Copyright (c) 2016 Jed Watson. 92 | -------------------------------------------------------------------------------- /app/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var _ = require('lodash'); 4 | var chalk = require('chalk'); 5 | var yeoman = require('yeoman-generator'); 6 | 7 | var ReactComponentGenerator = yeoman.generators.Base.extend({ 8 | 9 | initializing: function() { 10 | this.pkg = require('../package.json'); 11 | }, 12 | 13 | prompting_init: function() { 14 | var done = this.async(); 15 | 16 | this.log( 17 | '\n' + chalk.bold.underline('Welcome to the React Component generator') + 18 | '\n' + 19 | '\nWe\'re going to set up a new ' + chalk.bold('ReactJS') + ' Component, ready for development with' + 20 | '\n' + chalk.bold('gulp, browserify, live-reload') + ' and publishing to ' + chalk.bold('GitHub Pages') + '.' + 21 | '\n' 22 | ); 23 | 24 | var prompts = [{ 25 | type: 'input', 26 | name: 'projectName', 27 | message: 'First, what is the name of your component?', 28 | default: 'My Component' 29 | }]; 30 | 31 | this.prompt(prompts, function (props) { 32 | _.extend(this, props); 33 | this.packageName = _.kebabCase(_.deburr(this.projectName)); 34 | if (this.packageName.slice(0, 6) !== 'react-') { 35 | this.packageName = 'react-' + this.packageName; 36 | } 37 | this.componentName = _.capitalize(_.camelCase(this.projectName)); 38 | this.currentYear = new Date().getFullYear(); 39 | done(); 40 | }.bind(this)); 41 | }, 42 | 43 | prompting_names: function() { 44 | var done = this.async(); 45 | 46 | var prompts = [{ 47 | type: 'input', 48 | name: 'packageName', 49 | message: 'What is the ClassName for your component?', 50 | default: this.componentName 51 | }, { 52 | type: 'input', 53 | name: 'packageName', 54 | message: 'What will the npm package name be?', 55 | default: this.packageName 56 | }, { 57 | type: 'input', 58 | name: 'developerName', 59 | message: 'What is your name? (for copyright notice, etc.)' 60 | }]; 61 | 62 | this.prompt(prompts, function (props) { 63 | _.extend(this, props); 64 | done(); 65 | }.bind(this)); 66 | }, 67 | 68 | prompting_project: function() { 69 | var done = this.async(); 70 | 71 | var prompts = [{ 72 | type: 'input', 73 | name: 'ghUser', 74 | message: 'What is your GitHub Username?', 75 | default: _.capitalize(_.camelCase(this.developerName)) 76 | }, { 77 | type: 'input', 78 | name: 'ghRepo', 79 | message: 'What is the name of the GitHub repo this will be published at?', 80 | default: this.packageName 81 | }, { 82 | type: 'confirm', 83 | name: 'createDirectory', 84 | message: 'Would you like to create a new directory for your project?', 85 | default: true 86 | }]; 87 | 88 | this.prompt(prompts, function (props) { 89 | _.extend(this, props); 90 | if (props.createDirectory) { 91 | this.destinationRoot(this.packageName); 92 | } 93 | this.log('\n'); 94 | done(); 95 | }.bind(this)); 96 | }, 97 | 98 | writing: { 99 | project: function() { 100 | this.copy('editorconfig', '.editorconfig'); 101 | this.copy('eslintignore', '.eslintignore'); 102 | this.copy('eslintrc', '.eslintrc'); 103 | this.copy('gitignore', '.gitignore'); 104 | this.template('_bower.json', 'bower.json'); 105 | this.template('_gulpfile.js', 'gulpfile.js'); 106 | this.template('_package.json', 'package.json'); 107 | this.template('_readme.md', 'README.md'); 108 | }, 109 | component: function() { 110 | this.template('src/_Component.js', 'src/' + this.componentName + '.js'); 111 | }, 112 | examples: function() { 113 | this.copy('example/example.less', 'example/src/example.less'); 114 | this.copy('example/gitignore', 'example/src/.gitignore'); 115 | this.template('example/_example.js', 'example/src/example.js'); 116 | this.template('example/_index.html', 'example/src/index.html'); 117 | } 118 | }, 119 | 120 | install: function() { 121 | this.npmInstall(); 122 | }, 123 | 124 | end: function() { 125 | var chdir = this.createDirectory ? '"cd ' + this.packageName + '" then ' : ''; 126 | this.log( 127 | '\n' + chalk.green.underline('Your new React Component is ready!') + 128 | '\n' + 129 | '\nYour component is in /src and your examples are in /example/src.' + 130 | '\n' + 131 | '\nType ' + chdir + '"npm start" to run the development build and server tasks.' + 132 | '\n' 133 | ); 134 | } 135 | 136 | }); 137 | 138 | module.exports = ReactComponentGenerator; 139 | -------------------------------------------------------------------------------- /app/templates/_bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= packageName %>", 3 | "version": "0.0.0", 4 | "description": "<%= projectName %>", 5 | "main": "dist/<%= packageName %>.min.js", 6 | "homepage": "https://github.com/<%= ghUser %>/<%= ghRepo %>", 7 | "authors": [ 8 | "<%= developerName %>" 9 | ], 10 | "moduleType": [ 11 | "amd", 12 | "globals", 13 | "node" 14 | ], 15 | "keywords": [ 16 | "react", 17 | "react-component" 18 | ], 19 | "license": "MIT", 20 | "ignore": [ 21 | ".editorconfig", 22 | ".gitignore", 23 | "package.json", 24 | "src", 25 | "node_modules", 26 | "example", 27 | "test" 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /app/templates/_gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var initGulpTasks = require('react-component-gulp-tasks'); 3 | 4 | /** 5 | * Tasks are added by the react-component-gulp-tasks package 6 | * 7 | * See https://github.com/JedWatson/react-component-gulp-tasks 8 | * for documentation. 9 | * 10 | * You can also add your own additional gulp tasks if you like. 11 | */ 12 | 13 | var taskConfig = { 14 | 15 | component: { 16 | name: '<%= componentName %>', 17 | dependencies: [ 18 | 'classnames', 19 | 'react', 20 | 'react-dom' 21 | ], 22 | lib: 'lib' 23 | }, 24 | 25 | example: { 26 | src: 'example/src', 27 | dist: 'example/dist', 28 | files: [ 29 | 'index.html', 30 | '.gitignore' 31 | ], 32 | scripts: [ 33 | 'example.js' 34 | ], 35 | less: [ 36 | 'example.less' 37 | ] 38 | } 39 | 40 | }; 41 | 42 | initGulpTasks(gulp, taskConfig); 43 | -------------------------------------------------------------------------------- /app/templates/_package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= packageName %>", 3 | "version": "1.0.0", 4 | "description": "<%= projectName %>", 5 | "main": "lib/<%= componentName %>.js", 6 | "author": "<%= developerName %>", 7 | "homepage": "https://github.com/<%= ghUser %>/<%= ghRepo %>", 8 | "repository": { 9 | "type": "git", 10 | "url": "https://github.com/<%= ghUser %>/<%= ghRepo %>.git" 11 | }, 12 | "bugs": { 13 | "url": "https://github.com/<%= ghUser %>/<%= ghRepo %>/issues" 14 | }, 15 | "dependencies": { 16 | "classnames": "^2.1.2" 17 | }, 18 | "devDependencies": { 19 | "babel-eslint": "^4.1.3", 20 | "eslint": "^1.6.0", 21 | "eslint-plugin-react": "^3.5.1", 22 | "gulp": "^3.9.0", 23 | "react": "^0.14.0", 24 | "react-component-gulp-tasks": "^0.7.6", 25 | "react-dom": "^0.14.0" 26 | }, 27 | "peerDependencies": { 28 | "react": "^0.14.0" 29 | }, 30 | "browserify-shim": { 31 | "react": "global:React" 32 | }, 33 | "scripts": { 34 | "build": "gulp clean && NODE_ENV=production gulp build", 35 | "examples": "gulp dev:server", 36 | "lint": "eslint ./; true", 37 | "publish:site": "NODE_ENV=production gulp publish:examples", 38 | "release": "NODE_ENV=production gulp release", 39 | "start": "gulp dev", 40 | "test": "echo \"no tests yet\" && exit 0", 41 | "watch": "gulp watch:lib" 42 | }, 43 | "keywords": [ 44 | "react", 45 | "react-component" 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /app/templates/_readme.md: -------------------------------------------------------------------------------- 1 | # <%= projectName %> 2 | 3 | __COMPONENT DESCRIPTION GOES HERE__ 4 | 5 | 6 | ## Demo & Examples 7 | 8 | Live demo: [<%= ghUser %>.github.io/<%= ghRepo %>](http://<%= ghUser %>.github.io/<%= ghRepo %>/) 9 | 10 | To build the examples locally, run: 11 | 12 | ``` 13 | npm install 14 | npm start 15 | ``` 16 | 17 | Then open [`localhost:8000`](http://localhost:8000) in a browser. 18 | 19 | 20 | ## Installation 21 | 22 | The easiest way to use <%= packageName %> is to install it from NPM and include it in your own React build process (using [Browserify](http://browserify.org), [Webpack](http://webpack.github.io/), etc). 23 | 24 | You can also use the standalone build by including `dist/<%= packageName %>.js` in your page. If you use this, make sure you have already included React, and it is available as a global variable. 25 | 26 | ``` 27 | npm install <%= packageName %> --save 28 | ``` 29 | 30 | 31 | ## Usage 32 | 33 | __EXPLAIN USAGE HERE__ 34 | 35 | ``` 36 | var <%= componentName %> = require('<%= packageName %>'); 37 | 38 | <<%= componentName %>>Example<%= componentName %>> 39 | ``` 40 | 41 | ### Properties 42 | 43 | * __DOCUMENT PROPERTIES HERE__ 44 | 45 | ### Notes 46 | 47 | __ADDITIONAL USAGE NOTES__ 48 | 49 | 50 | ## Development (`src`, `lib` and the build process) 51 | 52 | **NOTE:** The source code for the component is in `src`. A transpiled CommonJS version (generated with Babel) is available in `lib` for use with node.js, browserify and webpack. A UMD bundle is also built to `dist`, which can be included without the need for any build system. 53 | 54 | To build, watch and serve the examples (which will also watch the component source), run `npm start`. If you just want to watch changes to `src` and rebuild `lib`, run `npm run watch` (this is useful if you are working with `npm link`). 55 | 56 | ## License 57 | 58 | __PUT LICENSE HERE__ 59 | 60 | Copyright (c) <%= currentYear %> <%= developerName %>. 61 | 62 | -------------------------------------------------------------------------------- /app/templates/editorconfig: -------------------------------------------------------------------------------- 1 | # This file is for unifying the coding style for different editors and IDEs 2 | # editorconfig.org 3 | root = true 4 | 5 | [*] 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = false 9 | insert_final_newline = true 10 | indent_style = tab 11 | 12 | [*.json] 13 | indent_style = space 14 | indent_size = 2 15 | -------------------------------------------------------------------------------- /app/templates/eslintignore: -------------------------------------------------------------------------------- 1 | .publish/* 2 | dist/* 3 | example/dist/* 4 | lib/* 5 | node_modules/* 6 | -------------------------------------------------------------------------------- /app/templates/eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "env": { 4 | "browser": true, 5 | "node": true 6 | }, 7 | "plugins": [ 8 | "react" 9 | ], 10 | "rules": { 11 | "curly": [2, "multi-line"], 12 | "quotes": [2, "single", "avoid-escape"], 13 | "react/display-name": 0, 14 | "react/jsx-boolean-value": 1, 15 | "react/jsx-quotes": 1, 16 | "react/jsx-no-undef": 1, 17 | "react/jsx-sort-props": 0, 18 | "react/jsx-sort-prop-types": 1, 19 | "react/jsx-uses-react": 1, 20 | "react/jsx-uses-vars": 1, 21 | "react/no-did-mount-set-state": 1, 22 | "react/no-did-update-set-state": 1, 23 | "react/no-multi-comp": 1, 24 | "react/no-unknown-property": 1, 25 | "react/prop-types": 1, 26 | "react/react-in-jsx-scope": 1, 27 | "react/self-closing-comp": 1, 28 | "react/wrap-multilines": 1, 29 | "semi": 2, 30 | "strict": 0 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/templates/example/_example.js: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | var ReactDOM = require('react-dom'); 3 | var <%= componentName %> = require('<%= packageName %>'); 4 | 5 | var App = React.createClass({ 6 | render () { 7 | return ( 8 |