diff --git a/.gitignore b/.gitignore index e29155f..87e2d4c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ .idea .DS_Store tmp -spm_modules node_modules examples/**/dist boilerplate/dist diff --git a/.npmignore b/.npmignore index 8869ccb..fb23fce 100644 --- a/.npmignore +++ b/.npmignore @@ -1,6 +1,5 @@ .idea .DS_Store tmp -spm_modules node_modules examples diff --git a/bin/antd-init b/bin/antd-init index 792231d..8c52b11 100755 --- a/bin/antd-init +++ b/bin/antd-init @@ -4,6 +4,7 @@ var vfs = require('vinyl-fs'); var fs = require('fs'); var through = require('through2'); var path = require('path'); +var inquirer = require('inquirer'); var join = path.join; var basename = path.basename; @@ -13,17 +14,38 @@ if (process.argv.length === 3 && return; } -var cwd = join(__dirname, '../boilerplate'); -var dest = process.cwd(); - -vfs.src('**/*', {cwd: cwd, cwdbase: true, dot: true}) - .pipe(template(dest)) - .pipe(vfs.dest(dest)) - .on('end', function() { - fs.renameSync(path.join(dest,'gitignore'),path.join(dest,'.gitignore')); - require('../lib/install'); +inquirer.prompt({ + name: 'type', + type: 'list', + message: 'Please select boilerplate type', + choices: [ + { + name: 'plain react - for simple project', + value: 'plain-react', + }, + { + name: 'redux - for complex project', + value: 'redux', + }, + ], }) - .resume(); + .then(function(answers) { + init(answers.type); + }); + +function init(type) { + var cwd = join(__dirname, '../boilerplates', type); + var dest = process.cwd(); + + vfs.src('**/*', {cwd: cwd, cwdbase: true, dot: true}) + .pipe(template(dest)) + .pipe(vfs.dest(dest)) + .on('end', function() { + fs.renameSync(path.join(dest,'gitignore'),path.join(dest,'.gitignore')); + require('../lib/install'); + }) + .resume(); +} function template(dest) { return through.obj(function (file, enc, cb) { diff --git a/boilerplate/.editorconfig b/boilerplates/plain-react/.editorconfig similarity index 100% rename from boilerplate/.editorconfig rename to boilerplates/plain-react/.editorconfig diff --git a/boilerplate/.eslintrc b/boilerplates/plain-react/.eslintrc similarity index 100% rename from boilerplate/.eslintrc rename to boilerplates/plain-react/.eslintrc diff --git a/boilerplate/README.md b/boilerplates/plain-react/README.md similarity index 100% rename from boilerplate/README.md rename to boilerplates/plain-react/README.md diff --git a/boilerplate/gitignore b/boilerplates/plain-react/gitignore similarity index 100% rename from boilerplate/gitignore rename to boilerplates/plain-react/gitignore diff --git a/boilerplate/index.html b/boilerplates/plain-react/index.html similarity index 100% rename from boilerplate/index.html rename to boilerplates/plain-react/index.html diff --git a/boilerplate/package.json b/boilerplates/plain-react/package.json similarity index 100% rename from boilerplate/package.json rename to boilerplates/plain-react/package.json diff --git a/boilerplate/proxy.config.js b/boilerplates/plain-react/proxy.config.js similarity index 100% rename from boilerplate/proxy.config.js rename to boilerplates/plain-react/proxy.config.js diff --git a/boilerplate/src/common/lib.js b/boilerplates/plain-react/src/common/lib.js similarity index 100% rename from boilerplate/src/common/lib.js rename to boilerplates/plain-react/src/common/lib.js diff --git a/boilerplate/src/component/App.jsx b/boilerplates/plain-react/src/component/App.jsx similarity index 100% rename from boilerplate/src/component/App.jsx rename to boilerplates/plain-react/src/component/App.jsx diff --git a/boilerplate/src/component/App.less b/boilerplates/plain-react/src/component/App.less similarity index 100% rename from boilerplate/src/component/App.less rename to boilerplates/plain-react/src/component/App.less diff --git a/boilerplate/src/entry/index.jsx b/boilerplates/plain-react/src/entry/index.jsx similarity index 100% rename from boilerplate/src/entry/index.jsx rename to boilerplates/plain-react/src/entry/index.jsx diff --git a/boilerplate/webpack.config.js b/boilerplates/plain-react/webpack.config.js similarity index 100% rename from boilerplate/webpack.config.js rename to boilerplates/plain-react/webpack.config.js diff --git a/boilerplates/redux/.eslintrc b/boilerplates/redux/.eslintrc new file mode 100644 index 0000000..4f1e575 --- /dev/null +++ b/boilerplates/redux/.eslintrc @@ -0,0 +1,20 @@ +{ + "parser": "babel-eslint", + "extends": "eslint-config-airbnb", + "rules": { + "spaced-comment": [0], + "no-unused-vars": [0], + "no-empty": [0], + "react/wrap-multilines": [0], + "react/no-multi-comp": [0], + "no-constant-condition": [0], + "react/jsx-no-bind": [0], + "react/prop-types": [0], + "arrow-body-style": [0], + "react/prefer-stateless-function": [0], + "semi": [0] + }, + "ecmaFeatures": { + "experimentalObjectRestSpread": true + } +} diff --git a/boilerplates/redux/README.md b/boilerplates/redux/README.md new file mode 100644 index 0000000..f01e872 --- /dev/null +++ b/boilerplates/redux/README.md @@ -0,0 +1,109 @@ +# react-redux-boilerplate + +A boilerplate with react, redux, redux-saga, react-router, webpack, babel, css-modules ... + +## 环境准备 + +先安装依赖 + +```bash +$ npm install +``` + +想要更好的开发体验,还需安装两个 Chrome 插件:[Redux DevTools](https://chrome.google.com/webstore/detail/lmhkpmbekcpmknklioeibfkpmmfibljd) 和 [LiveReload](https://chrome.google.com/webstore/detail/livereload/jnihajbhpnppcggbcgedagnkighmdlei) 。 + +## 启动调试 + +```bash +$ npm start +$ open http://localhost:8989/ +``` + +## 构建代码 + +```bash +$ npm run build + +// 构建但不压缩 +$ npm run build -- --no-compress +``` + +## 目录结构 + +``` +. +├── /dist/ # 构建输出的文件会在这里 +├── /node_modules/ # 第三方类库和工具 +├── /src/ # 应用源码 +│ ├── /components/ # React components +│ ├── /constants/ # 常量 (比如 action types 等) +│ ├── /containers/ # React containers +│ ├── /entries/ # 应用入口 +│ ├── /reducers/ # reducers +│ ├── /routes/ # 路由信息 +│ ├── /sagas/ # redux-sagas +│ └── /services/ # 处理和服务器的交互 +├── proxy.config.js # 配置 dora-plugin-proxy,用于 mock 和在线调试 +├── webpack.config.js # 扩展 webpack 配置 +└── package.json # 配置入口文件、依赖和 scripts +``` + +## 系统组织 + +![](https://camo.githubusercontent.com/068c4ff126977b861cff3338428bdde6927f7dad/68747470733a2f2f6f732e616c697061796f626a656374732e636f6d2f726d73706f7274616c2f43684d775a42755a6c614c725377652e706e67) + +详见:[React + Redux 最佳实践](https://github.com/sorrycc/blog/issues/1) + +## 内置类库 + +- [react](https://github.com/facebook/react) +- [redux](https://github.com/reactjs/redux) +- [redux-saga](https://github.com/yelouafi/redux-saga) +- [redux-actions](https://github.com/acdlite/redux-actions) +- [react-router](https://github.com/reactjs/react-router) +- [reselect](https://github.com/reactjs/reselect) +- [classnames](https://github.com/JedWatson/classnames) +- [isomorphic-fetch](https://github.com/matthew-andrews/isomorphic-fetch) +- [react-router](https://github.com/reactjs/react-router) +- [react-router-redux](https://github.com/reactjs/react-router-redux) + +## 工具特性 + +热替换和 LiveReload + +> 基于 [Webpack Vanilla HMR](https://webpack.github.io/docs/hot-module-replacement-with-webpack.html),支持 `components`, `containers`, `reducers`, `routers` 目录的模块热替换,其余目录的修改则会自动刷新页面。 + +> CSS 的自动刷新需通过 [LiveReload](https://chrome.google.com/webstore/detail/livereload/jnihajbhpnppcggbcgedagnkighmdlei) Chrome 插件配合使用。 + +> - [Why Vanilla HMR](https://github.com/reactjs/redux/pull/1455) + +支持 css-modules + +> 后缀为 `.module.less` 或 `.module.css` 的会被解析为 css-modules + +内置支持 jsx-control-statements + +> jsx 里可以通过 If, Else 和 For 标签来实现控制语句 + +运行错误和语法错误的提醒 + +> 通过 [redbox-react](https://github.com/KeywordBrain/redbox-react) 和 webpack hmr overlay 提示运行错误和语法错误 + +自动引入 `reducer` 和 `saga` + +> 通过 webpack 的 `require.context` 黑魔法批量引入 `reducer` 和 `saga`,新增、删除和重命名时会更方便 + +自动安装 npm 依赖 + +> ![](https://camo.githubusercontent.com/898e02d6539900efe65fadbfd15e2a1d7ce4dccf/68747470733a2f2f6f732e616c697061796f626a656374732e636f6d2f726d73706f7274616c2f4b6541474f776a70746a6152684d6d2e676966) + +数据 mock 和线上调试 + +> 通过 dora-plugin-proxy 实现,详见:https://github.com/dora-js/dora-plugin-proxy#规则定义 + +... + +## License + +MIT + diff --git a/boilerplates/redux/gitignore b/boilerplates/redux/gitignore new file mode 100644 index 0000000..a7cf257 --- /dev/null +++ b/boilerplates/redux/gitignore @@ -0,0 +1,4 @@ +dist +node_modules +.DS_Store +npm-debug.log diff --git a/boilerplates/redux/package.json b/boilerplates/redux/package.json new file mode 100644 index 0000000..4e19524 --- /dev/null +++ b/boilerplates/redux/package.json @@ -0,0 +1,45 @@ +{ + "private": true, + "entry": { + "index": "./src/entries/index.js" + }, + "dependencies": { + "atool-build": "0.6.x", + "babel-polyfill": "^6.3.14", + "classnames": "^2.2.3", + "history": "^2.0.1", + "isomorphic-fetch": "^2.2.1", + "jsx-control-statements": "^3.1.0", + "react": "0.14.x", + "react-dom": "0.14.x", + "react-redux": "4.4.x", + "react-router": "^2.0.1", + "react-router-redux": "^4.0.1", + "redux": "3.3.x", + "redux-actions": "0.9.x", + "redux-saga": "^0.9.5", + "reselect": "^2.0.3" + }, + "devDependencies": { + "babel-eslint": "^6.0.2", + "dora": "0.3.x", + "dora-plugin-browser-history": "^0.1.1", + "dora-plugin-livereload": "^0.3.0", + "dora-plugin-proxy": "^0.6.1", + "dora-plugin-webpack": "0.6.x", + "dora-plugin-webpack-hmr": "^0.1.0", + "eslint": "^2.7.0", + "eslint-config-airbnb": "^6.2.0", + "eslint-plugin-react": "^4.2.3", + "pre-commit": "1.x", + "redbox-react": "^1.2.2" + }, + "pre-commit": [ + "lint" + ], + "scripts": { + "start": "dora --plugins \"proxy,webpack,webpack-hmr,livereload?enableJs=false,browser-history?index=/src/entries/index.html\"", + "build": "atool-build", + "lint": "eslint --ext .js,.jsx src/" + } +} \ No newline at end of file diff --git a/boilerplates/redux/proxy.config.js b/boilerplates/redux/proxy.config.js new file mode 100644 index 0000000..eeeb1c5 --- /dev/null +++ b/boilerplates/redux/proxy.config.js @@ -0,0 +1,5 @@ +// More Examples: https://github.com/dora-js/dora-plugin-proxy#规则定义 + +module.exports = { + '/webapi/*': 'http://1.1.1.1', +}; diff --git a/boilerplates/redux/src/components/Count/Count.js b/boilerplates/redux/src/components/Count/Count.js new file mode 100644 index 0000000..b5b48f5 --- /dev/null +++ b/boilerplates/redux/src/components/Count/Count.js @@ -0,0 +1,27 @@ +import styles from './Count.module.less'; +import React, { Component, PropTypes } from 'react'; +import classnames from 'classnames'; +import { COUNT_DECREASE, COUNT_DECREASE_ASYNC, COUNT_REDUCE } from '../../constants/count'; + +const Count = ({ dispatch, count }) => +