diff --git a/.babelrc.js b/.babelrc.js
index 6d78bd1..853a932 100644
--- a/.babelrc.js
+++ b/.babelrc.js
@@ -1,9 +1,8 @@
module.exports = {
- presets: ['@babel/env', '@babel/react'],
- plugins: [
- ['@babel/plugin-proposal-class-properties'],
- ['@babel/plugin-proposal-object-rest-spread'],
- ['transform-react-remove-prop-types', { removeImport: true }],
- ['@babel/plugin-transform-runtime', { regenerator: false }]
- ]
+ presets: ['@babel/env', '@babel/react', '@babel/preset-typescript'],
+ plugins: [
+ ['@babel/plugin-proposal-class-properties'],
+ ['@babel/plugin-proposal-object-rest-spread'],
+ ['@babel/plugin-transform-runtime', { regenerator: false }],
+ ],
};
diff --git a/.editorconfig b/.editorconfig
index 9d08a1a..e291365 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -3,7 +3,7 @@ root = true
[*]
charset = utf-8
indent_style = space
-indent_size = 2
+indent_size = 4
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
diff --git a/.eslintignore b/.eslintignore
index cd65b0e..29080fb 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -1,3 +1,4 @@
+
# See https://help.github.com/ignore-files/ for more about ignoring files.
# dependencies
@@ -7,6 +8,7 @@ example/node_modules/**
# production
/build
/dist
+/coverage
# misc
.DS_Store
@@ -14,9 +16,14 @@ example/node_modules/**
npm-debug.log*
yarn-debug.log*
yarn-error.log*
+yarn.lock*
+package.json*
+CHANGELOG.md*
+README.md*
example/.DS_Store
example/.env
example/npm-debug.log*
example/yarn-debug.log*
-example/yarn-error.log*
\ No newline at end of file
+example/yarn-error.log*
+example/yarn.lock*
diff --git a/.eslintrc.js b/.eslintrc.js
index 4429190..a477bb1 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,40 +1,79 @@
+/* eslint-disable sort-keys */
/**
* Configure ESLint
*
* https://eslint.org/docs/user-guide/configuring
*/
module.exports = {
- parser: 'babel-eslint',
- extends: ['airbnb', 'prettier', 'prettier/react', 'plugin:import/warnings'],
- env: {
- es6: true
- },
- plugins: ['prettier', 'import', 'react-hooks'],
- globals: {
- document: true,
- window: true,
- process: true
- },
- parserOptions: {
- sourceType: 'module'
- },
- rules: {
- 'react/forbid-prop-types': 0,
- 'react/jsx-filename-extension': 0,
- 'react/react-in-jsx-scope': 0,
- 'class-methods-use-this': 0,
- 'no-unused-expressions': ['error', { allowTaggedTemplates: true }],
- 'react/no-unused-prop-types': 0,
- 'consistent-return': 0,
- 'jsx-a11y/anchor-is-valid': 0,
- 'import/no-extraneous-dependencies': 0,
- 'prettier/prettier': 'error',
- 'react/destructuring-assignment': 0,
- 'react/jsx-props-no-spreading': 0,
- 'react/static-property-placement': 0,
- // Enforce React Hooks rules
- // https://www.npmjs.com/package/eslint-plugin-react-hooks
- 'react-hooks/rules-of-hooks': 'error',
- 'react-hooks/exhaustive-deps': 'warn'
- }
+ env: {
+ browser: true,
+ es6: true,
+ jest: true,
+ },
+ extends: [
+ 'plugin:react/recommended',
+ 'plugin:import/warnings',
+ 'plugin:@typescript-eslint/recommended',
+ 'plugin:prettier/recommended',
+ 'prettier',
+ ],
+ globals: {
+ document: true,
+ window: true,
+ },
+ parser: '@typescript-eslint/parser',
+ parserOptions: {
+ sourceType: 'module',
+ },
+ plugins: [
+ 'prettier',
+ 'react',
+ 'react-hooks',
+ 'import',
+ 'sort-destructure-keys',
+ '@typescript-eslint',
+ ],
+ root: true,
+ rules: {
+ // Enforce React Hooks rules
+ // https://www.npmjs.com/package/eslint-plugin-react-hooks
+ 'react-hooks/rules-of-hooks': 'error',
+ 'react-hooks/exhaustive-deps': 'warn',
+
+ 'sort-destructure-keys/sort-destructure-keys': [
+ 'error',
+ { caseSensitive: false },
+ ],
+ 'sort-keys': ['error', 'asc', { caseSensitive: false, natural: false }],
+ 'sort-vars': [
+ 'error',
+ {
+ ignoreCase: true,
+ },
+ ],
+ 'react/jsx-sort-props': ['error', { ignoreCase: true }],
+ '@typescript-eslint/ban-ts-comment': 'off',
+ '@typescript-eslint/no-explicit-any': 'off',
+ '@typescript-eslint/explicit-module-boundary-types': 'off',
+ '@typescript-eslint/member-ordering': [
+ 'error',
+ {
+ default: {
+ order: 'alphabetically',
+ },
+ classes: {
+ order: 'as-written',
+ },
+ },
+ ],
+ },
+ settings: {
+ 'import/resolver': {
+ node: true,
+ 'eslint-import-resolver-typescript': true,
+ },
+ react: {
+ version: 'detect',
+ },
+ },
};
diff --git a/.gitignore b/.gitignore
index 1d63308..cb560af 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,9 +5,11 @@
node_modules
# builds
+coverage
build
dist
.rpt2_cache
+.next
# misc
.DS_Store
@@ -16,7 +18,6 @@ dist
.env.development.local
.env.test.local
.env.production.local
-.vscode
npm-debug.log*
yarn-debug.log*
diff --git a/.prettierignore b/.prettierignore
index 6cbb3c6..8b7f742 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -1,2 +1,13 @@
node_modules/**
-example/node_modules/**
\ No newline at end of file
+.next/**
+dist/**
+coverage/**
+example/node_modules/**
+example/.next/**
+yarn.lock
+yarn-error.log
+.editorconfig
+.eslintignore
+.gitignore
+.prettierignore
+.browserslistrc
diff --git a/.prettierrc.js b/.prettierrc.js
index dd50a19..6946354 100644
--- a/.prettierrc.js
+++ b/.prettierrc.js
@@ -4,6 +4,7 @@
* https://prettier.io/docs/en/configuration.html#basic-configuration
*/
module.exports = {
- singleQuote: true,
- semi: true
+ singleQuote: true,
+ semi: true,
+ tabWidth: 4,
};
diff --git a/.travis.yml b/.travis.yml
index 21a0bc3..e685158 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,18 +1,18 @@
language: node_js
node_js:
- - 'node'
- - 'lts/*'
-cache: yarn
-install:
- - yarn install
- - yarn link
- - cd example
- - yarn link react-particles-webgl
- - yarn install
-script:
- - yarn test
- - yarn build
+ - 'lts/*'
+cache:
+ yarn: true
+ directories:
+ - node_modules
+install: yarn install
+jobs:
+ include:
+ - stage: lint
+ script: yarn lint
+ - stage: build
+ script: yarn build
branches:
- only: master
+ only: master
notifications:
- email: false
+ email: false
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 4b262d0..9f41a23 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -4,5 +4,4 @@
"javascript.validate.enable": false,
"editor.tabSize": 2,
"editor.detectIndentation": false
- }
-
\ No newline at end of file
+}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4598152..36c6ce3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,23 +6,23 @@ All notable changes to this project will be documented in this file.
### Added
-- Upgrade to react-three-fiber v3
+- Upgrade to react-three-fiber v3
## [1.0.0]
### Added
-- This changelog
-- Jest testing via Puppeteer
+- This changelog
+- Jest testing via Puppeteer
## [0.5.2] - 2019-3-28
### Added
-- Snowfall preset to demo site
-- `config.direction` prop for controlling particle velocity in x, y, z directions
-- `config.boundaryType` prop for controlling interaction between particles and canvas boundary
+- Snowfall preset to demo site
+- `config.direction` prop for controlling particle velocity in x, y, z directions
+- `config.boundaryType` prop for controlling interaction between particles and canvas boundary
### Fixed
-- Prevent calculating line coords in animation loop if `config.lines.visible` is false
+- Prevent calculating line coords in animation loop if `config.lines.visible` is false
diff --git a/README.md b/README.md
index 60f35f8..495cad3 100644
--- a/README.md
+++ b/README.md
@@ -10,8 +10,8 @@
**Code Sandbox Demos**
-- 2D Green Particles [https://codesandbox.io/s/4x4lmpqz1w](https://codesandbox.io/s/4x4lmpqz1w)
-- 3D Snowfall [https://codesandbox.io/s/308zj3k7l1](https://codesandbox.io/s/308zj3k7l1)
+- 2D Green Particles [https://codesandbox.io/s/4x4lmpqz1w](https://codesandbox.io/s/4x4lmpqz1w)
+- 3D Snowfall [https://codesandbox.io/s/308zj3k7l1](https://codesandbox.io/s/308zj3k7l1)
[](https://www.npmjs.com/package/react-particles-webgl)
[](https://github.com/tim-soft/react-particles-webgl/blob/master/LICENSE)
@@ -23,10 +23,10 @@
## ✨ Features
-- Simple drop-in usage, plays nice with SSR (the demo is running Next.js)
-- Smooth 60FPS particles and lines via WebGL
-- Full Three.js OrbitControls for extreme (optional) scene interactivity
-- Highly customizable particles and lines
+- Simple drop-in usage, plays nice with SSR (the demo is running Next.js)
+- Smooth 60FPS particles and lines via WebGL
+- Full Three.js OrbitControls for extreme (optional) scene interactivity
+- Highly customizable particles and lines
## Install
@@ -36,95 +36,98 @@ yarn add react-particles-webgl three
## Usage
-```jsx
+```tsx
import React from 'react';
-import ParticleField from 'react-particles-webgl';
+import {
+ Particles as ParticleField,
+ ParticlesConfig,
+} from 'react-particles-webgl';
/**
* The default configuation for the ParticleField component
*
* Any option passed in via props will overwrite the default config
*/
-const config = {
- // Display reference cube, useful for orienting the field
- showCube: true,
- // '2D' or '3D' particle field
- dimension: '3D',
- // 'bounce' or 'passthru'
- // 'bounce' will make particles behave like balls thrown at a wall when hitting canvas boundaries
- // 'passthru' particles will disappear after hitting canvas boundaries and be added back into the scene elsewhere
- boundaryType: 'bounce',
- // Maximum velocity of particles
- velocity: 2,
- // Toggles antialiasing -- must be set during construction, cannot be changed after initial render
- // Slight performance optimization to set false, although lines will appear more jagged
- antialias: false,
- // Min/Max multipliers which constraint how particles move in each direction
- // The default values here allow for particles to move in completely random x, y, z directions
- // See the "Snowfall" preset for an example of how to use these values
- direction: {
- xMin: -1,
- xMax: 1,
- yMin: -1,
- yMax: 1,
- zMin: -1,
- zMax: 1
- },
- lines: {
- // 'rainbow' or 'solid' color of lines
- colorMode: 'rainbow',
- // Color of lines if colorMode: 'solid', must be hex color
- color: '#351CCB',
- // Transparency of lines
- transparency: 0.9,
- // true/false limit the maximum number of line connections per particle
- limitConnections: true,
- maxConnections: 20,
- // Minimum distance needed to draw line between to particles
- minDistance: 150,
- // true/false render lines
- visible: true
- },
- particles: {
- // 'rainbow' or 'solid' color of particles
- colorMode: 'rainbow',
- // Color of lines if colorMode: 'solid', must be hex color
- color: '#3FB568',
- // Transparency of particles
- transparency: 0.9,
- // 'square' or 'circle' shape of particles
- shape: 'square',
- // The exact number of particles to render
- count: 500,
- // The minimum particle size
- minSize: 10,
- // The maximum particle size
- maxSize: 75,
- // true/false render particles
- visible: true
- },
- /*
- * The camera rig is comprised of Three.js OrbitControls
- * Pass any valid OrbitControls properties, consult docs for more info
- *
- * https://threejs.org/docs/#examples/controls/OrbitControls
- */
- cameraControls: {
- // Enable or disable all camera interaction (click, drag, touch etc)
- enabled: true,
- // Enable or disable smooth dampening of camera movement
- enableDamping: true,
- dampingFactor: 0.2,
- // Enable or disable zooming in/out of camera
- enableZoom: true,
- // Enable or disable constant rotation of camera around scene
- autoRotate: true,
- // Rotation speed -- higher is faster
- autoRotateSpeed: 0.3,
- // If true, camera position will be reset whenever any option changes (including this one)
- // Useful when turning off autoRotate, the camera will return to FOV where scene fits to canvas
- resetCameraFlag: false
- }
+const config: ParticlesConfig = {
+ // Display reference cube, useful for orienting the field
+ showCube: true,
+ // '2D' or '3D' particle field
+ dimension: '3D',
+ // 'bounce' or 'passthru'
+ // 'bounce' will make particles behave like balls thrown at a wall when hitting canvas boundaries
+ // 'passthru' particles will disappear after hitting canvas boundaries and be added back into the scene elsewhere
+ boundaryType: 'bounce',
+ // Maximum velocity of particles
+ velocity: 2,
+ // Toggles antialiasing -- must be set during construction, cannot be changed after initial render
+ // Slight performance optimization to set false, although lines will appear more jagged
+ antialias: false,
+ // Min/Max multipliers which constraint how particles move in each direction
+ // The default values here allow for particles to move in completely random x, y, z directions
+ // See the "Snowfall" preset for an example of how to use these values
+ direction: {
+ xMin: -1,
+ xMax: 1,
+ yMin: -1,
+ yMax: 1,
+ zMin: -1,
+ zMax: 1,
+ },
+ lines: {
+ // 'rainbow' or 'solid' color of lines
+ colorMode: 'rainbow',
+ // Color of lines if colorMode: 'solid', must be hex color
+ color: '#351CCB',
+ // Transparency of lines
+ transparency: 0.9,
+ // true/false limit the maximum number of line connections per particle
+ limitConnections: true,
+ maxConnections: 20,
+ // Minimum distance needed to draw line between to particles
+ minDistance: 150,
+ // true/false render lines
+ visible: true,
+ },
+ particles: {
+ // 'rainbow' or 'solid' color of particles
+ colorMode: 'rainbow',
+ // Color of lines if colorMode: 'solid', must be hex color
+ color: '#3FB568',
+ // Transparency of particles
+ transparency: 0.9,
+ // 'square' or 'circle' shape of particles
+ shape: 'square',
+ // The exact number of particles to render
+ count: 500,
+ // The minimum particle size
+ minSize: 10,
+ // The maximum particle size
+ maxSize: 75,
+ // true/false render particles
+ visible: true,
+ },
+ /*
+ * The camera rig is comprised of Three.js OrbitControls
+ * Pass any valid OrbitControls properties, consult docs for more info
+ *
+ * https://threejs.org/docs/#examples/controls/OrbitControls
+ */
+ cameraControls: {
+ // Enable or disable all camera interaction (click, drag, touch etc)
+ enabled: true,
+ // Enable or disable smooth dampening of camera movement
+ enableDamping: true,
+ dampingFactor: 0.2,
+ // Enable or disable zooming in/out of camera
+ enableZoom: true,
+ // Enable or disable constant rotation of camera around scene
+ autoRotate: true,
+ // Rotation speed -- higher is faster
+ autoRotateSpeed: 0.3,
+ // If true, camera position will be reset whenever any option changes (including this one)
+ // Useful when turning off autoRotate, the camera will return to FOV where scene fits to canvas
+ resetCameraFlag: false,
+ },
};
export default () => ;
diff --git a/example/.babelrc b/example/.babelrc
new file mode 100644
index 0000000..9555ba3
--- /dev/null
+++ b/example/.babelrc
@@ -0,0 +1,4 @@
+{
+ "presets": ["next/babel"],
+ "plugins": [["styled-components", { "ssr": true }]]
+}
diff --git a/example/README.md b/example/README.md
index c55ccdf..c586ced 100644
--- a/example/README.md
+++ b/example/README.md
@@ -5,102 +5,102 @@ You can find the most recent version of this guide [here](https://github.com/fac
## Table of Contents
-- [Updating to New Releases](#updating-to-new-releases)
-- [Sending Feedback](#sending-feedback)
-- [Folder Structure](#folder-structure)
-- [Available Scripts](#available-scripts)
- - [npm start](#npm-start)
- - [npm test](#npm-test)
- - [npm run build](#npm-run-build)
- - [npm run eject](#npm-run-eject)
-- [Supported Language Features and Polyfills](#supported-language-features-and-polyfills)
-- [Syntax Highlighting in the Editor](#syntax-highlighting-in-the-editor)
-- [Displaying Lint Output in the Editor](#displaying-lint-output-in-the-editor)
-- [Debugging in the Editor](#debugging-in-the-editor)
-- [Formatting Code Automatically](#formatting-code-automatically)
-- [Changing the Page `
`](#changing-the-page-title)
-- [Installing a Dependency](#installing-a-dependency)
-- [Importing a Component](#importing-a-component)
-- [Code Splitting](#code-splitting)
-- [Adding a Stylesheet](#adding-a-stylesheet)
-- [Post-Processing CSS](#post-processing-css)
-- [Adding a CSS Preprocessor (Sass, Less etc.)](#adding-a-css-preprocessor-sass-less-etc)
-- [Adding Images, Fonts, and Files](#adding-images-fonts-and-files)
-- [Using the `public` Folder](#using-the-public-folder)
- - [Changing the HTML](#changing-the-html)
- - [Adding Assets Outside of the Module System](#adding-assets-outside-of-the-module-system)
- - [When to Use the `public` Folder](#when-to-use-the-public-folder)
-- [Using Global Variables](#using-global-variables)
-- [Adding Bootstrap](#adding-bootstrap)
- - [Using a Custom Theme](#using-a-custom-theme)
-- [Adding Flow](#adding-flow)
-- [Adding Custom Environment Variables](#adding-custom-environment-variables)
- - [Referencing Environment Variables in the HTML](#referencing-environment-variables-in-the-html)
- - [Adding Temporary Environment Variables In Your Shell](#adding-temporary-environment-variables-in-your-shell)
- - [Adding Development Environment Variables In `.env`](#adding-development-environment-variables-in-env)
-- [Can I Use Decorators?](#can-i-use-decorators)
-- [Integrating with an API Backend](#integrating-with-an-api-backend)
- - [Node](#node)
- - [Ruby on Rails](#ruby-on-rails)
-- [Proxying API Requests in Development](#proxying-api-requests-in-development)
- - ["Invalid Host Header" Errors After Configuring Proxy](#invalid-host-header-errors-after-configuring-proxy)
- - [Configuring the Proxy Manually](#configuring-the-proxy-manually)
- - [Configuring a WebSocket Proxy](#configuring-a-websocket-proxy)
-- [Using HTTPS in Development](#using-https-in-development)
-- [Generating Dynamic `` Tags on the Server](#generating-dynamic-meta-tags-on-the-server)
-- [Pre-Rendering into Static HTML Files](#pre-rendering-into-static-html-files)
-- [Injecting Data from the Server into the Page](#injecting-data-from-the-server-into-the-page)
-- [Running Tests](#running-tests)
- - [Filename Conventions](#filename-conventions)
- - [Command Line Interface](#command-line-interface)
- - [Version Control Integration](#version-control-integration)
- - [Writing Tests](#writing-tests)
- - [Testing Components](#testing-components)
- - [Using Third Party Assertion Libraries](#using-third-party-assertion-libraries)
- - [Initializing Test Environment](#initializing-test-environment)
- - [Focusing and Excluding Tests](#focusing-and-excluding-tests)
- - [Coverage Reporting](#coverage-reporting)
- - [Continuous Integration](#continuous-integration)
- - [Disabling jsdom](#disabling-jsdom)
- - [Snapshot Testing](#snapshot-testing)
- - [Editor Integration](#editor-integration)
-- [Developing Components in Isolation](#developing-components-in-isolation)
- - [Getting Started with Storybook](#getting-started-with-storybook)
- - [Getting Started with Styleguidist](#getting-started-with-styleguidist)
-- [Making a Progressive Web App](#making-a-progressive-web-app)
- - [Opting Out of Caching](#opting-out-of-caching)
- - [Offline-First Considerations](#offline-first-considerations)
- - [Progressive Web App Metadata](#progressive-web-app-metadata)
-- [Analyzing the Bundle Size](#analyzing-the-bundle-size)
-- [Deployment](#deployment)
- - [Static Server](#static-server)
- - [Other Solutions](#other-solutions)
- - [Serving Apps with Client-Side Routing](#serving-apps-with-client-side-routing)
- - [Building for Relative Paths](#building-for-relative-paths)
- - [Azure](#azure)
- - [Firebase](#firebase)
- - [GitHub Pages](#github-pages)
- - [Heroku](#heroku)
- - [Netlify](#netlify)
- - [Now](#now)
- - [S3 and CloudFront](#s3-and-cloudfront)
- - [Surge](#surge)
-- [Advanced Configuration](#advanced-configuration)
-- [Troubleshooting](#troubleshooting)
- - [`npm start` doesn’t detect changes](#npm-start-doesnt-detect-changes)
- - [`npm test` hangs on macOS Sierra](#npm-test-hangs-on-macos-sierra)
- - [`npm run build` exits too early](#npm-run-build-exits-too-early)
- - [`npm run build` fails on Heroku](#npm-run-build-fails-on-heroku)
- - [`npm run build` fails to minify](#npm-run-build-fails-to-minify)
- - [Moment.js locales are missing](#momentjs-locales-are-missing)
-- [Something Missing?](#something-missing)
+- [Updating to New Releases](#updating-to-new-releases)
+- [Sending Feedback](#sending-feedback)
+- [Folder Structure](#folder-structure)
+- [Available Scripts](#available-scripts)
+ - [npm start](#npm-start)
+ - [npm test](#npm-test)
+ - [npm run build](#npm-run-build)
+ - [npm run eject](#npm-run-eject)
+- [Supported Language Features and Polyfills](#supported-language-features-and-polyfills)
+- [Syntax Highlighting in the Editor](#syntax-highlighting-in-the-editor)
+- [Displaying Lint Output in the Editor](#displaying-lint-output-in-the-editor)
+- [Debugging in the Editor](#debugging-in-the-editor)
+- [Formatting Code Automatically](#formatting-code-automatically)
+- [Changing the Page ``](#changing-the-page-title)
+- [Installing a Dependency](#installing-a-dependency)
+- [Importing a Component](#importing-a-component)
+- [Code Splitting](#code-splitting)
+- [Adding a Stylesheet](#adding-a-stylesheet)
+- [Post-Processing CSS](#post-processing-css)
+- [Adding a CSS Preprocessor (Sass, Less etc.)](#adding-a-css-preprocessor-sass-less-etc)
+- [Adding Images, Fonts, and Files](#adding-images-fonts-and-files)
+- [Using the `public` Folder](#using-the-public-folder)
+ - [Changing the HTML](#changing-the-html)
+ - [Adding Assets Outside of the Module System](#adding-assets-outside-of-the-module-system)
+ - [When to Use the `public` Folder](#when-to-use-the-public-folder)
+- [Using Global Variables](#using-global-variables)
+- [Adding Bootstrap](#adding-bootstrap)
+ - [Using a Custom Theme](#using-a-custom-theme)
+- [Adding Flow](#adding-flow)
+- [Adding Custom Environment Variables](#adding-custom-environment-variables)
+ - [Referencing Environment Variables in the HTML](#referencing-environment-variables-in-the-html)
+ - [Adding Temporary Environment Variables In Your Shell](#adding-temporary-environment-variables-in-your-shell)
+ - [Adding Development Environment Variables In `.env`](#adding-development-environment-variables-in-env)
+- [Can I Use Decorators?](#can-i-use-decorators)
+- [Integrating with an API Backend](#integrating-with-an-api-backend)
+ - [Node](#node)
+ - [Ruby on Rails](#ruby-on-rails)
+- [Proxying API Requests in Development](#proxying-api-requests-in-development)
+ - ["Invalid Host Header" Errors After Configuring Proxy](#invalid-host-header-errors-after-configuring-proxy)
+ - [Configuring the Proxy Manually](#configuring-the-proxy-manually)
+ - [Configuring a WebSocket Proxy](#configuring-a-websocket-proxy)
+- [Using HTTPS in Development](#using-https-in-development)
+- [Generating Dynamic `` Tags on the Server](#generating-dynamic-meta-tags-on-the-server)
+- [Pre-Rendering into Static HTML Files](#pre-rendering-into-static-html-files)
+- [Injecting Data from the Server into the Page](#injecting-data-from-the-server-into-the-page)
+- [Running Tests](#running-tests)
+ - [Filename Conventions](#filename-conventions)
+ - [Command Line Interface](#command-line-interface)
+ - [Version Control Integration](#version-control-integration)
+ - [Writing Tests](#writing-tests)
+ - [Testing Components](#testing-components)
+ - [Using Third Party Assertion Libraries](#using-third-party-assertion-libraries)
+ - [Initializing Test Environment](#initializing-test-environment)
+ - [Focusing and Excluding Tests](#focusing-and-excluding-tests)
+ - [Coverage Reporting](#coverage-reporting)
+ - [Continuous Integration](#continuous-integration)
+ - [Disabling jsdom](#disabling-jsdom)
+ - [Snapshot Testing](#snapshot-testing)
+ - [Editor Integration](#editor-integration)
+- [Developing Components in Isolation](#developing-components-in-isolation)
+ - [Getting Started with Storybook](#getting-started-with-storybook)
+ - [Getting Started with Styleguidist](#getting-started-with-styleguidist)
+- [Making a Progressive Web App](#making-a-progressive-web-app)
+ - [Opting Out of Caching](#opting-out-of-caching)
+ - [Offline-First Considerations](#offline-first-considerations)
+ - [Progressive Web App Metadata](#progressive-web-app-metadata)
+- [Analyzing the Bundle Size](#analyzing-the-bundle-size)
+- [Deployment](#deployment)
+ - [Static Server](#static-server)
+ - [Other Solutions](#other-solutions)
+ - [Serving Apps with Client-Side Routing](#serving-apps-with-client-side-routing)
+ - [Building for Relative Paths](#building-for-relative-paths)
+ - [Azure](#azure)
+ - [Firebase](#firebase)
+ - [GitHub Pages](#github-pages)
+ - [Heroku](#heroku)
+ - [Netlify](#netlify)
+ - [Now](#now)
+ - [S3 and CloudFront](#s3-and-cloudfront)
+ - [Surge](#surge)
+- [Advanced Configuration](#advanced-configuration)
+- [Troubleshooting](#troubleshooting)
+ - [`npm start` doesn’t detect changes](#npm-start-doesnt-detect-changes)
+ - [`npm test` hangs on macOS Sierra](#npm-test-hangs-on-macos-sierra)
+ - [`npm run build` exits too early](#npm-run-build-exits-too-early)
+ - [`npm run build` fails on Heroku](#npm-run-build-fails-on-heroku)
+ - [`npm run build` fails to minify](#npm-run-build-fails-to-minify)
+ - [Moment.js locales are missing](#momentjs-locales-are-missing)
+- [Something Missing?](#something-missing)
## Updating to New Releases
Create React App is divided into two packages:
-* `create-react-app` is a global command-line utility that you use to create new projects.
-* `react-scripts` is a development dependency in the generated projects (including this one).
+- `create-react-app` is a global command-line utility that you use to create new projects.
+- `react-scripts` is a development dependency in the generated projects (including this one).
You almost never need to update `create-react-app` itself: it delegates all the setup to `react-scripts`.
@@ -139,8 +139,8 @@ my-app/
For the project to build, **these files must exist with exact filenames**:
-* `public/index.html` is the page template;
-* `src/index.js` is the JavaScript entry point.
+- `public/index.html` is the page template;
+- `src/index.js` is the JavaScript entry point.
You can delete or rename the other files.
@@ -195,12 +195,12 @@ You don’t have to ever use `eject`. The curated feature set is suitable for sm
This project supports a superset of the latest JavaScript standard.
In addition to [ES6](https://github.com/lukehoban/es6features) syntax features, it also supports:
-* [Exponentiation Operator](https://github.com/rwaldron/exponentiation-operator) (ES2016).
-* [Async/await](https://github.com/tc39/ecmascript-asyncawait) (ES2017).
-* [Object Rest/Spread Properties](https://github.com/sebmarkbage/ecmascript-rest-spread) (stage 3 proposal).
-* [Dynamic import()](https://github.com/tc39/proposal-dynamic-import) (stage 3 proposal)
-* [Class Fields and Static Properties](https://github.com/tc39/proposal-class-public-fields) (stage 2 proposal).
-* [JSX](https://facebook.github.io/react/docs/introducing-jsx.html) and [Flow](https://flowtype.org/) syntax.
+- [Exponentiation Operator](https://github.com/rwaldron/exponentiation-operator) (ES2016).
+- [Async/await](https://github.com/tc39/ecmascript-asyncawait) (ES2017).
+- [Object Rest/Spread Properties](https://github.com/sebmarkbage/ecmascript-rest-spread) (stage 3 proposal).
+- [Dynamic import()](https://github.com/tc39/proposal-dynamic-import) (stage 3 proposal)
+- [Class Fields and Static Properties](https://github.com/tc39/proposal-class-public-fields) (stage 2 proposal).
+- [JSX](https://facebook.github.io/react/docs/introducing-jsx.html) and [Flow](https://flowtype.org/) syntax.
Learn more about [different proposal stages](https://babeljs.io/docs/plugins/#presets-stage-x-experimental-presets-).
@@ -208,9 +208,9 @@ While we recommend to use experimental proposals with some caution, Facebook hea
Note that **the project only includes a few ES6 [polyfills](https://en.wikipedia.org/wiki/Polyfill)**:
-* [`Object.assign()`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) via [`object-assign`](https://github.com/sindresorhus/object-assign).
-* [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) via [`promise`](https://github.com/then/promise).
-* [`fetch()`](https://developer.mozilla.org/en/docs/Web/API/Fetch_API) via [`whatwg-fetch`](https://github.com/github/fetch).
+- [`Object.assign()`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) via [`object-assign`](https://github.com/sindresorhus/object-assign).
+- [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) via [`promise`](https://github.com/then/promise).
+- [`fetch()`](https://developer.mozilla.org/en/docs/Web/API/Fetch_API) via [`whatwg-fetch`](https://github.com/github/fetch).
If you use any other ES6+ features that need **runtime support** (such as `Array.from()` or `Symbol`), make sure you are including the appropriate polyfills manually, or that the browsers you are targeting already support them.
@@ -220,8 +220,8 @@ To configure the syntax highlighting in your favorite text editor, head to the [
## Displaying Lint Output in the Editor
->Note: this feature is available with `react-scripts@0.2.0` and higher.
->It also only works with npm 3 or higher.
+> Note: this feature is available with `react-scripts@0.2.0` and higher.
+> It also only works with npm 3 or higher.
Some editors, including Sublime Text, Atom, and Visual Studio Code, provide plugins for ESLint.
@@ -255,21 +255,24 @@ Then add the block below to your `launch.json` file and put it inside the `.vsco
```json
{
- "version": "0.2.0",
- "configurations": [{
- "name": "Chrome",
- "type": "chrome",
- "request": "launch",
- "url": "http://localhost:3000",
- "webRoot": "${workspaceRoot}/src",
- "userDataDir": "${workspaceRoot}/.vscode/chrome",
- "sourceMapPathOverrides": {
- "webpack:///src/*": "${webRoot}/*"
- }
- }]
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Chrome",
+ "type": "chrome",
+ "request": "launch",
+ "url": "http://localhost:3000",
+ "webRoot": "${workspaceRoot}/src",
+ "userDataDir": "${workspaceRoot}/.vscode/chrome",
+ "sourceMapPathOverrides": {
+ "webpack:///src/*": "${webRoot}/*"
+ }
+ }
+ ]
}
```
->Note: the URL may be different if you've made adjustments via the [HOST or PORT environment variables](#advanced-configuration).
+
+> Note: the URL may be different if you've made adjustments via the [HOST or PORT environment variables](#advanced-configuration).
Start your app by running `npm start`, and start debugging in VS Code by pressing `F5` or by clicking the green debug icon. You can now write code, set breakpoints, make changes to the code, and debug your newly modified code—all from your editor.
@@ -279,11 +282,11 @@ You would need to have [WebStorm](https://www.jetbrains.com/webstorm/) and [JetB
In the WebStorm menu `Run` select `Edit Configurations...`. Then click `+` and select `JavaScript Debug`. Paste `http://localhost:3000` into the URL field and save the configuration.
->Note: the URL may be different if you've made adjustments via the [HOST or PORT environment variables](#advanced-configuration).
+> Note: the URL may be different if you've made adjustments via the [HOST or PORT environment variables](#advanced-configuration).
Start your app by running `npm start`, then press `^D` on macOS or `F9` on Windows and Linux or click the green debug icon to start debugging in WebStorm.
-The same way you can debug your application in IntelliJ IDEA Ultimate, PhpStorm, PyCharm Pro, and RubyMine.
+The same way you can debug your application in IntelliJ IDEA Ultimate, PhpStorm, PyCharm Pro, and RubyMine.
## Formatting Code Automatically
@@ -301,9 +304,9 @@ Alternatively you may use `yarn`:
yarn add husky lint-staged prettier
```
-* `husky` makes it easy to use githooks as if they are npm scripts.
-* `lint-staged` allows us to run scripts on staged files in git. See this [blog post about lint-staged to learn more about it](https://medium.com/@okonetchnikov/make-linting-great-again-f3890e1ad6b8).
-* `prettier` is the JavaScript formatter we will run before commits.
+- `husky` makes it easy to use githooks as if they are npm scripts.
+- `lint-staged` allows us to run scripts on staged files in git. See this [blog post about lint-staged to learn more about it](https://medium.com/@okonetchnikov/make-linting-great-again-f3890e1ad6b8).
+- `prettier` is the JavaScript formatter we will run before commits.
Now we can make sure every file is formatted correctly by adding a few lines to the `package.json` in the project root.
@@ -374,9 +377,9 @@ For example:
import React, { Component } from 'react';
class Button extends Component {
- render() {
- // ...
- }
+ render() {
+ // ...
+ }
}
export default Button; // Don’t forget to use export default!
@@ -384,15 +387,14 @@ export default Button; // Don’t forget to use export default!
### `DangerButton.js`
-
```js
import React, { Component } from 'react';
import Button from './Button'; // Import a component from another file
class DangerButton extends Component {
- render() {
- return ;
- }
+ render() {
+ return ;
+ }
}
export default DangerButton;
@@ -406,9 +408,9 @@ Named exports are useful for utility modules that export several functions. A mo
Learn more about ES6 modules:
-* [When to use the curly braces?](http://stackoverflow.com/questions/36795819/react-native-es-6-when-should-i-use-curly-braces-for-import/36796281#36796281)
-* [Exploring ES6: Modules](http://exploringjs.com/es6/ch_modules.html)
-* [Understanding ES6: Modules](https://leanpub.com/understandinges6/read#leanpub-auto-encapsulating-code-with-modules)
+- [When to use the curly braces?](http://stackoverflow.com/questions/36795819/react-native-es-6-when-should-i-use-curly-braces-for-import/36796281#36796281)
+- [Exploring ES6: Modules](http://exploringjs.com/es6/ch_modules.html)
+- [Understanding ES6: Modules](https://leanpub.com/understandinges6/read#leanpub-auto-encapsulating-code-with-modules)
## Code Splitting
@@ -425,29 +427,30 @@ const moduleA = 'Hello';
export { moduleA };
```
+
### `App.js`
```js
import React, { Component } from 'react';
class App extends Component {
- handleClick = () => {
- import('./moduleA')
- .then(({ moduleA }) => {
- // Use moduleA
- })
- .catch(err => {
- // Handle failure
- });
- };
-
- render() {
- return (
-
+ );
+ }
}
export default App;
@@ -469,7 +472,7 @@ This project setup uses [Webpack](https://webpack.js.org/) for handling all asse
```css
.Button {
- padding: 20px;
+ padding: 20px;
}
```
@@ -480,10 +483,10 @@ import React, { Component } from 'react';
import './Button.css'; // Tell Webpack that Button.js uses these styles
class Button extends Component {
- render() {
- // You can use them as regular CSS styles
- return ;
- }
+ render() {
+ // You can use them as regular CSS styles
+ return ;
+ }
}
```
@@ -501,9 +504,9 @@ For example, this:
```css
.App {
- display: flex;
- flex-direction: row;
- align-items: center;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
}
```
@@ -511,16 +514,16 @@ becomes this:
```css
.App {
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- -webkit-box-orient: horizontal;
- -webkit-box-direction: normal;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
}
```
@@ -555,13 +558,13 @@ Then in `package.json`, add the following lines to `scripts`:
"test": "react-scripts test --env=jsdom",
```
->Note: To use a different preprocessor, replace `build-css` and `watch-css` commands according to your preprocessor’s documentation.
+> Note: To use a different preprocessor, replace `build-css` and `watch-css` commands according to your preprocessor’s documentation.
Now you can rename `src/App.css` to `src/App.scss` and run `npm run watch-css`. The watcher will find every Sass file in `src` subdirectories, and create a corresponding CSS file next to it, in our case overwriting `src/App.css`. Since `src/App.js` still imports `src/App.css`, the styles become a part of your application. You can now edit `src/App.scss`, and `src/App.css` will be regenerated.
To share variables between Sass files, you can use Sass imports. For example, `src/App.scss` and other component style files could include `@import "./shared.scss";` with variable definitions.
-To enable importing files without using relative paths, you can add the `--include-path` option to the command in `package.json`.
+To enable importing files without using relative paths, you can add the `--include-path` option to the command in `package.json`.
```
"build-css": "node-sass-chokidar --include-path ./src --include-path ./node_modules src/ -o src/",
@@ -611,13 +614,13 @@ Now running `npm start` and `npm run build` also builds Sass files.
`node-sass` has been reported as having the following issues:
-- `node-sass --watch` has been reported to have *performance issues* in certain conditions when used in a virtual machine or with docker.
+- `node-sass --watch` has been reported to have _performance issues_ in certain conditions when used in a virtual machine or with docker.
-- Infinite styles compiling [#1939](https://github.com/facebookincubator/create-react-app/issues/1939)
+- Infinite styles compiling [#1939](https://github.com/facebookincubator/create-react-app/issues/1939)
-- `node-sass` has been reported as having issues with detecting new files in a directory [#1891](https://github.com/sass/node-sass/issues/1891)
+- `node-sass` has been reported as having issues with detecting new files in a directory [#1891](https://github.com/sass/node-sass/issues/1891)
- `node-sass-chokidar` is used here as it addresses these issues.
+`node-sass-chokidar` is used here as it addresses these issues.
## Adding Images, Fonts, and Files
@@ -636,8 +639,8 @@ import logo from './logo.png'; // Tell Webpack this JS file uses this image
console.log(logo); // /logo.84287d09.png
function Header() {
- // Import result is the URL of your image
- return ;
+ // Import result is the URL of your image
+ return ;
}
export default Header;
@@ -649,7 +652,7 @@ This works in CSS too:
```css
.Logo {
- background-image: url(./logo.png);
+ background-image: url(./logo.png);
}
```
@@ -662,7 +665,7 @@ An alternative way of handling static assets is described in the next section.
## Using the `public` Folder
->Note: this feature is available with `react-scripts@0.5.0` and higher.
+> Note: this feature is available with `react-scripts@0.5.0` and higher.
### Changing the HTML
@@ -677,18 +680,18 @@ Note that we normally encourage you to `import` assets in JavaScript files inste
For example, see the sections on [adding a stylesheet](#adding-a-stylesheet) and [adding images and fonts](#adding-images-fonts-and-files).
This mechanism provides a number of benefits:
-* Scripts and stylesheets get minified and bundled together to avoid extra network requests.
-* Missing files cause compilation errors instead of 404 errors for your users.
-* Result filenames include content hashes so you don’t need to worry about browsers caching their old versions.
+- Scripts and stylesheets get minified and bundled together to avoid extra network requests.
+- Missing files cause compilation errors instead of 404 errors for your users.
+- Result filenames include content hashes so you don’t need to worry about browsers caching their old versions.
However there is an **escape hatch** that you can use to add an asset outside of the module system.
-If you put a file into the `public` folder, it will **not** be processed by Webpack. Instead it will be copied into the build folder untouched. To reference assets in the `public` folder, you need to use a special variable called `PUBLIC_URL`.
+If you put a file into the `public` folder, it will **not** be processed by Webpack. Instead it will be copied into the build folder untouched. To reference assets in the `public` folder, you need to use a special variable called `PUBLIC_URL`.
Inside `index.html`, you can use it like this:
```html
-
+
```
Only files inside the `public` folder will be accessible by `%PUBLIC_URL%` prefix. If you need to use a file from `src` or `node_modules`, you’ll have to copy it there to explicitly specify your intention to make this file a part of the build.
@@ -708,19 +711,19 @@ render() {
Keep in mind the downsides of this approach:
-* None of the files in `public` folder get post-processed or minified.
-* Missing files will not be called at compilation time, and will cause 404 errors for your users.
-* Result filenames won’t include content hashes so you’ll need to add query arguments or rename them every time they change.
+- None of the files in `public` folder get post-processed or minified.
+- Missing files will not be called at compilation time, and will cause 404 errors for your users.
+- Result filenames won’t include content hashes so you’ll need to add query arguments or rename them every time they change.
### When to Use the `public` Folder
Normally we recommend importing [stylesheets](#adding-a-stylesheet), [images, and fonts](#adding-images-fonts-and-files) from JavaScript.
The `public` folder is useful as a workaround for a number of less common cases:
-* You need a file with a specific name in the build output, such as [`manifest.webmanifest`](https://developer.mozilla.org/en-US/docs/Web/Manifest).
-* You have thousands of images and need to dynamically reference their paths.
-* You want to include a small script like [`pace.js`](http://github.hubspot.com/pace/docs/welcome/) outside of the bundled code.
-* Some library may be incompatible with Webpack and you have no other option but to include it as a `