From 9b5ebaf829e92b0a66dd11ecaad5ac0531a0c736 Mon Sep 17 00:00:00 2001 From: kiki le singe Date: Sun, 29 Jan 2017 14:32:53 +0100 Subject: [PATCH 01/10] feat(project): upgrade project use the new release of https://github.com/kiki-le-singe/react-redux-universal-boilerplate --- .babelrc | 14 +- .editorconfig | 0 .eslintrc.yaml | 15 +- .gitignore | 9 + .release.json | 17 + .travis.yml | 0 CHANGELOG.md | 133 + CONTRIBUTING.md | 53 + LICENSE | 21 + README.md | 0 __tests__/.eslintrc.yaml | 7 + __tests__/components/Hello/hello.spec.js | 22 + __tests__/example.spec.js | 46 + __tests__/index.test.js | 15 + config/index.js | 18 +- index.js | 1 - karma.conf.js | 31 + nodemon.json | 9 + package.json | 235 +- postcss.config.js | 8 + readyToDeploy/README.md | 27 + readyToDeploy/package.json | 36 + {static => readyToDeploy/static}/favicon.ico | Bin readyToDeploy/static/humans.txt | 17 + readyToDeploy/static/robots.txt | 5 + readyToDeploy/yarn.lock | 883 ++ src/client/index.js | 51 +- src/common/components/Hello/Hello.jsx | 20 + src/common/components/Hello/index.js | 3 + src/common/components/views/About/index.jsx | 22 - src/common/components/views/Hello/index.jsx | 22 - src/common/components/views/Home/index.jsx | 15 - src/common/components/views/Posts/Post.jsx | 22 - src/common/components/views/Posts/index.jsx | 50 - .../components/views/SlideInLeft/index.jsx | 47 - src/common/components/views/Tabs/Tab1.jsx | 11 - src/common/components/views/Tabs/Tab2.jsx | 11 - src/common/config/dev.js | 10 + src/common/config/index.js | 3 + src/common/config/prod.js | 7 + src/common/containers/DevTools.jsx | 13 - src/common/containers/Root.js | 3 - src/common/containers/RootDev.jsx | 29 - src/common/containers/RootProd.jsx | 26 - src/common/layouts/AppLayout/AppLayout.jsx | 36 + src/common/layouts/AppLayout/index.js | 6 + src/common/layouts/AppLayout/index.jsx | 69 - src/common/redux/actions/CounterActions.js | 27 +- .../redux/constants/CounterConstants.js | 4 - src/common/redux/middleware/logger.js | 24 +- src/common/redux/reducers/counter.js | 10 +- src/common/redux/reducers/index.js | 0 src/common/redux/store/configureStoreDev.js | 27 +- src/common/redux/store/configureStoreProd.js | 12 +- src/common/redux/store/index.js | 3 +- src/common/routes/AboutRoute.js | 7 + src/common/routes/CounterRoute.js | 7 + src/common/routes/HelloRoute.js | 7 + src/common/routes/HomeRoute.js | 6 + src/common/routes/NotFoundRoute.js | 7 + src/common/routes/index.js | 22 + src/common/routes/index.jsx | 26 - src/common/styles/global/app.css | 60 +- src/common/styles/global/core.css | 6 - src/common/styles/global/transitions.css | 89 - src/common/styles/global/variables.css | 2 +- src/common/styles/global/views/hello.css | 8 +- src/common/styles/global/views/home.css | 25 +- src/common/styles/global/views/index.css | 2 - src/common/styles/global/views/post.css | 3 - src/common/styles/global/views/posts.css | 3 - src/common/styles/local/title.css | 3 + src/common/views/AboutView/AboutView.css | 3 + src/common/views/AboutView/AboutView.jsx | 15 + src/common/views/AboutView/index.js | 3 + src/common/views/CounterView/CounterView.jsx | 27 + src/common/views/CounterView/index.js | 12 + src/common/views/HelloView/HelloView.jsx | 18 + src/common/views/HelloView/index.js | 3 + src/common/views/HomeView/HomeView.jsx | 19 + src/common/views/HomeView/index.js | 3 + .../views/Home => views/HomeView}/kiki.jpg | Bin src/server/components/Html/index.jsx | 48 +- src/server/index.js | 38 +- src/server/{server.dev.js => koa.dev.js} | 11 +- src/server/koa.prod.js | 57 + src/server/server.prod.js | 22 - src/server/utils/{index.js => render.js} | 19 +- webpack/dev.config.js | 144 +- webpack/dev.server.js | 2 +- webpack/isomorphic.tools.config.js | 32 +- webpack/middleware/webpack-dev.js | 15 +- webpack/middleware/webpack-hot.js | 0 webpack/prod.config.js | 143 +- webpack/server.config.js | 115 + webpack/test.config.js | 99 + yarn.lock | 8102 +++++++++++++++++ 97 files changed, 10524 insertions(+), 914 deletions(-) mode change 100755 => 100644 .babelrc mode change 100755 => 100644 .editorconfig mode change 100755 => 100644 .eslintrc.yaml mode change 100755 => 100644 .gitignore create mode 100644 .release.json mode change 100755 => 100644 .travis.yml create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE mode change 100755 => 100644 README.md create mode 100644 __tests__/.eslintrc.yaml create mode 100644 __tests__/components/Hello/hello.spec.js create mode 100644 __tests__/example.spec.js create mode 100644 __tests__/index.test.js mode change 100755 => 100644 config/index.js delete mode 100755 index.js create mode 100644 karma.conf.js create mode 100644 nodemon.json create mode 100644 postcss.config.js create mode 100644 readyToDeploy/README.md create mode 100644 readyToDeploy/package.json rename {static => readyToDeploy/static}/favicon.ico (100%) mode change 100755 => 100644 create mode 100644 readyToDeploy/static/humans.txt create mode 100644 readyToDeploy/static/robots.txt create mode 100644 readyToDeploy/yarn.lock mode change 100755 => 100644 src/client/index.js create mode 100644 src/common/components/Hello/Hello.jsx create mode 100644 src/common/components/Hello/index.js delete mode 100755 src/common/components/views/About/index.jsx delete mode 100755 src/common/components/views/Hello/index.jsx delete mode 100755 src/common/components/views/Home/index.jsx delete mode 100644 src/common/components/views/Posts/Post.jsx delete mode 100644 src/common/components/views/Posts/index.jsx delete mode 100644 src/common/components/views/SlideInLeft/index.jsx delete mode 100644 src/common/components/views/Tabs/Tab1.jsx delete mode 100644 src/common/components/views/Tabs/Tab2.jsx create mode 100644 src/common/config/dev.js create mode 100644 src/common/config/index.js create mode 100644 src/common/config/prod.js delete mode 100755 src/common/containers/DevTools.jsx delete mode 100755 src/common/containers/Root.js delete mode 100755 src/common/containers/RootDev.jsx delete mode 100755 src/common/containers/RootProd.jsx create mode 100644 src/common/layouts/AppLayout/AppLayout.jsx create mode 100644 src/common/layouts/AppLayout/index.js delete mode 100755 src/common/layouts/AppLayout/index.jsx mode change 100755 => 100644 src/common/redux/actions/CounterActions.js delete mode 100755 src/common/redux/constants/CounterConstants.js mode change 100755 => 100644 src/common/redux/middleware/logger.js mode change 100755 => 100644 src/common/redux/reducers/counter.js mode change 100755 => 100644 src/common/redux/reducers/index.js mode change 100755 => 100644 src/common/redux/store/configureStoreDev.js mode change 100755 => 100644 src/common/redux/store/configureStoreProd.js mode change 100755 => 100644 src/common/redux/store/index.js create mode 100644 src/common/routes/AboutRoute.js create mode 100644 src/common/routes/CounterRoute.js create mode 100644 src/common/routes/HelloRoute.js create mode 100644 src/common/routes/HomeRoute.js create mode 100644 src/common/routes/NotFoundRoute.js create mode 100644 src/common/routes/index.js delete mode 100755 src/common/routes/index.jsx mode change 100755 => 100644 src/common/styles/global/app.css delete mode 100644 src/common/styles/global/core.css delete mode 100644 src/common/styles/global/transitions.css mode change 100755 => 100644 src/common/styles/global/variables.css mode change 100755 => 100644 src/common/styles/global/views/hello.css mode change 100755 => 100644 src/common/styles/global/views/home.css mode change 100755 => 100644 src/common/styles/global/views/index.css delete mode 100644 src/common/styles/global/views/post.css delete mode 100644 src/common/styles/global/views/posts.css create mode 100644 src/common/styles/local/title.css create mode 100644 src/common/views/AboutView/AboutView.css create mode 100644 src/common/views/AboutView/AboutView.jsx create mode 100644 src/common/views/AboutView/index.js create mode 100644 src/common/views/CounterView/CounterView.jsx create mode 100644 src/common/views/CounterView/index.js create mode 100644 src/common/views/HelloView/HelloView.jsx create mode 100644 src/common/views/HelloView/index.js create mode 100644 src/common/views/HomeView/HomeView.jsx create mode 100644 src/common/views/HomeView/index.js rename src/common/{components/views/Home => views/HomeView}/kiki.jpg (100%) mode change 100755 => 100644 mode change 100755 => 100644 src/server/components/Html/index.jsx mode change 100755 => 100644 src/server/index.js rename src/server/{server.dev.js => koa.dev.js} (73%) mode change 100755 => 100644 create mode 100644 src/server/koa.prod.js delete mode 100755 src/server/server.prod.js rename src/server/utils/{index.js => render.js} (71%) mode change 100755 => 100644 mode change 100755 => 100644 webpack/dev.config.js mode change 100755 => 100644 webpack/dev.server.js mode change 100755 => 100644 webpack/isomorphic.tools.config.js mode change 100755 => 100644 webpack/middleware/webpack-dev.js mode change 100755 => 100644 webpack/middleware/webpack-hot.js mode change 100755 => 100644 webpack/prod.config.js create mode 100644 webpack/server.config.js create mode 100644 webpack/test.config.js create mode 100644 yarn.lock diff --git a/.babelrc b/.babelrc old mode 100755 new mode 100644 index aa2d4fd..2a3c10f --- a/.babelrc +++ b/.babelrc @@ -1,7 +1,19 @@ { - "presets": ["es2015", "react", "stage-0"], + "presets": [["latest", { "modules": false }], "react", "stage-0"], "plugins": ["transform-runtime"], "env": { + "test": { + "plugins": [ + [ + "istanbul", { + "exclude": ["**/*.spec.js"] + } + ] + ] + }, + "server": { + "plugins": ["system-import-transformer"] + }, "production": { "presets": ["react-optimize"] } diff --git a/.editorconfig b/.editorconfig old mode 100755 new mode 100644 diff --git a/.eslintrc.yaml b/.eslintrc.yaml old mode 100755 new mode 100644 index ac3ca67..195fc12 --- a/.eslintrc.yaml +++ b/.eslintrc.yaml @@ -3,12 +3,7 @@ env: browser: true node: true es6: true -parserOptions: - sourceType: module - ecmaVersion: 7 - ecmaFeatures: - jsx: true - experimentalObjectRestSpread: true +parser: babel-eslint plugins: - react - jsx-a11y @@ -29,9 +24,13 @@ globals: __SERVER__: false __DEV__: false __PROD__: false - __DEBUG__: false webpackIsomorphicTools: false rules: semi: [2, "never"] - comma-dangle: [1, "never"] + comma-dangle: 0 no-underscore-dangle: off + global-require: 0 + react/forbid-prop-types: 0 + react/jsx-filename-extension: [1, { "extensions": [".js", ".jsx"] }] + react/prefer-stateless-function: [2, {"ignorePureComponents": true}] + react/require-extension: "off" diff --git a/.gitignore b/.gitignore old mode 100755 new mode 100644 index d4742e8..319cd70 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,15 @@ dist .sass-cache build/* reports +coverage + +# ready to deploy +readyToDeploy/* +!readyToDeploy/static +!readyToDeploy/package.json +!readyToDeploy/yarn.lock +!readyToDeploy/README.md +readyToDeploy/static/dist/ # webpack-isomorphic-tools webpack-assets.json diff --git a/.release.json b/.release.json new file mode 100644 index 0000000..e00aa1f --- /dev/null +++ b/.release.json @@ -0,0 +1,17 @@ +{ + "non-interactive": false, + "dry-run": false, + "verbose": true, + "force": false, + "pkgFiles": ["package.json"], + "increment": "patch", + "commitMessage": "Release %s", + "tagName": "%s", + "tagAnnotation": "Release %s", + "changelogCommand": "conventional-changelog -p angular -i CHANGELOG.md -s", + "github": { + "release": true, + "releaseName": "Release %s", + "tokenRef": "GITHUB_API_TOKEN" + } +} diff --git a/.travis.yml b/.travis.yml old mode 100755 new mode 100644 diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..ba861e0 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,133 @@ + +# [2.0.2](https://github.com/kiki-le-singe/react-redux-universal-boilerplate/compare/v2.0.1...v2.0.2) (2017-01-18) + + +### Bug Fixes + +* **webpack.cssnext:** change include path ([06173ea](https://github.com/kiki-le-singe/react-redux-universal-boilerplate/commit/06173ea)) + + + + +# [2.0.0](https://github.com/kiki-le-singe/react-redux-universal-boilerplate/compare/v1.8.1...v2.0.0) (2017-01-13) + + +### Bug Fixes + +* **koa.prod:** update path ([992fee2](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/992fee2)) +* **package:** fix json error ([43d4922](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/43d4922)) +* **setup:** remove wrong command line ([269ae83](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/269ae83)) +* **webpack:** fix syntax error ([da61df6](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/da61df6)) + + +### Features + +* **AboutView:** add About view ([a1e5a0e](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/a1e5a0e)) +* **AboutView.cssnext:** add About view cssnext ([6965cd8](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/6965cd8)) +* **AppLayout:** add counter link ([58d45ee](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/58d45ee)) +* **AppLayout:** implement App Layout ([dbb15be](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/dbb15be)) +* **AppLayout.cssnext:** implement App Layout cssnext ([60f9e86](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/60f9e86)) +* **config:** add DIR_PROJECT_CONFIG constant ([7979583](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/7979583)) +* **config:** add project config ([7add9f1](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/7add9f1)) +* **config:** set staticDir ([be032c3](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/be032c3)) +* **config:** update config ([782d537](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/782d537)) +* **config:** update configuration ([6cd7c6b](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/6cd7c6b)) +* **Counter:** add Counter route ([516f0a1](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/516f0a1)) +* **Counter:** add Counter view ([90ce274](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/90ce274)) +* **HelloView:** add Hello view ([7f6bbb2](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/7f6bbb2)) +* **HomeView:** implement Home view ([b8a4c74](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/b8a4c74)) +* **Html:** transform Html as component ([9577eee](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/9577eee)) +* **Html:** use serialize-javascript package ([053416e](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/053416e)) +* **koa:** implement htmlMinifier ([fe9f890](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/fe9f890)) +* **koa:** implement koa-compress ([cdbefef](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/cdbefef)) +* **koa:** implement koa-helmet package ([caa6410](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/caa6410)) +* **koa:** implement static cache ([6c64e90](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/6c64e90)) +* **react.perf:** implement whyDidYouUpdate tool ([a233c5f](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/a233c5f)) +* **redux:** add counter actions ([4cb5fc1](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/4cb5fc1)) +* **redux:** add counter reducer ([a7141c8](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/a7141c8)) +* **redux:** add logger middleware ([580446e](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/580446e)) +* **redux:** add store ([604caff](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/604caff)) +* **render:** add render utils file ([ef8ef3f](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/ef8ef3f)) +* **routes:** add AboutRoute ([ec31c9d](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/ec31c9d)) +* **routes:** add HelloRoute ([beb81a0](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/beb81a0)) +* **routes:** add HomeRoute route ([f7d855d](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/f7d855d)) +* **routes:** add NotFoundRoute ([e5f7f83](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/e5f7f83)) +* **routes:** add some routes ([040daf1](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/040daf1)) +* **routes:** transform jsx routes to plain routes ([0c77ea1](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/0c77ea1)) +* **routes:** use routes as function to pass some options ([f07818d](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/f07818d)) +* **server:** update server ([12d87dc](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/12d87dc)) +* **server:** use babel-register instead of babel-node for prod mode ([ebbaf28](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/ebbaf28)) +* **setup:** add next setup file ([e350fd6](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/e350fd6)) +* **setup:** Remove bin dir ([6256e0f](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/6256e0f)) +* **styles:** add default(scss) styles ([344a856](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/344a856)) +* **styles.cssnext:** add cssnext styles ([fcd4eaa](https://github.com/kiki-le-singe/react-redux-universal-boilerplate-next/commit/fcd4eaa)) + + + + +# [1.8.1](https://github.com/kiki-le-singe/react-redux-universal-boilerplate/compare/v1.8.0...v1.8.1) (2016-10-31) + + +### Bug Fixes + +* **package:** add missing `ext` option ([73a8395](https://github.com/kiki-le-singe/react-redux-universal-boilerplate/commit/73a83954902a0d0bff73d7306f27166e53f7ddff)) + + + +# [1.8.0](https://github.com/kiki-le-singe/react-redux-universal-boilerplate/compare/v1.7.0...v1.8.0) (2016-10-16) + + +### Features + +* **yarn:** add yarn file ([b7941dd](https://github.com/kiki-le-singe/react-redux-universal-boilerplate/commit/b7941dd)) +* **README:** update documentation ([a01d845](https://github.com/kiki-le-singe/react-redux-universal-boilerplate/commit/a01d845)) + + + + +# [1.7.0](https://github.com/kiki-le-singe/react-redux-universal-boilerplate/compare/v1.6.0...v1.7.0) (2016-09-25) + + +### Features + +* **babel:** implement babel latest preset ([78f2b0d](https://github.com/kiki-le-singe/react-redux-universal-boilerplate/commit/78f2b0d)) +* **babel:** implement transform-react-jsx-source plugin ([4a818d5](https://github.com/kiki-le-singe/react-redux-universal-boilerplate/commit/4a818d5)) + + + + +# [1.6.0](https://github.com/kiki-le-singe/react-redux-universal-boilerplate/compare/v1.4.1...v1.6.0) (2016-09-16) + + +### Features + +* **react.perf:** implement whyDidYouUpdate tool ([57a87e1](https://github.com/kiki-le-singe/react-redux-universal-boilerplate/commit/57a87e1)) + + + + +# [1.4.1](https://github.com/kiki-le-singe/react-redux-universal-boilerplate/compare/v1.4.0...v1.4.1) (2016-09-11) + + +### Bug Fixes + +* **webpack.dev:** set devtool to `source-map` ([25d9864](https://github.com/kiki-le-singe/react-redux-universal-boilerplate/commit/25d9864ec794b5002272c0b3eb702923eb877aeb)) + + + + +# [1.3.0](https://github.com/kiki-le-singe/react-redux-universal-boilerplate/compare/v1.0.10...v1.3.0) (2016-09-10) + + +### Bug Fixes + +* **karma.conf:** import missing yargs package ([80162a4](https://github.com/kiki-le-singe/react-redux-universal-boilerplate/commit/80162a4)) + +### Features + +* **config:** use local ip as default server host ([efe8350](https://github.com/kiki-le-singe/react-redux-universal-boilerplate/commit/efe8350)) +* **Hello:** add Hello component ([fb4c54a](https://github.com/kiki-le-singe/react-redux-universal-boilerplate/commit/fb4c54a)) +* **Hello:** set className attribute to `hello` ([733a0ee](https://github.com/kiki-le-singe/react-redux-universal-boilerplate/commit/733a0ee)) +* **HelloView:** implement the Hello component ([32b6416](https://github.com/kiki-le-singe/react-redux-universal-boilerplate/commit/32b6416)) +* **test.config:** setup webpack to use enzyme ([b8ae060](https://github.com/kiki-le-singe/react-redux-universal-boilerplate/commit/b8ae060)) +* **webpack.prod:** generate a manifest file ([b86de24](https://github.com/kiki-le-singe/react-redux-universal-boilerplate/commit/b86de24)) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..90408c1 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,53 @@ +# Contributing + +I am open to any contributions made by you. + +### Linting + +Please check your code using `npm run lint` before submitting your pull requests. + +> Some .cssnext.js files will display an error. This is normal because we use sass as default extension language. + + +### Testing + +Please check your code using `npm run test` before submitting your pull requests. + + +### Commit Message Format + +Each commit message should include a **type**, a **scope** and a **subject**: + +``` + (): +``` + +Any line of the commit message cannot be longer 100 characters! This allows the message to be easier to read on GitHub as well as in various git tools. + +#### Type + +Must be one of the following: + +* **feat**: A new feature +* **fix**: A bug fix +* **docs**: Documentation only changes +* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing + semi-colons, etc) +* **refactor**: A code change that neither fixes a bug or adds a feature +* **perf**: A code change that improves performance +* **test**: Adding missing tests +* **chore**: Changes to the build process or auxiliary tools and libraries such as documentation + generation + +#### Scope + +The scope could be anything specifying place of the commit change. For example `webpack`, `server`, +`eslint`, `babel`, `reactComponentName` etc... + +#### Subject + +The subject contains succinct description of the change: + +* use the imperative, present tense: "change" not "changed" nor "changes" +* don't capitalize first letter +* no dot (.) at the end diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9e2fccb --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Anthony Albertini + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md old mode 100755 new mode 100644 diff --git a/__tests__/.eslintrc.yaml b/__tests__/.eslintrc.yaml new file mode 100644 index 0000000..ca4916c --- /dev/null +++ b/__tests__/.eslintrc.yaml @@ -0,0 +1,7 @@ +extends: ../.eslintrc.yaml +env: + mocha: true +globals: + expect: false + should: false + sinon: false diff --git a/__tests__/components/Hello/hello.spec.js b/__tests__/components/Hello/hello.spec.js new file mode 100644 index 0000000..1af17fa --- /dev/null +++ b/__tests__/components/Hello/hello.spec.js @@ -0,0 +1,22 @@ +import React from 'react' +import { mount, render, shallow } from 'enzyme' +import Hello from 'common/components/Hello' + +describe('Hello', () => { + it('renders an `.hello`', () => { + const wrapper = shallow() + expect(wrapper.find('.hello')).to.have.length(1) + }) + + it('should contain `Hello World`', () => { + const wrapper = render() + expect(wrapper.text()).to.contain('Hello World') + }) + + it('allows us to set props', () => { + const wrapper = mount() + expect(wrapper.props().name).to.equal('baz') + wrapper.setProps({ name: 'foo' }) + expect(wrapper.props().name).to.equal('foo') + }) +}) diff --git a/__tests__/example.spec.js b/__tests__/example.spec.js new file mode 100644 index 0000000..6c30d96 --- /dev/null +++ b/__tests__/example.spec.js @@ -0,0 +1,46 @@ +import React from 'react' +import { mount, render, shallow } from 'enzyme' + +const Fixture = () => ( +
+ test +
+) + +function hello(name, cb) { + cb(`hello ${name}`) +} + +// Using of Chai +describe('add', () => { + it('adds', () => { + expect(1 + 1).to.equal(2) + }) +}) + +// Using of Sinon–Chai +describe('hello', () => { + it('should call callback with correct greeting', () => { + const cb = sinon.spy() + + hello('foo', cb) + + cb.should.have.been.calledWith('hello foo') + }) +}) + +// Using of enzyme +describe('Fixture', () => { + it('should have enzyme working', () => { + let wrapper = shallow() + expect(wrapper.find('.root')).to.have.length(1) + expect(wrapper.find('.child')).to.have.length(1) + + wrapper = mount() + wrapper.setProps({ bar: 'foo' }) + expect(wrapper.props().bar).to.equal('foo') + + wrapper = render() + expect(wrapper.text()).to.contain('test') + }) +}) diff --git a/__tests__/index.test.js b/__tests__/index.test.js new file mode 100644 index 0000000..10165d2 --- /dev/null +++ b/__tests__/index.test.js @@ -0,0 +1,15 @@ +import sinon from 'sinon' +import chai from 'chai' +import sinonChai from 'sinon-chai' + +chai.use(sinonChai) + +global.chai = chai +global.sinon = sinon +global.expect = chai.expect +global.should = chai.should() + +// require all modules ending in "_test" from the +// current directory and all subdirectories +const testsContext = require.context('.', true, /spec$/) +testsContext.keys().forEach(testsContext) diff --git a/config/index.js b/config/index.js old mode 100755 new mode 100644 index 72d3ceb..03ef3f1 --- a/config/index.js +++ b/config/index.js @@ -1,5 +1,5 @@ -import { argv } from 'yargs' import path from 'path' +import ip from 'ip' const NODE_ENV = process.env.NODE_ENV || 'development' @@ -10,10 +10,9 @@ const config = { __SERVER__: false, __DEV__: NODE_ENV === 'development', __PROD__: NODE_ENV === 'production', - __DEBUG__: !!argv.debug, // Server Configuration - SERVER_HOST: 'localhost', + SERVER_HOST: process.env.HOST || ip.address(), SERVER_PORT: process.env.PORT || 3000, // Webpack Configuration @@ -25,7 +24,6 @@ const config = { 'react-router', 'react-router-redux', 'redux', - 'classnames' ], // Project Structure @@ -36,10 +34,12 @@ const config = { DIR_GLOBAL_STYLES: 'common/styles/global', DIR_STATIC: 'static', DIR_DIST: 'dist', + DIR_READY_TO_DEPLOY: 'readyToDeploy', DIR_BUILD: 'build', DIR_SERVER: 'server', DIR_TEST: '__tests__', - DIR_NODE_MODULES: 'node_modules' + DIR_NODE_MODULES: 'node_modules', + DIR_PROJECT_CONFIG: 'config', } const paths = (dir = 'base') => { @@ -50,13 +50,17 @@ const paths = (dir = 'base') => { const _paths = { base: base(), entryApp: base(config.DIR_SRC, config.DIR_CLIENT, config.ENTRY_APP), + entryServer: base(config.DIR_SRC, config.DIR_SERVER, config.ENTRY_APP), src: base(config.DIR_SRC), globalStyles: base(config.DIR_SRC, config.DIR_GLOBAL_STYLES), - dist: base(config.DIR_STATIC, config.DIR_DIST), + dist: base(config.DIR_READY_TO_DEPLOY, config.DIR_STATIC, config.DIR_DIST), + distServer: base(config.DIR_READY_TO_DEPLOY), + staticDir: base(config.DIR_STATIC), build: base(config.DIR_BUILD), server: base(config.DIR_SERVER), test: base(config.DIR_TEST), - nodeModules: base(config.DIR_NODE_MODULES) + nodeModules: base(config.DIR_NODE_MODULES), + projectConfig: base(config.DIR_PROJECT_CONFIG), } return _paths[dir] diff --git a/index.js b/index.js deleted file mode 100755 index 548e337..0000000 --- a/index.js +++ /dev/null @@ -1 +0,0 @@ -require('./src/client') diff --git a/karma.conf.js b/karma.conf.js new file mode 100644 index 0000000..0faee4d --- /dev/null +++ b/karma.conf.js @@ -0,0 +1,31 @@ +import { argv } from 'yargs' +import _debug from 'debug' +import webpackTestConfig from './webpack/test.config' + +const debug = _debug('app:karma') +debug('Create configuration.') + +const karmaConfig = { + frameworks: ['mocha'], + reporters: ['spec', 'coverage'], + files: ['__tests__/index.test.js'], + preprocessors: { + '__tests__/index.test.js': ['webpack', 'sourcemap'] + }, + browsers: [ + // 'Chrome', + 'PhantomJS' + ], + singleRun: !argv.watch, + coverageReporter: { + dir: 'coverage/', + type: 'html' + }, + webpack: webpackTestConfig, + webpackMiddleware: { + noInfo: true + } +} + +// cannot use `export default` because of Karma. +module.exports = (config) => config.set(karmaConfig) diff --git a/nodemon.json b/nodemon.json new file mode 100644 index 0000000..77d61da --- /dev/null +++ b/nodemon.json @@ -0,0 +1,9 @@ +{ + "watch": [ + "webpack/", + "src/server/index.js", + "src/server/koa.dev.js", + "src/server/utils/render.js", + "src/server/components/Html/index.jsx" + ] +} diff --git a/package.json b/package.json index bafa4cb..0a668cf 100644 --- a/package.json +++ b/package.json @@ -7,99 +7,212 @@ "license": "MIT", "repository": { "type": "git", - "url": "https://github.com/kiki-le-singe/react-router-animation-examples.git" + "url": "https://github.com/kiki-le-singe/react-router-animation-examples" }, "homepage": "https://github.com/kiki-le-singe/react-router-animation-examples", "bugs": "https://github.com/kiki-le-singe/react-router-animation-examples/issues", "keywords": [ + "starter", "boilerplate", "react", "react-router", + "react-helmet", "redux", - "es6", - "ES2015", - "es7", + "es2015", + "es2016", + "es2017", "babel", "webpack", "hot", "reload", "hmr", + "hot-loader", "koa", - "cssnext", "postcss", + "cssnext", + "sass", "css-modules", + "ssr", "isomorphic", - "universal" + "universal", + "karma", + "mocha", + "sinon", + "chai", + "enzyme" ], - "description": "Simple example using React's Animations with React Router", + "description": "Get started with a Universal boilerplate containing tools like React, Redux, Koa...", "engines": { - "node": ">=5.0.0", - "npm": "^3.3.12" + "node": ">=6.0.0", + "npm": "^3.8.6" }, + "main": "src/server/index.js", "dependencies": { - "classnames": "^2.2.5", - "debug": "^2.2.0", + "autoprefixer": "^6.7.0", + "babel-core": "^6.22.1", + "babel-runtime": "^6.20.0", + "better-npm-run": "0.0.14", + "debug": "^2.6.0", + "extract-text-webpack-plugin": "^2.0.0-rc.2", + "fs-extra": "^2.0.0", + "globby": "^6.1.0", + "inquirer": "^3.0.1", + "ip": "^1.1.4", "koa": "^2.0.0", + "koa-compress": "next", "koa-convert": "^1.2.0", - "koa-proxy": "^0.6.0", + "koa-helmet": "^2.0.0", + "koa-html-minifier": "^1.0.1", + "koa-proxy": "^0.7.0", "koa-static": "^3.0.0", - "normalize.css": "^4.1.1", - "react": "^15.3.1", - "react-addons-css-transition-group": "^15.3.1", - "react-dom": "^15.3.1", - "react-redux": "^4.4.5", - "react-router": "^2.8.1", - "react-router-redux": "^4.0.2", + "koa-static-cache": "^3.2.0", + "koa-webpack-dev-middleware": "^1.3.0", + "koa-webpack-hot-middleware": "^1.0.3", + "normalize.css": "^5.0.0", + "purifycss-webpack-plugin": "^2.0.3", + "react": "^15.4.2", + "react-addons-css-transition-group": "^15.4.2", + "react-dom": "^15.4.2", + "react-helmet": "^4.0.0", + "react-hot-loader": "^3.0.0-beta.6", + "react-redux": "^5.0.2", + "react-router": "^3.0.2", + "react-router-redux": "^4.0.7", "redux": "^3.6.0", - "serve-static": "^1.10.0", - "webpack-isomorphic-tools": "^2.3.0", - "yargs": "^4.7.1" + "serialize-javascript": "^1.3.0", + "source-map-support": "^0.4.11", + "webpack": "^2.2.0", + "webpack-isomorphic-tools": "^2.6.6", + "webpack-md5-hash": "^0.0.5", + "why-did-you-update": "^0.0.8" }, "devDependencies": { - "babel-cli": "^6.9.0", - "babel-core": "^6.9.0", - "babel-eslint": "^6.0.3", - "babel-loader": "^6.2.4", - "babel-plugin-transform-runtime": "^6.9.0", - "babel-preset-es2015": "^6.9.0", - "babel-preset-react": "^6.5.0", + "babel-cli": "^6.22.2", + "babel-eslint": "^7.1.0", + "babel-loader": "^6.2.10", + "babel-plugin-istanbul": "^3.1.2", + "babel-plugin-system-import-transformer": "^2.4.0", + "babel-plugin-transform-react-jsx-source": "^6.22.0", + "babel-plugin-transform-runtime": "^6.22.0", + "babel-preset-latest": "^6.22.0", + "babel-preset-react": "^6.22.0", "babel-preset-react-optimize": "^1.0.1", - "babel-preset-stage-0": "^6.5.0", - "babel-register": "^6.9.0", - "babel-runtime": "^6.9.0", - "copy-webpack-plugin": "^3.0.0", - "css-loader": "^0.23.1", - "eslint": "^2.11.0", - "eslint-config-airbnb": "^9.0.1", - "eslint-loader": "^1.3.0", - "eslint-plugin-babel": "^3.2.0", - "eslint-plugin-import": "^1.8.1", - "eslint-plugin-jsx-a11y": "^1.2.2", - "eslint-plugin-react": "^5.1.1", - "extract-text-webpack-plugin": "^1.0.1", - "file-loader": "^0.8.5", + "babel-preset-stage-0": "^6.22.0", + "chai": "^3.5.0", + "clean-webpack-plugin": "^0.1.15", + "css-loader": "^0.26.1", + "enzyme": "^2.7.1", + "eslint": "^3.14.1", + "eslint-config-airbnb": "^14.0.0", + "eslint-loader": "^1.6.1", + "eslint-plugin-import": "^2.2.0", + "eslint-plugin-jsx-a11y": "^3.0.2", + "eslint-plugin-react": "^6.9.0", + "file-loader": "^0.10.0", + "image-webpack-loader": "^3.2.0", "json-loader": "^0.5.4", - "koa-webpack-dev-middleware": "^1.2.1", - "koa-webpack-hot-middleware": "^1.0.3", - "npm-run-all": "^2.3.0", - "postcss-cssnext": "^2.5.2", - "postcss-import": "^8.1.2", - "postcss-loader": "^0.9.1", - "postcss-url": "^5.1.2", - "redux-devtools": "^3.3.1", - "redux-devtools-dock-monitor": "^1.1.1", - "redux-devtools-log-monitor": "^1.0.11", + "karma": "^1.4.0", + "karma-chrome-launcher": "^2.0.0", + "karma-coverage": "^1.1.1", + "karma-mocha": "^1.3.0", + "karma-phantomjs-launcher": "^1.0.2", + "karma-sourcemap-loader": "^0.3.7", + "karma-spec-reporter": "^0.0.26", + "karma-webpack": "^2.0.2", + "mocha": "^3.2.0", + "node-sass": "^4.4.0", + "nodemon": "^1.11.0", + "npm-run-all": "^4.0.1", + "postcss": "^5.2.11", + "postcss-cssnext": "^2.9.0", + "postcss-loader": "^1.2.2", + "postcss-smart-import": "^0.6.7", + "react-addons-test-utils": "^15.4.2", + "react-hot-loader": "^3.0.0-beta.6", + "sass-loader": "^4.1.0", + "sinon": "^1.17.7", + "sinon-chai": "^2.8.0", "style-loader": "^0.13.1", "url-loader": "^0.5.7", - "webpack": "^1.13.1" + "webpack-node-externals": "^1.5.4" }, "scripts": { - "compile": "NODE_ENV=production babel-node ./node_modules/.bin/webpack --optimize-minimize --progress --config ./webpack/prod.config", - "clean:dist": "rm -rf static/dist", - "deploy": "npm run clean:dist && npm run compile && npm run prod", - "prod": "DEBUG=app:* NODE_PATH=src NODE_ENV=production babel-node src/server/index.js", - "start": "npm-run-all --parallel start:client:server start:server", - "start:server": "DEBUG=app:* NODE_PATH=src babel-node -- src/server/index.js", - "start:client:server": "DEBUG=app:* babel-node webpack/dev.server.js" + "build:client": "better-npm-run build:client", + "build:server": "better-npm-run build:server", + "deploy": "better-npm-run deploy", + "start": "better-npm-run start", + "dev": "better-npm-run dev", + "start:server": "better-npm-run start:server", + "start:client:server": "better-npm-run start:client:server", + "test": "better-npm-run test", + "test:dev": "npm run test -- --watch", + "lint": "eslint src tests --ext .jsx,.js", + "setup": "better-npm-run setup", + "postinstall": "npm run setup" + }, + "betterScripts": { + "dev": { + "command": "npm-run-all --parallel start:client:server start:server", + "env": { + "NODE_ENV": "development", + "DEBUG": "app:*" + } + }, + "start": { + "command": "npm run dev", + "env": { + "NODE_ENV": "development", + "BABEL_ENV": "server", + "DEBUG": "app:*" + } + }, + "start:client:server": { + "command": "babel-node -- webpack/dev.server", + "env": { + "NODE_ENV": "development", + "DEBUG": "app:*" + } + }, + "start:server": { + "command": "nodemon ./node_modules/.bin/babel-node -- src/server/index", + "env": { + "NODE_ENV": "development", + "NODE_PATH": "src", + "DEBUG": "app:*" + } + }, + "deploy": { + "command": "npm run build:client && npm run build:server" + }, + "build:client": { + "command": "./node_modules/.bin/babel-node node_modules/.bin/webpack --progress --config webpack/prod.config", + "env": { + "NODE_ENV": "production", + "NODE_PATH": "src", + "DEBUG": "app:*" + } + }, + "build:server": { + "command": "./node_modules/.bin/babel-node node_modules/.bin/webpack --progress --config webpack/server.config", + "env": { + "NODE_ENV": "production", + "BABEL_ENV": "server", + "NODE_PATH": "src", + "DEBUG": "app:*" + } + }, + "test": { + "command": "babel-node node_modules/.bin/karma start", + "env": { + "NODE_ENV": "test", + "DEBUG": "app:*" + } + }, + "setup": { + "command": "babel-node bin/setup", + "env": { + "DEBUG": "app:*" + } + } } } diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..13fe57b --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,8 @@ +/* Set your postcss-loader configuration here */ + +module.exports = { + plugins: { + 'postcss-smart-import': {}, + 'postcss-cssnext': {}, + }, +} diff --git a/readyToDeploy/README.md b/readyToDeploy/README.md new file mode 100644 index 0000000..37f7073 --- /dev/null +++ b/readyToDeploy/README.md @@ -0,0 +1,27 @@ +# React Redux Universal Boilerplate + +An Universal ReactJS/Redux Boilerplate. + +## Requirements + + * [nodejs](http://nodejs.org/) + +> Node `>=6.0.0` + +## Optional + + * [yarn](https://yarnpkg.com/) + +## Installation + +```shell +$ npm install or yarn +``` + +## Scripts + +```shell +$ npm start +``` + +Starts the server to serve your app at `localip:3000`. diff --git a/readyToDeploy/package.json b/readyToDeploy/package.json new file mode 100644 index 0000000..728f649 --- /dev/null +++ b/readyToDeploy/package.json @@ -0,0 +1,36 @@ +{ + "name": "react-redux-universal-boilerplate", + "version": "0.0.0", + "description": "Get started with a Universal boilerplate containing tools like React, Redux, Koa...", + "engines": { + "node": ">=6.0.0", + "npm": "^3.8.6" + }, + "main": "server.js", + "dependencies": { + "babel-runtime": "^6.22.0", + "debug": "^2.6.0", + "ip": "^1.1.4", + "koa": "^2.0.0", + "koa-compress": "^2.0.0", + "koa-convert": "^1.2.0", + "koa-helmet": "^3.1.0", + "koa-html-minifier": "^1.0.1", + "koa-static": "^3.0.0", + "koa-static-cache": "^3.2.0", + "react": "^15.4.2", + "react-dom": "^15.4.2", + "react-helmet": "^4.0.0", + "react-redux": "^5.0.2", + "react-router": "^3.0.2", + "react-router-redux": "^4.0.7", + "redux": "^3.6.0", + "serialize-javascript": "^1.3.0", + "source-map-support": "^0.4.11" + }, + "scripts": { + "start": "DEBUG=app:* node server.js" + }, + "author": "Kiki le singe", + "license": "MIT" +} diff --git a/static/favicon.ico b/readyToDeploy/static/favicon.ico old mode 100755 new mode 100644 similarity index 100% rename from static/favicon.ico rename to readyToDeploy/static/favicon.ico diff --git a/readyToDeploy/static/humans.txt b/readyToDeploy/static/humans.txt new file mode 100644 index 0000000..5c8a523 --- /dev/null +++ b/readyToDeploy/static/humans.txt @@ -0,0 +1,17 @@ +# humanstxt.org/ +# The humans responsible & technology colophon + +# TEAM + + -- -- + +# THANKS + + + +# TECHNOLOGY COLOPHON + + CSS3, CSSNEXT, SASS, HTML5 + Javascript, React, Redux, Normalize.css + koa + Webpack, Babel diff --git a/readyToDeploy/static/robots.txt b/readyToDeploy/static/robots.txt new file mode 100644 index 0000000..d0e5f1b --- /dev/null +++ b/readyToDeploy/static/robots.txt @@ -0,0 +1,5 @@ +# www.robotstxt.org/ + +# Allow crawling of all content +User-agent: * +Disallow: diff --git a/readyToDeploy/yarn.lock b/readyToDeploy/yarn.lock new file mode 100644 index 0000000..5f74a4a --- /dev/null +++ b/readyToDeploy/yarn.lock @@ -0,0 +1,883 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +accepts@^1.2.2: + version "1.3.3" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.3.tgz#c3ca7434938648c3e0d9c1e328dd68b622c284ca" + dependencies: + mime-types "~2.1.11" + negotiator "0.6.1" + +align-text@^0.1.1, align-text@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" + dependencies: + kind-of "^3.0.2" + longest "^1.0.1" + repeat-string "^1.5.2" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + +any-promise@^1.0.0, any-promise@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + +asap@~2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.5.tgz#522765b50c3510490e52d7dcfe085ef9ba96958f" + +async@~0.2.6: + version "0.2.10" + resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" + +babel-runtime@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.22.0.tgz#1cf8b4ac67c77a4ddb0db2ae1f74de52ac4ca611" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.10.0" + +bytes@^2.3.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.4.0.tgz#7d97196f9d5baf7f6935e25985549edd2a6c2339" + +camel-case@3.0.x: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" + dependencies: + no-case "^2.2.0" + upper-case "^1.1.1" + +camelcase@^1.0.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" + +camelize@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" + +center-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" + dependencies: + align-text "^0.1.3" + lazy-cache "^1.0.3" + +clean-css@3.4.x: + version "3.4.23" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-3.4.23.tgz#604fbbca24c12feb59b02f00b84f1fb7ded6d001" + dependencies: + commander "2.8.x" + source-map "0.4.x" + +cliui@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" + dependencies: + center-align "^0.1.1" + right-align "^0.1.1" + wordwrap "0.0.2" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + +commander@2.8.x: + version "2.8.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4" + dependencies: + graceful-readlink ">= 1.0.0" + +commander@2.9.x: + version "2.9.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" + dependencies: + graceful-readlink ">= 1.0.0" + +compressible@^2.0.0, compressible@~2.0.6: + version "2.0.9" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.9.tgz#6daab4e2b599c2770dd9e21e7a891b1c5a755425" + dependencies: + mime-db ">= 1.24.0 < 2" + +connect@3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.5.0.tgz#b357525a0b4c1f50599cd983e1d9efeea9677198" + dependencies: + debug "~2.2.0" + finalhandler "0.5.0" + parseurl "~1.3.1" + utils-merge "1.0.0" + +content-disposition@~0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" + +content-security-policy-builder@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/content-security-policy-builder/-/content-security-policy-builder-1.1.0.tgz#d91f1b076236c119850c7dee9924bf55e05772b3" + dependencies: + dashify "^0.2.0" + +content-type@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.2.tgz#b7d113aee7a8dd27bd21133c4dc2529df1721eed" + +cookies@~0.6.1: + version "0.6.2" + resolved "https://registry.yarnpkg.com/cookies/-/cookies-0.6.2.tgz#6ac1b052895208e8fc4c4f5f86a9ed31b9cb5ccf" + dependencies: + depd "~1.1.0" + keygrip "~1.0.1" + +core-js@^1.0.0: + version "1.2.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" + +core-js@^2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" + +core-util-is@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + +dasherize@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dasherize/-/dasherize-2.0.0.tgz#6d809c9cd0cf7bb8952d80fc84fa13d47ddb1308" + +dashify@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/dashify/-/dashify-0.2.2.tgz#6a07415a01c91faf4a32e38d9dfba71f61cb20fe" + +debug@*: + version "2.5.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.5.2.tgz#50c295a53dbf1657146e0c1b21307275e90d49cb" + dependencies: + ms "0.7.2" + +debug@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.0.tgz#bc596bcabe7617f11d9fa15361eded5608b8499b" + dependencies: + ms "0.7.2" + +debug@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" + dependencies: + ms "0.7.1" + +decamelize@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + +deep-equal@1.0.1, deep-equal@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + +depd@^1.1.0, depd@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.0.tgz#e1bd82c6aab6ced965b97b88b17ed3e528ca18c3" + +destroy@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + +dns-prefetch-control@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/dns-prefetch-control/-/dns-prefetch-control-0.1.0.tgz#60ddb457774e178f1f9415f0cabb0e85b0b300b2" + +dont-sniff-mimetype@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dont-sniff-mimetype/-/dont-sniff-mimetype-1.0.0.tgz#5932890dc9f4e2f19e5eb02a20026e5e5efc8f58" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + +encoding@^0.1.11: + version "0.1.12" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" + dependencies: + iconv-lite "~0.4.13" + +error-inject@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/error-inject/-/error-inject-1.0.0.tgz#e2b3d91b54aed672f309d950d154850fa11d4f37" + +escape-html@~1.0.1, escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + +exenv@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.1.tgz#75de1c8dee02e952b102aa17f8875973e0df14f9" + +fbjs@^0.8.1, fbjs@^0.8.4: + version "0.8.8" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.8.tgz#02f1b6e0ea0d46c24e0b51a2d24df069563a5ad6" + dependencies: + core-js "^1.0.0" + isomorphic-fetch "^2.1.1" + loose-envify "^1.0.0" + object-assign "^4.1.0" + promise "^7.1.1" + setimmediate "^1.0.5" + ua-parser-js "^0.7.9" + +finalhandler@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-0.5.0.tgz#e9508abece9b6dba871a6942a1d7911b91911ac7" + dependencies: + debug "~2.2.0" + escape-html "~1.0.3" + on-finished "~2.3.0" + statuses "~1.3.0" + unpipe "~1.0.0" + +frameguard@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/frameguard/-/frameguard-3.0.0.tgz#7bcad469ee7b96e91d12ceb3959c78235a9272e9" + +fresh@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.3.0.tgz#651f838e22424e7566de161d8358caa199f83d4f" + +fs-readdir-recursive@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.0.0.tgz#8cd1745c8b4f8a29c8caec392476921ba195f560" + +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + +he@1.1.x: + version "1.1.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.1.0.tgz#29319d49beec13a9b1f3c4f9b2a6dde4859bb2a7" + +helmet-csp@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/helmet-csp/-/helmet-csp-2.3.0.tgz#bc341939dfef5266cc817abcf53f079f61fe7e3f" + dependencies: + camelize "1.0.0" + content-security-policy-builder "1.1.0" + dasherize "2.0.0" + lodash.reduce "4.6.0" + platform "1.3.3" + +helmet@^3.0.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/helmet/-/helmet-3.4.0.tgz#05a9437486b05ca219ed8d21dc5e3b6ec0c18118" + dependencies: + connect "3.5.0" + dns-prefetch-control "0.1.0" + dont-sniff-mimetype "1.0.0" + frameguard "3.0.0" + helmet-csp "2.3.0" + hide-powered-by "1.0.0" + hpkp "2.0.0" + hsts "2.0.0" + ienoopen "1.0.0" + nocache "2.0.0" + referrer-policy "1.1.0" + x-xss-protection "1.0.0" + +hide-powered-by@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/hide-powered-by/-/hide-powered-by-1.0.0.tgz#4a85ad65881f62857fc70af7174a1184dccce32b" + +history@^3.0.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/history/-/history-3.2.1.tgz#71c7497f4e6090363d19a6713bb52a1bfcdd99aa" + dependencies: + invariant "^2.2.1" + loose-envify "^1.2.0" + query-string "^4.2.2" + warning "^3.0.0" + +hoist-non-react-statics@^1.0.3, hoist-non-react-statics@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz#aa448cf0986d55cc40773b17174b7dd066cb7cfb" + +hpkp@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hpkp/-/hpkp-2.0.0.tgz#10e142264e76215a5d30c44ec43de64dee6d1672" + +hsts@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hsts/-/hsts-2.0.0.tgz#a52234c6070decf214b2b6b70bb144d07e4776c7" + dependencies: + core-util-is "1.0.2" + +html-minifier@*: + version "3.2.3" + resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.2.3.tgz#d2ff536e24d95726c332493d8f77d84dbed85372" + dependencies: + camel-case "3.0.x" + clean-css "3.4.x" + commander "2.9.x" + he "1.1.x" + ncname "1.0.x" + param-case "2.1.x" + relateurl "0.2.x" + uglify-js "2.7.x" + +http-assert@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-assert/-/http-assert-1.2.0.tgz#d6392e6f6519def4e340266b35096db6d3feba00" + dependencies: + deep-equal "~1.0.0" + http-errors "~1.4.0" + +http-errors@^1.2.8, http-errors@~1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.5.1.tgz#788c0d2c1de2c81b9e6e8c01843b6b97eb920750" + dependencies: + inherits "2.0.3" + setprototypeof "1.0.2" + statuses ">= 1.3.1 < 2" + +http-errors@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.4.0.tgz#6c0242dea6b3df7afda153c71089b31c6e82aabf" + dependencies: + inherits "2.0.1" + statuses ">= 1.2.1 < 2" + +iconv-lite@~0.4.13: + version "0.4.15" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.15.tgz#fe265a218ac6a57cfe854927e9d04c19825eddeb" + +ienoopen@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ienoopen/-/ienoopen-1.0.0.tgz#346a428f474aac8f50cf3784ea2d0f16f62bda6b" + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +invariant@^2.0.0, invariant@^2.2.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" + dependencies: + loose-envify "^1.0.0" + +ip@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.4.tgz#de8247ffef940451832550fba284945e6e039bfb" + +is-buffer@^1.0.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.4.tgz#cfc86ccd5dc5a52fa80489111c6920c457e2d98b" + +is-generator-function@^1.0.3: + version "1.0.6" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.6.tgz#9e71653cd15fff341c79c4151460a131d31e9fc4" + +is-stream@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + +isomorphic-fetch@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" + dependencies: + node-fetch "^1.0.1" + whatwg-fetch ">=0.10.0" + +js-tokens@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-2.0.0.tgz#79903f5563ee778cc1162e6dcf1a0027c97f9cb5" + +keygrip@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/keygrip/-/keygrip-1.0.1.tgz#b02fa4816eef21a8c4b35ca9e52921ffc89a30e9" + +kind-of@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.1.0.tgz#475d698a5e49ff5e53d14e3e732429dc8bf4cf47" + dependencies: + is-buffer "^1.0.2" + +koa-compose@^3.0.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/koa-compose/-/koa-compose-3.2.1.tgz#a85ccb40b7d986d8e5a345b3a1ace8eabcf54de7" + dependencies: + any-promise "^1.1.0" + +koa-compress@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/koa-compress/-/koa-compress-2.0.0.tgz#7b7eb2921b847746b5e122ba9f5cd8a671e8ea3a" + dependencies: + bytes "^2.3.0" + compressible "^2.0.0" + koa-is-json "^1.0.0" + statuses "^1.0.0" + +koa-convert@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/koa-convert/-/koa-convert-1.2.0.tgz#da40875df49de0539098d1700b50820cebcd21d0" + dependencies: + co "^4.6.0" + koa-compose "^3.0.0" + +koa-helmet@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/koa-helmet/-/koa-helmet-3.1.0.tgz#67da33a3ab41b8308c0d1c517396ebc668d9a14e" + dependencies: + helmet "^3.0.0" + +koa-html-minifier@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/koa-html-minifier/-/koa-html-minifier-1.0.1.tgz#6838a0c2a6cfd58fa919f10fbefd746f2b1fd91e" + dependencies: + html-minifier "*" + +koa-is-json@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/koa-is-json/-/koa-is-json-1.0.0.tgz#273c07edcdcb8df6a2c1ab7d59ee76491451ec14" + +koa-send@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/koa-send/-/koa-send-3.2.0.tgz#a4063c2631b7ebed9f9fc2a77568799ba606449b" + dependencies: + co "^4.6.0" + debug "*" + mz "^2.3.1" + resolve-path "^1.3.1" + +koa-static-cache@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/koa-static-cache/-/koa-static-cache-3.2.0.tgz#54886189653bc4dc9a72e6312c19dba40c73ed89" + dependencies: + compressible "~2.0.6" + debug "*" + fs-readdir-recursive "~1.0.0" + mime-types "~2.1.8" + mz "~2.4.0" + +koa-static@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/koa-static/-/koa-static-3.0.0.tgz#40442233d2c0b35c225e450199c10bf8a539e416" + dependencies: + debug "*" + koa-send "^3.2.0" + +koa@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/koa/-/koa-2.0.0.tgz#da865ae8ee4afae070425290455d2cdf4885f9dc" + dependencies: + accepts "^1.2.2" + content-disposition "~0.5.0" + content-type "^1.0.0" + cookies "~0.6.1" + debug "*" + delegates "^1.0.0" + depd "^1.1.0" + destroy "^1.0.3" + error-inject "~1.0.0" + escape-html "~1.0.1" + fresh "^0.3.0" + http-assert "^1.1.0" + http-errors "^1.2.8" + is-generator-function "^1.0.3" + koa-compose "^3.0.0" + koa-convert "^1.2.0" + koa-is-json "^1.0.0" + mime-types "^2.0.7" + on-finished "^2.1.0" + only "0.0.2" + parseurl "^1.3.0" + statuses "^1.2.0" + type-is "^1.5.5" + vary "^1.0.0" + +lazy-cache@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" + +lodash-es@^4.2.0, lodash-es@^4.2.1: + version "4.17.3" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.3.tgz#567a08d2f0c91d92b31ce35c5565e1f337fb81db" + +lodash._getnative@^3.0.0: + version "3.9.1" + resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" + +lodash.isarguments@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + +lodash.isarray@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" + +lodash.keys@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" + dependencies: + lodash._getnative "^3.0.0" + lodash.isarguments "^3.0.0" + lodash.isarray "^3.0.0" + +lodash.reduce@4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.reduce/-/lodash.reduce-4.6.0.tgz#f1ab6b839299ad48f784abbf476596f03b914d3b" + +lodash@^4.2.0, lodash@^4.2.1: + version "4.17.3" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.3.tgz#557ed7d2a9438cac5fd5a43043ca60cb455e01f7" + +longest@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" + +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.0.tgz#6b26248c42f6d4fa4b0d8542f78edfcde35642a8" + dependencies: + js-tokens "^2.0.0" + +lower-case@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.3.tgz#c92393d976793eee5ba4edb583cf8eae35bd9bfb" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + +"mime-db@>= 1.24.0 < 2", mime-db@~1.25.0: + version "1.25.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.25.0.tgz#c18dbd7c73a5dbf6f44a024dc0d165a1e7b1c392" + +mime-types@^2.0.7, mime-types@~2.1.11, mime-types@~2.1.13, mime-types@~2.1.8: + version "2.1.13" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.13.tgz#e07aaa9c6c6b9a7ca3012c69003ad25a39e92a88" + dependencies: + mime-db "~1.25.0" + +ms@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" + +ms@0.7.2: + version "0.7.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765" + +mz@^2.3.1, mz@~2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/mz/-/mz-2.4.0.tgz#987ba9624d89395388c37cb4741e2caf4dd13b1a" + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + +ncname@1.0.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ncname/-/ncname-1.0.0.tgz#5b57ad18b1ca092864ef62b0b1ed8194f383b71c" + dependencies: + xml-char-classes "^1.0.0" + +negotiator@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" + +no-case@^2.2.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.1.tgz#7aeba1c73a52184265554b7dc03baf720df80081" + dependencies: + lower-case "^1.1.1" + +nocache@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/nocache/-/nocache-2.0.0.tgz#202b48021a0c4cbde2df80de15a17443c8b43980" + +node-fetch@^1.0.1: + version "1.6.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.6.3.tgz#dc234edd6489982d58e8f0db4f695029abcd8c04" + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + +object-assign@^4.0.1, object-assign@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.0.tgz#7a3b3d0e98063d43f4c03f2e8ae6cd51a86883a0" + +on-finished@^2.1.0, on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + dependencies: + ee-first "1.1.1" + +only@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4" + +param-case@2.1.x: + version "2.1.0" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.0.tgz#2619f90fd6c829ed0b958f1c84ed03a745a6d70a" + dependencies: + no-case "^2.2.0" + +parseurl@^1.3.0, parseurl@~1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.1.tgz#c8ab8c9223ba34888aa64a297b28853bec18da56" + +path-is-absolute@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +platform@1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.3.tgz#646c77011899870b6a0903e75e997e8e51da7461" + +promise@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.1.1.tgz#489654c692616b8aa55b0724fa809bb7db49c5bf" + dependencies: + asap "~2.0.3" + +query-string@^4.2.2: + version "4.2.3" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.2.3.tgz#9f27273d207a25a8ee4c7b8c74dcd45d556db822" + dependencies: + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + +react-dom@^15.4.2: + version "15.4.2" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.4.2.tgz#015363f05b0a1fd52ae9efdd3a0060d90695208f" + dependencies: + fbjs "^0.8.1" + loose-envify "^1.1.0" + object-assign "^4.1.0" + +react-helmet@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/react-helmet/-/react-helmet-4.0.0.tgz#df74bcd6ff585a1ccbbfba5aaa1c346cabc43d03" + dependencies: + deep-equal "1.0.1" + object-assign "^4.0.1" + react-side-effect "^1.1.0" + +react-redux@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.2.tgz#3d9878f5f71c6fafcd45de1fbb162ea31f389814" + dependencies: + hoist-non-react-statics "^1.0.3" + invariant "^2.0.0" + lodash "^4.2.0" + lodash-es "^4.2.0" + loose-envify "^1.1.0" + +react-router-redux@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/react-router-redux/-/react-router-redux-4.0.7.tgz#9b1fde4e70106c50f47214e12bdd888cfb96e2a6" + +react-router@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-3.0.2.tgz#5a19156678810e01d81901f9c0fef63284b8a514" + dependencies: + history "^3.0.0" + hoist-non-react-statics "^1.2.0" + invariant "^2.2.1" + loose-envify "^1.2.0" + warning "^3.0.0" + +react-side-effect@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/react-side-effect/-/react-side-effect-1.1.0.tgz#57209f7ebc940d55e0fda82fe51422654175d609" + dependencies: + exenv "^1.2.1" + shallowequal "^0.2.2" + +react@^15.4.2: + version "15.4.2" + resolved "https://registry.yarnpkg.com/react/-/react-15.4.2.tgz#41f7991b26185392ba9bae96c8889e7e018397ef" + dependencies: + fbjs "^0.8.4" + loose-envify "^1.1.0" + object-assign "^4.1.0" + +redux@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/redux/-/redux-3.6.0.tgz#887c2b3d0b9bd86eca2be70571c27654c19e188d" + dependencies: + lodash "^4.2.1" + lodash-es "^4.2.1" + loose-envify "^1.1.0" + symbol-observable "^1.0.2" + +referrer-policy@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/referrer-policy/-/referrer-policy-1.1.0.tgz#35774eb735bf50fb6c078e83334b472350207d79" + +regenerator-runtime@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.1.tgz#257f41961ce44558b18f7814af48c17559f9faeb" + +relateurl@0.2.x: + version "0.2.7" + resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" + +repeat-string@^1.5.2: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + +resolve-path@^1.3.1: + version "1.3.3" + resolved "https://registry.yarnpkg.com/resolve-path/-/resolve-path-1.3.3.tgz#4d83aba6468c2b8e632a575e3f52b0fa0dbe1a5c" + dependencies: + http-errors "~1.5.0" + path-is-absolute "1.0.1" + +right-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" + dependencies: + align-text "^0.1.1" + +serialize-javascript@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.3.0.tgz#86a4f3752f5c7e47295449b0bbb63d64ba533f05" + +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + +setprototypeof@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.2.tgz#81a552141ec104b88e89ce383103ad5c66564d08" + +shallowequal@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-0.2.2.tgz#1e32fd5bcab6ad688a4812cb0cc04efc75c7014e" + dependencies: + lodash.keys "^3.1.2" + +source-map-support@^0.4.11: + version "0.4.11" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.11.tgz#647f939978b38535909530885303daf23279f322" + dependencies: + source-map "^0.5.3" + +source-map@0.4.x: + version "0.4.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" + dependencies: + amdefine ">=0.0.4" + +source-map@^0.5.3, source-map@~0.5.1: + version "0.5.6" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" + +"statuses@>= 1.2.1 < 2", "statuses@>= 1.3.1 < 2", statuses@^1.0.0, statuses@^1.2.0, statuses@~1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" + +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + +symbol-observable@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d" + +thenify-all@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + dependencies: + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.2.1" + resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.2.1.tgz#251fd1c80aff6e5cf57cb179ab1fcb724269bd11" + dependencies: + any-promise "^1.0.0" + +type-is@^1.5.5: + version "1.6.14" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.14.tgz#e219639c17ded1ca0789092dd54a03826b817cb2" + dependencies: + media-typer "0.3.0" + mime-types "~2.1.13" + +ua-parser-js@^0.7.9: + version "0.7.12" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.12.tgz#04c81a99bdd5dc52263ea29d24c6bf8d4818a4bb" + +uglify-js@2.7.x: + version "2.7.5" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.7.5.tgz#4612c0c7baaee2ba7c487de4904ae122079f2ca8" + dependencies: + async "~0.2.6" + source-map "~0.5.1" + uglify-to-browserify "~1.0.0" + yargs "~3.10.0" + +uglify-to-browserify@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" + +unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + +upper-case@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" + +utils-merge@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8" + +vary@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.0.tgz#e1e5affbbd16ae768dd2674394b9ad3022653140" + +warning@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/warning/-/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c" + dependencies: + loose-envify "^1.0.0" + +whatwg-fetch@>=0.10.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.1.tgz#078b9461bbe91cea73cbce8bb122a05f9e92b772" + +window-size@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" + +wordwrap@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" + +x-xss-protection@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/x-xss-protection/-/x-xss-protection-1.0.0.tgz#898afb93869b24661cf9c52f9ee8db8ed0764dd9" + +xml-char-classes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/xml-char-classes/-/xml-char-classes-1.0.0.tgz#64657848a20ffc5df583a42ad8a277b4512bbc4d" + +yargs@~3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" + dependencies: + camelcase "^1.0.2" + cliui "^2.1.0" + decamelize "^1.0.0" + window-size "0.1.0" diff --git a/src/client/index.js b/src/client/index.js old mode 100755 new mode 100644 index 10db2d4..7035834 --- a/src/client/index.js +++ b/src/client/index.js @@ -1,15 +1,46 @@ import React from 'react' -import ReactDOM from 'react-dom' -import { browserHistory } from 'react-router' +import { render, unmountComponentAtNode } from 'react-dom' +import { Provider } from 'react-redux' +import { match, Router, browserHistory } from 'react-router' import { syncHistoryWithStore } from 'react-router-redux' +import { AppContainer } from 'react-hot-loader' +import configureStore from '../common/redux/store' +import routes from '../common/routes' -import configureStore from 'common/redux/store' -import Root from 'common/containers/Root' - -const initialState = window.__INITIAL_STATE__ -const store = configureStore(initialState) -// Create an enhanced history that syncs navigation events with the store +const preloadedState = window.__PRELOADED_STATE__ +const store = configureStore(preloadedState) const history = syncHistoryWithStore(browserHistory, store) -const root = () +const rootEl = document.getElementById('root') + +const renderApp = () => { + // Sync routes both on client and server + match({ history, routes: routes(store) }, (error, redirectLocation, renderProps) => { + render( + + + + + , + rootEl, + ) + }) +} + +// Enable hot reload by react-hot-loader +if (module.hot) { + module.hot.accept('../common/routes', () => { + setImmediate(() => { + // Preventing the hot reloading error from react-router + unmountComponentAtNode(rootEl) + renderApp() + }) + }) +} + +if (!__PROD__) { + const { whyDidYouUpdate } = require('why-did-you-update') + + whyDidYouUpdate(React) +} -ReactDOM.render(root, document.getElementById('root')) +renderApp() diff --git a/src/common/components/Hello/Hello.jsx b/src/common/components/Hello/Hello.jsx new file mode 100644 index 0000000..feb58b7 --- /dev/null +++ b/src/common/components/Hello/Hello.jsx @@ -0,0 +1,20 @@ +import React, { PropTypes } from 'react' + +const propTypes = { + name: React.PropTypes.oneOfType([ + PropTypes.string, + PropTypes.element + ]) +} +const defaultProps = { + name: '' +} + +function Hello(props) { + return
Hello {props.name}
+} + +Hello.propTypes = propTypes +Hello.defaultProps = defaultProps + +export default Hello diff --git a/src/common/components/Hello/index.js b/src/common/components/Hello/index.js new file mode 100644 index 0000000..7bf75c2 --- /dev/null +++ b/src/common/components/Hello/index.js @@ -0,0 +1,3 @@ +import Hello from './Hello' + +export default Hello diff --git a/src/common/components/views/About/index.jsx b/src/common/components/views/About/index.jsx deleted file mode 100755 index 949b697..0000000 --- a/src/common/components/views/About/index.jsx +++ /dev/null @@ -1,22 +0,0 @@ -import React, { PropTypes } from 'react' - -const contextTypes = { - router: PropTypes.object -} - -export default function About(props, context) { - const closeView = () => { - context.router.push('/') - } - - return ( -
-
-

About

- -
-
- ) -} - -About.contextTypes = contextTypes diff --git a/src/common/components/views/Hello/index.jsx b/src/common/components/views/Hello/index.jsx deleted file mode 100755 index 039991b..0000000 --- a/src/common/components/views/Hello/index.jsx +++ /dev/null @@ -1,22 +0,0 @@ -import React, { PropTypes } from 'react' - -const contextTypes = { - router: PropTypes.object -} - -export default function Hello(props, context) { - const closeView = () => { - context.router.push('/') - } - - return ( -
-
-

Hello

- -
-
- ) -} - -Hello.contextTypes = contextTypes diff --git a/src/common/components/views/Home/index.jsx b/src/common/components/views/Home/index.jsx deleted file mode 100755 index 37912a7..0000000 --- a/src/common/components/views/Home/index.jsx +++ /dev/null @@ -1,15 +0,0 @@ -import React from 'react' - -// require the logo image both from client and server -const logoImage = require('./kiki.jpg') - -export default function Home() { - return ( -
-
-

