From c47480bbc8c75c7aaeadbcbfefd70429b13a5344 Mon Sep 17 00:00:00 2001 From: Jack Hsu Date: Wed, 24 Jun 2020 14:02:01 -0400 Subject: [PATCH] chore(react): update library versions and update RTK generated code (#3226) --- packages/react/migrations.json | 42 +++++++++++ .../update-9-5-0/update-9-5-0.spec.ts | 43 +++++++++++ .../migrations/update-9-5-0/update-9-5-0.ts | 13 ++++ .../__fileName__.slice.spec.ts__tmpl__ | 8 +- .../__fileName__.slice.ts__tmpl__ | 74 +++++++++++++------ packages/react/src/utils/ast-utils.ts | 9 ++- packages/react/src/utils/versions.ts | 16 ++-- 7 files changed, 167 insertions(+), 38 deletions(-) create mode 100644 packages/react/src/migrations/update-9-5-0/update-9-5-0.spec.ts create mode 100644 packages/react/src/migrations/update-9-5-0/update-9-5-0.ts diff --git a/packages/react/migrations.json b/packages/react/migrations.json index 7e263f2f68..e77a9e0d7e 100644 --- a/packages/react/migrations.json +++ b/packages/react/migrations.json @@ -49,6 +49,11 @@ "version": "9.4.0-beta.1", "description": "Migrate to new babel setup for greater flexibility", "factory": "./src/migrations/update-9-4-0/babelrc-9-4-0" + }, + "update-9.5.0": { + "version": "9.5.0-beta.1", + "description": "Update libraries", + "factory": "./src/migrations/update-9-5-0/update-9-5-0" } }, "packageJsonUpdates": { @@ -264,6 +269,43 @@ "alwaysAddToPackageJson": false } } + }, + "9.5.0": { + "version": "9.5.0-beta.1", + "packages": { + "@types/react": { + "version": "16.9.38", + "alwaysAddToPackageJson": false + }, + "styled-components": { + "version": "5.1.1", + "alwaysAddToPackageJson": false + }, + "@emotion/core": { + "version": "10.0.28", + "alwaysAddToPackageJson": false + }, + "@testing-library/react": { + "version": "10.4.1", + "alwaysAddToPackageJson": false + }, + "@reduxjs/toolkit": { + "version": "1.4.0", + "alwaysAddToPackageJson": false + }, + "eslint-plugin-import": { + "version": "2.21.2", + "alwaysAddToPackageJson": false + }, + "eslint-plugin-a11y": { + "version": "6.3.1", + "alwaysAddToPackageJson": false + }, + "eslint-plugin-react-hooks": { + "version": "4.0.4", + "alwaysAddToPackageJson": false + } + } } } } diff --git a/packages/react/src/migrations/update-9-5-0/update-9-5-0.spec.ts b/packages/react/src/migrations/update-9-5-0/update-9-5-0.spec.ts new file mode 100644 index 0000000000..b61cc74ba4 --- /dev/null +++ b/packages/react/src/migrations/update-9-5-0/update-9-5-0.spec.ts @@ -0,0 +1,43 @@ +import { Tree } from '@angular-devkit/schematics'; +import { SchematicTestRunner } from '@angular-devkit/schematics/testing'; +import { readJsonInTree } from '@nrwl/workspace'; +import * as path from 'path'; +import { createEmptyWorkspace } from '@nrwl/workspace/testing'; + +describe('Update 9.5.0', () => { + let tree: Tree; + let schematicRunner: SchematicTestRunner; + + beforeEach(async () => { + tree = Tree.empty(); + tree = createEmptyWorkspace(tree); + schematicRunner = new SchematicTestRunner( + '@nrwl/react', + path.join(__dirname, '../../../migrations.json') + ); + }); + + it(`should update libs`, async () => { + tree.overwrite( + 'package.json', + JSON.stringify({ + dependencies: {}, + devDependencies: { + '@testing-library/react': '10.0.4', + }, + }) + ); + + tree = await schematicRunner + .runSchematicAsync('update-9.5.0', {}, tree) + .toPromise(); + + const packageJson = readJsonInTree(tree, '/package.json'); + expect(packageJson).toMatchObject({ + dependencies: {}, + devDependencies: { + '@testing-library/react': '10.4.1', + }, + }); + }); +}); diff --git a/packages/react/src/migrations/update-9-5-0/update-9-5-0.ts b/packages/react/src/migrations/update-9-5-0/update-9-5-0.ts new file mode 100644 index 0000000000..7e02967c91 --- /dev/null +++ b/packages/react/src/migrations/update-9-5-0/update-9-5-0.ts @@ -0,0 +1,13 @@ +import { chain, Rule } from '@angular-devkit/schematics'; +import { formatFiles, updatePackagesInPackageJson } from '@nrwl/workspace'; +import * as path from 'path'; + +export default function update(): Rule { + return chain([ + updatePackagesInPackageJson( + path.join(__dirname, '../../../', 'migrations.json'), + '9.5.0' + ), + formatFiles(), + ]); +} diff --git a/packages/react/src/schematics/redux/files/__directory__/__fileName__.slice.spec.ts__tmpl__ b/packages/react/src/schematics/redux/files/__directory__/__fileName__.slice.spec.ts__tmpl__ index b48463f111..b96f5f281e 100644 --- a/packages/react/src/schematics/redux/files/__directory__/__fileName__.slice.spec.ts__tmpl__ +++ b/packages/react/src/schematics/redux/files/__directory__/__fileName__.slice.spec.ts__tmpl__ @@ -1,4 +1,4 @@ -import { <%= propertyName %>Actions, <%= propertyName %>Adapter, <%= propertyName %>Reducer } from './<%= fileName %>.slice'; +import { fetch<%= className %>, <%= propertyName %>Adapter, <%= propertyName %>Reducer } from './<%= fileName %>.slice'; describe('<%= propertyName %> reducer', () => { it('should handle initial state', () => { @@ -13,7 +13,7 @@ describe('<%= propertyName %> reducer', () => { it('should handle fetch<%= className %>s', () => { let state = <%= propertyName %>Reducer( undefined, - <%= propertyName %>Actions.fetch<%= className %>s.pending(null, null) + fetch<%= className %>.pending(null, null) ); expect(state).toEqual( @@ -26,7 +26,7 @@ describe('<%= propertyName %> reducer', () => { state = <%= propertyName %>Reducer( state, - <%= propertyName %>Actions.fetch<%= className %>s.fulfilled([{ id: 1 }], null, null) + fetch<%= className %>.fulfilled([{ id: 1 }], null, null) ); expect(state).toEqual( @@ -39,7 +39,7 @@ describe('<%= propertyName %> reducer', () => { state = <%= propertyName %>Reducer( state, - <%= propertyName %>Actions.fetch<%= className %>s.rejected(new Error('Uh oh'), null, null) + fetch<%= className %>.rejected(new Error('Uh oh'), null, null) ); expect(state).toEqual( diff --git a/packages/react/src/schematics/redux/files/__directory__/__fileName__.slice.ts__tmpl__ b/packages/react/src/schematics/redux/files/__directory__/__fileName__.slice.ts__tmpl__ index 980a2aae0f..f6addfdd41 100644 --- a/packages/react/src/schematics/redux/files/__directory__/__fileName__.slice.ts__tmpl__ +++ b/packages/react/src/schematics/redux/files/__directory__/__fileName__.slice.ts__tmpl__ @@ -1,6 +1,7 @@ import { createAsyncThunk, createEntityAdapter, + createSelector, createSlice, EntityState, PayloadAction @@ -25,8 +26,21 @@ export const <%= propertyName %>Adapter = createEntityAdapter<<%= className %>En /** * Export an effect using createAsyncThunk from * the Redux Toolkit: https://redux-toolkit.js.org/api/createAsyncThunk + * + * e.g. + * ``` + * import React, { useEffect } from 'react'; + * import { useDispatch } from 'react-redux'; + * + * // ... + * + * const dispatch = useDispatch(); + * useEffect(() => { + * dispatch(fetch<%= className %>()) + * }, [dispatch]); + * ``` */ -export const fetch<%= className %>s = createAsyncThunk( +export const fetch<%= className %> = createAsyncThunk( '<%= propertyName %>/fetchStatus', async (_, thunkAPI) => { /** @@ -47,22 +61,23 @@ export const <%= propertyName %>Slice = createSlice({ name: <%= constantName %>_FEATURE_KEY, initialState: initial<%= className %>State, reducers: { - add<%= className %>: <%= propertyName %>Adapter.addOne, - remove<%= className %>: <%= propertyName %>Adapter.removeOne + add: <%= propertyName %>Adapter.addOne, + remove: <%= propertyName %>Adapter.removeOne // ... }, extraReducers: builder => { - builder.addCase(fetch<%= className %>s.pending, (state: <%= className %>State) => { - state.loadingStatus = 'loading'; - }); - builder.addCase(fetch<%= className %>s.fulfilled, (state: <%= className %>State, action: PayloadAction<<%= className %>Entity[]>) => { - <%= propertyName %>Adapter.addMany(state, action.payload); - state.loadingStatus = 'loaded'; - }); - builder.addCase(fetch<%= className %>s.rejected, (state: <%= className %>State, action) => { - state.loadingStatus = 'error'; - state.error = action.error.message; - }); + builder + .addCase(fetch<%= className %>.pending, (state: <%= className %>State) => { + state.loadingStatus = 'loading'; + }) + .addCase(fetch<%= className %>.fulfilled, (state: <%= className %>State, action: PayloadAction<<%= className %>Entity[]>) => { + <%= propertyName %>Adapter.setAll(state, action.payload); + state.loadingStatus = 'loaded'; + }) + .addCase(fetch<%= className %>.rejected, (state: <%= className %>State, action) => { + state.loadingStatus = 'error'; + state.error = action.error.message; + }); } }); @@ -76,28 +91,39 @@ export const <%= propertyName %>Reducer = <%= propertyName %>Slice.reducer; * * e.g. * ``` + * import React, { useEffect } from 'react'; + * import { useDispatch } from 'react-redux'; + * + * // ... + * * const dispatch = useDispatch(); - * dispatch(<%= propertyName %>Actions.add<%= className %>([{ id: 1 }])); + * useEffect(() => { + * dispatch(<%= propertyName %>Actions.add({ id: 1 })) + * }, [dispatch]); * ``` * * See: https://react-redux.js.org/next/api/hooks#usedispatch */ -export const <%= propertyName %>Actions = { - ...<%= propertyName %>Slice.actions, - fetch<%= className %>s -}; +export const <%= propertyName %>Actions = <%= propertyName %>Slice.actions; /* * Export selectors to query state. For use with the `useSelector` hook. * * e.g. * ``` - * const entities = useSelector(select<%= className %>Entities); + * import { useSelector } from 'react-redux'; + * + * // ... + * + * const entities = useSelector(selectAll<%= className %>); * ``` * * See: https://react-redux.js.org/next/api/hooks#useselector */ -export const <%= propertyName %>Selectors = { - get<%= className %>State: (rootState: unknown): <%= className %>State => rootState[<%= constantName %>_FEATURE_KEY], - ...<%= propertyName %>Adapter.getSelectors() -}; \ No newline at end of file +const { selectAll, selectEntities } = <%= propertyName %>Adapter.getSelectors(); + +export const get<%= className %>State = (rootState: unknown): <%= className %>State => rootState[<%= constantName %>_FEATURE_KEY]; + +export const selectAll<%= className %> = createSelector(get<%= className %>State, selectAll); + +export const select<%= className %>Entities = createSelector(get<%= className %>State, selectEntities); diff --git a/packages/react/src/utils/ast-utils.ts b/packages/react/src/utils/ast-utils.ts index d4502c1202..dd1a4d8967 100644 --- a/packages/react/src/utils/ast-utils.ts +++ b/packages/react/src/utils/ast-utils.ts @@ -356,7 +356,7 @@ export function addReduxStoreToMain( ...addGlobal( source, sourcePath, - `import { configureStore } from '@reduxjs/toolkit'; + `import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit'; import { Provider } from 'react-redux';` ), new InsertChange( @@ -364,7 +364,12 @@ import { Provider } from 'react-redux';` renderStmt.getStart(), ` const store = configureStore({ - reducer: {} + reducer: {}, + // Additional middleware can be passed to this array + middleware: [...getDefaultMiddleware()], + devTools: process.env.NODE_ENV !== 'production', + // Optional Redux store enhancers + enhancers: [], }); ` diff --git a/packages/react/src/utils/versions.ts b/packages/react/src/utils/versions.ts index dcec4a4d15..a0b33d96d7 100644 --- a/packages/react/src/utils/versions.ts +++ b/packages/react/src/utils/versions.ts @@ -2,17 +2,17 @@ export const nxVersion = '*'; export const reactVersion = '16.13.1'; export const reactDomVersion = '16.13.1'; -export const typesReactVersion = '16.9.35'; +export const typesReactVersion = '16.9.38'; export const typesReactDomVersion = '16.9.8'; -export const styledComponentsVersion = '5.1.0'; +export const styledComponentsVersion = '5.1.1'; export const typesStyledComponentsVersion = '5.1.0'; export const reactIsVersion = '16.13.1'; export const typesReactIsVersion = '16.7.1'; export const emotionStyledVersion = '10.0.27'; -export const emotionCoreVersion = '10.0.27'; +export const emotionCoreVersion = '10.0.28'; export const emotionBabelPresetCssPropVersion = '10.0.27'; export const styledJsxVersion = '3.3.0'; @@ -21,15 +21,15 @@ export const typesStyledJsxVersion = '2.2.8'; export const reactRouterDomVersion = '5.2.0'; export const typesReactRouterDomVersion = '5.1.5'; -export const testingLibraryReactVersion = '10.0.4'; +export const testingLibraryReactVersion = '10.4.1'; -export const reduxjsToolkitVersion = '1.3.6'; +export const reduxjsToolkitVersion = '1.4.0'; export const reactReduxVersion = '7.2.0'; export const typesReactReduxVersion = '7.1.9'; -export const eslintPluginImportVersion = '2.20.2'; -export const eslintPluginJsxA11yVersion = '6.2.3'; +export const eslintPluginImportVersion = '2.21.2'; +export const eslintPluginJsxA11yVersion = '6.3.1'; export const eslintPluginReactVersion = '7.20.0'; -export const eslintPluginReactHooksVersion = '4.0.2'; +export const eslintPluginReactHooksVersion = '4.0.4'; export const babelPluginStyledComponentsVersion = '1.10.7';