From de966e1619eb2d40041bb783e54f226723051c93 Mon Sep 17 00:00:00 2001 From: Pedro Moreira Date: Wed, 6 Jun 2018 04:47:14 -0300 Subject: [PATCH] Add duck battlecry generator (#74) --- README.md | 12 +++ battlecry/generators/duck/duck.generator.js | 77 +++++++++++++++++++ .../generators/duck/templates/__naMe__.js | 10 +++ .../duck/templates/configureStore.js | 12 +++ 4 files changed, 111 insertions(+) create mode 100644 battlecry/generators/duck/duck.generator.js create mode 100644 battlecry/generators/duck/templates/__naMe__.js create mode 100644 battlecry/generators/duck/templates/configureStore.js diff --git a/README.md b/README.md index bf90700..960b23c 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,18 @@ bindActionCreators({loadWidgets, createWidget, updateWidget, removeWidget}, disp [Todomvc using ducks.](https://github.com/goopscoop/ga-react-tutorial/tree/6-reduxActionsAndReducers) +### BattleCry generators + +There are configurable [BattleCry](https://github.com/pedsmoreira/battlecry) generators ready to be downloaded and help scaffolding ducks: + +```sh +npm install -g battlecry +cry download erikras/ducks-modular-redux +cry init duck +``` + +Run `cry --help` to check more info about the generators available; + ### Implementation The migration to this code structure was [painless](https://github.com/erikras/react-redux-universal-hot-example/commit/3fdf194683abb7c40f3cb7969fd1f8aa6a4f9c57), and I foresee it reducing much future development misery. diff --git a/battlecry/generators/duck/duck.generator.js b/battlecry/generators/duck/duck.generator.js new file mode 100644 index 0000000..dd5cc99 --- /dev/null +++ b/battlecry/generators/duck/duck.generator.js @@ -0,0 +1,77 @@ +import { Generator, File, namedCasex, casex, log } from 'battlecry'; + +const CONFIG_FILE = 'configureStore.js'; +const REDUX_PATH = 'src/redux'; + +export default class DuckGenerator extends Generator { + config = { + init: { + description: 'Create configStore.js file and an example duck' + }, + generate: { + args: 'name ...actions?', + description: 'Create or modify duck to add actions' + } + }; + + get configFile() { + const template = this.template(CONFIG_FILE); + const path = `${REDUX_PATH}/${template.filename}`; + + return new File(path); + } + + get actions() { + return (this.args.actions || ['set']).reverse(); + } + + init() { + const configFile = this.configFile; + if(configFile.exists) return log.warn(`Modular ducks have already been initiated. Please check the ${configFile.path} file`); + + this.template(CONFIG_FILE).saveAs(configFile.path); + this.generator('duck').setArgs({name: 'todo'}).play('generate'); + } + + generate() { + this.addActionsToDuck(); + this.addDuckToConfig(); + } + + addActionsToDuck() { + const template = this.template('_*'); + const path = `${REDUX_PATH}/modules/${template.filename}`; + + let file = new File(path, this.args.name); + if(!file.exists) file = template; + + this.actions.forEach(action => { + file.after('// Actions', `const __NA_ME__ = '${casex(this.args.name, 'na-me')}/__NA-ME__';`, action); + + file.after('switch (action.type) {', [ + ' case __NA_ME__:', + ' // Perform action', + ' return state;' + ], action); + + file.after('// Action Creators', [ + namedCasex('export function __naMe__() {', + `${action}_${this.args.name}`), + ' return { type: __NA_ME__ };', + '}', + '' + ], action); + }); + + file.saveAs(path, this.args.name); + } + + addDuckToConfig() { + const file = this.configFile; + if(!file.exists) return null; + + file + .afterLast('import ', "import __naMe__ from './modules/__naMe__'", this.args.name) + .after('combineReducers({', ' __naMe__,', this.args.name) + .save(); + } +} diff --git a/battlecry/generators/duck/templates/__naMe__.js b/battlecry/generators/duck/templates/__naMe__.js new file mode 100644 index 0000000..bcb6e1f --- /dev/null +++ b/battlecry/generators/duck/templates/__naMe__.js @@ -0,0 +1,10 @@ +// Actions + +// Reducer +export default function reducer(state = {}, action = {}) { + switch (action.type) { + default: return state; + } +} + +// Action Creators \ No newline at end of file diff --git a/battlecry/generators/duck/templates/configureStore.js b/battlecry/generators/duck/templates/configureStore.js new file mode 100644 index 0000000..207c7a5 --- /dev/null +++ b/battlecry/generators/duck/templates/configureStore.js @@ -0,0 +1,12 @@ +import { createStore, applyMiddleware, combineReducers } from 'redux'; +import createLogger from 'redux-logger'; + +const loggerMiddleware = createLogger(); // initialize logger + +const createStoreWithMiddleware = applyMiddleware(loggerMiddleware)(createStore); // apply logger to redux + +const reducer = combineReducers({ +}); + +const configureStore = (initialState) => createStoreWithMiddleware(reducer, initialState); +export default configureStore; \ No newline at end of file