Home

-

Kiki

-
-
- ) -} diff --git a/src/common/components/views/Posts/Post.jsx b/src/common/components/views/Posts/Post.jsx deleted file mode 100644 index d74bf10..0000000 --- a/src/common/components/views/Posts/Post.jsx +++ /dev/null @@ -1,22 +0,0 @@ -import React, { PropTypes } from 'react' - -const contextTypes = { - router: PropTypes.object -} - -export default function Post(props, context) { - const closeView = () => { - context.router.push('/posts') - } - - return ( -
-
-

Post

- -
-
- ) -} - -Post.contextTypes = contextTypes diff --git a/src/common/components/views/Posts/index.jsx b/src/common/components/views/Posts/index.jsx deleted file mode 100644 index 231303a..0000000 --- a/src/common/components/views/Posts/index.jsx +++ /dev/null @@ -1,50 +0,0 @@ -import React, { PropTypes, cloneElement } from 'react' -import { Link } from 'react-router' -import ReactCSSTransitionGroup from 'react-addons-css-transition-group' - -const propTypes = { - location: PropTypes.object, - children: PropTypes.object -} - -const contextTypes = { - router: PropTypes.object -} - -export default function Posts(props, context) { - const closeView = () => { - context.router.push('/') - } - const { children, location } = props - - return ( -
-
-

Posts

- -
-
-
    -
  • Post 1
  • -
  • Post 2
  • -
  • Post 3
  • -
  • Post 4
  • -
  • Post 5
  • -
-
- - - {children && cloneElement(children, { - key: location.pathname - })} - -
- ) -} - -Posts.propTypes = propTypes -Posts.contextTypes = contextTypes diff --git a/src/common/components/views/SlideInLeft/index.jsx b/src/common/components/views/SlideInLeft/index.jsx deleted file mode 100644 index 9286062..0000000 --- a/src/common/components/views/SlideInLeft/index.jsx +++ /dev/null @@ -1,47 +0,0 @@ -import React, { PropTypes, cloneElement } from 'react' -import { Link } from 'react-router' -import ReactCSSTransitionGroup from 'react-addons-css-transition-group' - -const propTypes = { - location: PropTypes.object, - children: PropTypes.object -} - -const contextTypes = { - router: PropTypes.object -} - -export default function SlideInLeft(props, context) { - const closeView = () => { - context.router.push('/') - } - const { children, location } = props - - return ( -
-
-

SlideInLeft

- -
- -
    -
  • Tab 1
  • -
  • Tab 2
  • -
- - - {children && cloneElement(children, { - key: location.pathname - })} - -
- ) -} - -SlideInLeft.propTypes = propTypes -SlideInLeft.contextTypes = contextTypes diff --git a/src/common/components/views/Tabs/Tab1.jsx b/src/common/components/views/Tabs/Tab1.jsx deleted file mode 100644 index 9afd09a..0000000 --- a/src/common/components/views/Tabs/Tab1.jsx +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react' - -export default function Tab1() { - return ( -
-
-

