From 4ab4053796dddd48d4315269173ced059005c9b6 Mon Sep 17 00:00:00 2001 From: Ian Schmitz Date: Fri, 8 Nov 2019 22:10:20 -0800 Subject: [PATCH 1/2] Add optional chaining and nullish coalescing tests --- .../fixtures/kitchensink/template/src/App.js | 10 ++++ .../src/features/syntax/NullishCoalescing.js | 48 +++++++++++++++++++ .../features/syntax/NullishCoalescing.test.js | 19 ++++++++ .../src/features/syntax/OptionalChaining.js | 48 +++++++++++++++++++ .../features/syntax/OptionalChaining.test.js | 19 ++++++++ 5 files changed, 144 insertions(+) create mode 100644 packages/react-scripts/fixtures/kitchensink/template/src/features/syntax/NullishCoalescing.js create mode 100644 packages/react-scripts/fixtures/kitchensink/template/src/features/syntax/NullishCoalescing.test.js create mode 100644 packages/react-scripts/fixtures/kitchensink/template/src/features/syntax/OptionalChaining.js create mode 100644 packages/react-scripts/fixtures/kitchensink/template/src/features/syntax/OptionalChaining.test.js diff --git a/packages/react-scripts/fixtures/kitchensink/template/src/App.js b/packages/react-scripts/fixtures/kitchensink/template/src/App.js index 50fd8932341..c9d768f28df 100644 --- a/packages/react-scripts/fixtures/kitchensink/template/src/App.js +++ b/packages/react-scripts/fixtures/kitchensink/template/src/App.js @@ -171,6 +171,11 @@ class App extends Component { this.setFeature(f.default) ); break; + case 'nullish-coalescing': + import('./features/syntax/NullishCoalescing').then(f => + this.setFeature(f.default) + ); + break; case 'object-destructuring': import('./features/syntax/ObjectDestructuring').then(f => this.setFeature(f.default) @@ -181,6 +186,11 @@ class App extends Component { this.setFeature(f.default) ); break; + case 'optional-chaining': + import('./features/syntax/OptionalChaining').then(f => + this.setFeature(f.default) + ); + break; case 'promises': import('./features/syntax/Promises').then(f => this.setFeature(f.default) diff --git a/packages/react-scripts/fixtures/kitchensink/template/src/features/syntax/NullishCoalescing.js b/packages/react-scripts/fixtures/kitchensink/template/src/features/syntax/NullishCoalescing.js new file mode 100644 index 00000000000..ed5f916399c --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/template/src/features/syntax/NullishCoalescing.js @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; + +function load() { + return [ + { id: 1, name: '1' }, + { id: 2, name: '2' }, + { id: 3, name: '3' }, + { id: 4, name: '4' }, + ]; +} + +export default class extends Component { + static propTypes = { + onReady: PropTypes.func.isRequired, + }; + + constructor(props) { + super(props); + this.state = { users: [] }; + } + + async componentDidMount() { + const users = load(); + this.setState({ users }); + } + + componentDidUpdate() { + this.props.onReady(); + } + + render() { + return ( +
+ {this.state.users.map(user => ( +
{user.name ?? 'John Doe'}
+ ))} +
+ ); + } +} diff --git a/packages/react-scripts/fixtures/kitchensink/template/src/features/syntax/NullishCoalescing.test.js b/packages/react-scripts/fixtures/kitchensink/template/src/features/syntax/NullishCoalescing.test.js new file mode 100644 index 00000000000..781896da290 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/template/src/features/syntax/NullishCoalescing.test.js @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React from 'react'; +import ReactDOM from 'react-dom'; +import NullishCoalescing from './NullishCoalescing'; + +describe('nullish coalescing', () => { + it('renders without crashing', () => { + const div = document.createElement('div'); + return new Promise(resolve => { + ReactDOM.render(, div); + }); + }); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/template/src/features/syntax/OptionalChaining.js b/packages/react-scripts/fixtures/kitchensink/template/src/features/syntax/OptionalChaining.js new file mode 100644 index 00000000000..5b0fd1e3e47 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/template/src/features/syntax/OptionalChaining.js @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; + +function load() { + return [ + { id: 1, name: '1' }, + { id: 2, name: '2' }, + { id: 3, name: '3' }, + { id: 4, name: '4' }, + ]; +} + +export default class extends Component { + static propTypes = { + onReady: PropTypes.func.isRequired, + }; + + constructor(props) { + super(props); + this.state = { users: [] }; + } + + async componentDidMount() { + const users = load?.(); + this.setState({ users }); + } + + componentDidUpdate() { + this.props.onReady(); + } + + render() { + return ( +
+ {this.state.users.map(user => ( +
{user?.name}
+ ))} +
+ ); + } +} diff --git a/packages/react-scripts/fixtures/kitchensink/template/src/features/syntax/OptionalChaining.test.js b/packages/react-scripts/fixtures/kitchensink/template/src/features/syntax/OptionalChaining.test.js new file mode 100644 index 00000000000..229037c6de9 --- /dev/null +++ b/packages/react-scripts/fixtures/kitchensink/template/src/features/syntax/OptionalChaining.test.js @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React from 'react'; +import ReactDOM from 'react-dom'; +import OptionalChaining from './OptionalChaining'; + +describe('optional chaining', () => { + it('renders without crashing', () => { + const div = document.createElement('div'); + return new Promise(resolve => { + ReactDOM.render(, div); + }); + }); +}); From 305058e86f5e6c85d67db09245c8632db8c7eb7c Mon Sep 17 00:00:00 2001 From: Ian Schmitz Date: Fri, 8 Nov 2019 22:44:09 -0800 Subject: [PATCH 2/2] Add draft changelog --- CHANGELOG.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08c995a14ab..11c865f62d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,46 @@ +## 3.3.0 (2019-xx-xx) + +DRAFT + +### Custom Templates + +DRAFT + +### Optional Chaining and Nullish Coalescing Operators + +We now support the [optional chaining](https://github.com/TC39/proposal-optional-chaining) and [nullish coalescing](https://github.com/tc39/proposal-nullish-coalescing) operators! + +```js +// Optional chaining +a?.(); // undefined if `a` is null/undefined +b?.c; // undefined if `b` is null/undefined + +// Nullish coalescing +undefined ?? 'some other default'; // result: 'some other default' +null ?? 'some other default'; // result: 'some other default' +'' ?? 'some other default'; // result: '' +0 ?? 300; // result: 0 +false ?? true; // result: false +``` + +**If your're using TypeScript, you will need to upgrade your `typescript` dependency to `3.7.0` or later if you wish to use the new operators.** + +**If you're using Visual Studio Code 1.40 (the latest as of this release) or earlier, you will need to configure your editor if you want it to understand the new operators.** + +If you're using TypeScript in your project and have already upgrade its version as described above, then you can [configure VS Code to `Use Workspace Version` of TypeScript](https://code.visualstudio.com/docs/typescript/typescript-compiling#_using-newer-typescript-versions). If your project isn't using TypeScript, you can use the [JavaScript and TypeScript Nightly extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.vscode-typescript-next) until VS Code releases a newer version including TypeScript `3.7.0` or newer. + +### Numeric Separators + +We've added support for [numeric separators](https://github.com/tc39/proposal-numeric-separator) to improve readability of numeric literals. + +```js +1000000000; // Is this a billion? a hundred millions? Ten millions? +101475938.38; // what scale is this? what power of 10? + +1_000_000_000; // Ah, so a billion +101_475_938.38; // And this is hundreds of millions +``` + ## 3.2.0 (2019-10-03) v3.2.0 is a minor release that adds support for production profiling and ignoring TypeScript type errors to make migrating JavaScript projects to TypeScript easier. It also includes other minor bug fixes and documentation updates.