├── .gitignore ├── .gitattributes ├── .yo-rc.json ├── app ├── templates │ ├── style │ │ ├── test.less │ │ └── style.less │ ├── README.md │ ├── gulpfile.js │ ├── index.js │ ├── npmignore │ ├── ui-test │ │ ├── ui-test.jsx │ │ ├── index.html │ │ └── page.jsx │ ├── gitignore │ ├── src │ │ ├── template.jsx │ │ ├── store.js │ │ └── index.js │ ├── config.js │ ├── webpack.config.js │ ├── test │ │ └── index.jsx │ ├── editorconfig │ ├── webpack.config.prod.js │ └── package.json └── index.js ├── .travis.yml ├── .jshintrc ├── .editorconfig ├── test └── test-app.js ├── package.json ├── README.md └── .eslintrc /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.yo-rc.json: -------------------------------------------------------------------------------- 1 | { 2 | "generator-generator": {} 3 | } -------------------------------------------------------------------------------- /app/templates/style/test.less: -------------------------------------------------------------------------------- 1 | // use this file to include any test files 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - 'iojs' 5 | - '0.12' 6 | - '0.10' 7 | -------------------------------------------------------------------------------- /app/templates/style/style.less: -------------------------------------------------------------------------------- 1 | .<%= _.camelCase(name) %>-component { 2 | // put you styles here 3 | } 4 | -------------------------------------------------------------------------------- /app/templates/README.md: -------------------------------------------------------------------------------- 1 | # Awesome <%= name %> component 2 | 3 | <%= description %> 4 | 5 | Made with [Turris.js](https://github.com/turrisjs) 6 | -------------------------------------------------------------------------------- /app/templates/gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('turris-gulp-tasks')(require('./config.js')); 2 | 3 | gulp.task('default', ['debug', 'serve']); 4 | -------------------------------------------------------------------------------- /app/templates/index.js: -------------------------------------------------------------------------------- 1 | /* global __WEBPACK__ */ 2 | // only load style when using webpack 3 | if (__WEBPACK__) { 4 | require('./style/style.less'); 5 | } 6 | // code 7 | import Component from './src'; 8 | 9 | export default Component; 10 | -------------------------------------------------------------------------------- /app/templates/npmignore: -------------------------------------------------------------------------------- 1 | # ignore git 2 | .git/ 3 | .gitignore 4 | 5 | # ignore submodule files 6 | common-files/ 7 | .gitmodules 8 | 9 | # ignore tests 10 | ui-test/ 11 | test/ 12 | 13 | # ignore coverage report 14 | coverage/ 15 | 16 | # ignore symlinks 17 | .editorconfig 18 | -------------------------------------------------------------------------------- /app/templates/ui-test/ui-test.jsx: -------------------------------------------------------------------------------- 1 | import 'bootstrap'; 2 | import React from 'react'; 3 | import Page from './page.jsx'; 4 | 5 | const testInstance = ( 6 | 7 | ); 8 | 9 | const render = () => React.render(testInstance, document.getElementById('react')); 10 | 11 | render(); 12 | -------------------------------------------------------------------------------- /app/templates/ui-test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Component test 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/templates/gitignore: -------------------------------------------------------------------------------- 1 | # ignore node deps 2 | node_modules/ 3 | 4 | # ignore compiled 5 | es5/ 6 | ui-test/component.min.js 7 | ui-test/*.eot 8 | ui-test/*.woff* 9 | ui-test/*.ttf 10 | ui-test/*.svg 11 | 12 | # ignore tests and coverage report 13 | coverage/ 14 | 15 | # ignore symlinks 16 | .editorconfig 17 | -------------------------------------------------------------------------------- /app/templates/src/template.jsx: -------------------------------------------------------------------------------- 1 | // react 2 | import React from 'react'; 3 | 4 | const render = function() { 5 | return ( 6 |
7 | I am standalone <%= name %> component 8 |
9 | ); 10 | }; 11 | 12 | export default render; 13 | -------------------------------------------------------------------------------- /app/templates/src/store.js: -------------------------------------------------------------------------------- 1 | import postal from 'postal'; 2 | 3 | const <%= _.camelCase(name) %>Channel = postal.channel('<%= _.camelCase(name) %>'); 4 | 5 | <%= _.camelCase(name) %>Channel.subscribe('action', ({data}) => { 6 | // your stuff here 7 | }); 8 | 9 | export default <%= _.camelCase(name) %>Channel; 10 | -------------------------------------------------------------------------------- /app/templates/config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | 3 | module.exports = { 4 | path: path.join(__dirname, 'ui-test'), 5 | testEntryPoint: path.join(__dirname, 'test', 'index.jsx'), 6 | webpackConfig: { 7 | debug: require('./webpack.config.js'), 8 | production: require('./webpack.config.prod.js'), 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /app/templates/ui-test/page.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | // style 3 | import '../style/test.less'; 4 | // component 5 | import Component from '../index.js'; 6 | 7 | const Page = React.createClass({ 8 | // template rendering 9 | render: function() { 10 | return ; 11 | }, 12 | }); 13 | 14 | export default Page; 15 | -------------------------------------------------------------------------------- /.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/webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | 3 | module.exports = { 4 | devtool: 'inline-source-map', 5 | debug: true, 6 | context: path.resolve(__dirname), 7 | entry: './ui-test/ui-test.jsx', 8 | output: { 9 | path: path.join(__dirname, 'ui-test'), 10 | filename: 'component.min.js', 11 | }, 12 | resolve: { 13 | root: path.resolve(__dirname), 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /app/templates/test/index.jsx: -------------------------------------------------------------------------------- 1 | /* global describe, it */ 2 | // import helpers 3 | import should from 'turris-test-helpers'; 4 | 5 | // imports 6 | import TestComp from '../index.js'; 7 | 8 | describe('Component', function() { 9 | it('Should render', function() { 10 | const React = this.React; 11 | const TestUtils = this.TestUtils; 12 | 13 | // render 14 | var comp = TestUtils.renderIntoDocument( 15 | , 16 | this.container 17 | ); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /app/templates/src/index.js: -------------------------------------------------------------------------------- 1 | // react 2 | import React from 'react'; 3 | // store 4 | import <%= _.camelCase(name) %>Channel from './store'; 5 | // template 6 | import Template from './template.jsx'; 7 | 8 | // create component 9 | const <%= _.capitalize(_.camelCase(name)) %>Component = React.createClass({ 10 | // initilize state 11 | getInitialState() { 12 | // return state 13 | return { 14 | }; 15 | }, 16 | render: Template, 17 | }); 18 | 19 | export default <%= _.capitalize(_.camelCase(name)) %>Component; 20 | -------------------------------------------------------------------------------- /app/templates/editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig: http://EditorConfig.org 2 | # all files defaults 3 | [**] 4 | # Unix-style newlines with a newline ending 5 | end_of_line = lf 6 | insert_final_newline = true 7 | # Set default charset 8 | charset = utf-8 9 | # 4 space indentation 10 | indent_style = space 11 | indent_size = 4 12 | # trim whitespaces 13 | trim_trailing_whitespace = true 14 | # always insert final newline 15 | insert_final_newline = true 16 | 17 | # 2 spaces indent for config files 18 | [{package.json}] 19 | indent_style = space 20 | indent_size = 2 21 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig: http://EditorConfig.org 2 | # all files defaults 3 | [**] 4 | # Unix-style newlines with a newline ending 5 | end_of_line = lf 6 | insert_final_newline = true 7 | # Set default charset 8 | charset = utf-8 9 | # 4 space indentation 10 | indent_style = space 11 | indent_size = 4 12 | # trim whitespaces 13 | trim_trailing_whitespace = true 14 | # always insert final newline 15 | insert_final_newline = true 16 | 17 | # 2 spaces indent for config files 18 | [{package.json}] 19 | indent_style = space 20 | indent_size = 2 21 | 22 | [*.md] 23 | trim_trailing_whitespace = false 24 | -------------------------------------------------------------------------------- /test/test-app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var path = require('path'); 4 | var assert = require('yeoman-generator').assert; 5 | var helpers = require('yeoman-generator').test; 6 | var os = require('os'); 7 | 8 | describe('turris-component:app', function () { 9 | before(function (done) { 10 | helpers.run(path.join(__dirname, '../app')) 11 | .withOptions({ skipInstall: true }) 12 | .withPrompts({ someOption: true }) 13 | .on('end', done); 14 | }); 15 | 16 | it('creates files', function () { 17 | assert.file([ 18 | 'bower.json', 19 | 'package.json', 20 | '.editorconfig', 21 | '.jshintrc' 22 | ]); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /app/templates/webpack.config.prod.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var fs = require('fs'); 3 | 4 | var nodeModules = {}; 5 | fs.readdirSync('node_modules') 6 | .filter(function(x) { 7 | return ['.bin'].indexOf(x) === -1; 8 | }).forEach(function(mod) { 9 | nodeModules[mod] = 'commonjs ' + mod; 10 | }); 11 | 12 | module.exports = { 13 | context: path.resolve(__dirname), 14 | entry: './index.js', 15 | output: { 16 | path: path.join(__dirname, 'es5'), 17 | filename: 'component.js', 18 | libraryTarget: 'commonjs2', 19 | }, 20 | resolve: { 21 | root: path.resolve(__dirname), 22 | }, 23 | externals: nodeModules, 24 | }; 25 | -------------------------------------------------------------------------------- /app/templates/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "component-<%= _.camelCase(name) %>", 3 | "version": "0.1.0", 4 | "description": "<%= description %>", 5 | "main": "es5/component.js", 6 | "es6": "index.js", 7 | "scripts": { 8 | "test": "gulp test", 9 | "cover": "gulp cover", 10 | "start": "gulp", 11 | "build": "gulp build", 12 | "prepublish": "npm run build" 13 | }, 14 | "author": "", 15 | "license": "MIT", 16 | "dependencies": { 17 | "postal": "^1.0.6", 18 | "react": "^0.13.2" 19 | }, 20 | "devDependencies": { 21 | "bootstrap": "^3.3.4", 22 | "gulp": "^3.8.11", 23 | "turris-gulp-tasks": "^0.4.0", 24 | "turris-test-helpers": "^0.1.3" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "generator-turris-component", 3 | "version": "0.2.1", 4 | "description": "Yeoman generator for standalone React ES6 component for Turris.js", 5 | "license": "MIT", 6 | "main": "app/index.js", 7 | "repository": "yamalight/generator-turris-component", 8 | "author": { 9 | "name": "Tim Ermilov", 10 | "email": "yamalight@gmail.com", 11 | "url": "https://github.com/yamalight" 12 | }, 13 | "scripts": { 14 | "test": "mocha" 15 | }, 16 | "files": [ 17 | "app" 18 | ], 19 | "keywords": [ 20 | "yeoman-generator", 21 | "turrisjs", 22 | "react", 23 | "es6", 24 | "babel" 25 | ], 26 | "dependencies": { 27 | "yeoman-generator": "^0.19.0", 28 | "chalk": "^1.0.0", 29 | "yosay": "^1.0.2" 30 | }, 31 | "devDependencies": { 32 | "mocha": "*" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # generator-turris-component 2 | 3 | [![No Maintenance Intended](http://unmaintained.tech/badge.svg)](http://unmaintained.tech/) 4 | 5 | > [Yeoman](http://yeoman.io) generator for Turris.js standalone ES6 React components 6 | 7 | ## About Turris.js 8 | 9 | Turris.js is a combination of existing libraries and tools that allows fast and simple creation of single page web applications using [ES6](http://www.ecma-international.org/publications/standards/Ecma-262.htm). 10 | 11 | This is a generator for standalone components. For more information please find the main generator in it's own [github repository](https://github.com/turrisjs/generator-turris). 12 | 13 | ## Getting Started 14 | 15 | ### Requirements 16 | 17 | Refer to [main Turris.js generator requirements](https://github.com/turrisjs/generator-turris#requirements). 18 | 19 | ### Installation 20 | 21 | ``` 22 | $ npm install -g generator-turris-component 23 | ``` 24 | 25 | ### Usage 26 | 27 | ``` 28 | $ yo turris-component 29 | ``` 30 | 31 | ## Learning Your Way Around 32 | 33 | Once installed, you can create a basic Turris.js React component by following the prompts. 34 | 35 | ```shell 36 | $ mkdir HelloWorld-Component 37 | $ cd HelloWorld-Component 38 | $ yo turris-component 39 | 40 | _-----_ 41 | | | .--------------------------. 42 | |--(o)--| | Welcome to the | 43 | `---------´ | stupendous | 44 | ( _´U`_ ) | TurrisComponent | 45 | /___A___\ | generator! | 46 | | ~ | '--------------------------' 47 | __'.___.'__ 48 | ´ ` |° ´ Y ` 49 | 50 | ? Your component name: (HelloWorld-Component) 51 | ... 52 | ``` 53 | 54 | To run your component in test mode, just type `npm start`. 55 | 56 | ### Project Structure 57 | 58 | Client: 59 | - **/index.js** - Component entry point 60 | - **/style/** - LESS style files 61 | - **/src/index.js** - React component definition 62 | - **/src/template.jsx** - React template 63 | 64 | Misc: 65 | - **/test/** - Unit and functional tests 66 | - **/config.js** - Build config 67 | - **/gulpfile.js** - Gulp bootstrapper 68 | - **/webpack.config.js** - Webpack config for development 69 | - **/webpack.config.prod.js** - Webpack config for production 70 | 71 | ### TODO 72 | 73 | Add more docs and a proper test suite. 74 | 75 | ## License 76 | 77 | [MIT](http://opensource.org/licenses/MIT) 78 | -------------------------------------------------------------------------------- /app/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var yeoman = require('yeoman-generator'); 3 | var chalk = require('chalk'); 4 | var yosay = require('yosay'); 5 | 6 | module.exports = yeoman.generators.Base.extend({ 7 | initializing: function () { 8 | this.pkg = require('../package.json'); 9 | }, 10 | 11 | prompting: function () { 12 | var done = this.async(); 13 | 14 | // Have Yeoman greet the user. 15 | this.log(yosay( 16 | 'Welcome to the stupendous ' + chalk.red('TurrisComponent') + ' generator!' 17 | )); 18 | 19 | var prompts = [{ 20 | type: 'input', 21 | name: 'name', 22 | message: 'Your component name', 23 | default: this.appname, 24 | }, { 25 | type: 'input', 26 | name: 'description', 27 | message: 'Your component description', 28 | default: 'No description yet', 29 | }]; 30 | 31 | this.prompt(prompts, function (props) { 32 | this.props = props; 33 | done(); 34 | }.bind(this)); 35 | }, 36 | 37 | writing: { 38 | app: function () { 39 | this.fs.copyTpl( 40 | this.templatePath('package.json'), 41 | this.destinationPath('package.json'), 42 | this.props 43 | ); 44 | this.fs.copyTpl( 45 | this.templatePath('README.md'), 46 | this.destinationPath('README.md'), 47 | this.props 48 | ); 49 | }, 50 | 51 | projectfiles: function () { 52 | this.fs.copy( 53 | this.templatePath('editorconfig'), 54 | this.destinationPath('.editorconfig') 55 | ); 56 | this.fs.copy( 57 | this.templatePath('gitignore'), 58 | this.destinationPath('.gitignore') 59 | ); 60 | this.fs.copy( 61 | this.templatePath('npmignore'), 62 | this.destinationPath('.npmignore') 63 | ); 64 | this.fs.copy( 65 | this.templatePath('config.js'), 66 | this.destinationPath('config.js') 67 | ); 68 | this.fs.copy( 69 | this.templatePath('gulpfile.js'), 70 | this.destinationPath('gulpfile.js') 71 | ); 72 | this.fs.copy( 73 | this.templatePath('index.js'), 74 | this.destinationPath('index.js') 75 | ); 76 | this.fs.copy( 77 | this.templatePath('webpack.config.js'), 78 | this.destinationPath('webpack.config.js') 79 | ); 80 | this.fs.copy( 81 | this.templatePath('webpack.config.prod.js'), 82 | this.destinationPath('webpack.config.prod.js') 83 | ); 84 | 85 | // folders 86 | this.fs.copyTpl( 87 | this.templatePath('src'), 88 | this.destinationPath('src'), 89 | this.props 90 | ); 91 | this.fs.copyTpl( 92 | this.templatePath('style'), 93 | this.destinationPath('style'), 94 | this.props 95 | ); 96 | this.fs.copy( 97 | this.templatePath('test'), 98 | this.destinationPath('test') 99 | ); 100 | this.fs.copy( 101 | this.templatePath('ui-test'), 102 | this.destinationPath('ui-test') 103 | ); 104 | } 105 | }, 106 | 107 | install: function () { 108 | this.installDependencies(); 109 | } 110 | }); 111 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | // I want to use babel-eslint for parsing! 3 | "parser": "babel-eslint", 4 | "env": { 5 | // I write for browser 6 | "browser": true, 7 | // in CommonJS 8 | "node": true, 9 | // use ES6 10 | "es6": true 11 | }, 12 | "ecmaProperties": { 13 | // enable JSX support 14 | "jsx": true 15 | }, 16 | "plugins": [ 17 | // enable react plugin 18 | "react" 19 | ], 20 | // To give you an idea how to override rule options 21 | "rules": { 22 | // Possible Errors 23 | "comma-dangle": 0, 24 | "no-console": 2, 25 | "no-debugger": 2, 26 | "no-dupe-keys": 2, 27 | "no-dupe-args": 2, 28 | "no-empty": 2, 29 | "no-extra-boolean-cast": 2, 30 | "no-extra-semi": 2, 31 | "no-invalid-regexp": 2, 32 | "no-irregular-whitespace": 2, 33 | "no-reserved-keys": 0, 34 | "no-sparse-arrays": 2, 35 | "no-unreachable": 2, 36 | "use-isnan": 2, 37 | "valid-jsdoc": 2, 38 | "valid-typeof": 2, 39 | // Best Practices 40 | "consistent-return": 1, 41 | "curly": 2, 42 | "default-case": 2, 43 | "dot-notation": 2, 44 | "eqeqeq": 2, 45 | "no-alert": 2, 46 | "no-caller": 2, 47 | "no-else-return": 2, 48 | "no-eq-null": 2, 49 | "no-eval": 2, 50 | "no-extend-native": 2, 51 | "no-floating-decimal": 2, 52 | "no-implied-eval": 2, 53 | "no-iterator": 2, 54 | "no-labels": 2, 55 | "no-loop-func": 1, 56 | "no-lone-blocks": 2, 57 | "no-multi-spaces": 2, 58 | "no-native-reassign": 2, 59 | "no-new": 2, 60 | "no-new-func": 2, 61 | "no-new-wrappers": 2, 62 | "no-proto": 2, 63 | "no-redeclare": 2, 64 | "no-return-assign": 2, 65 | "no-script-url": 2, 66 | "no-self-compare": 2, 67 | "no-sequences": 2, 68 | "no-throw-literal": 2, 69 | "no-unused-expressions": 2, 70 | "no-void": 2, 71 | "radix": 2, 72 | "yoda": 0, 73 | // Strict Mode 74 | "strict": 0, 75 | // Variables 76 | "no-catch-shadow": 2, 77 | "no-delete-var": 2, 78 | "no-shadow": 2, 79 | "no-shadow-restricted-names": 2, 80 | "no-undef": 2, 81 | "no-unused-vars": [2, {"vars": "all", "args": "after-used"}], 82 | "no-use-before-define": 2, 83 | // Node 84 | "handle-callback-err": 2, 85 | "no-new-require": 2, 86 | "no-path-concat": 2, 87 | // Stylistic Issues 88 | "indent": [2, 2], // 2 spaces 89 | "camelcase": 2, 90 | "comma-spacing": [2, {"before": false, "after": true}], 91 | "comma-style": [2, "last"], 92 | "eol-last": 2, 93 | "func-style": [2, "expression"], 94 | "max-nested-callbacks": [2, 3], 95 | "no-array-constructor": 2, 96 | "no-mixed-spaces-and-tabs": 2, 97 | "no-multiple-empty-lines": [1, {"max": 2}], 98 | "no-nested-ternary": 2, 99 | "no-new-object": 2, 100 | "no-space-before-semi": 2, 101 | "no-spaced-func": 2, 102 | "no-trailing-spaces": 2, 103 | "no-underscore-dangle": 2, 104 | "no-wrap-func": 2, 105 | "quote-props": [1, "as-needed"], 106 | "quotes": [1, "single"], 107 | "semi": [2, "always"], 108 | "semi-spacing": [2, {"before": false, "after": true}], 109 | "space-after-function-name": [1, "never"], 110 | "space-after-keywords": [1, "always"], 111 | "space-before-blocks": [1, "always"], 112 | "space-before-function-parentheses": [2, "always"], 113 | "space-in-brackets": [1, "never"], 114 | "space-in-parens": [1, "never"], 115 | "space-infix-ops": 2, 116 | // complexity rules 117 | "max-depth": [2, 2], 118 | "max-statements": [2, 8], 119 | "complexity": [2, 5], 120 | "max-len": [2, 120], 121 | "max-params": [2, 2], 122 | "max-nested-callbacks": [2, 1], 123 | // jsx rules 124 | "react/jsx-quotes": 1, 125 | "react/jsx-no-undef": 1, 126 | "react/jsx-uses-react": 1, 127 | "react/jsx-uses-vars": 1, 128 | "react/no-did-mount-set-state": 1, 129 | "react/no-did-update-set-state": 1, 130 | "react/no-multi-comp": 1, 131 | "react/react-in-jsx-scope": 1, 132 | "react/self-closing-comp": 1, 133 | "react/wrap-multilines": 1 134 | } 135 | } 136 | --------------------------------------------------------------------------------