Tab1

-
-
- ) -} diff --git a/src/common/components/views/Tabs/Tab2.jsx b/src/common/components/views/Tabs/Tab2.jsx deleted file mode 100644 index 2900a87..0000000 --- a/src/common/components/views/Tabs/Tab2.jsx +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react' - -export default function Tab2() { - return ( -
-
-

Tab2

-
-
- ) -} diff --git a/src/common/config/dev.js b/src/common/config/dev.js new file mode 100644 index 0000000..650a71d --- /dev/null +++ b/src/common/config/dev.js @@ -0,0 +1,10 @@ +export default { + app: { + htmlAttributes: { lang: 'en' }, + title: 'React Redux Universal Boilerplate', + titleTemplate: 'React Redux Universal Boilerplate - %s', + meta: [ + { name: 'description', content: 'Another React/Redux universal boilerplate.' }, + ], + }, +} diff --git a/src/common/config/index.js b/src/common/config/index.js new file mode 100644 index 0000000..c2a26bb --- /dev/null +++ b/src/common/config/index.js @@ -0,0 +1,3 @@ +const config = __DEV__ ? require('./dev').default : require('./prod').default + +export default config diff --git a/src/common/config/prod.js b/src/common/config/prod.js new file mode 100644 index 0000000..ae39753 --- /dev/null +++ b/src/common/config/prod.js @@ -0,0 +1,7 @@ +import defaultConfig from './dev' + +const config = { + // extend and override dev config here. +} + +export default { ...defaultConfig, config } diff --git a/src/common/containers/DevTools.jsx b/src/common/containers/DevTools.jsx deleted file mode 100755 index 42035e1..0000000 --- a/src/common/containers/DevTools.jsx +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react' -import { createDevTools } from 'redux-devtools' -import LogMonitor from 'redux-devtools-log-monitor' -import DockMonitor from 'redux-devtools-dock-monitor' - -export default createDevTools( - - - -) diff --git a/src/common/containers/Root.js b/src/common/containers/Root.js deleted file mode 100755 index 8fc2e43..0000000 --- a/src/common/containers/Root.js +++ /dev/null @@ -1,3 +0,0 @@ -const Root = __DEV__ ? require('./RootDev').default : require('./RootProd').default - -export default Root diff --git a/src/common/containers/RootDev.jsx b/src/common/containers/RootDev.jsx deleted file mode 100755 index 23bb7df..0000000 --- a/src/common/containers/RootDev.jsx +++ /dev/null @@ -1,29 +0,0 @@ -import React, { PropTypes } from 'react' -import { Provider } from 'react-redux' -import { Router } from 'react-router' - -import DevTools from './DevTools' -import routes from 'common/routes' - -const propTypes = { - history: PropTypes.object.isRequired, - store: PropTypes.object.isRequired -} - -function RootDev(props) { - const { history, store } = props - const showDevTools = () => (__DEBUG__ ? () : null) - - return ( - -
- - {showDevTools()} -
-
- ) -} - -RootDev.propTypes = propTypes - -export default RootDev diff --git a/src/common/containers/RootProd.jsx b/src/common/containers/RootProd.jsx deleted file mode 100755 index a7317e8..0000000 --- a/src/common/containers/RootProd.jsx +++ /dev/null @@ -1,26 +0,0 @@ -import React, { PropTypes } from 'react' -import { Provider } from 'react-redux' -import { Router } from 'react-router' - -import routes from 'common/routes' - -const propTypes = { - history: PropTypes.object.isRequired, - store: PropTypes.object.isRequired -} - -function RootProd(props) { - const { history, store } = props - - return ( - -
- -
-
- ) -} - -RootProd.propTypes = propTypes - -export default RootProd diff --git a/src/common/layouts/AppLayout/AppLayout.jsx b/src/common/layouts/AppLayout/AppLayout.jsx new file mode 100644 index 0000000..8eeeca1 --- /dev/null +++ b/src/common/layouts/AppLayout/AppLayout.jsx @@ -0,0 +1,36 @@ +import React, { PropTypes } from 'react' +import { Link } from 'react-router' +import Helmet from 'react-helmet' + +import config from '../../config' + +const propTypes = { + children: PropTypes.object +} +const defaultProps = { + children: {} +} + +function AppLayout(props) { + return ( +
+ + +

{config.app.title}

+ +
    +
  • Home
  • +
  • Hello
  • +
  • About
  • +
  • Counter
  • +
+ + {props.children} +
+ ) +} + +AppLayout.propTypes = propTypes +AppLayout.defaultProps = defaultProps + +export default AppLayout diff --git a/src/common/layouts/AppLayout/index.js b/src/common/layouts/AppLayout/index.js new file mode 100644 index 0000000..4bb2694 --- /dev/null +++ b/src/common/layouts/AppLayout/index.js @@ -0,0 +1,6 @@ +// *** GLOBAL STYLES *** // +import 'common/styles/global/app.css' + +import AppLayout from './AppLayout' + +export default AppLayout diff --git a/src/common/layouts/AppLayout/index.jsx b/src/common/layouts/AppLayout/index.jsx deleted file mode 100755 index ddaf67c..0000000 --- a/src/common/layouts/AppLayout/index.jsx +++ /dev/null @@ -1,69 +0,0 @@ -import React, { Component, PropTypes, cloneElement } from 'react' -import { Link } from 'react-router' -import ReactCSSTransitionGroup from 'react-addons-css-transition-group' - -import Home from 'common/components/views/Home' - -// *** STYLES *** // -import 'common/styles/global/core.css' - -const propTypes = { - location: PropTypes.object, - children: PropTypes.object -} - -class AppLayout extends Component { - constructor() { - super() - - this.state = { transition: '' } - - this.setTransitionName = this.setTransitionName.bind(this) - } - - setTransitionName(transition = '') { - this.setState({ transition }) - } - - render() { - const { children, location: { pathname } } = this.props - // Only take the first-level part of the path as key, instead of the whole path. - const key = pathname.split('/')[1] || 'root' - - /* eslint-disable */ - return ( -
-
-

