Fix SSR, upgrade react router and loadable components.
This commit is contained in:
parent
5b3e5522b0
commit
737ec0e59c
|
@ -286,9 +286,15 @@ class Routes extends React.PureComponent<Props> {
|
|||
const routeComponents = routeConfigs.map(config => {
|
||||
const { route, onlyLoggedIn, onlyLoggedOut } = config;
|
||||
if (onlyLoggedIn || onlyLoggedOut) {
|
||||
return <AuthRoute key={route.path} onlyLoggedOut={onlyLoggedOut} {...route} />;
|
||||
return (
|
||||
<AuthRoute
|
||||
key={route.path as string}
|
||||
onlyLoggedOut={onlyLoggedOut}
|
||||
{...route}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
return <Route key={route.path} {...route} />;
|
||||
return <Route key={route.path as string} {...route} />;
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { Route, Redirect, RouteProps } from 'react-router-dom';
|
||||
import { Route, Redirect, RouteProps } from 'react-router';
|
||||
import { message } from 'antd';
|
||||
import { AppState } from 'store/reducers';
|
||||
import { authActions } from 'modules/auth';
|
||||
|
|
|
@ -2,12 +2,12 @@ import '@babel/polyfill';
|
|||
import React from 'react';
|
||||
import { hot } from 'react-hot-loader';
|
||||
import { hydrate } from 'react-dom';
|
||||
import { loadComponents } from 'loadable-components';
|
||||
import { Provider } from 'react-redux';
|
||||
import { Router } from 'react-router-dom';
|
||||
import { PersistGate } from 'redux-persist/integration/react';
|
||||
import * as Sentry from '@sentry/browser';
|
||||
import { I18nextProvider } from 'react-i18next';
|
||||
import { loadableReady } from '@loadable/component';
|
||||
import { configureStore } from 'store/configure';
|
||||
import history from 'store/history';
|
||||
import { massageSerializedState } from 'utils/api';
|
||||
|
@ -38,6 +38,6 @@ const App = hot(module)(() => (
|
|||
</I18nextProvider>
|
||||
));
|
||||
|
||||
loadComponents().then(() => {
|
||||
loadableReady(() => {
|
||||
hydrate(<App />, document.getElementById('app'));
|
||||
});
|
||||
|
|
|
@ -26,7 +26,7 @@ interface Props {
|
|||
code: '403' | '404' | '500';
|
||||
}
|
||||
|
||||
const ExceptionComponent: React.SFC<Props> = ({ code }) => (
|
||||
const ExceptionComponent = ({ code }: Props) => (
|
||||
<Exception type={code} {...content[code]} />
|
||||
);
|
||||
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
declare module 'loadable-components/server' {
|
||||
import * as React from 'react';
|
||||
|
||||
export function getLoadableState(
|
||||
rootElement: React.ReactElement<{}>,
|
||||
rootContext?: any,
|
||||
fetchRoot?: boolean,
|
||||
tree?: any,
|
||||
): Promise<DeferredState>;
|
||||
|
||||
export interface DeferredStateTree {
|
||||
id: string;
|
||||
children: DeferredStateTree[];
|
||||
}
|
||||
|
||||
export interface DeferredState {
|
||||
tree: DeferredStateTree;
|
||||
getScriptContent(): string;
|
||||
getScriptTag(): string;
|
||||
getScriptElement(): React.ReactHTMLElement<HTMLScriptElement>;
|
||||
}
|
||||
}
|
|
@ -23,7 +23,7 @@ const tsBabelLoaderClient = {
|
|||
options: {
|
||||
plugins: [
|
||||
'dynamic-import-webpack', // for client
|
||||
'loadable-components/babel',
|
||||
'@loadable/babel-plugin',
|
||||
'react-hot-loader/babel',
|
||||
'@babel/plugin-proposal-object-rest-spread',
|
||||
'@babel/plugin-proposal-class-properties',
|
||||
|
@ -47,7 +47,7 @@ const tsBabelLoaderServer = {
|
|||
options: {
|
||||
plugins: [
|
||||
'dynamic-import-node', // for server
|
||||
'loadable-components/babel',
|
||||
'@loadable/babel-plugin',
|
||||
'@babel/plugin-proposal-object-rest-spread',
|
||||
'@babel/plugin-proposal-class-properties',
|
||||
['import', { libraryName: 'antd', style: false }],
|
||||
|
|
|
@ -6,6 +6,7 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
|||
const ModuleDependencyWarning = require('./module-dependency-warning');
|
||||
const WebappWebpackPlugin = require('webapp-webpack-plugin');
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||
const LoadablePlugin = require('@loadable/webpack-plugin');
|
||||
|
||||
const env = require('../env')();
|
||||
const paths = require('../paths');
|
||||
|
@ -75,6 +76,7 @@ const client = [
|
|||
return JSON.stringify(trans, null, 2);
|
||||
},
|
||||
}),
|
||||
new LoadablePlugin(),
|
||||
];
|
||||
|
||||
const server = [
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
"@types/react-dom": "16.0.9",
|
||||
"@types/react-helmet": "^5.0.7",
|
||||
"@types/react-redux": "^6.0.2",
|
||||
"@types/react-router": "^4.0.31",
|
||||
"@types/react-router": "4.4.3",
|
||||
"@types/react-router-dom": "^4.3.1",
|
||||
"@types/recompose": "^0.26.1",
|
||||
"@types/redux-actions": "^2.3.0",
|
||||
|
@ -131,8 +131,8 @@
|
|||
"react-i18next": "^8.3.5",
|
||||
"react-mde": "^5.8.0",
|
||||
"react-redux": "^5.0.7",
|
||||
"react-router": "^4.3.1",
|
||||
"react-router-dom": "^4.3.1",
|
||||
"react-router": "4.4.0-beta.6",
|
||||
"react-router-dom": "4.4.0-beta.6",
|
||||
"recompose": "^0.27.1",
|
||||
"redux": "^4.0.0",
|
||||
"redux-devtools-extension": "^2.13.2",
|
||||
|
@ -167,9 +167,13 @@
|
|||
"xss": "1.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@loadable/babel-plugin": "5.5.0",
|
||||
"@loadable/server": "5.5.0",
|
||||
"@loadable/webpack-plugin": "5.5.0",
|
||||
"@storybook/react": "4.0.0-alpha.22",
|
||||
"@types/bn.js": "4.11.1",
|
||||
"@types/loadable__component": "5.2.0",
|
||||
"@types/loadable__server": "5.2.0",
|
||||
"@types/qrcode.react": "^0.8.1",
|
||||
"@types/query-string": "6.1.0",
|
||||
"@types/react-copy-to-clipboard": "^4.2.6",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import * as React from 'react';
|
||||
import Helmet from 'react-helmet';
|
||||
import { ChunkExtractor } from '@loadable/server';
|
||||
|
||||
export interface Props {
|
||||
children: any;
|
||||
|
@ -9,7 +10,7 @@ export interface Props {
|
|||
metaTags: Array<React.MetaHTMLAttributes<HTMLMetaElement>>;
|
||||
state: string;
|
||||
i18n: string;
|
||||
loadableStateScript: string;
|
||||
extractor: ChunkExtractor;
|
||||
}
|
||||
|
||||
const HTML: React.SFC<Props> = ({
|
||||
|
@ -20,7 +21,7 @@ const HTML: React.SFC<Props> = ({
|
|||
i18n,
|
||||
linkTags,
|
||||
metaTags,
|
||||
loadableStateScript,
|
||||
extractor,
|
||||
}) => {
|
||||
const head = Helmet.renderStatic();
|
||||
return (
|
||||
|
@ -43,6 +44,7 @@ const HTML: React.SFC<Props> = ({
|
|||
crossOrigin="anonymous"
|
||||
/> */}
|
||||
{/* Custom link & meta tags from webpack */}
|
||||
{extractor.getLinkElements()}
|
||||
{linkTags.map((l, idx) => (
|
||||
<link key={idx} {...l as any} />
|
||||
))}
|
||||
|
@ -57,9 +59,12 @@ const HTML: React.SFC<Props> = ({
|
|||
{head.link.toComponent()}
|
||||
{head.script.toComponent()}
|
||||
|
||||
{extractor.getStyleElements()}
|
||||
{css.map(href => {
|
||||
return <link key={href} rel="stylesheet" href={href} />;
|
||||
})}
|
||||
|
||||
{extractor.getScriptElements()}
|
||||
<script
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `window.__PRELOADED_STATE__ = ${state}`,
|
||||
|
@ -73,7 +78,6 @@ const HTML: React.SFC<Props> = ({
|
|||
</head>
|
||||
<body>
|
||||
<div id="app" dangerouslySetInnerHTML={{ __html: children }} />
|
||||
<script dangerouslySetInnerHTML={{ __html: loadableStateScript }} />
|
||||
{scripts.map(src => {
|
||||
return <script key={src} src={src} />;
|
||||
})}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import React from 'react';
|
||||
import { Request, Response } from 'express';
|
||||
import { renderToString } from 'react-dom/server';
|
||||
import { getLoadableState } from 'loadable-components/server';
|
||||
import { ChunkExtractor } from '@loadable/server';
|
||||
import { StaticRouter as Router } from 'react-router-dom';
|
||||
import { Provider } from 'react-redux';
|
||||
import { I18nextProvider } from 'react-i18next';
|
||||
|
@ -19,63 +18,6 @@ import i18n from './i18n';
|
|||
// @ts-ignore
|
||||
import * as paths from '../config/paths';
|
||||
import { storeActionsForPath } from './ssrAsync';
|
||||
const isDev = process.env.NODE_ENV === 'development';
|
||||
|
||||
let cachedStats: any;
|
||||
const getStats = () =>
|
||||
new Promise((res, rej) => {
|
||||
if (!isDev && cachedStats) {
|
||||
res(cachedStats);
|
||||
return;
|
||||
}
|
||||
const statsPath = path.join(paths.clientBuild, paths.publicPath, 'stats.json');
|
||||
fs.readFile(statsPath, (e, d) => {
|
||||
if (e) {
|
||||
rej(e);
|
||||
return;
|
||||
}
|
||||
cachedStats = JSON.parse(d.toString());
|
||||
res(cachedStats);
|
||||
});
|
||||
});
|
||||
|
||||
const extractLoadableIds = (tree: any): string[] => {
|
||||
const ids = (tree.id && [tree.id]) || [];
|
||||
if (tree.children) {
|
||||
return tree.children
|
||||
.reduce((a: string[], c: any) => a.concat(extractLoadableIds(c)), [])
|
||||
.concat(ids);
|
||||
}
|
||||
return ids;
|
||||
};
|
||||
|
||||
// TODO: write tests for this
|
||||
const chunkExtractFromLoadables = (loadableState: any) =>
|
||||
getStats().then((stats: any) => {
|
||||
const loadableIds = extractLoadableIds(loadableState.tree);
|
||||
const mods = stats.modules.filter(
|
||||
(m: any) =>
|
||||
m.reasons.filter((r: any) => loadableIds.indexOf(r.userRequest) > -1).length > 0,
|
||||
);
|
||||
const chunks = mods.reduce((a: string[], m: any) => a.concat(m.chunks), []);
|
||||
const origins = stats.chunks
|
||||
.filter((c: any) => chunks.indexOf(c.id) > -1)
|
||||
.map((c: any) => ({ loc: c.origins[0].loc, moduleId: c.origins[0].moduleId }));
|
||||
const origin = origins[0];
|
||||
const files = stats.chunks
|
||||
.filter(
|
||||
(c: any) =>
|
||||
c.origins.filter(
|
||||
(o: any) => origin && o.loc === origin.loc && o.moduleId === origin.moduleId,
|
||||
).length > 0,
|
||||
)
|
||||
.reduce((a: string[], c: any) => a.concat(c.files), []);
|
||||
|
||||
return {
|
||||
css: files.filter((f: string) => /.css$/.test(f)),
|
||||
js: files.filter((f: string) => /.js$/.test(f)),
|
||||
};
|
||||
});
|
||||
|
||||
const serverRenderer = () => async (req: Request, res: Response) => {
|
||||
const { store } = configureStore();
|
||||
|
@ -98,18 +40,22 @@ const serverRenderer = () => async (req: Request, res: Response) => {
|
|||
</I18nextProvider>
|
||||
);
|
||||
|
||||
let loadableState;
|
||||
let loadableFiles;
|
||||
let extractor;
|
||||
// 1. loadable state will render dynamic imports
|
||||
try {
|
||||
loadableState = await getLoadableState(reactApp);
|
||||
loadableFiles = await chunkExtractFromLoadables(loadableState);
|
||||
const statsFile = path.join(
|
||||
paths.clientBuild,
|
||||
paths.publicPath,
|
||||
'loadable-stats.json',
|
||||
);
|
||||
extractor = new ChunkExtractor({ statsFile, entrypoints: ['bundle'] });
|
||||
} catch (e) {
|
||||
const disp = `Error getting loadable state for SSR`;
|
||||
e.message = disp + ': ' + e.message;
|
||||
log.error(e);
|
||||
return res.status(500).send(disp + ' (more info in server logs)');
|
||||
}
|
||||
|
||||
// 2. render and collect state
|
||||
const content = renderToString(reactApp);
|
||||
const state = JSON.stringify(store.getState());
|
||||
|
@ -124,10 +70,19 @@ const serverRenderer = () => async (req: Request, res: Response) => {
|
|||
return res.status(500).send(disp);
|
||||
}
|
||||
|
||||
const cssFiles = ['bundle.css', 'vendor.css', ...loadableFiles.css]
|
||||
console.log('About to ask extractor for shit');
|
||||
try {
|
||||
console.log('style', extractor.getStyleTags());
|
||||
console.log('script', extractor.getScriptTags());
|
||||
console.log('link', extractor.getLinkTags());
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
console.log('Donezo');
|
||||
const cssFiles = ['bundle.css', 'vendor.css']
|
||||
.map(f => res.locals.assetPath(f))
|
||||
.filter(Boolean);
|
||||
const jsFiles = [...loadableFiles.js, 'vendor.js', 'bundle.js']
|
||||
const jsFiles = ['vendor.js', 'bundle.js']
|
||||
.map(f => res.locals.assetPath(f))
|
||||
.filter(Boolean);
|
||||
const mappedLinkTags = linkTags
|
||||
|
@ -137,6 +92,7 @@ const serverRenderer = () => async (req: Request, res: Response) => {
|
|||
.map(m => ({ ...m, content: res.locals.assetPath(m.content) }))
|
||||
.filter(m => !!m.content);
|
||||
|
||||
console.log('Sending!');
|
||||
return res.send(
|
||||
'<!doctype html>' +
|
||||
renderToString(
|
||||
|
@ -147,7 +103,7 @@ const serverRenderer = () => async (req: Request, res: Response) => {
|
|||
metaTags={mappedMetaTags}
|
||||
state={state}
|
||||
i18n={i18nClient}
|
||||
loadableStateScript={loadableState.getScriptContent()}
|
||||
extractor={extractor}
|
||||
>
|
||||
{content}
|
||||
</Html>,
|
||||
|
|
|
@ -613,6 +613,12 @@
|
|||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.0.0"
|
||||
|
||||
"@babel/plugin-syntax-dynamic-import@^7.2.0":
|
||||
version "7.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz#69c159ffaf4998122161ad8ebc5e6d1f55df8612"
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.0.0"
|
||||
|
||||
"@babel/plugin-syntax-export-default-from@^7.0.0":
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.0.0.tgz#084b639bce3d42f3c5bf3f68ccb42220bb2d729d"
|
||||
|
@ -1564,12 +1570,28 @@
|
|||
dependencies:
|
||||
core-js "^2.5.7"
|
||||
|
||||
"@loadable/babel-plugin@5.5.0":
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@loadable/babel-plugin/-/babel-plugin-5.5.0.tgz#72387f03c6c85e75c0055ab64e2b4b8bb7c028b6"
|
||||
dependencies:
|
||||
"@babel/plugin-syntax-dynamic-import" "^7.2.0"
|
||||
|
||||
"@loadable/component@5.5.0":
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@loadable/component/-/component-5.5.0.tgz#d26ae31bb4da3cac6ae34074eda7e70ffcc2617b"
|
||||
dependencies:
|
||||
hoist-non-react-statics "^3.2.1"
|
||||
|
||||
"@loadable/server@5.5.0":
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@loadable/server/-/server-5.5.0.tgz#b5fb14826db5d4f4e603c47c1232c80f2081251b"
|
||||
dependencies:
|
||||
lodash "^4.17.11"
|
||||
|
||||
"@loadable/webpack-plugin@5.5.0":
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@loadable/webpack-plugin/-/webpack-plugin-5.5.0.tgz#4d44812d3cc106b6278570fa4c8ebdeb07cc3549"
|
||||
|
||||
"@mrmlnc/readdir-enhanced@^2.2.1":
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde"
|
||||
|
@ -1975,6 +1997,12 @@
|
|||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/loadable__server@5.2.0":
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/loadable__server/-/loadable__server-5.2.0.tgz#32a236fc012053d071fd201fcfc9f87a6c6c4fc5"
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/lodash@^4.14.112":
|
||||
version "4.14.116"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.116.tgz#5ccf215653e3e8c786a58390751033a9adca0eb9"
|
||||
|
@ -2052,13 +2080,20 @@
|
|||
"@types/react" "*"
|
||||
"@types/react-router" "*"
|
||||
|
||||
"@types/react-router@*", "@types/react-router@^4.0.31":
|
||||
"@types/react-router@*":
|
||||
version "4.0.31"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-4.0.31.tgz#416bac49d746800810886c7b8582a622ed9604fc"
|
||||
dependencies:
|
||||
"@types/history" "*"
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-router@4.4.3":
|
||||
version "4.4.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-4.4.3.tgz#ea68b4021cb576866f83365b2201411537423d50"
|
||||
dependencies:
|
||||
"@types/history" "*"
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react@*":
|
||||
version "16.4.11"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.4.11.tgz#330f3d864300f71150dc2d125e48644c098f8770"
|
||||
|
@ -4717,7 +4752,7 @@ create-react-context@0.2.2:
|
|||
fbjs "^0.8.0"
|
||||
gud "^1.0.0"
|
||||
|
||||
create-react-context@0.2.3:
|
||||
create-react-context@0.2.3, create-react-context@^0.2.2:
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/create-react-context/-/create-react-context-0.2.3.tgz#9ec140a6914a22ef04b8b09b7771de89567cb6f3"
|
||||
dependencies:
|
||||
|
@ -7236,6 +7271,17 @@ history@4.7.2, history@^4.7.2:
|
|||
value-equal "^0.4.0"
|
||||
warning "^3.0.0"
|
||||
|
||||
history@^4.8.0-beta.0:
|
||||
version "4.8.0-beta.0"
|
||||
resolved "https://registry.yarnpkg.com/history/-/history-4.8.0-beta.0.tgz#8b48c1354ac290341c0d73dd33c763bd140531f4"
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.1.2"
|
||||
loose-envify "^1.2.0"
|
||||
resolve-pathname "^2.2.0"
|
||||
tiny-invariant "^1.0.2"
|
||||
tiny-warning "^1.0.0"
|
||||
value-equal "^0.4.0"
|
||||
|
||||
hmac-drbg@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
|
||||
|
@ -9273,7 +9319,7 @@ lodash.without@~4.4.0:
|
|||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.without/-/lodash.without-4.4.0.tgz#3cd4574a00b67bae373a94b748772640507b7aac"
|
||||
|
||||
"lodash@>=3.5 <5", lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.2, lodash@^4.3.0:
|
||||
"lodash@>=3.5 <5", lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.11, lodash@^4.17.2, lodash@^4.3.0:
|
||||
version "4.17.11"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
|
||||
|
||||
|
@ -12401,6 +12447,18 @@ react-router-dom@4.3.1, react-router-dom@^4.3.1:
|
|||
react-router "^4.3.1"
|
||||
warning "^4.0.1"
|
||||
|
||||
react-router-dom@4.4.0-beta.6:
|
||||
version "4.4.0-beta.6"
|
||||
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-4.4.0-beta.6.tgz#0bec50c8a4276a555b5f1159bb94e7b6fbb73699"
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.1.2"
|
||||
history "^4.8.0-beta.0"
|
||||
loose-envify "^1.3.1"
|
||||
prop-types "^15.6.2"
|
||||
react-router "^4.4.0-beta.6"
|
||||
tiny-invariant "^1.0.2"
|
||||
tiny-warning "^1.0.0"
|
||||
|
||||
react-router@4.3.1, react-router@^4.3.1:
|
||||
version "4.3.1"
|
||||
resolved "https://registry.yarnpkg.com/react-router/-/react-router-4.3.1.tgz#aada4aef14c809cb2e686b05cee4742234506c4e"
|
||||
|
@ -12413,6 +12471,21 @@ react-router@4.3.1, react-router@^4.3.1:
|
|||
prop-types "^15.6.1"
|
||||
warning "^4.0.1"
|
||||
|
||||
react-router@4.4.0-beta.6, react-router@^4.4.0-beta.6:
|
||||
version "4.4.0-beta.6"
|
||||
resolved "https://registry.yarnpkg.com/react-router/-/react-router-4.4.0-beta.6.tgz#37e1d9ce2be93df397cc1feb1dcd6460ea0b236b"
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.1.2"
|
||||
create-react-context "^0.2.2"
|
||||
history "^4.8.0-beta.0"
|
||||
hoist-non-react-statics "^2.5.0"
|
||||
loose-envify "^1.3.1"
|
||||
path-to-regexp "^1.7.0"
|
||||
prop-types "^15.6.2"
|
||||
react-is "^16.5.2"
|
||||
tiny-invariant "^1.0.2"
|
||||
tiny-warning "^1.0.0"
|
||||
|
||||
react-side-effect@^1.0.2, react-side-effect@^1.1.0:
|
||||
version "1.1.5"
|
||||
resolved "https://registry.yarnpkg.com/react-side-effect/-/react-side-effect-1.1.5.tgz#f26059e50ed9c626d91d661b9f3c8bb38cd0ff2d"
|
||||
|
@ -14339,10 +14412,18 @@ timsort@^0.3.0:
|
|||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
|
||||
|
||||
tiny-invariant@^1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.0.3.tgz#91efaaa0269ccb6271f0296aeedb05fc3e067b7a"
|
||||
|
||||
tiny-relative-date@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/tiny-relative-date/-/tiny-relative-date-1.3.0.tgz#fa08aad501ed730f31cc043181d995c39a935e07"
|
||||
|
||||
tiny-warning@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.2.tgz#1dfae771ee1a04396bdfde27a3adcebc6b648b28"
|
||||
|
||||
tinycolor2@^1.1.2, tinycolor2@^1.4.1:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.1.tgz#f4fad333447bc0b07d4dc8e9209d8f39a8ac77e8"
|
||||
|
|
Loading…
Reference in New Issue