{"id":13494290,"url":"https://github.com/mz026/universal-redux-template","last_synced_at":"2026-02-13T12:34:56.629Z","repository":{"id":54564230,"uuid":"44169330","full_name":"mz026/universal-redux-template","owner":"mz026","description":"A clean, extensible react + redux boilerplate with universal/isomorphic rendering, testing and more","archived":false,"fork":false,"pushed_at":"2023-02-27T09:23:27.000Z","size":448,"stargazers_count":465,"open_issues_count":6,"forks_count":95,"subscribers_count":19,"default_branch":"master","last_synced_at":"2024-08-01T19:49:35.376Z","etag":null,"topics":["boilerplate","isomorphic","react","redux","server-rendering","starter-kit"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mz026.png","metadata":{"files":{"readme":"README.md","changelog":"History.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-10-13T10:37:26.000Z","updated_at":"2024-06-02T14:25:07.000Z","dependencies_parsed_at":"2022-08-13T19:50:38.643Z","dependency_job_id":null,"html_url":"https://github.com/mz026/universal-redux-template","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mz026%2Funiversal-redux-template","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mz026%2Funiversal-redux-template/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mz026%2Funiversal-redux-template/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mz026%2Funiversal-redux-template/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mz026","download_url":"https://codeload.github.com/mz026/universal-redux-template/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":222382545,"owners_count":16975383,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["boilerplate","isomorphic","react","redux","server-rendering","starter-kit"],"created_at":"2024-07-31T19:01:23.539Z","updated_at":"2026-02-13T12:34:56.556Z","avatar_url":"https://github.com/mz026.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","Marks"],"sub_categories":["Boilerplate"],"readme":"[![Build Status](https://travis-ci.org/mz026/universal-redux-template.svg?branch=master)](https://travis-ci.org/mz026/universal-redux-template)\n\n# Universal Redux Template\nA boilerplate doing universal/isomorphic rendering with Redux + React-router + Express, based on [Redux-Realword-Example](https://github.com/reactjs/redux/tree/master/examples/real-world)\n\n## Philosophy\n\nTo bootstrap a React app development environment is not an easy task, there are so many libraries to setup, including webpack, babel, testing stuff and others. I'd like this boilerplate to be a ready-to-use one *with the essential tools and the simplest logic that just work* to build a universal rendering React + Redux app. That's why there is no fancy stuff in this app, since it's a basis of your killer app rather than a showcase one.\n\n## How to use this template?\n\n- clone this app and name it as whatever your want:\n`$ git clone https://github.com/mz026/universal-redux-template.git my-killer-app`\n\n- remove the `.git` folder since you won't need the history of this boilerplate:\n`$ cd my-killer-app; rm -rf .git`\n\n- start out a new git history:\n`$ git init`\n\n- Install dependencies:\n`$ yarn install`\n\n- Host dev environment and start to build something changing the world!\n`$ yarn start`\n\n- To run the test with Mocha, Enzyme, Sinon and Chai:\n`$ yarn test:ci`\n\n- To generate a container/component/action and its tests:\n`$ ./bin/generate \u003ctype\u003e \u003cpath\u003e`\n\neg: `$ ./bin/generate component myNamespace/MyComponent`\n\n\n## Features:\n- Universal rendering, with async data support\n- Server side redirect\n- Separate vendor and app js files\n- Use [Immutable](https://facebook.github.io/immutable-js/) as store data\n- Hot Reload on client side by Webpack\n- Hot Reload on server side ([ref](https://medium.com/@kevinsimper/dont-use-nodemon-there-are-better-ways-fc016b50b45e))\n\n## Stack:\n- [react](https://github.com/facebook/react)@15.4.2\n- [react-router](https://github.com/ReactTraining/react-router)@3.0.5\n- [Immutable.js](https://facebook.github.io/immutable-js/)\n- [Webpack](https://webpack.github.io/)@2.2\n- [Babel](https://babeljs.io/)@6\n- Express as isomorphic server\n- `yarn` as package manager\n\n\n## Testing:\n\n### Tools:\n\n- [Mocha](https://mochajs.org/) as testing framework\n- [Chai](http://chaijs.com/) as assertion library\n- [Rewire](https://github.com/speedskater/babel-plugin-rewire) and [Sinon](http://sinonjs.org/) to mock/stub\n- [Enzyme](http://airbnb.io/enzyme/index.html) to do React rendering\n\n### Development process:\n\nWhen developing a feature,\n\n* First run a separate process converting ES6 to ES5 lively:\n\n```\n$ yarn run test:watch\n```\n\n* Run the test case of a single file/directory by:\n\n```\n$ yarn test -- \u003cthe-file-path\u003e\n```\n\nFor example:\n\n```\n$ yarn test -- app/test/actions\n```\n\n* Before deployment, run all the test cases to make sure everything is fine by:\n\n```\n$ yarn test:ci\n```\n\n### Why\n\nThe way suggested by [babel's doc](https://babeljs.io/docs/setup/#installation) compiles the code on the fly, which is too slow, especially when the number of files grows:\n\n```\n//package.json\n\n{\n  \"scripts\": {\n    \"test\": \"mocha --compilers js:babel-register\"\n  }\n}\n```\n\nSo here we pre-compile the code, watch it, and maintain a cache to avoid repeated build of the files that doesn't change. After the pre-compile, the testing cycle can be *much faster* than before, especially when doing TDD.\n\n### For ~Winners~ Vimmers:\n\nFor vim users, there's a plugin called [vim-test](https://github.com/janko-m/vim-test) binding tests with the editor. You can trigger a test \"nearest the cursor\", which is super handy when doing TDD.\n\nTo make `vim-test` work together with the pre-compile process,\n\n1. copy the `editor_configs/vimrc` to `\u003cproject-root\u003e/.vimrc`\n2. make sure these two lines exist in your `~/.vimrc` to enable directory-based `.vimrc`:\n\n```\nset exrc\nset secure\n```\n\nThen you can enjoy the fast feedback loop ~powered by the greatest editor on the planet~.\n\n\n## Routes Draft:\n- Intro page: `{base_url}`\n- Questions Page: `{base_url}/questions`\n- Question Detail Page: `{base_url}/questions/:id`\n\n## How it works:\n\n### Assets Management\n\nWhen handling static assets, we want to achieve the following goals:\n\n- Make assigning assets url a no-brainer\n- Apply revision when deploying to production to integrate with CDN services easily\n\nThe usage example can be found in `[Intro Container](https://github.com/mz026/universal-redux-template/blob/master/app/containers/Intro.js)`\n\n\nWe achieve this by:\n\nFirst, creating an assets container folder: `app/assets`\n\n### In development mode:\n\nAssign static folder linking `/assets` to the folder above\n\n### In production mode:\n\nUse a gulp task (`gulp build`) to handle it:\n\n- A set of `[rev](https://github.com/smysnk/gulp-rev-all)-ed` assets with hash code appended would be built into `dist/public/assets`\n- A static middleware mapping root url to the folder mentioned above is configured in `server.js`\n- A set of `[revReplace](https://github.com/jamesknelson/gulp-rev-replace)-ed` server code would be built into `dist/server-build`, so that the rev-ed assets can be used when doing server rendering\n\n\n### Redirect after API Calls\n\nUnder some cases, we'd like to do 302 redirect after fetching API. For example:\n\n```\nWhen users try to access a question page via an unexisting Id, redirect her to Index route.\n```\n\nIn the code layer, we want the implementation to be shared on both client and server side.\nThis is achieved by passing a `history` instance to action creators, and use `history.push` whenever needed.\n\nOn the client side, `react-router` would then take care the rest of redirecting logic,\nwhile on server side, we subscribe the url-chaning events on each request, and redirect requests to proper pages if needed.\n\nSuch implementation can be found in [`QuestionContainer`](https://github.com/mz026/universal-redux-template/blob/master/app/containers/Question.js),\n[`questions action`](https://github.com/mz026/universal-redux-template/blob/master/app/actions/questions.js)\n\n\n## Vendor Scripts:\n\nVendor related scripts are bundled into a `vendor.js`,\nassociated settings can be found in the `entry` field of `webpack.config.js`.\n\n(thanks [@dlombardi](https://github.com/dlombardi) for pointing it out!)\n\n\n## For Windows Users:\n\n### `yarn test`:\n\nThe single quotes in `yarn test` script surrounding path do not work on Windows, while [they're necessary on unix-like machines](https://github.com/mochajs/mocha/issues/1115).\nPlease remove them in `scripts.test` section in `package.json` like this:\n\n```\n\"test\": \"NODE_ENV=test NODE_PATH=./app mocha --compilers js:babel-register -r app/spec/support/setup.mocha.js --recursive app/spec/**/*.test.js -w\"\n```\n\n(thanks [@jbuffin](https://github.com/jbuffin) for pointing it out!)\n\n\n## Deployment:\n\nTo deploy this app to production environment:\n\n- Prepare a server with NodeJS environment\n\n- Use whatever tool to upload this app to server. ([Capistrano](http://capistranorb.com/) is a good choice.)\n\n- Run `$ NODE_ENV=production yarn install` on server\n  - After the installation above, `postinstall` script will run automatically, building front-end related assets and rev-ed server code under `dist/` folder.\n\n- Kick off the server with:\n\n` NODE_ENV=production NODE_PATH=./dist/server-build node dist/server-build/server`\n\n### Deploy to Heroku\n\nTo deploy this app to heroku,\n\n- Set up heroku git remote url\n- Set `API_BASE_URL` to heroku config var. (without trailing slash)\n\nHere's a [sample](https://redux-template-test.herokuapp.com/) deployed to heroku: https://redux-template-test.herokuapp.com/\nFor this case, the `API_BASE_URL` mention above would be `https://redux-template-test.herokuapp.com`\n\n\n## Resources:\n- [Blogpost on Codementor](https://www.codementor.io/reactjs/tutorial/redux-server-rendering-react-router-universal-web-app)\n- [Chinese version of the above](http://mz026.logdown.com/posts/308147-hello-redux-2-3-server-rendering)\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmz026%2Funiversal-redux-template","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmz026%2Funiversal-redux-template","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmz026%2Funiversal-redux-template/lists"}