Hello! For a better experience, reduce your screen or open your Javascript console and simulate mobile devices

-

I will disappear if it's good

-
-
    -
  • Hello
  • -
  • About
  • -
  • - SlideInLeft -
  • -
  • - Posts -
  • -
- - - - - {children && cloneElement(children, { - key - })} - -
- ) - } -} - -AppLayout.propTypes = propTypes - -export default AppLayout diff --git a/src/common/redux/actions/CounterActions.js b/src/common/redux/actions/CounterActions.js old mode 100755 new mode 100644 index 3d0ceef..b990c0b --- a/src/common/redux/actions/CounterActions.js +++ b/src/common/redux/actions/CounterActions.js @@ -1,15 +1,20 @@ -import types from '../constants/CounterConstants' +export const INCREMENT_COUNTER = 'INCREMENT_COUNTER' +export const DECREMENT_COUNTER = 'DECREMENT_COUNTER' -/* - * action creators - */ +export const constants = { + INCREMENT_COUNTER, + DECREMENT_COUNTER, +} -const increment = () => ( - { type: types.INCREMENT_COUNTER } -) +export const increment = () => ({ + type: INCREMENT_COUNTER +}) -const decrement = () => ( - { type: types.DECREMENT_COUNTER } -) +export const decrement = () => ({ + type: DECREMENT_COUNTER +}) -export default { increment, decrement } +export const actions = { + increment, + decrement, +} diff --git a/src/common/redux/constants/CounterConstants.js b/src/common/redux/constants/CounterConstants.js deleted file mode 100755 index e38185b..0000000 --- a/src/common/redux/constants/CounterConstants.js +++ /dev/null @@ -1,4 +0,0 @@ -export default { - INCREMENT_COUNTER: 'INCREMENT_COUNTER', - DECREMENT_COUNTER: 'DECREMENT_COUNTER' -} diff --git a/src/common/redux/middleware/logger.js b/src/common/redux/middleware/logger.js old mode 100755 new mode 100644 index 4e53f1e..d4eb14e --- a/src/common/redux/middleware/logger.js +++ b/src/common/redux/middleware/logger.js @@ -1,18 +1,22 @@ /** * Logs all actions and states after they are dispatched. */ -const logger = store => next => action => { +const logger = store => next => (action) => { // Notes: // next = store.dispatch; // next(action) = dispatch(action); - /* eslint-disable */ - console.group(action.type); - console.info('dispatching', action); - const result = next(action); - console.log('next state', store.getState()); - console.groupEnd(action.type); - return result; -}; + if (__CLIENT__) { + /* eslint-disable */ + console.group(action.type) + console.info('dispatching', action) + const result = next(action) + console.log('next state', store.getState()) + console.groupEnd(action.type) + return result + } -export default logger; + return +} + +export default logger diff --git a/src/common/redux/reducers/counter.js b/src/common/redux/reducers/counter.js old mode 100755 new mode 100644 index d613985..6291bb3 --- a/src/common/redux/reducers/counter.js +++ b/src/common/redux/reducers/counter.js @@ -1,11 +1,13 @@ -import types from '../constants/CounterConstants' +import { INCREMENT_COUNTER, DECREMENT_COUNTER } from '../actions/CounterActions' -const counter = (state = 0, action) => { +const initialState = 0 + +const counter = (state = initialState, action) => { switch (action.type) { - case types.INCREMENT_COUNTER: + case INCREMENT_COUNTER: return state + 1 - case types.DECREMENT_COUNTER: + case DECREMENT_COUNTER: return state - 1 default: diff --git a/src/common/redux/reducers/index.js b/src/common/redux/reducers/index.js old mode 100755 new mode 100644 diff --git a/src/common/redux/store/configureStoreDev.js b/src/common/redux/store/configureStoreDev.js old mode 100755 new mode 100644 index fd2cf8f..9a8da34 --- a/src/common/redux/store/configureStoreDev.js +++ b/src/common/redux/store/configureStoreDev.js @@ -1,31 +1,22 @@ import { createStore, applyMiddleware, compose } from 'redux' -import DevTools from 'common/containers/DevTools' - import logger from '../middleware/logger' import rootReducer from '../reducers' -let finalCreateStore - -const configureStoreDev = (initialState = {}) => { - if (__DEBUG__) { - finalCreateStore = compose( +const configureStoreDev = (preloadedState = {}) => { + const store = createStore( + rootReducer, + preloadedState, + compose( applyMiddleware(logger), - DevTools.instrument() - )(createStore) - } else { - finalCreateStore = compose( - applyMiddleware(logger) - )(createStore) - } - - const store = finalCreateStore(rootReducer, initialState) + (__CLIENT__ && window.devToolsExtension) ? window.devToolsExtension() : f => f + )) if (module.hot) { // Enable Webpack hot module replacement for reducers module.hot.accept('../reducers', () => { - const nextReducer = require('../reducers').default // eslint-disable-line - store.replaceReducer(nextReducer) + const nextRootReducer = require('../reducers').default + store.replaceReducer(nextRootReducer) }) } diff --git a/src/common/redux/store/configureStoreProd.js b/src/common/redux/store/configureStoreProd.js old mode 100755 new mode 100644 index 20b9ac2..22725e1 --- a/src/common/redux/store/configureStoreProd.js +++ b/src/common/redux/store/configureStoreProd.js @@ -1,15 +1,7 @@ -import { createStore, applyMiddleware, compose } from 'redux' +import { createStore } from 'redux' -// Note: Should not use logger in production. It's just for example -import logger from '../middleware/logger' import rootReducer from '../reducers' -const configureStoreProd = (initialState = {}) => { - const finalCreateStore = compose( - applyMiddleware(logger) - )(createStore) - - return finalCreateStore(rootReducer, initialState) -} +const configureStoreProd = (preloadedState = {}) => createStore(rootReducer, preloadedState) export default configureStoreProd diff --git a/src/common/redux/store/index.js b/src/common/redux/store/index.js old mode 100755 new mode 100644 index adc75f5..c0f732f --- a/src/common/redux/store/index.js +++ b/src/common/redux/store/index.js @@ -1,4 +1,5 @@ const store = __DEV__ ? - require('./configureStoreDev').default : require('./configureStoreProd').default + require('./configureStoreDev').default : + require('./configureStoreProd').default export default store diff --git a/src/common/routes/AboutRoute.js b/src/common/routes/AboutRoute.js new file mode 100644 index 0000000..c376ec3 --- /dev/null +++ b/src/common/routes/AboutRoute.js @@ -0,0 +1,7 @@ +export default () => ({ + path: 'about', + getComponent: async (location, cb) => { + const component = await System.import('common/views/AboutView') + cb(null, component.default) + } +}) diff --git a/src/common/routes/CounterRoute.js b/src/common/routes/CounterRoute.js new file mode 100644 index 0000000..9f9f904 --- /dev/null +++ b/src/common/routes/CounterRoute.js @@ -0,0 +1,7 @@ +export default () => ({ + path: 'counter', + getComponent: async (location, cb) => { + const component = await System.import('common/views/CounterView') + cb(null, component.default) + } +}) diff --git a/src/common/routes/HelloRoute.js b/src/common/routes/HelloRoute.js new file mode 100644 index 0000000..b3476af --- /dev/null +++ b/src/common/routes/HelloRoute.js @@ -0,0 +1,7 @@ +export default () => ({ + path: 'hello', + getComponent: async (location, cb) => { + const component = await System.import('common/views/HelloView') + cb(null, component.default) + } +}) diff --git a/src/common/routes/HomeRoute.js b/src/common/routes/HomeRoute.js new file mode 100644 index 0000000..1d2615f --- /dev/null +++ b/src/common/routes/HomeRoute.js @@ -0,0 +1,6 @@ +export default () => ({ + getComponent: async (location, cb) => { + const component = await System.import('common/views/HomeView') + cb(null, component.default) + } +}) diff --git a/src/common/routes/NotFoundRoute.js b/src/common/routes/NotFoundRoute.js new file mode 100644 index 0000000..52b8ef4 --- /dev/null +++ b/src/common/routes/NotFoundRoute.js @@ -0,0 +1,7 @@ +export default () => ({ + path: '*', + onEnter(nextState, replace, callback) { + replace('/') + callback() + } +}) diff --git a/src/common/routes/index.js b/src/common/routes/index.js new file mode 100644 index 0000000..a97346e --- /dev/null +++ b/src/common/routes/index.js @@ -0,0 +1,22 @@ +// https://github.com/ReactTraining/react-router/blob/master/docs/API.md#plainroute +// https://webpack.js.org/guides/migrating/#code-splitting-with-es2015 + +import AppLayout from 'common/layouts/AppLayout' +import HomeRoute from './HomeRoute' +import HelloRoute from './HelloRoute' +import AboutRoute from './AboutRoute' +import CounterRoute from './CounterRoute' +import NotFoundRoute from './NotFoundRoute' + +// Possibility to pass the store to routes: HelloRoute(store) +export default store => ({ // eslint-disable-line + path: '/', + component: AppLayout, + indexRoute: HomeRoute(), + childRoutes: [ + HelloRoute(), + AboutRoute(), + CounterRoute(), + NotFoundRoute(), // this route must be at end because (path: '*'). + ], +}) diff --git a/src/common/routes/index.jsx b/src/common/routes/index.jsx deleted file mode 100755 index 1fe9eca..0000000 --- a/src/common/routes/index.jsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react' -import { Route, Redirect } from 'react-router' - -import AppLayout from 'common/layouts/AppLayout' -import About from 'common/components/views/About' -import Hello from 'common/components/views/Hello' -import Posts from 'common/components/views/Posts' -import Post from 'common/components/views/Posts/Post' -import SlideInLeft from 'common/components/views/SlideInLeft' -import Tab1 from 'common/components/views/Tabs/Tab1' -import Tab2 from 'common/components/views/Tabs/Tab2' - -export default ( - - - - - - - - - - - - -) diff --git a/src/common/styles/global/app.css b/src/common/styles/global/app.css old mode 100755 new mode 100644 index 383e4ef..1e21731 --- a/src/common/styles/global/app.css +++ b/src/common/styles/global/app.css @@ -1,60 +1,8 @@ -html, body, #root, .app, .views { - height: 100%; -} +@import 'normalize.css'; + +@import 'variables'; +@import 'views'; body { background: var(--bodyColor); } - -h1, h2, ul { - margin: 0; - padding: 0; -} - -ul { - list-style-type: none; -} - -.page { - height: 100%; - width: 100%; - - @nest & header { - overflow: hidden; - } - - @nest & h1 { - float: left; - } - - @nest & button { - float: right; - } -} - -.page-slide-in-right { - position: absolute; - top: 0; -} - -.page-slide-in-left { - background-color: orange; - position: absolute; - top: 0; -} - -.page-slide-in-up { - background-color: blue; - position: absolute; - bottom: 0; -} - -.page-slide-in-down { - background-color: pink; - position: absolute; - top: 0; -} - -img { - width: 100%; -} diff --git a/src/common/styles/global/core.css b/src/common/styles/global/core.css deleted file mode 100644 index ee024ca..0000000 --- a/src/common/styles/global/core.css +++ /dev/null @@ -1,6 +0,0 @@ -@import 'normalize.css/normalize'; - -@import 'variables'; -@import 'app'; -@import 'transitions'; -@import 'views'; diff --git a/src/common/styles/global/transitions.css b/src/common/styles/global/transitions.css deleted file mode 100644 index af34f8c..0000000 --- a/src/common/styles/global/transitions.css +++ /dev/null @@ -1,89 +0,0 @@ -.slideInRight-enter { - right: -100%; - transition: right .4s ease-in-out; -} - -.slideInRight-enter.slideInRight-enter-active { - right: 0; -} - -.slideInRight-leave { - right: 0; - transition: right .4s ease-in-out; -} - -.slideInRight-leave.slideInRight-leave-active { - right: -100%; -} - -.slideInLeft-enter { - left: -100%; - transition: left .4s ease-in-out; -} - -.slideInLeft-enter.slideInLeft-enter-active { - left: 0; -} - -.slideInLeft-leave { - left: 0; - transition: left .4s ease-in-out; -} - -.slideInLeft-leave.slideInLeft-leave-active { - left: -100%; -} - -.slideInUp-enter { - bottom: -100%; - transition: bottom .4s ease-in-out; -} - -.slideInUp-enter.slideInUp-enter-active { - bottom: 0; -} - -.slideInUp-leave { - bottom: 0; - transition: bottom .4s ease-in-out; -} - -.slideInUp-leave.slideInUp-leave-active { - bottom: -100%; -} - -.slideInDown-enter { - top: -100%; - transition: top .4s ease-in-out; -} - -.slideInDown-enter.slideInDown-enter-active { - top: 0; -} - -.slideInDown-leave { - top: 0; - transition: top .4s ease-in-out; -} - -.slideInDown-leave.slideInDown-leave-active { - top: -100%; -} - -.fadeIn-enter { - opacity: 0.01; - transition: opacity .4s ease-in; -} - -.fadeIn-enter.fadeIn-enter-active { - opacity: 1; -} - -.fadeIn-leave { - opacity: 1; - transition: opacity .4s ease-in; -} - -.fadeIn-leave.fadeIn-leave-active { - opacity: 0; -} diff --git a/src/common/styles/global/variables.css b/src/common/styles/global/variables.css old mode 100755 new mode 100644 index fba7abc..cea36bb --- a/src/common/styles/global/variables.css +++ b/src/common/styles/global/variables.css @@ -1,3 +1,3 @@ :root { - --bodyColor: #000; + --bodyColor: #d3cfcf; } diff --git a/src/common/styles/global/views/hello.css b/src/common/styles/global/views/hello.css old mode 100755 new mode 100644 index 27b9819..3c7c0ef --- a/src/common/styles/global/views/hello.css +++ b/src/common/styles/global/views/hello.css @@ -1,3 +1,7 @@ -.page-hello { - color: black; +.view__hello { + color: green; + + @nest & .text { + color: blue; + } } diff --git a/src/common/styles/global/views/home.css b/src/common/styles/global/views/home.css old mode 100755 new mode 100644 index 241e788..dd3d0de --- a/src/common/styles/global/views/home.css +++ b/src/common/styles/global/views/home.css @@ -1,26 +1,3 @@ -@custom-media --tablet-viewport (max-width: 375px); - -.page-home { +.view__home { color: blue; } - -.alert { - padding: 15px; - margin-bottom: 20px; - border: 1px solid transparent; - border-radius: 4px; - width: 80%; - margin: 10px auto; -} - -.alert-info { - color: #31708f; - background-color: #d9edf7; - border-color: #bce8f1; -} - -@media (--tablet-viewport) { - .alert-info { - display: none; - } -} diff --git a/src/common/styles/global/views/index.css b/src/common/styles/global/views/index.css old mode 100755 new mode 100644 index 2935d86..9c58acc --- a/src/common/styles/global/views/index.css +++ b/src/common/styles/global/views/index.css @@ -1,4 +1,2 @@ @import 'home'; @import 'hello'; -@import 'posts'; -@import 'post'; diff --git a/src/common/styles/global/views/post.css b/src/common/styles/global/views/post.css deleted file mode 100644 index b7698cd..0000000 --- a/src/common/styles/global/views/post.css +++ /dev/null @@ -1,3 +0,0 @@ -.page-post { - background-color: red; -} diff --git a/src/common/styles/global/views/posts.css b/src/common/styles/global/views/posts.css deleted file mode 100644 index 3bb7749..0000000 --- a/src/common/styles/global/views/posts.css +++ /dev/null @@ -1,3 +0,0 @@ -.page-posts { - background-color: green; -} diff --git a/src/common/styles/local/title.css b/src/common/styles/local/title.css new file mode 100644 index 0000000..d42d53d --- /dev/null +++ b/src/common/styles/local/title.css @@ -0,0 +1,3 @@ +.h2 { + text-decoration: underline; +} diff --git a/src/common/views/AboutView/AboutView.css b/src/common/views/AboutView/AboutView.css new file mode 100644 index 0000000..6802b16 --- /dev/null +++ b/src/common/views/AboutView/AboutView.css @@ -0,0 +1,3 @@ +.title { + color: #ff0000; +} diff --git a/src/common/views/AboutView/AboutView.jsx b/src/common/views/AboutView/AboutView.jsx new file mode 100644 index 0000000..92877cc --- /dev/null +++ b/src/common/views/AboutView/AboutView.jsx @@ -0,0 +1,15 @@ +import React from 'react' +import Helmet from 'react-helmet' + +import titleStyles from 'common/styles/local/title.css' +import styles from './AboutView.css' + +export default function AboutView() { + return ( +
+ + +

About

+
+ ) +} diff --git a/src/common/views/AboutView/index.js b/src/common/views/AboutView/index.js new file mode 100644 index 0000000..597a1e7 --- /dev/null +++ b/src/common/views/AboutView/index.js @@ -0,0 +1,3 @@ +import AboutView from './AboutView' + +export default AboutView diff --git a/src/common/views/CounterView/CounterView.jsx b/src/common/views/CounterView/CounterView.jsx new file mode 100644 index 0000000..dfd2468 --- /dev/null +++ b/src/common/views/CounterView/CounterView.jsx @@ -0,0 +1,27 @@ +import React, { PropTypes } from 'react' +import Helmet from 'react-helmet' + +export default function CounterView({ counter, increment, decrement }) { + return ( +
+ + +

Counter: {counter}

+ +
+ + +
+
+ ) +} + +CounterView.propTypes = { + counter: PropTypes.number, + increment: PropTypes.func.isRequired, + decrement: PropTypes.func.isRequired, +} + +CounterView.defaultProps = { + counter: 0, +} diff --git a/src/common/views/CounterView/index.js b/src/common/views/CounterView/index.js new file mode 100644 index 0000000..3b2625f --- /dev/null +++ b/src/common/views/CounterView/index.js @@ -0,0 +1,12 @@ +import { connect } from 'react-redux' + +import { actions } from 'common/redux/actions/CounterActions' +import CounterView from './CounterView' + +const mapStateToProps = state => ({ + counter: state.counter +}) + +const connectedCounterView = connect(mapStateToProps, actions)(CounterView) + +export { connectedCounterView as default, CounterView } diff --git a/src/common/views/HelloView/HelloView.jsx b/src/common/views/HelloView/HelloView.jsx new file mode 100644 index 0000000..145d660 --- /dev/null +++ b/src/common/views/HelloView/HelloView.jsx @@ -0,0 +1,18 @@ +import React from 'react' +import Helmet from 'react-helmet' + +import Hello from 'common/components/Hello' + +export default function HelloView() { + return ( +
+ + +

Hello

+ +
+ World!} /> +
+
+ ) +} diff --git a/src/common/views/HelloView/index.js b/src/common/views/HelloView/index.js new file mode 100644 index 0000000..e8abcab --- /dev/null +++ b/src/common/views/HelloView/index.js @@ -0,0 +1,3 @@ +import HelloView from './HelloView' + +export default HelloView diff --git a/src/common/views/HomeView/HomeView.jsx b/src/common/views/HomeView/HomeView.jsx new file mode 100644 index 0000000..0bbbd7c --- /dev/null +++ b/src/common/views/HomeView/HomeView.jsx @@ -0,0 +1,19 @@ +import React from 'react' +import Helmet from 'react-helmet' + +// require the logo image both from client and server +const logoImage = require('./kiki.jpg') + +export default function Home() { + return ( +
+ + +

