diff --git a/.babelrc b/.babelrc deleted file mode 100644 index ce840ab86..000000000 --- a/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "stage": 0 -} \ No newline at end of file diff --git a/.csscomb.json b/.csscomb.json deleted file mode 100644 index 6f6b30fef..000000000 --- a/.csscomb.json +++ /dev/null @@ -1,303 +0,0 @@ -{ - "always-semicolon": true, - "block-indent": 2, - "color-case": "lower", - "color-shorthand": true, - "eof-newline": true, - "leading-zero": false, - "remove-empty-rulesets": true, - "space-after-colon": 1, - "space-after-combinator": 1, - "space-before-selector-delimiter": 0, - "space-between-declarations": "\n", - "space-after-opening-brace": "\n", - "space-before-closing-brace": "\n", - "space-before-colon": 0, - "space-before-combinator": 1, - "space-before-opening-brace": 1, - "strip-spaces": true, - "unitless-zero": true, - "vendor-prefix-align": true, - "sort-order": [ - [ - "position", - "top", - "right", - "bottom", - "left", - "z-index", - "display", - "float", - "width", - "min-width", - "max-width", - "height", - "min-height", - "max-height", - "-webkit-box-sizing", - "-moz-box-sizing", - "box-sizing", - "-webkit-appearance", - "padding", - "padding-top", - "padding-right", - "padding-bottom", - "padding-left", - "margin", - "margin-top", - "margin-right", - "margin-bottom", - "margin-left", - "overflow", - "overflow-x", - "overflow-y", - "-webkit-overflow-scrolling", - "-ms-overflow-x", - "-ms-overflow-y", - "-ms-overflow-style", - "clip", - "clear", - "font", - "font-family", - "font-size", - "font-style", - "font-weight", - "font-variant", - "font-size-adjust", - "font-stretch", - "font-effect", - "font-emphasize", - "font-emphasize-position", - "font-emphasize-style", - "font-smooth", - "-webkit-hyphens", - "-moz-hyphens", - "hyphens", - "line-height", - "color", - "text-align", - "-webkit-text-align-last", - "-moz-text-align-last", - "-ms-text-align-last", - "text-align-last", - "text-emphasis", - "text-emphasis-color", - "text-emphasis-style", - "text-emphasis-position", - "text-decoration", - "text-indent", - "text-justify", - "text-outline", - "-ms-text-overflow", - "text-overflow", - "text-overflow-ellipsis", - "text-overflow-mode", - "text-shadow", - "text-transform", - "text-wrap", - "-webkit-text-size-adjust", - "-ms-text-size-adjust", - "letter-spacing", - "-ms-word-break", - "word-break", - "word-spacing", - "-ms-word-wrap", - "word-wrap", - "-moz-tab-size", - "-o-tab-size", - "tab-size", - "white-space", - "vertical-align", - "list-style", - "list-style-position", - "list-style-type", - "list-style-image", - "pointer-events", - "-ms-touch-action", - "touch-action", - "cursor", - "visibility", - "zoom", - "flex-direction", - "flex-order", - "flex-pack", - "flex-align", - "table-layout", - "empty-cells", - "caption-side", - "border-spacing", - "border-collapse", - "content", - "quotes", - "counter-reset", - "counter-increment", - "resize", - "-webkit-user-select", - "-moz-user-select", - "-ms-user-select", - "-o-user-select", - "user-select", - "nav-index", - "nav-up", - "nav-right", - "nav-down", - "nav-left", - "background", - "background-color", - "background-image", - "-ms-filter:\\'progid:DXImageTransform.Microsoft.gradient", - "filter:progid:DXImageTransform.Microsoft.gradient", - "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader", - "filter", - "background-repeat", - "background-attachment", - "background-position", - "background-position-x", - "background-position-y", - "-webkit-background-clip", - "-moz-background-clip", - "background-clip", - "background-origin", - "-webkit-background-size", - "-moz-background-size", - "-o-background-size", - "background-size", - "border", - "border-color", - "border-style", - "border-width", - "border-top", - "border-top-color", - "border-top-style", - "border-top-width", - "border-right", - "border-right-color", - "border-right-style", - "border-right-width", - "border-bottom", - "border-bottom-color", - "border-bottom-style", - "border-bottom-width", - "border-left", - "border-left-color", - "border-left-style", - "border-left-width", - "border-radius", - "border-top-left-radius", - "border-top-right-radius", - "border-bottom-right-radius", - "border-bottom-left-radius", - "-webkit-border-image", - "-moz-border-image", - "-o-border-image", - "border-image", - "-webkit-border-image-source", - "-moz-border-image-source", - "-o-border-image-source", - "border-image-source", - "-webkit-border-image-slice", - "-moz-border-image-slice", - "-o-border-image-slice", - "border-image-slice", - "-webkit-border-image-width", - "-moz-border-image-width", - "-o-border-image-width", - "border-image-width", - "-webkit-border-image-outset", - "-moz-border-image-outset", - "-o-border-image-outset", - "border-image-outset", - "-webkit-border-image-repeat", - "-moz-border-image-repeat", - "-o-border-image-repeat", - "border-image-repeat", - "outline", - "outline-width", - "outline-style", - "outline-color", - "outline-offset", - "-webkit-box-shadow", - "-moz-box-shadow", - "box-shadow", - "filter:progid:DXImageTransform.Microsoft.Alpha(Opacity", - "-ms-filter:\\'progid:DXImageTransform.Microsoft.Alpha", - "opacity", - "-ms-interpolation-mode", - "-webkit-transition", - "-moz-transition", - "-ms-transition", - "-o-transition", - "transition", - "-webkit-transition-delay", - "-moz-transition-delay", - "-ms-transition-delay", - "-o-transition-delay", - "transition-delay", - "-webkit-transition-timing-function", - "-moz-transition-timing-function", - "-ms-transition-timing-function", - "-o-transition-timing-function", - "transition-timing-function", - "-webkit-transition-duration", - "-moz-transition-duration", - "-ms-transition-duration", - "-o-transition-duration", - "transition-duration", - "-webkit-transition-property", - "-moz-transition-property", - "-ms-transition-property", - "-o-transition-property", - "transition-property", - "-webkit-transform", - "-moz-transform", - "-ms-transform", - "-o-transform", - "transform", - "-webkit-transform-origin", - "-moz-transform-origin", - "-ms-transform-origin", - "-o-transform-origin", - "transform-origin", - "-webkit-animation", - "-moz-animation", - "-ms-animation", - "-o-animation", - "animation", - "-webkit-animation-name", - "-moz-animation-name", - "-ms-animation-name", - "-o-animation-name", - "animation-name", - "-webkit-animation-duration", - "-moz-animation-duration", - "-ms-animation-duration", - "-o-animation-duration", - "animation-duration", - "-webkit-animation-play-state", - "-moz-animation-play-state", - "-ms-animation-play-state", - "-o-animation-play-state", - "animation-play-state", - "-webkit-animation-timing-function", - "-moz-animation-timing-function", - "-ms-animation-timing-function", - "-o-animation-timing-function", - "animation-timing-function", - "-webkit-animation-delay", - "-moz-animation-delay", - "-ms-animation-delay", - "-o-animation-delay", - "animation-delay", - "-webkit-animation-iteration-count", - "-moz-animation-iteration-count", - "-ms-animation-iteration-count", - "-o-animation-iteration-count", - "animation-iteration-count", - "-webkit-animation-direction", - "-moz-animation-direction", - "-ms-animation-direction", - "-o-animation-direction", - "animation-direction" - ] - ] -} diff --git a/.csslintrc b/.csslintrc deleted file mode 100644 index 005b86236..000000000 --- a/.csslintrc +++ /dev/null @@ -1,19 +0,0 @@ -{ - "adjoining-classes": false, - "box-sizing": false, - "box-model": false, - "compatible-vendor-prefixes": false, - "floats": false, - "font-sizes": false, - "gradients": false, - "important": false, - "known-properties": false, - "outline-none": false, - "qualified-headings": false, - "regex-selectors": false, - "shorthand": false, - "text-indent": false, - "unique-headings": false, - "universal-selector": false, - "unqualified-attributes": false -} diff --git a/.editorconfig b/.editorconfig index 259cf3d46..959db8a94 100644 --- a/.editorconfig +++ b/.editorconfig @@ -16,5 +16,5 @@ charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true -[*.md] -trim_trailing_whitespace = false +# editorconfig-tools is unable to ignore longs strings or urls +max_line_length = null diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 842fefb59..000000000 --- a/.eslintrc +++ /dev/null @@ -1,11 +0,0 @@ -{ - "parser": "babel-eslint", - "extends": "airbnb", - "globals": { - "__DEV__": true - }, - "rules": { - "react/jsx-quotes": 0, - "jsx-quotes": [2, "prefer-double"] - } -} diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 000000000..3efc19186 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,105 @@ +/** + * React Starter Kit (https://www.reactstarterkit.com/) + * + * Copyright © 2014-present Kriasoft, LLC. All rights reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE.txt file in the root directory of this source tree. + */ + +// ESLint configuration +// http://eslint.org/docs/user-guide/configuring +module.exports = { + parser: 'babel-eslint', + + extends: [ + 'airbnb', + 'plugin:flowtype/recommended', + 'plugin:css-modules/recommended', + 'prettier', + 'prettier/flowtype', + 'prettier/react', + ], + + plugins: ['flowtype', 'css-modules', 'prettier', 'jest'], + + globals: { + __DEV__: true, + }, + + env: { + browser: true, + jest: true, + }, + + rules: { + // Forbid the use of extraneous packages + // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-extraneous-dependencies.md + 'import/no-extraneous-dependencies': ['error', { packageDir: '.' }], + + // Recommend not to leave any console.log in your code + // Use console.error, console.warn and console.info instead + // https://eslint.org/docs/rules/no-console + 'no-console': [ + 'error', + { + allow: ['warn', 'error', 'info'], + }, + ], + + // Prefer destructuring from arrays and objects + // http://eslint.org/docs/rules/prefer-destructuring + 'prefer-destructuring': [ + 'error', + { + VariableDeclarator: { + array: false, + object: true, + }, + AssignmentExpression: { + array: false, + object: false, + }, + }, + { + enforceForRenamedProperties: false, + }, + ], + + // Ensure tags are valid + // https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/anchor-is-valid.md + 'jsx-a11y/anchor-is-valid': [ + 'error', + { + components: ['Link'], + specialLink: ['to'], + aspects: ['noHref', 'invalidHref', 'preferButton'], + }, + ], + + // Allow .js files to use JSX syntax + // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-filename-extension.md + 'react/jsx-filename-extension': ['error', { extensions: ['.js', '.jsx'] }], + + // Functional and class components are equivalent from React’s point of view + // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/prefer-stateless-function.md + 'react/prefer-stateless-function': 'off', + + // ESLint plugin for prettier formatting + // https://github.com/prettier/eslint-plugin-prettier + 'prettier/prettier': 'error', + + 'react/forbid-prop-types': 'off', + 'react/destructuring-assignment': 'off', + }, + + settings: { + // Allow absolute paths in imports, e.g. import Button from 'components/Button' + // https://github.com/benmosher/eslint-plugin-import/tree/master/resolvers + 'import/resolver': { + node: { + moduleDirectory: ['node_modules', 'src'], + }, + }, + }, +}; diff --git a/.flowconfig b/.flowconfig index fadd349b1..f111649a9 100644 --- a/.flowconfig +++ b/.flowconfig @@ -1,7 +1,11 @@ [ignore] .*/build -.*/config +.*/docs .*/node_modules -.*/gulpfile.js +.*/public [include] + +[options] +module.system.node.resolve_dirname=node_modules +module.system.node.resolve_dirname=src diff --git a/.gitattributes b/.gitattributes index 073c188c9..ae3b4c513 100644 --- a/.gitattributes +++ b/.gitattributes @@ -7,13 +7,19 @@ # (this is required in order to prevent newline related issues like, # for example, after the build script is run) .* text eol=lf -*.css text eol=lf *.html text eol=lf -*.jade text eol=lf +*.css text eol=lf +*.less text eol=lf +*.styl text eol=lf +*.scss text eol=lf +*.sass text eol=lf +*.sss text eol=lf *.js text eol=lf +*.jsx text eol=lf *.json text eol=lf -*.less text eol=lf *.md text eol=lf +*.mjs text eol=lf *.sh text eol=lf +*.svg text eol=lf *.txt text eol=lf *.xml text eol=lf diff --git a/.gitignore b/.gitignore index a03526900..1a0fe2e26 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,29 @@ -# Include your project-specific ignores in this file -# Read about how to use .gitignore: https://help.github.com/articles/ignoring-files +# See https://help.github.com/ignore-files/ for more about ignoring files. +# Dependencies +node_modules/ + +# Compiled output build -node_modules -ncp-debug.log -npm-debug.log + +# Runtime data +database.sqlite + +# Test coverage +coverage + +# Logs +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editors and IDEs +.idea +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +# Misc +.DS_Store diff --git a/.jscsrc b/.jscsrc deleted file mode 100644 index 4035efbb6..000000000 --- a/.jscsrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "preset": "airbnb", - "excludeFiles": ["build/**", "node_modules/**"], - "validateQuoteMarks": null -} diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..ec6d3cdd7 --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +package.json diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 000000000..227072ef1 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,16 @@ +/** + * React Starter Kit (https://www.reactstarterkit.com/) + * + * Copyright © 2014-present Kriasoft, LLC. All rights reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE.txt file in the root directory of this source tree. + */ + +// Prettier configuration +// https://prettier.io/docs/en/configuration.html +module.exports = { + printWidth: 80, + singleQuote: true, + trailingComma: 'all', +}; diff --git a/.stylelintrc.js b/.stylelintrc.js new file mode 100644 index 000000000..3477d9a3d --- /dev/null +++ b/.stylelintrc.js @@ -0,0 +1,62 @@ +/** + * React Starter Kit (https://www.reactstarterkit.com/) + * + * Copyright © 2014-present Kriasoft, LLC. All rights reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE.txt file in the root directory of this source tree. + */ + +// stylelint configuration +// https://stylelint.io/user-guide/configuration/ +module.exports = { + // The standard config based on a handful of CSS style guides + // https://github.com/stylelint/stylelint-config-standard + extends: 'stylelint-config-standard', + + plugins: [ + // stylelint plugin to sort CSS rules content with specified order + // https://github.com/hudochenkov/stylelint-order + 'stylelint-order', + ], + + rules: { + 'property-no-unknown': [ + true, + { + ignoreProperties: [ + // CSS Modules composition + // https://github.com/css-modules/css-modules#composition + 'composes', + ], + }, + ], + + 'selector-pseudo-class-no-unknown': [ + true, + { + ignorePseudoClasses: [ + // CSS Modules :global scope + // https://github.com/css-modules/css-modules#exceptions + 'global', + 'local', + ], + }, + ], + + // Opinionated rule, you can disable it if you want + 'string-quotes': 'single', + + // https://github.com/hudochenkov/stylelint-order/blob/master/rules/order/README.md + 'order/order': [ + 'custom-properties', + 'dollar-variables', + 'declarations', + 'at-rules', + 'rules', + ], + + // https://github.com/hudochenkov/stylelint-order/blob/master/rules/properties-order/README.md + 'order/properties-order': [], + }, +}; diff --git a/.travis.yml b/.travis.yml index 09cbb6d21..6105d4a58 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,9 @@ -sudo: false language: node_js node_js: - - '5' + - 'stable' + - '12' + - '10' + - '8' env: - CXX=g++-4.8 addons: @@ -10,3 +12,8 @@ addons: - ubuntu-toolchain-r-test packages: - g++-4.8 +cache: yarn +script: + - yarn lint + - yarn test + - yarn build --release diff --git a/CHANGELOG.md b/CHANGELOG.md index a164a722c..d6803765d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,46 @@ All notable changes to this project will be documented in this file. ### [Unreleased][unreleased] +- Split the `App` component into `App` setting context variables and `Layout` setting general look and feel of the app (BREAKING CHANGE) +- Upgrade `history` npm module to v4.x, update `Link` component (BREAKING CHANGE) +- Remove `core/createHistory.js` in favor of initializing a new history instance inside `server.js` and `client.js` (BREAKING CHANGE) +- Remove Jade dependency in favor of React-based templates: `src/views/index.jade => src/components/Html` + (BREAKING CHANGE) [#711](https://github.com/kriasoft/react-starter-kit/pull/711) +- Update `isomorphic-style-loader` to `v1.0.0`, it adds comparability with ES2015+ decorators. + Code such as `export default withStyles(MyComponent, style1, style2)` must be replaced with + `export default withStyles(style1, style2)(MyComponent)` (BREAKING CHANGE). +- Replace Jest with Mocha, Chai, Sinon. Unit test files must be renamed from + `MyComponent/__test__/MyComponent-test.js` to `MyComponent/MyComponent.test.js` (BREAKING CHANGE). +- Remove `actions`, `stores` folders since there is no Flux library included into the kit +- Rename `server` variable in `server.js` to `app` +- Integrate [Sequelize](http://docs.sequelizejs.com/) to make the project compatible with different types of databases +- Rename `onSetTitle`, `onSetMeta` context variables to `setTitle`, `setMeta` +- Move `Content` component to `src/routes/content` +- Move `ErrorPage` component to `src/routes/error` +- Move the list of top-level routes to `src/routes/index` +- Update routing to use `universal-router` library +- Move Babel, ESLint and JSCS configurations to `package.json` [#497](https://github.com/kriasoft/react-starter-kit/pull/497) +- Convert `Feedback`, `Footer`, `Header`, and `Navigation` to functional stateless components +- Move page / screen components into the `src/routes` folder along with the routing information for them (BREAKING CHANGE). [6553936](https://github.com/kriasoft/react-starter-kit/commit/6553936e693e24a8ac6178f4962af15e0ea87dfd) + +### [v0.5.1] + +> 2016-03-02 + +- Remove `Html` React component in favor of compiled Jade templates (`src/views`) (BREAKING CHANGE). [e188388](https://github.com/kriasoft/react-starter-kit/commit/e188388f87069cdc7d501b385d6b0e46c98fed60) +- Add global error handling in Node.js/Express app. [e188388](https://github.com/kriasoft/react-starter-kit/commit/e188388f87069cdc7d501b385d6b0e46c98fed60) +- Add support for Markdown and HTML for static pages. [#469](https://github.com/kriasoft/react-starter-kit/pull/469), [#477](https://github.com/kriasoft/react-starter-kit/pull/477) + +### [v0.5.0] + +> 2016-02-27 + +- Replace RESTful API endpoint (`src/api`) with GraphQL (`src/data`) +- Add a sample GraphQL endpoint [localhost:3000/graphql](https://localhost:3000/graphql) +- Change the default Node.js server port from `5000` to `3000` +- Add a JWT-based authentication cookies (see `src/server.js`) +- Add a reference implementation of Facebook authentication strategy (`src/core/passport.js`) +- Add a sample database client utility for PostgreSQL (`src/core/db.js`) - Optimize the `tools/start.js` script that launches dev server with Browsersync and HMR - Replace Superagent with WHATWG Fetch library - Rename `app.js` to `client.js` (aka client-side code) @@ -15,14 +55,18 @@ All notable changes to this project will be documented in this file. - Add support of `--release` and `--verbose` flags to build scripts - Add `CHANGELOG.md` file with a list of notable changes to this project -### [v0.4.1] - 2015-10-04 +### [v0.4.1] + +> 2015-10-04 -- Replace React Hot Loader (depricated) with React Transform +- Replace React Hot Loader (deprecated) with React Transform - Replace `index.html` template with `Html` (shell) React component - Update the deployment script (`tools/deploy.js`), add Git-based deployment example - Update ESLint and JSCS settings to use AirBnb JavaScript style guide - Update `docs/how-to-configure-text-editors.md` to cover Atom editor - Update NPM production and dev dependencies to use the latest versions -[unreleased]: https://github.com/kriasoft/react-starter-kit/compare/v0.4.1...HEAD +[unreleased]: https://github.com/kriasoft/react-starter-kit/compare/v0.5.1...HEAD +[v0.5.1]: https://github.com/kriasoft/react-starter-kit/compare/v0.5.0...v0.5.1 +[v0.5.0]: https://github.com/kriasoft/react-starter-kit/compare/v0.4.1...v0.5.0 [v0.4.1]: https://github.com/kriasoft/react-starter-kit/compare/v0.4.0...v0.4.1 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..24e66a167 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,66 @@ +## Contributing to React Starter Kit + +React Starter Kit is currently the most widely adopted Node.js/React boilerplate used by many +tech startups around the globe. We're working hard to keep it up to date, making sure that it +follows best practices and high coding standards, paying extremely close attention to details. + +Your contributions are welcome and are greatly appreciated! Every little bit helps, and credit +will always be given. + +Please take a moment to review this document in order to make the contribution process easy and +effective for everyone involved. + +### Conduct + +Please, follow the [golden rule](https://en.wikipedia.org/wiki/Golden_Rule). Be respectful, even to +those that are disrespectful. + +### Feedback + +Feedback is the breakfast for champions! We'd love to hear your opinions, discuss potential +improvements, architecture, theory, internal implementation, etc. Please, join or start a new +conversation in our [issue tracker](https://github.com/kriasoft/react-starter-kit/issues), +[Gitter](https://gitter.im/kriasoft/react-starter-kit) chat room, or let's talk face-to-face on +[Appear.in](https://appear.in/react) or [Skype](http://hatscripts.com/addskype?koistya). + +### Documentation + +We need your help with improving documentation to the project. This might be the easiest way for +you to contribute, because you don't even need to clone the repo but can edit or create new `.md` +files right from GitHub website as described [here](https://help.github.com/articles/editing-files-in-your-repository/). + +### Bugs & Feature Requests + +Before opening an issue, please: + +- Check the [Getting Started](https://github.com/kriasoft/react-starter-kit/blob/master/docs/getting-started.md) guide. +- Search the [issue tracker](https://github.com/kriasoft/react-starter-kit/issues) to make sure + your issue hasn’t already been reported. +- If your issue sounds more like a question, please post it on StackOverflow.com instead with the + tag [react-starter-kit](http://stackoverflow.com/questions/tagged/react-starter-kit). + +### Pull Requests + +Before you submit a [pull request](https://help.github.com/articles/using-pull-requests/) from your +forked repo, check that it meets these guidelines: + +- If the pull request adds functionality, the docs should be updated as part of the same PR. +- Create a separate PR for each small feature or bug fix. +- [Squash](http://stackoverflow.com/questions/5189560/squash-my-last-x-commits-together-using-git) + your commits into one for each PR. +- Run `yarn test` to make sure that your code style is OK and there are no any regression bugs. +- When contributing to an opt-in feature, apply the `[feature/...]` tag as a prefix to your PR title + +#### Style Guide + +Our linter will catch most styling issues that may exist in your code. You can check the status +of your code styling by simply running: `yarn lint` + +However, there are still some styles that the linter cannot pick up. If you are unsure about +something, looking at [Airbnb's Style Guide](https://github.com/airbnb/javascript) will guide you +in the right direction. + +### License + +By contributing to React Starter Kit, you agree that your contributions will be licensed under its +[MIT license](https://github.com/kriasoft/react-starter-kit/blob/master/LICENSE.txt). diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..d8f277125 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,25 @@ +FROM node:8.16.2-alpine + +# Set a working directory +WORKDIR /usr/src/app + +COPY ./build/package.json . +COPY ./build/yarn.lock . + +# Install Node.js dependencies +RUN yarn install --production --no-progress + +# Copy application files +COPY ./build . + +# Set permissions for "node" user +RUN chown -R node:node /usr/src/app +RUN chmod 755 /usr/src/app + +# Run the container under "node" user by default +USER node + +# Set NODE_ENV env variable to "production" for faster expressjs +ENV NODE_ENV production + +CMD [ "node", "server.js" ] diff --git a/LICENSE.txt b/LICENSE.txt index 63623803e..2e4e7b16b 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,6 +1,6 @@ - The MIT License +The MIT License -Copyright (c) 2014 Konstantin Tarkus (@koistya), KriaSoft LLC. +Copyright (c) 2014-present Konstantin Tarkus, Kriasoft LLC. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -18,4 +18,4 @@ 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. \ No newline at end of file +THE SOFTWARE. diff --git a/README.md b/README.md index 000437de4..7e33bc201 100644 --- a/README.md +++ b/README.md @@ -1,97 +1,228 @@ -## React Starter Kit — "isomorphic" web app boilerplate - -[![Support us on Bountysource](https://dl.dropboxusercontent.com/u/16006521/react-starter-kit/banner.png)](https://salt.bountysource.com/teams/react-starter-kit)
- -> [React Starter Kit](https://www.reactstarterkit.com) is an opinionated -> boilerplate for web development built on top of Facebook's -> [React](https://facebook.github.io/react/) library, -> [Node.js](https://nodejs.org/) / [Express](http://expressjs.com/) server -> and [Flux](http://facebook.github.io/flux/) architecture. Containing -> modern web development tools such as [Webpack](http://webpack.github.io/), -> [Babel](http://babeljs.io/) and [BrowserSync](http://www.browsersync.io/). -> Helping you to stay productive following the best practices. A solid starting -> point for both professionals and newcomers to the industry. - -See [demo](http://demo.reactstarterkit.com)  |  -[docs](https://github.com/kriasoft/react-starter-kit/tree/master/docs)  |  -[bugs & feature requests](https://waffle.io/kriasoft/react-starter-kit)  |  -join [#react-starter-kit](https://gitter.im/kriasoft/react-starter-kit) chatroom to stay up to date  |  -visit our sponsors: - -[![Rollbar - Full-stack error tracking for all apps in any language](https://dl.dropboxusercontent.com/u/16006521/react-starter-kit/rollbar.png)](https://rollbar.com/?utm_source=reactstartkit(github)&utm_medium=link&utm_campaign=reactstartkit(github))    -[![Localize - Translate your web app in minutes](https://dl.dropboxusercontent.com/u/16006521/react-starter-kit/localize.png)](https://localizejs.com/?cid=802&utm_source=rsk) +## React Starter Kit — "[isomorphic](http://nerds.airbnb.com/isomorphic-javascript-future-web-apps/)" web app boilerplate  
+ +[React Starter Kit](https://www.reactstarterkit.com) is an opinionated boilerplate for web +development built on top of [Node.js](https://nodejs.org/), +[Express](http://expressjs.com/), [GraphQL](http://graphql.org/) and +[React](https://facebook.github.io/react/), containing modern web development +tools such as [Webpack](http://webpack.github.io/), [Babel](http://babeljs.io/) +and [Browsersync](http://www.browsersync.io/). Helping you to stay productive +following the best practices. A solid starting point for both professionals +and newcomers to the industry. + +**See** [getting started guide](./docs/getting-started.md), [demo][demo], +[docs](https://github.com/kriasoft/react-starter-kit/tree/master/docs), +[roadmap](https://github.com/kriasoft/react-starter-kit/projects/1)  |  +**Join** [#react-starter-kit][chat] chat room on Gitter  |  +**Visit our sponsors**:

+ +

+ + + Hiring +

### Getting Started - * Follow the [getting started guide](./docs/getting-started.md) to download and run the project - * Check the [code recipes](./docs/recipes) used in this boilerplate, or share yours - -### Directory Layout - -``` -. -├── /build/ # The folder for compiled output -├── /docs/ # Documentation files for the project -├── /node_modules/ # 3rd-party libraries and utilities -├── /src/ # The source code of the application -│ ├── /actions/ # Action creators that allow to trigger a dispatch to stores -│ ├── /api/ # REST API / Relay endpoints -│ ├── /components/ # React components -│ ├── /constants/ # Constants (action types etc.) -│ ├── /content/ # Static content (plain HTML or Markdown, Jade, you name it) -│ ├── /core/ # Core framework and utility functions -│ ├── /decorators/ # Higher-order React components -│ ├── /public/ # Static files which are copied into the /build/public folder -│ ├── /stores/ # Stores contain the application state and logic -│ ├── /client.js # Client-side startup script -│ ├── /config.js # Global application settings -│ ├── /routes.js # Universal (isomorphic) application routes -│ └── /server.js # Server-side startup script -├── /tools/ # Build automation scripts and utilities -│ ├── /lib/ # Library for utility snippets -│ ├── /build.js # Builds the project from source to output (build) folder -│ ├── /bundle.js # Bundles the web resources into package(s) through Webpack -│ ├── /clean.js # Cleans up the output (build) folder -│ ├── /copy.js # Copies static files to output (build) folder -│ ├── /deploy.js # Deploys your web application -│ ├── /run.js # Helper function for running build automation tasks -│ ├── /runServer.js # Launches (or restarts) Node.js server -│ ├── /start.js # Launches the development web server with "live reload" -│ └── /webpack.config.js # Configurations for client-side and server-side bundles -│── package.json # The list of 3rd party libraries and utilities -└── preprocessor.js # ES6 transpiler settings for Jest -``` +- Follow the [getting started guide](./docs/getting-started.md) to download and run the project + ([Node.js](https://nodejs.org/) >= 8.16.2) +- Check the [code recipes](./docs/recipes) used in this boilerplate, or share yours + +### Customization + +The `master` branch of React Starter Kit doesn't include a Flux implementation or any other +advanced integrations. Nevertheless, we have some integrations available to you in _feature_ +branches that you can use either as a reference or merge into your project: + +- [feature/redux](https://github.com/kriasoft/react-starter-kit/tree/feature/redux) ([PR](https://github.com/kriasoft/react-starter-kit/pull/1084)) + — isomorphic Redux by [Pavel Lang](https://github.com/langpavel) + (see [how to integrate Redux](./docs/recipes/how-to-integrate-redux.md)) (based on `master`) +- [feature/apollo](https://github.com/kriasoft/react-starter-kit/tree/feature/apollo) ([PR](https://github.com/kriasoft/react-starter-kit/pull/1147)) + — isomorphic Apollo Client by [Pavel Lang](https://github.com/langpavel) + (see [Tracking PR #1147](https://github.com/kriasoft/react-starter-kit/pull/1147)) (based on `feature/redux`) +- [feature/react-intl](https://github.com/kriasoft/react-starter-kit/tree/feature/react-intl) ([PR](https://github.com/kriasoft/react-starter-kit/pull/1135)) + — isomorphic Redux and React Intl by [Pavel Lang](https://github.com/langpavel) + (see [how to integrate React Intl](./docs/recipes/how-to-integrate-react-intl.md)) (based on `feature/apollo`) +- [feature/apollo-pure](https://github.com/kriasoft/react-starter-kit/tree/feature/apollo-pure) ([PR](https://github.com/kriasoft/react-starter-kit/pull/1666)) + — Apollo devtools and TypeScript integration by [piglovesyou](https://github.com/piglovesyou) (based on `master`) + +You can see status of most reasonable merge combination as [PRs labeled as `TRACKING`](https://github.com/kriasoft/react-starter-kit/labels/TRACKING) + +If you think that any of these features should be on `master`, or vice versa, some features should +removed from the `master` branch, please [let us know](https://gitter.im/kriasoft/react-starter-kit). +We love your feedback! + +### Comparison + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  +

React Starter Kit

+ + +
+

React Static Boilerplate

+ + +
+

ASP.NET Core Starter Kit

+ + +
App typeIsomorphic (universal)Single-page applicationSingle-page application
Frontend
LanguageJavaScript (ES2015+, JSX)JavaScript (ES2015+, JSX)JavaScript (ES2015+, JSX)
Libraries + React, + History, + Universal Router + + React, + History, + Redux + + React, + History, + Redux +
RoutesImperative (functional)DeclarativeDeclarative, cross-stack
Backend
LanguageJavaScript (ES2015+, JSX)n/aC#, F#
Libraries + Node.js, + Express, + Sequelize,
+ GraphQL
n/a + ASP.NET Core, + EF Core,
+ ASP.NET Identity +
SSRYesn/an/a
Data APIGraphQLn/aWeb API
+ +### Backers + +♥ React Starter Kit? Help us keep it alive by donating funds to cover project +expenses via [OpenCollective](https://opencollective.com/react-starter-kit) or +[Bountysource](https://salt.bountysource.com/teams/react-starter-kit)! + + + lehneres + + + Tarkan Anlar + + + Morten Olsen + + + Adam + + + David Ernst + + + Zane Hitchcox + + + + + +### How to Contribute + +Anyone and everyone is welcome to [contribute](CONTRIBUTING.md) to this project. The best way to +start is by checking our [open issues](https://github.com/kriasoft/react-starter-kit/issues), +[submit a new issue](https://github.com/kriasoft/react-starter-kit/issues/new?labels=bug) or +[feature request](https://github.com/kriasoft/react-starter-kit/issues/new?labels=enhancement), +participate in discussions, upvote or downvote the issues you like or dislike, send [pull +requests](CONTRIBUTING.md#pull-requests). -### Related Projects +### Learn More - * [React Static Boilerplate](https://github.com/koistya/react-static-boilerplate) — Generates static websites from React components - * [Babel Starter Kit](https://github.com/kriasoft/babel-starter-kit) — Boilerplate for authoring JavaScript/React.js libraries - * [React Decorators](https://github.com/kriasoft/react-decorators) — A collection of higher-order React components +- [Getting Started with React.js](http://facebook.github.io/react/) +- [Getting Started with GraphQL and Relay](https://quip.com/oLxzA1gTsJsE) +- [React.js Questions on StackOverflow](http://stackoverflow.com/questions/tagged/reactjs) +- [React.js Discussion Board](https://discuss.reactjs.org/) +- [Flux Architecture for Building User Interfaces](http://facebook.github.io/flux/) +- [Enzyme — JavaScript Testing utilities for React](http://airbnb.io/enzyme/) +- [Flow — A static type checker for JavaScript](http://flowtype.org/) +- [The Future of React](https://github.com/reactjs/react-future) +- [Learn ES6](https://babeljs.io/docs/learn-es6/), [ES6 Features](https://github.com/lukehoban/es6features#readme) -### Learn More +### Related Projects - * [Getting Started with React.js](http://facebook.github.io/react/) - * [Getting Started with GraphQL and Relay](https://quip.com/oLxzA1gTsJsE) - * [React.js Questions on StackOverflow](http://stackoverflow.com/questions/tagged/reactjs) - * [React.js Discussion Board](https://discuss.reactjs.org/) - * [Flux Architecture for Building User Interfaces](http://facebook.github.io/flux/) - * [Jest - Painless Unit Testing](http://facebook.github.io/jest/) - * [Flow - A static type checker for JavaScript](http://flowtype.org/) - * [The Future of React](https://github.com/reactjs/react-future) - * [Learn ES6](https://babeljs.io/docs/learn-es6/), [ES6 Features](https://github.com/lukehoban/es6features#readme) +- [GraphQL Starter Kit](https://github.com/kriasoft/graphql-starter-kit) — Boilerplate for building data APIs with Node.js, JavaScript (via Babel) and GraphQL +- [Membership Database](https://github.com/membership/membership.db) — SQL schema boilerplate for user accounts, profiles, roles, and auth claims +- [Babel Starter Kit](https://github.com/kriasoft/babel-starter-kit) — Boilerplate for authoring JavaScript/React.js libraries ### Support - * [#react-starter-kit](https://gitter.im/kriasoft/react-starter-kit) on Gitter — Feedback, feature requests, Q&A - * [@koistya](https://www.codementor.io/koistya) on Codementor — Mentorship, pair coding, code reviews - * support@kriasoft.com — Customization requests, help with GraphQL/Relay, database design etc. +- [#react-starter-kit](http://stackoverflow.com/questions/tagged/react-starter-kit) on Stack Overflow — Questions and answers +- [#react-starter-kit](https://gitter.im/kriasoft/react-starter-kit) on Gitter — Watch announcements, share ideas and feedback +- [GitHub issues](https://github.com/kriasoft/react-starter-kit/issues), or [Scrum board](https://waffle.io/kriasoft/react-starter-kit) — File issues, send feature requests +- [appear.in/react](https://appear.in/react) — Open hours! Exchange ideas and experiences (React, GraphQL, startups and pet projects) +- [@koistya](https://twitter.com/koistya) on [Codementor](https://www.codementor.io/koistya), or [Skype](http://hatscripts.com/addskype?koistya) — Private consulting ### License -Copyright © 2014-2016 Kriasoft, LLC. This source code is licensed under the MIT +Copyright © 2014-present Kriasoft, LLC. This source code is licensed under the MIT license found in the [LICENSE.txt](https://github.com/kriasoft/react-starter-kit/blob/master/LICENSE.txt) file. The documentation to the project is licensed under the [CC BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/) license. --- + Made with ♥ by Konstantin Tarkus ([@koistya](https://twitter.com/koistya)) and [contributors](https://github.com/kriasoft/react-starter-kit/graphs/contributors) + +[rsk]: https://www.reactstarterkit.com +[demo]: http://demo.reactstarterkit.com +[node]: https://nodejs.org +[chat]: https://gitter.im/kriasoft/react-starter-kit diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 000000000..fdbbc882a --- /dev/null +++ b/babel.config.js @@ -0,0 +1,30 @@ +/** + * React Starter Kit (https://www.reactstarterkit.com/) + * + * Copyright © 2014-present Kriasoft, LLC. All rights reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE.txt file in the root directory of this source tree. + */ + +// Babel configuration +// https://babeljs.io/docs/usage/api/ +module.exports = { + presets: [ + [ + '@babel/preset-env', + { + targets: { + node: 'current', + }, + }, + ], + '@babel/preset-flow', + '@babel/preset-react', + ], + plugins: [ + '@babel/plugin-proposal-class-properties', + '@babel/plugin-syntax-dynamic-import', + ], + ignore: ['node_modules', 'build'], +}; diff --git a/docs/README.md b/docs/README.md index a3c529cf7..b261f203b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,17 +2,22 @@ ### General -* [Getting Started](./getting-started.md) -* [React Style Guide](./react-style-guide.md) -* [How to configure text editors and IDEs](./how-to-configure-text-editors.md) -* [Data fetching with WHATWG Fetch](./data-fetching.md) +- [Getting Started](./getting-started.md) +- [React Style Guide](./react-style-guide.md) +- [How to configure text editors and IDEs](./how-to-configure-text-editors.md) +- [Data fetching with WHATWG Fetch](./data-fetching.md) +- [Testing your application](./testing-your-application.md) ### Questions -* [Which module bundler should I use?](https://github.com/kriasoft/react-starter-kit/issues/3) -* [Which Flux implementation should I use?](https://github.com/kriasoft/react-starter-kit/issues/22) +- [Which module bundler should I use?](https://github.com/kriasoft/react-starter-kit/issues/3) +- [Which Flux implementation should I use?](https://github.com/kriasoft/react-starter-kit/issues/22) ### Recipes -* [How to Implement Routing and Navigation](./recipes/how-to-implement-routing.md) -* [How to Integrate Disqus](./recipes/how-to-integrate-disqus.md) +- [How to Implement Routing and Navigation](./recipes/how-to-implement-routing.md) +- [How to Integrate Redux](./recipes/how-to-integrate-redux.md) +- [How to Integrate React Intl](./recipes/how-to-integrate-react-intl.md) +- [How to Integrate Disqus](./recipes/how-to-integrate-disqus.md) +- [How to Use Sass/SCSS](./recipes/how-to-use-sass.md) +- [How to Configure Facebook Login](./recipes/how-to-configure-facebook-login.md) diff --git a/docs/data-fetching.md b/docs/data-fetching.md index 6665c9af3..cdb0eb9e5 100644 --- a/docs/data-fetching.md +++ b/docs/data-fetching.md @@ -1,32 +1,71 @@ -## Data Fetching with WHATWG Fetch +## Data Fetching -There is isomorphic `core/fetch` module that can be used the same way in both -client-side and server-side code as follows: +At a bare minimum you may want to use [HTML5 Fetch API][fetch] as an HTTP client +utility for making Ajax request to the [data API server][nodeapi]. This API is +supported natively in all the major browsers except for IE (note, that Edge +browser does support Fetch). -```jsx -import fetch from '../core/fetch'; +**React Starter Kit** is pre-configured with [`whatwg-fetch`][wfetch] polyfill +for the browser environment and [`node-fetch`][nfetch] module for the +server-side environment (see [`src/createFetch.js`](../src/createFetch.js)), +allowing you to use the `fetch(url, options)` method universally in both the +client-side and server-side code bases. -export const path = '/products'; -export const action = async () => { - const response = await fetch('/api/products'); - const data = await response.json(); - return ; -}; +In order to avoid the amount of boilerplate code needed when using the raw +`fetch(..)` function, a simple wrapper was created that provides a base URL of +the data API server, credentials (cookies), CORS etc. For example, in a browser +environment the base URL of the data API server might be an empty string, so +when you make an Ajax request to the `/graphql` endpoint it's being sent to the +same origin, and when the same code is executed on the server, during +server-side rendering, it fetches data from the `http://api:8080/graphql` +endpoint (`node-fetch` doesn't support relative URLs for obvious reasons). + +Because of these subtle differences of how the `fetch` method works internally, +it makes total sense to pass it as a `context` variable to your React +application, so it can be used from either routing level or from inside your +React components as follows: + +#### Route Example + +```js +{ + path: '/posts/:id', + async action({ params, fetch }) { + const resp = await fetch(`/api/posts/${params.id}`, { method: 'GET' }); + const data = await resp.json(); + return { title: data.title, component: }; + } +} ``` -When this code executes on the client, the Ajax request will be sent via -GitHub's [fetch](https://github.com/github/fetch) library (`whatwg-fetch`), -that itself uses XHMLHttpRequest behind the scene unless `fetch` is supported -natively by the user's browser. +#### React Component -Whenever the same code executes on the server, it uses -[node-fetch](https://github.com/bitinn/node-fetch) module behind the scene that -itself sends an HTTP request via Node.js `http` module. It also converts -relative URLs to absolute (see `./core/fetch/fetch.server.js`). +```js +import {useContext} from 'react'; +import ApplicationContext from '../ApplicationContext'; -Both `whatwg-fetch` and `node-fetch` modules have almost identical API. If -you're new to this API, the following article may give you a good introduction: +function Post() { + const {context} = useContext(ApplicationContext); + return ( +
+ ... + { + event.preventDefault(); + const id = event.target.dataset['id']; + // Use context.fetch to make it work in both server-side and client-side + context.fetch(`/api/posts/${id}`, { method: 'DELETE' }).then(...); + }}>Delete +
+ ); +} +``` -https://jakearchibald.com/2015/thats-so-fetch/ +#### Related articles +- [That's so fetch!](https://jakearchibald.com/2015/thats-so-fetch/) by + [Jake Archibald](https://twitter.com/jaffathecake) +[fetch]: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch +[wfetch]: https://github.com/github/fetchno +[nfetch]: https://github.com/bitinn/node-fetch +[nodeapi]: https://github.com/kriasoft/nodejs-api-starter diff --git a/docs/getting-started.md b/docs/getting-started.md index eaf2dddf8..a461a1d44 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -2,11 +2,52 @@ ### Requirements - * Mac OS X, Windows, or Linux - * [Node.js](https://nodejs.org/) v5.0 or newer - * `npm` v3.3 or newer (new to [npm](https://docs.npmjs.com/)?) - * `node-gyp` prerequisites mentioned [here](https://github.com/nodejs/node-gyp) - * Text editor or IDE pre-configured with React/JSX/Flow/ESlint ([learn more](./how-to-configure-text-editors.md)) +- Mac OS X, Windows, or Linux +- [Yarn](https://yarnpkg.com/) package + [Node.js](https://nodejs.org/) v8.16.2 or + newer +- Text editor or IDE pre-configured with React/JSX/Flow/ESlint + ([learn more](./how-to-configure-text-editors.md)) + +### Directory Layout + +Before you start, take a moment to see how the project structure looks like: + +``` +. +├── /build/ # The folder for compiled output +├── /docs/ # Documentation files for the project +├── /node_modules/ # 3rd-party libraries and utilities +├── /public/ # Static files which are copied into the /build/public folder +├── /src/ # The source code of the application +│ ├── /components/ # React components +│ ├── /data/ # GraphQL server schema and data models +│ ├── /routes/ # Page/screen components along with the routing information +│ ├── /client.js # Client-side startup script +│ ├── /config.js # Global application settings +│ ├── /server.js # Server-side startup script +│ └── ... # Other core framework modules +├── /test/ # Unit and end-to-end tests +├── /tools/ # Build automation scripts and utilities +│ ├── /lib/ # Library for utility snippets +│ ├── /build.js # Builds the project from source to output (build) folder +│ ├── /bundle.js # Bundles the web resources into package(s) through Webpack +│ ├── /clean.js # Cleans up the output (build) folder +│ ├── /copy.js # Copies static files to output (build) folder +│ ├── /deploy.js # Deploys your web application +│ ├── /postcss.config.js # Configuration for transforming styles with PostCSS plugins +│ ├── /run.js # Helper function for running build automation tasks +│ ├── /runServer.js # Launches (or restarts) Node.js server +│ ├── /start.js # Launches the development web server with "live reload" +│ └── /webpack.config.js # Configurations for client-side and server-side bundles +├── Dockerfile # Commands for building a Docker image for production +├── package.json # The list of 3rd party libraries and utilities +└── yarn.lock # Fixed versions of all the dependencies +``` + +**Note**: The current version of RSK does not contain a Flux implementation. It +can be easily integrated with any Flux library of your choice. The most commonly +used Flux libraries are [Flux](http://facebook.github.io/flux/), +[Redux](http://redux.js.org/) and [Relay](http://facebook.github.io/relay/). ### Quick Start @@ -16,57 +57,75 @@ You can start by cloning the latest version of React Starter Kit (RSK) on your local machine by running: ```shell -$ git clone -o react-starter-kit -b master --single-branch \ - https://github.com/kriasoft/react-starter-kit.git MyApp +$ git clone -o react-starter-kit -b master --single-branch https://github.com/kriasoft/react-starter-kit.git MyApp $ cd MyApp ``` Alternatively, you can start a new project based on RSK right from -[WebStorm IDE](https://www.jetbrains.com/webstorm/help/create-new-project-react-starter-kit.html), -or by using [Yeoman generator](https://www.npmjs.com/package/generator-react-fullstack). +[WebStorm IDE](https://www.jetbrains.com/help/webstorm/generating-a-project-from-a-framework-template.html#d88767e51), +or by using +[Yeoman generator](https://www.npmjs.com/package/generator-react-fullstack). -#### 2. Run `npm install` +#### 2. Run `yarn install` This will install both run-time project dependencies and developer tools listed in [package.json](../package.json) file. -#### 3. Run `npm start` +#### 3. Run `yarn start` This command will build the app from the source files (`/src`) into the output `/build` folder. As soon as the initial build completes, it will start the -Node.js server (`node build/server.js`) and [Browsersync](https://browsersync.io/) -with [HMR](https://webpack.github.io/docs/hot-module-replacement) on top of it. - -Now you can open your web app in a browser, on mobile devices and start -hacking. Whenever you modify any of the source files inside the `/src` folder, -the module bundler ([Webpack](http://webpack.github.io/)) will recompile the -app on the fly and refresh all the connected browsers. +Node.js server (`node build/server.js`) and +[Browsersync](https://browsersync.io/) with +[HMR](https://webpack.github.io/docs/hot-module-replacement) on top of it. + +> [http://localhost:3000/](http://localhost:3000/) — Node.js server +> (`build/server.js`) with Browsersync and HMR enabled\ +> [http://localhost:3000/graphql](http://localhost:3000/graphql) — GraphQL server +> and IDE\ +> [http://localhost:3001/](http://localhost:3001/) — Browsersync control panel +> (UI) + +Now you can open your web app in a browser, on mobile devices and start hacking. +Whenever you modify any of the source files inside the `/src` folder, the module +bundler ([Webpack](http://webpack.github.io/)) will recompile the app on the fly +and refresh all the connected browsers. ![browsersync](https://dl.dropboxusercontent.com/u/16006521/react-starter-kit/brwosersync.jpg) -Note that the `npm start` command launches the app in `development` mode, -the compiled output files are not optimized and minimized in this case. -You can use `--release` command line argument to check how your app works -in release (production) mode: +Note that the `yarn start` command launches the app in `development` mode, the +compiled output files are not optimized and minimized in this case. You can use +`--release` command line argument to check how your app works in release +(production) mode: ```shell -$ npm start -- --release +$ yarn start --release ``` +_NOTE: double dashes are required_ + ### How to Build, Test, Deploy If you need just to build the app (without running a dev server), simply run: ```shell -$ npm run build +$ yarn run build ``` or, for a production build: ```shell -$ npm run build -- --release +$ yarn run build --release +``` + +or, for a production docker build: + +```shell +$ yarn run build --release --docker ``` +_NOTE: double dashes are required_ + After running this command, the `/build` folder will contain the compiled version of the app. For example, you can launch Node.js server normally by running `node build/server.js`. @@ -74,41 +133,43 @@ running `node build/server.js`. To check the source code for syntax errors and potential issues run: ```shell -$ npm run lint +$ yarn run lint ``` To launch unit tests: ```shell -$ npm test +$ yarn run test # Run unit tests with Jest +$ yarn run test-watch # Launch unit test runner and start watching for changes ``` -Test any javascript module by creating a `__tests__/` directory where -the file is. Append `-test.js` to the filename and -[Jest](https://facebook.github.io/jest/) will do the rest. +By default, [Jest](https://jestjs.io/) test runner is looking for test files +matching the `src/**/*.test.js` pattern. Take a look at +`src/components/Layout/Layout.test.js` as an example. To deploy the app, run: ```shell -$ npm run deploy +$ yarn run deploy ``` The deployment script `tools/deploy.js` is configured to push the contents of the `/build` folder to a remote server via Git. You can easily deploy your app -to [Azure Web Apps](https://azure.microsoft.com/en-us/services/app-service/web/), -or [Heroku](https://www.heroku.com/) this way. Both will execute `npm install --production` -upon receiving new files from you. Note, you should only deploy the contents -of the `/build` folder to a remote server. +to +[Azure Web Apps](https://azure.microsoft.com/en-us/services/app-service/web/), +or [Heroku](https://www.heroku.com/) this way. Both will execute `yarn install --production` upon receiving new files from you. Note, you should only deploy +the contents of the `/build` folder to a remote server. ### How to Update If you need to keep your project up to date with the recent changes made to RSK, -you can always fetch and merge them from [this repo](https://github.com/kriasoft/react-starter-kit) -back into your own project by running: +you can always fetch and merge them from +[this repo](https://github.com/kriasoft/react-starter-kit) back into your own +project by running: ```shell $ git checkout master $ git fetch react-starter-kit $ git merge react-starter-kit/master -$ npm install +$ yarn install ``` diff --git a/docs/how-to-configure-text-editors.md b/docs/how-to-configure-text-editors.md index 41d047ef5..786dc041d 100644 --- a/docs/how-to-configure-text-editors.md +++ b/docs/how-to-configure-text-editors.md @@ -7,69 +7,81 @@ Create a new project based on **React Starter Kit template** -![react-project-template-in-webstorm](https://dl.dropboxusercontent.com/u/16006521/react-starter-kit/webstorm-new-project.png) +[react-project-template-in-webstorm](https://plugins.jetbrains.com/plugin/7648-react-templates) -Make sure that **JSX** support is enabled in your project. This is set by default, if you create a new project based on React.js template. +Make sure that **JSX** support is enabled in your project. This is set by +default, if you create a new project based on React.js template. -![jsx-support-in-webstorm](https://dl.dropboxusercontent.com/u/16006521/react-starter-kit/webstorm-jsx.png) +[jsx-support-in-webstorm](https://blog.jetbrains.com/webstorm/2015/10/working-with-reactjs-in-webstorm-coding-assistance/) Configure JavaScript libraries for **auto-complete** -![javascript-libraries-in-webstorm](https://dl.dropboxusercontent.com/u/16006521/react-starter-kit/webstorm-libraries.png) +[javascript-libraries-in-webstorm](https://blog.jetbrains.com/webstorm/2017/08/how-to-configure-code-completion-in-full-stack-javascript-projects/) Enable **ESLint** support -![eslint-support-in-webstorm](https://dl.dropboxusercontent.com/u/16006521/react-starter-kit/webstorm-eslint.png) +[eslint-support-in-webstorm](https://www.jetbrains.com/help/webstorm/eslint.html) -Enable **CSSComb** by installing CSSReorder plug-in +Enable **CSSComb** by following the instructions +[here](https://github.com/csscomb/jetbrains-csscomb). -![csscomb-in-webstorm](https://dl.dropboxusercontent.com/u/16006521/react-starter-kit/webstorm-csscomb.png) +**If you have trouble with autoreloading** try to disable "safe write" in +`File > Settings > System Settings > Use "safe write" (save changes to a temporary file first)` ### Atom Install atom packages -* [linter](https://atom.io/packages/linter) -* [linter-eslint](https://atom.io/packages/linter-eslint) -* [react](https://atom.io/packages/react) +- [linter](https://atom.io/packages/linter) +- [linter-eslint](https://atom.io/packages/linter-eslint) +- [linter-stylelint](https://atom.io/packages/linter-stylelint) +- [react](https://atom.io/packages/react) ```shell -apm install linter linter-eslint react +apm install linter linter-eslint react linter-stylelint ``` Install local npm packages -* [eslint](https://www.npmjs.com/package/eslint) -* [babel-eslint](https://www.npmjs.com/package/babel-eslint) -* [eslint-plugin-react](https://www.npmjs.com/package/eslint-plugin-react) +- [eslint](https://www.npmjs.com/package/eslint) +- [babel-eslint](https://www.npmjs.com/package/babel-eslint) +- [eslint-plugin-react](https://www.npmjs.com/package/eslint-plugin-react) +- [stylelint](https://www.npmjs.com/package/stylelint) ```shell -npm install --save-dev eslint babel-eslint eslint-plugin-react +yarn add --dev eslint babel-eslint eslint-plugin-react stylelint ``` -*You may need to restart atom for changes to take effect* +_You may need to restart atom for changes to take effect_ ### SublimeText -Install SublimeText packages -Easiest with [Package Control](https://packagecontrol.io/) and then "Package Control: Install Package" (Ctrl+Shift+P) +Install SublimeText packages\ +Easiest with [Package Control](https://packagecontrol.io/) and then "Package Control: +Install Package" (Ctrl+Shift+P) -* [Babel](https://packagecontrol.io/packages/Babel) -* [Sublime-linter](http://www.sublimelinter.com/en/latest/) -* [SublimeLinter-contrib-eslint](https://packagecontrol.io/packages/SublimeLinter-contrib-eslint) +- [Babel](https://packagecontrol.io/packages/Babel) +- [Sublime-linter](http://www.sublimelinter.com/en/latest/) +- [SublimeLinter-contrib-eslint](https://packagecontrol.io/packages/SublimeLinter-contrib-eslint) +- [SublimeLinter-contrib-stylelint](https://packagecontrol.io/packages/SublimeLinter-contrib-stylelint) -You can also use [SublimeLinter-contrib-eslint_d](https://packagecontrol.io/packages/SublimeLinter-contrib-eslint_d) for faster linting. +You can also use +[SublimeLinter-contrib-eslint_d](https://packagecontrol.io/packages/SublimeLinter-contrib-eslint_d) +for faster linting. Set Babel as default syntax for a particular extension: -* Open a file with that extension, -* Select `View` from the menu, -* Then `Syntax` `->` `Open all with current extension as...` `->` `Babel` `->` `JavaScript (Babel)`. -* Repeat this for each extension (e.g.: .js and .jsx). +- Open a file with that extension, +- Select `View` from the menu, +- Then `Syntax` `->` `Open all with current extension as...` `->` `Babel` `->` + `JavaScript (Babel)`. +- Repeat this for each extension (e.g.: .js and .jsx). Install local npm packages + ``` -npm install eslint@latest -npm install babel-eslint@latest -npm install eslint-plugin-react +yarn add --dev eslint@latest +yarn add --dev babel-eslint@latest +yarn add --dev eslint-plugin-react +yarn add --dev stylelint ``` diff --git a/docs/react-style-guide.md b/docs/react-style-guide.md index 6cb39617b..c4d71fe53 100644 --- a/docs/react-style-guide.md +++ b/docs/react-style-guide.md @@ -1,27 +1,28 @@ ## React Style Guide -> This style guide comes as an addition to [Airbnb React/JSX Guide](https://github.com/airbnb/javascript/tree/master/react). -> Feel free to modify it to suit your project's needs. +> This style guide comes as an addition to +> [Airbnb React/JSX Guide](https://github.com/airbnb/javascript/tree/master/react). +> Feel free to modify it to suit your project's needs. ### Table of Contents -* [Separate folder per UI component](#separate-folder-per-ui-component) -* [Prefer using functional components](#prefer-using-functional-components) -* [Use CSS Modules](#use-css-modules) -* [Use higher-order components](#use-higher-order-components) +- [Separate folder per UI component](#separate-folder-per-ui-component) +- [Prefer using functional components](#prefer-using-functional-components) +- [Use CSS Modules](#use-css-modules) +- [Use higher-order components](#use-higher-order-components) ### Separate folder per UI component -* Place each major UI component along with its resources in a separate folder
- This will make it easier to find related resources for any particular UI - element (CSS, images, unit tests, localization files etc.). Removing such - components during refactorings should also be easy. -* Avoid having CSS, images and other resource files shared between multiple components.
+- Place each major UI component along with its resources in a separate folder\ + This will make it easier to find related resources for any particular UI element + (CSS, images, unit tests, localization files etc.). Removing such components during + refactorings should also be easy. +- Avoid having CSS, images and other resource files shared between multiple + components.\ This will make your code more maintainable, easy to refactor. -* Add `package.json` file into each component's folder.
- This will allow to easily reference such components from other places in - your code.
- `import Nav from '../Nav'` vs `import Nav from '../Nav/Nav.js'` +- Add `package.json` file into each component's folder.\ + This will allow to easily reference such components from other places in your code.\ + Use `import Nav from '../Navigation'` instead of `import Nav from '../Navigation/Navigation.js'` ``` /components/Navigation/icon.svg @@ -33,18 +34,19 @@ ``` ``` -// components/Navigation/package.json +// components/Navigation/package.json { "name:": "Navigation", "main": "./Navigation.js" } ``` -For more information google for [component-based UI development](https://google.com/search?q=component-based+ui+development). +For more information google for +[component-based UI development](https://google.com/search?q=component-based+ui+development). ### Prefer using functional components -* Prefer using stateless functional components whenever possible.
+- Prefer using stateless functional components whenever possible.\ Components that don't use state are better to be written as simple pure functions. ```jsx @@ -52,14 +54,14 @@ For more information google for [component-based UI development](https://google. class Navigation extends Component { static propTypes = { items: PropTypes.array.isRequired }; render() { - return ; + return ; } } // Better function Navigation({ items }) { return ( - ; + ; ); } Navigation.propTypes = { items: PropTypes.array.isRequired }; @@ -67,13 +69,17 @@ Navigation.propTypes = { items: PropTypes.array.isRequired }; ### Use CSS Modules -* Use CSS Modules
+- Use CSS Modules\ This will allow using short CSS class names and at the same time avoid conflicts. -* Keep CSS simple and declarative. Avoid loops, mixins etc. -* Feel free to use variables in CSS via [precss](https://github.com/jonathantneal/precss) plugin for [PostCSS](https://github.com/postcss/postcss) -* Prefer CSS class selectors instead of element and `id` selectors (see [BEM](https://bem.info/)) -* Avoid nested CSS selectors (see [BEM](https://bem.info/)) -* When in doubt, use `.root { }` class name for the root elements of your components +- Keep CSS simple and declarative. Avoid loops, mixins etc. +- Feel free to use variables in CSS via + [precss](https://github.com/jonathantneal/precss) plugin for + [PostCSS](https://github.com/postcss/postcss) +- Prefer CSS class selectors instead of element and `id` selectors (see + [BEM](https://bem.info/)) +- Avoid nested CSS selectors (see [BEM](https://bem.info/)) +- When in doubt, use `.root { }` class name for the root elements of your + components ```scss // Navigation.scss @@ -103,7 +109,7 @@ Navigation.propTypes = { items: PropTypes.array.isRequired }; color: $default-color; text-decoration: none; line-height: 25px; - transition: background-color .3s ease; + transition: background-color 0.3s ease; &, .items:hover & { @@ -119,19 +125,25 @@ Navigation.propTypes = { items: PropTypes.array.isRequired }; ```jsx // Navigation.js -import React, { PropTypes } from 'react'; +import React from 'react'; +import PropTypes from 'prop-types'; +import useStyles from 'isomorphic-style-loader/useStyles'; import s from './Navigation.scss'; -import withStyles from '../../decorators/withStyles'; -function Navigation() { +export default function Navigation() { + useStyles(s); return ( -