Home

+ +
+

Kiki

+
+
+ ) +} diff --git a/src/common/views/HomeView/index.js b/src/common/views/HomeView/index.js new file mode 100644 index 0000000..cac3591 --- /dev/null +++ b/src/common/views/HomeView/index.js @@ -0,0 +1,3 @@ +import HomeView from './HomeView' + +export default HomeView diff --git a/src/common/components/views/Home/kiki.jpg b/src/common/views/HomeView/kiki.jpg old mode 100755 new mode 100644 similarity index 100% rename from src/common/components/views/Home/kiki.jpg rename to src/common/views/HomeView/kiki.jpg diff --git a/src/server/components/Html/index.jsx b/src/server/components/Html/index.jsx old mode 100755 new mode 100644 index 81a6e06..a394471 --- a/src/server/components/Html/index.jsx +++ b/src/server/components/Html/index.jsx @@ -1,19 +1,22 @@ import React, { Component, PropTypes } from 'react' import { renderToString } from 'react-dom/server' +import Helmet from 'react-helmet' +import serialize from 'serialize-javascript' export default class Html extends Component { static propTypes = { - assets: PropTypes.object, - component: PropTypes.node, - store: PropTypes.object + assets: PropTypes.object.isRequired, + component: PropTypes.node.isRequired, + store: PropTypes.object.isRequired } get scripts() { const { javascript } = this.props.assets - return Object.keys(javascript).map((script, i) => - - - + + + + + +