Configure code splitting ⚡️⚡️⚡️ (#7017)
This commit is contained in:
Родитель
26b8dc6b13
Коммит
c64b638d46
3
.babelrc
3
.babelrc
|
@ -11,7 +11,8 @@
|
|||
],
|
||||
"plugins": [
|
||||
"@babel/plugin-proposal-class-properties",
|
||||
"@babel/plugin-syntax-dynamic-import"
|
||||
"@babel/plugin-syntax-dynamic-import",
|
||||
"@loadable/babel-plugin"
|
||||
],
|
||||
"env": {
|
||||
"test": {
|
||||
|
|
|
@ -24,6 +24,10 @@ module.exports = {
|
|||
staticHost,
|
||||
'https://www.google-analytics.com',
|
||||
],
|
||||
// This is needed because `prefetchSrc` isn't supported by FF yet.
|
||||
// See: https://bugzilla.mozilla.org/show_bug.cgi?id=1457204
|
||||
defaultSrc: [amoProdCDN],
|
||||
prefetchSrc: [amoProdCDN],
|
||||
},
|
||||
},
|
||||
enableTrailingSlashesMiddleware: true,
|
||||
|
|
|
@ -18,10 +18,17 @@ if (appName && !validAppNames.includes(appName)) {
|
|||
`App "${appName}" is not enabled; valid app names: ${validAppNames}`);
|
||||
}
|
||||
|
||||
const basePath = path.resolve(__dirname, '../');
|
||||
const distPath = path.join(basePath, 'dist');
|
||||
const loadableStatsFilename = 'loadable-stats.json';
|
||||
|
||||
module.exports = {
|
||||
appName,
|
||||
basePath: path.resolve(__dirname, '../'),
|
||||
basePath,
|
||||
|
||||
// This is needed for code-splitting.
|
||||
loadableStatsFilename,
|
||||
loadableStatsFile: path.join(distPath, loadableStatsFilename),
|
||||
|
||||
// The base URL of the site (for SEO purpose).
|
||||
baseURL: baseUrlProd,
|
||||
|
|
|
@ -24,6 +24,10 @@ module.exports = {
|
|||
staticHost,
|
||||
'https://www.google-analytics.com',
|
||||
],
|
||||
// This is needed because `prefetchSrc` isn't supported by FF yet.
|
||||
// See: https://bugzilla.mozilla.org/show_bug.cgi?id=1457204
|
||||
defaultSrc: [amoDevCDN],
|
||||
prefetchSrc: [amoDevCDN],
|
||||
},
|
||||
},
|
||||
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
const webpackServerHost = process.env.WEBPACK_SERVER_HOST || '127.0.0.1';
|
||||
const webpackServerPort = 3001;
|
||||
const webpackHost = `${webpackServerHost}:${webpackServerPort}`;
|
||||
|
||||
module.exports = {
|
||||
apiHost: 'http://localhost:3000',
|
||||
|
||||
|
@ -20,4 +24,13 @@ module.exports = {
|
|||
enableFeatureHomeHeroGuides: true,
|
||||
|
||||
enableFeatureStaticThemesForAndroid: false,
|
||||
|
||||
CSP: {
|
||||
directives: {
|
||||
// This is needed because `prefetchSrc` isn't supported by FF yet.
|
||||
// See: https://bugzilla.mozilla.org/show_bug.cgi?id=1457204
|
||||
defaultSrc: [webpackHost],
|
||||
prefetchSrc: [webpackHost],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -31,6 +31,8 @@ module.exports = {
|
|||
amoDevCDN,
|
||||
sentryHost,
|
||||
webpackHost,
|
||||
// This is needed for pino-devtools.
|
||||
`${webpackServerHost}:3010`,
|
||||
],
|
||||
fontSrc: [
|
||||
webpackHost,
|
||||
|
|
|
@ -24,6 +24,10 @@ module.exports = {
|
|||
staticHost,
|
||||
'https://www.google-analytics.com',
|
||||
],
|
||||
// This is needed because `prefetchSrc` isn't supported by FF yet.
|
||||
// See: https://bugzilla.mozilla.org/show_bug.cgi?id=1457204
|
||||
defaultSrc: [amoStageCDN],
|
||||
prefetchSrc: [amoStageCDN],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
import path from 'path';
|
||||
|
||||
const fixturesPath = path.join(__dirname, '..', 'tests', '__fixtures__');
|
||||
|
||||
// Put any test configuration overrides here.
|
||||
module.exports = {
|
||||
appName: 'test-app-set-from-config',
|
||||
|
@ -9,4 +13,7 @@ module.exports = {
|
|||
// We do not enable the request ID feature because httpContext eats all the
|
||||
// memory we have (and more...).
|
||||
enableRequestID: false,
|
||||
|
||||
// We use a fake/incomplete file for the test suite.
|
||||
loadableStatsFile: path.join(fixturesPath, 'loadable-stats.json'),
|
||||
};
|
||||
|
|
|
@ -204,6 +204,8 @@
|
|||
"dependencies": {
|
||||
"@babel/polyfill": "7.0.0",
|
||||
"base62": "2.0.0",
|
||||
"@loadable/component": "5.1.2",
|
||||
"@loadable/server": "5.2.0",
|
||||
"base64url": "3.0.1",
|
||||
"better-npm-run": "0.1.1",
|
||||
"chokidar": "2.0.4",
|
||||
|
@ -284,6 +286,8 @@
|
|||
"@babel/preset-flow": "^7.0.0",
|
||||
"@babel/preset-react": "^7.0.0",
|
||||
"@babel/register": "^7.0.0",
|
||||
"@loadable/babel-plugin": "^5.0.1",
|
||||
"@loadable/webpack-plugin": "^5.2.1",
|
||||
"@storybook/addon-info": "^4.0.8",
|
||||
"@storybook/addon-options": "^4.0.8",
|
||||
"@storybook/addons": "^4.0.8",
|
||||
|
@ -361,7 +365,6 @@
|
|||
"webpack": "^4.26.0",
|
||||
"webpack-cli": "^3.1.2",
|
||||
"webpack-dev-middleware": "^3.4.0",
|
||||
"webpack-dev-server": "^3.1.10",
|
||||
"webpack-hot-middleware": "^2.24.3",
|
||||
"webpack-subresource-integrity": "^1.3.0"
|
||||
},
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
import config from 'config';
|
||||
import * as React from 'react';
|
||||
import { Route, Switch } from 'react-router-dom';
|
||||
import loadable from '@loadable/component';
|
||||
|
||||
import About from 'amo/pages/StaticPages/About';
|
||||
import Addon from 'amo/pages/Addon';
|
||||
import AddonInfo, {
|
||||
ADDON_INFO_TYPE_CUSTOM_LICENSE,
|
||||
|
@ -23,7 +23,6 @@ import LanguageTools from 'amo/pages/LanguageTools';
|
|||
import SearchTools from 'amo/pages/SearchTools';
|
||||
import NotAuthorized from 'amo/components/ErrorPage/NotAuthorized';
|
||||
import NotFound from 'amo/components/ErrorPage/NotFound';
|
||||
import ReviewGuide from 'amo/pages/StaticPages/ReviewGuide';
|
||||
import SearchPage from 'amo/pages/SearchPage';
|
||||
import ServerError from 'amo/components/ErrorPage/ServerError';
|
||||
import UserProfile from 'amo/pages/UserProfile';
|
||||
|
@ -33,6 +32,25 @@ import SimulateClientError from 'core/pages/error-simulation/SimulateClientError
|
|||
import SimulateSyncError from 'core/pages/error-simulation/SimulateSyncError';
|
||||
import type { ConfigType } from 'core/types/config';
|
||||
|
||||
// About `loadable()` and code-splitting:
|
||||
//
|
||||
// 1. Set `webpackChunkName` to the name of the page component
|
||||
// 2. Set `webpackPreload: true` as already done below
|
||||
//
|
||||
// Important: We do not use `webpackPrefetch: true` to prevent webpack to
|
||||
// inject anything in the HTML returned by the server. Webpack does not inject
|
||||
// anything when `webpackPreload` is set to `true` but '@loadable/server'
|
||||
// gathers these chunks and we render the appropriate tags in the HTML in
|
||||
// `ServerHtml`.
|
||||
|
||||
const About = loadable(() =>
|
||||
import(/* webpackPreload: true, webpackChunkName: "About" */ '../../pages/StaticPages/About'),
|
||||
);
|
||||
|
||||
const ReviewGuide = loadable(() =>
|
||||
import(/* webpackPreload: true, webpackChunkName: "ReviewGuide" */ '../../pages/StaticPages/ReviewGuide'),
|
||||
);
|
||||
|
||||
type Props = {|
|
||||
_config?: ConfigType,
|
||||
|};
|
||||
|
|
|
@ -7,6 +7,7 @@ import { createBrowserHistory } from 'history';
|
|||
import RavenJs from 'raven-js';
|
||||
import * as React from 'react';
|
||||
import { render } from 'react-dom';
|
||||
import { loadableReady } from '@loadable/component';
|
||||
|
||||
import Root from 'core/components/Root';
|
||||
import { langToLocale, makeI18n, sanitizeLanguage } from 'core/i18n/utils';
|
||||
|
@ -89,12 +90,14 @@ export default async function createClient(
|
|||
const i18n = makeI18n(i18nData, lang);
|
||||
|
||||
const renderApp = (App) => {
|
||||
render(
|
||||
<Root history={history} i18n={i18n} store={store}>
|
||||
<App />
|
||||
</Root>,
|
||||
document.getElementById('react-view'),
|
||||
);
|
||||
return loadableReady(() => {
|
||||
render(
|
||||
<Root history={history} i18n={i18n} store={store}>
|
||||
<App />
|
||||
</Root>,
|
||||
document.getElementById('react-view'),
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
return { history, renderApp, store };
|
||||
|
|
|
@ -17,6 +17,7 @@ export default class ServerHtml extends Component {
|
|||
appName: PropTypes.string.isRequired,
|
||||
appState: PropTypes.object.isRequired,
|
||||
assets: PropTypes.object.isRequired,
|
||||
chunkExtractor: PropTypes.object.isRequired,
|
||||
component: PropTypes.element.isRequired,
|
||||
htmlDir: PropTypes.string,
|
||||
htmlLang: PropTypes.string,
|
||||
|
@ -33,21 +34,34 @@ export default class ServerHtml extends Component {
|
|||
_config: config,
|
||||
};
|
||||
|
||||
getStatic({ filePath, type, index }) {
|
||||
const { includeSri, sriData, appName } = this.props;
|
||||
const leafName = filePath.split('/').pop();
|
||||
getSriProps(assetName) {
|
||||
const { includeSri, sriData } = this.props;
|
||||
|
||||
let sriProps = {};
|
||||
if (!includeSri) {
|
||||
return sriProps;
|
||||
}
|
||||
|
||||
sriProps = {
|
||||
integrity: sriData[assetName],
|
||||
crossOrigin: 'anonymous',
|
||||
};
|
||||
|
||||
if (!sriProps.integrity) {
|
||||
throw new Error(`SRI Data is missing for "${assetName}"`);
|
||||
}
|
||||
|
||||
return sriProps;
|
||||
}
|
||||
|
||||
getStatic({ filePath, type, index }) {
|
||||
const { appName } = this.props;
|
||||
const leafName = filePath.split('/').pop();
|
||||
|
||||
// Only output files for the current app.
|
||||
if (leafName.startsWith(appName) && !JS_CHUNK_EXCLUDES.test(leafName)) {
|
||||
if (includeSri) {
|
||||
sriProps = {
|
||||
integrity: sriData[leafName],
|
||||
crossOrigin: 'anonymous',
|
||||
};
|
||||
if (!sriProps.integrity) {
|
||||
throw new Error(`SRI Data is missing for ${leafName}`);
|
||||
}
|
||||
}
|
||||
const sriProps = this.getSriProps(leafName);
|
||||
|
||||
switch (type) {
|
||||
case 'css':
|
||||
return (
|
||||
|
@ -99,8 +113,93 @@ export default class ServerHtml extends Component {
|
|||
)}`;
|
||||
}
|
||||
|
||||
renderStyles() {
|
||||
const { _config, chunkExtractor } = this.props;
|
||||
|
||||
return chunkExtractor
|
||||
.getMainAssets('style')
|
||||
.filter(
|
||||
// We render the main bundle with `getScript()`, so we skip it here.
|
||||
(asset) => !_config.get('validAppNames').includes(asset.chunk),
|
||||
)
|
||||
.map((asset) => {
|
||||
const sriProps = this.getSriProps(asset.filename);
|
||||
|
||||
return (
|
||||
<link
|
||||
data-chunk={asset.chunk}
|
||||
href={asset.url}
|
||||
key={asset.url}
|
||||
rel="stylesheet"
|
||||
type="text/css"
|
||||
{...sriProps}
|
||||
/>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
renderPreLinks() {
|
||||
const { chunkExtractor } = this.props;
|
||||
|
||||
return (
|
||||
chunkExtractor
|
||||
.getPreAssets()
|
||||
// We want to retrieve the bundles with "webpackPreload: true" only, and
|
||||
// not the main bundle (amo or disco).
|
||||
.filter((asset) => asset.type === 'childAsset')
|
||||
// We return both "preload" and "prefetch" links to maximize browser
|
||||
// support, even though both links don't have the same goal.
|
||||
.map((asset) => [
|
||||
<link
|
||||
as={asset.scriptType}
|
||||
data-parent-chunk={asset.chunk}
|
||||
href={asset.url}
|
||||
key={`preload-${asset.url}`}
|
||||
rel="preload"
|
||||
/>,
|
||||
<link
|
||||
as={asset.scriptType}
|
||||
data-parent-chunk={asset.chunk}
|
||||
href={asset.url}
|
||||
key={`prefetch-${asset.url}`}
|
||||
rel="prefetch"
|
||||
/>,
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
renderAsyncScripts() {
|
||||
const { _config, chunkExtractor } = this.props;
|
||||
|
||||
return chunkExtractor
|
||||
.getMainAssets('script')
|
||||
.filter(
|
||||
// We render the main bundle with `getScript()`, so we skip it here.
|
||||
(asset) => !_config.get('validAppNames').includes(asset.chunk),
|
||||
)
|
||||
.map((asset) => {
|
||||
const sriProps = this.getSriProps(asset.filename);
|
||||
|
||||
return (
|
||||
<script
|
||||
async
|
||||
data-chunk={asset.chunk}
|
||||
key={asset.url}
|
||||
src={asset.url}
|
||||
{...sriProps}
|
||||
/>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { appState, component, htmlLang, htmlDir } = this.props;
|
||||
const {
|
||||
appState,
|
||||
chunkExtractor,
|
||||
component,
|
||||
htmlDir,
|
||||
htmlLang,
|
||||
} = this.props;
|
||||
|
||||
// This must happen before Helmet.rewind() see
|
||||
// https://github.com/nfl/react-helmet#server-usage for more info.
|
||||
|
@ -110,24 +209,34 @@ export default class ServerHtml extends Component {
|
|||
return (
|
||||
<html lang={htmlLang} dir={htmlDir}>
|
||||
<head>
|
||||
{head.title.toComponent()}
|
||||
|
||||
<meta charSet="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
{head.meta.toComponent()}
|
||||
|
||||
<link rel="shortcut icon" href={this.getFaviconLink()} />
|
||||
{head.link.toComponent()}
|
||||
{head.title.toComponent()}
|
||||
{head.meta.toComponent()}
|
||||
{head.script.toComponent()}
|
||||
{this.renderPreLinks()}
|
||||
|
||||
{this.getStyle()}
|
||||
{this.renderStyles()}
|
||||
|
||||
{head.script.toComponent()}
|
||||
</head>
|
||||
<body>
|
||||
<div id="react-view" dangerouslySetInnerHTML={{ __html: content }} />
|
||||
|
||||
<script
|
||||
dangerouslySetInnerHTML={{ __html: serialize(appState) }}
|
||||
type="application/json"
|
||||
id="redux-store-state"
|
||||
/>
|
||||
{chunkExtractor.getRequiredChunksScriptElement()}
|
||||
|
||||
{this.getAnalytics()}
|
||||
{this.getScript()}
|
||||
{this.renderAsyncScripts()}
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
|
|
|
@ -16,6 +16,7 @@ import NestedStatus from 'react-nested-status';
|
|||
import { END } from 'redux-saga';
|
||||
import cookiesMiddleware from 'universal-cookie-express';
|
||||
import WebpackIsomorphicTools from 'webpack-isomorphic-tools';
|
||||
import { ChunkExtractor, ChunkExtractorManager } from '@loadable/server';
|
||||
|
||||
import log from 'core/logger';
|
||||
import { createApiError } from 'core/api';
|
||||
|
@ -61,6 +62,12 @@ export function getPageProps({ store, req, res, config }) {
|
|||
)
|
||||
: {};
|
||||
|
||||
// Code-splitting.
|
||||
const chunkExtractor = new ChunkExtractor({
|
||||
stats: JSON.parse(fs.readFileSync(config.get('loadableStatsFile'))),
|
||||
entrypoints: [appName],
|
||||
});
|
||||
|
||||
// Check the lang supplied by res.locals.lang for validity
|
||||
// or fall-back to the default.
|
||||
const lang = isValidLang(res.locals.lang)
|
||||
|
@ -84,6 +91,7 @@ export function getPageProps({ store, req, res, config }) {
|
|||
return {
|
||||
appName,
|
||||
assets: webpackIsomorphicTools.assets(),
|
||||
chunkExtractor,
|
||||
htmlLang: lang,
|
||||
htmlDir: dir,
|
||||
includeSri: isDeployed,
|
||||
|
@ -364,14 +372,16 @@ function baseServer(
|
|||
|
||||
const props = {
|
||||
component: (
|
||||
<Root
|
||||
cookies={req.universalCookies}
|
||||
history={history}
|
||||
i18n={i18n}
|
||||
store={store}
|
||||
>
|
||||
<App />
|
||||
</Root>
|
||||
<ChunkExtractorManager extractor={pageProps.chunkExtractor}>
|
||||
<Root
|
||||
cookies={req.universalCookies}
|
||||
history={history}
|
||||
i18n={i18n}
|
||||
store={store}
|
||||
>
|
||||
<App />
|
||||
</Root>
|
||||
</ChunkExtractorManager>
|
||||
),
|
||||
};
|
||||
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
// This is a webpack plugin to expose the data generated by SriPlugin.
|
||||
// See webpack.prod.config.babel.js
|
||||
import fs from 'fs';
|
||||
|
||||
import { oneLine } from 'common-tags';
|
||||
import config from 'config';
|
||||
|
||||
// This is a webpack plugin to expose the data generated by SriPlugin.
|
||||
// See webpack.prod.config.babel.js
|
||||
export default class SriDataPlugin {
|
||||
constructor({ saveAs } = {}) {
|
||||
constructor({ saveAs, _config = config } = {}) {
|
||||
this.config = _config;
|
||||
|
||||
if (!saveAs) {
|
||||
throw new Error('The saveAs parameter cannot be empty');
|
||||
}
|
||||
|
@ -13,12 +16,17 @@ export default class SriDataPlugin {
|
|||
}
|
||||
|
||||
apply(compiler) {
|
||||
const loadableStatsFilename = this.config.get('loadableStatsFilename');
|
||||
|
||||
compiler.plugin('done', (stats) => {
|
||||
const sriStats = {};
|
||||
try {
|
||||
Object.keys(stats.compilation.assets).forEach((baseName) => {
|
||||
const asset = stats.compilation.assets[baseName];
|
||||
if (!asset.integrity) {
|
||||
// The `loadable-stats.json` is created by the `LoadablePlugin`
|
||||
// (webpack). No need to create SRI for it, it is only used by the
|
||||
// server.
|
||||
if (baseName !== loadableStatsFilename && !asset.integrity) {
|
||||
throw new Error(
|
||||
oneLine`The integrity property is falsey for
|
||||
asset ${baseName}; Is the webpack-subresource-integrity
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"namedChunkGroups": {
|
||||
"test-app-set-from-config": {
|
||||
"assets": [],
|
||||
"childAssets": {
|
||||
"preload": []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,15 +21,26 @@ describe(__filename, () => {
|
|||
Helmet.canUseDOM = _helmetCanUseDOM;
|
||||
});
|
||||
|
||||
const createFakeChunkExtractor = (props = {}) => {
|
||||
return {
|
||||
getLinkElements: sinon.stub(),
|
||||
getMainAssets: sinon.stub().returns([]),
|
||||
getPreAssets: sinon.stub().returns([]),
|
||||
getRequiredChunksScriptElement: sinon.stub(),
|
||||
...props,
|
||||
};
|
||||
};
|
||||
|
||||
function render(opts = {}) {
|
||||
const pageProps = {
|
||||
appName: 'disco',
|
||||
appState: { appStateExample: { things: 'lots-of-things' } },
|
||||
component: <FakeApp />,
|
||||
assets: fakeAssets,
|
||||
chunkExtractor: createFakeChunkExtractor(),
|
||||
component: <FakeApp />,
|
||||
includeSri: true,
|
||||
trackingEnabled: false,
|
||||
sriData: fakeSRIData,
|
||||
trackingEnabled: false,
|
||||
...opts,
|
||||
};
|
||||
return shallow(<ServerHtml {...pageProps} />);
|
||||
|
@ -182,4 +193,178 @@ describe(__filename, () => {
|
|||
// This is defined in the `FakeApp` component.
|
||||
expect(root.find('link[rel="canonical"]')).toHaveLength(1);
|
||||
});
|
||||
|
||||
describe('renderStyles()', () => {
|
||||
it('renders a "link" tag for the main "style" asset', () => {
|
||||
const asset = { chunk: 'foo', url: '/foo.css' };
|
||||
const chunkExtractor = createFakeChunkExtractor({
|
||||
getMainAssets: () => [asset],
|
||||
});
|
||||
|
||||
const root = render({ chunkExtractor, includeSri: false });
|
||||
|
||||
expect(root.find('link[data-chunk]')).toHaveLength(1);
|
||||
|
||||
const link = root.find(`link[data-chunk="${asset.chunk}"]`);
|
||||
expect(link).toHaveProp('href', asset.url);
|
||||
expect(link).toHaveProp('rel', 'stylesheet');
|
||||
});
|
||||
|
||||
it('excludes the main bundle', () => {
|
||||
const _config = getFakeConfig({ validAppNames: ['main'] });
|
||||
|
||||
const fooAsset = { chunk: 'foo', url: '/foo.css' };
|
||||
const mainAsset = { chunk: 'main', url: '/main.css' };
|
||||
const chunkExtractor = createFakeChunkExtractor({
|
||||
getMainAssets: () => [fooAsset, mainAsset],
|
||||
});
|
||||
|
||||
const root = render({ _config, chunkExtractor, includeSri: false });
|
||||
|
||||
expect(root.find('link[data-chunk]')).toHaveLength(1);
|
||||
expect(root.find(`link[data-chunk="${mainAsset.chunk}"]`)).toHaveLength(
|
||||
0,
|
||||
);
|
||||
});
|
||||
|
||||
it('throws an error when SRI data are not found', () => {
|
||||
const asset = { chunk: 'foo', url: '/foo.css', filename: 'foo.css' };
|
||||
const chunkExtractor = createFakeChunkExtractor({
|
||||
getMainAssets: () => [asset],
|
||||
});
|
||||
const sriData = {
|
||||
...fakeSRIData,
|
||||
[asset.filename]: undefined,
|
||||
};
|
||||
|
||||
expect(() => {
|
||||
render({ chunkExtractor, includeSri: true, sriData });
|
||||
}).toThrow(`SRI Data is missing for "${asset.filename}"`);
|
||||
});
|
||||
|
||||
it('adds SRI props when `includeSri` prop is set to `true`', () => {
|
||||
const asset = { chunk: 'foo', url: '/foo.css', filename: 'foo.css' };
|
||||
const chunkExtractor = createFakeChunkExtractor({
|
||||
getMainAssets: () => [asset],
|
||||
});
|
||||
const sriData = {
|
||||
...fakeSRIData,
|
||||
[asset.filename]: 'sha512-something-something',
|
||||
};
|
||||
|
||||
const root = render({ chunkExtractor, includeSri: true, sriData });
|
||||
|
||||
const link = root.find(`link[data-chunk="${asset.chunk}"]`);
|
||||
expect(link).toHaveProp('crossOrigin', 'anonymous');
|
||||
expect(link).toHaveProp('integrity', sriData[asset.filename]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('renderPreLinks', () => {
|
||||
it('returns both "prefetch" and "preload" links for a given asset', () => {
|
||||
const asset = {
|
||||
chunk: 'foo',
|
||||
url: '/foo.js',
|
||||
type: 'childAsset',
|
||||
scriptType: 'script',
|
||||
};
|
||||
const chunkExtractor = createFakeChunkExtractor({
|
||||
getPreAssets: () => [asset],
|
||||
});
|
||||
|
||||
const root = render({ chunkExtractor });
|
||||
|
||||
expect(root.find('link[data-parent-chunk]')).toHaveLength(2);
|
||||
|
||||
const preloadLink = root.find('link[data-parent-chunk]').at(0);
|
||||
expect(preloadLink).toHaveProp('as', asset.scriptType);
|
||||
expect(preloadLink).toHaveProp('data-parent-chunk', asset.chunk);
|
||||
expect(preloadLink).toHaveProp('href', asset.url);
|
||||
expect(preloadLink).toHaveProp('rel', 'preload');
|
||||
|
||||
const prefetchLink = root.find('link[data-parent-chunk]').at(1);
|
||||
expect(prefetchLink).toHaveProp('as', asset.scriptType);
|
||||
expect(prefetchLink).toHaveProp('data-parent-chunk', asset.chunk);
|
||||
expect(prefetchLink).toHaveProp('href', asset.url);
|
||||
expect(prefetchLink).toHaveProp('rel', 'prefetch');
|
||||
});
|
||||
});
|
||||
|
||||
describe('renderAsyncScripts()', () => {
|
||||
it('renders a "script" tag for the main "script" asset', () => {
|
||||
const asset = { chunk: 'foo', url: '/foo.js' };
|
||||
const chunkExtractor = createFakeChunkExtractor({
|
||||
getMainAssets: () => [asset],
|
||||
});
|
||||
|
||||
const root = render({ chunkExtractor, includeSri: false });
|
||||
|
||||
expect(root.find('link[data-chunk]')).toHaveLength(1);
|
||||
|
||||
const link = root.find(`script[data-chunk="${asset.chunk}"]`);
|
||||
expect(link).toHaveProp('async', true);
|
||||
expect(link).toHaveProp('src', asset.url);
|
||||
});
|
||||
|
||||
it('excludes the main bundle', () => {
|
||||
const _config = getFakeConfig({ validAppNames: ['main'] });
|
||||
|
||||
const fooAsset = { chunk: 'foo', url: '/foo.js' };
|
||||
const mainAsset = { chunk: 'main', url: '/main.js' };
|
||||
const chunkExtractor = createFakeChunkExtractor({
|
||||
getMainAssets: () => [fooAsset, mainAsset],
|
||||
});
|
||||
|
||||
const root = render({ _config, chunkExtractor, includeSri: false });
|
||||
|
||||
expect(root.find('script[data-chunk]')).toHaveLength(1);
|
||||
expect(root.find(`script[data-chunk="${mainAsset.chunk}"]`)).toHaveLength(
|
||||
0,
|
||||
);
|
||||
});
|
||||
|
||||
it('throws an error when SRI data are not found', () => {
|
||||
const asset = { chunk: 'foo', url: '/foo.js', filename: 'foo.js' };
|
||||
const chunkExtractor = createFakeChunkExtractor({
|
||||
getMainAssets: () => [asset],
|
||||
});
|
||||
const sriData = {
|
||||
...fakeSRIData,
|
||||
[asset.filename]: undefined,
|
||||
};
|
||||
|
||||
expect(() => {
|
||||
render({ chunkExtractor, includeSri: true, sriData });
|
||||
}).toThrow(`SRI Data is missing for "${asset.filename}"`);
|
||||
});
|
||||
|
||||
it('adds SRI props when `includeSri` prop is set to `true`', () => {
|
||||
const asset = { chunk: 'foo', url: '/foo.js', filename: 'foo.js' };
|
||||
const chunkExtractor = createFakeChunkExtractor({
|
||||
getMainAssets: () => [asset],
|
||||
});
|
||||
const sriData = {
|
||||
...fakeSRIData,
|
||||
[asset.filename]: 'sha512-something-something',
|
||||
};
|
||||
|
||||
const root = render({ chunkExtractor, includeSri: true, sriData });
|
||||
|
||||
const link = root.find(`script[data-chunk="${asset.chunk}"]`);
|
||||
expect(link).toHaveProp('crossOrigin', 'anonymous');
|
||||
expect(link).toHaveProp('integrity', sriData[asset.filename]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('code-splitting', () => {
|
||||
it('renders the required chunks script element', () => {
|
||||
const chunkExtractor = createFakeChunkExtractor();
|
||||
|
||||
sinon.assert.notCalled(chunkExtractor.getRequiredChunksScriptElement);
|
||||
|
||||
render({ chunkExtractor });
|
||||
|
||||
sinon.assert.calledOnce(chunkExtractor.getRequiredChunksScriptElement);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -10,6 +10,7 @@ import SriPlugin from 'webpack-subresource-integrity';
|
|||
import tmp from 'tmp';
|
||||
|
||||
import SriDataPlugin from 'core/server/sriDataPlugin';
|
||||
import { getFakeConfig } from 'tests/unit/helpers';
|
||||
|
||||
describe(__filename, () => {
|
||||
let distDir;
|
||||
|
@ -110,6 +111,38 @@ describe(__filename, () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('skips the integrity check for "loadable-stats.json"', async () => {
|
||||
const loadableStatsFilename = 'some-loadable-stats-file.json';
|
||||
|
||||
const _config = getFakeConfig({ loadableStatsFilename });
|
||||
const sriFile = path.join(distDir, 'sri.json');
|
||||
const plugin = new SriDataPlugin({ _config, saveAs: sriFile });
|
||||
|
||||
// This is a quick-hack to retrieve the hook in the plugin.
|
||||
const compiler = {
|
||||
hook: null,
|
||||
plugin(event, hook) {
|
||||
this.hook = hook;
|
||||
},
|
||||
};
|
||||
plugin.apply(compiler);
|
||||
|
||||
const stats = {
|
||||
compilation: {
|
||||
assets: {
|
||||
// No `integrity` property in this asset.
|
||||
[loadableStatsFilename]: {},
|
||||
},
|
||||
errors: [],
|
||||
},
|
||||
};
|
||||
|
||||
// Execute the hook.
|
||||
compiler.hook(stats);
|
||||
|
||||
expect(stats.compilation.errors).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('requires a saveAs parameter', () => {
|
||||
expect(() => new SriDataPlugin()).toThrowError(
|
||||
/saveAs parameter cannot be empty/,
|
|
@ -4,6 +4,7 @@ import CircularDependencyPlugin from 'circular-dependency-plugin';
|
|||
import config from 'config';
|
||||
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
|
||||
import webpack from 'webpack';
|
||||
import LoadablePlugin from '@loadable/webpack-plugin';
|
||||
|
||||
import 'core/polyfill';
|
||||
import { getClientConfig } from 'core/utils';
|
||||
|
@ -117,6 +118,10 @@ export function getPlugins({ excludeOtherAppLocales = true } = {}) {
|
|||
const clientConfig = getClientConfig(config);
|
||||
|
||||
const plugins = [
|
||||
// We need this file to be written on disk so that our server code can read
|
||||
// it. In development mode, webpack usually serves the file from memory but
|
||||
// that's not what we want for this file.
|
||||
new LoadablePlugin({ writeToDisk: true }),
|
||||
new webpack.DefinePlugin({
|
||||
CLIENT_CONFIG: JSON.stringify(clientConfig),
|
||||
'process.env.NODE_ENV': JSON.stringify('production'),
|
||||
|
|
|
@ -54,6 +54,7 @@ export default Object.assign({}, webpackConfig, {
|
|||
path: assetsPath,
|
||||
filename: '[name]-[hash].js',
|
||||
chunkFilename: '[name]-[hash].js',
|
||||
// We need to remove the protocol because of `yarn amo:dev-https`.
|
||||
publicPath: `//${webpackHost}:${webpackPort}/`,
|
||||
}),
|
||||
module: {
|
||||
|
|
|
@ -68,7 +68,7 @@ export default {
|
|||
...getPlugins(),
|
||||
new MiniCssExtractPlugin({
|
||||
filename: '[name]-[hash].css',
|
||||
chunkFilename: '[id]-[hash].css',
|
||||
chunkFilename: '[name]-[hash].css',
|
||||
}),
|
||||
new WebpackIsomorphicToolsPlugin(webpackIsomorphicToolsConfig),
|
||||
new SriPlugin({ hashFuncNames: ['sha512'] }),
|
||||
|
|
441
yarn.lock
441
yarn.lock
|
@ -832,6 +832,32 @@
|
|||
resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.1.3.tgz#b700d97385fa91affed60c71dfd51c67e9dad762"
|
||||
integrity sha512-QsYGKdhhuDFNq7bjm2r44y0mp5xW3uO3csuTPDWZc0OIiMQv+AIY5Cqwd4mJiC5N8estVl7qlvOx1hbtOuUWbw==
|
||||
|
||||
"@loadable/babel-plugin@^5.0.1":
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@loadable/babel-plugin/-/babel-plugin-5.0.1.tgz#90ec99b64ed749ae311149e70b7d3394bbca33d3"
|
||||
integrity sha512-jrq70wKsL4Iyr6xqndEeDkHJkWkY2sHZexTYWumNkw2MhwbifB+DzT1q38s23H0WjsXMPd/ACUXB3kE/7C+Xxg==
|
||||
dependencies:
|
||||
"@babel/plugin-syntax-dynamic-import" "^7.0.0"
|
||||
|
||||
"@loadable/component@5.1.2":
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@loadable/component/-/component-5.1.2.tgz#77d8bf883202bef949f526c496e5d305e058cbd4"
|
||||
integrity sha512-OZr9pP8Ghv8LoEHIVGCLYPvQFmq6i2eg3oQym1+RhfYmqrnXlT16BY1NjucLmqYD2LmCWlgEX+edrBXJMdQCgA==
|
||||
dependencies:
|
||||
hoist-non-react-statics "^3.1.0"
|
||||
|
||||
"@loadable/server@5.2.0":
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@loadable/server/-/server-5.2.0.tgz#0ba622ce31b81c49d1803eeb74467ba7111b1273"
|
||||
integrity sha512-wKHvL0I0Ko7F6yIrr28nDsl1/rOy2bov8sYEvNKpsk4SLcJzBU0gBjYW8TCd5EWpF3sI80fpoQwW3NKCFx9NMw==
|
||||
dependencies:
|
||||
lodash "^4.17.11"
|
||||
|
||||
"@loadable/webpack-plugin@^5.2.1":
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@loadable/webpack-plugin/-/webpack-plugin-5.2.1.tgz#419dae6901b4ae5525407c830074ede22311bbb8"
|
||||
integrity sha512-lVOn67IKuegsG9xMWaPtZx1hrLjrtvOqpO6nnvs4F/YF8DWj8nQ/SjCNw7JB7lpyN1NyozoCkfAAKVj3R5hqFQ==
|
||||
|
||||
"@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"
|
||||
|
@ -1544,7 +1570,7 @@ abbrev@1, abbrev@^1.1.1:
|
|||
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
|
||||
integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
|
||||
|
||||
accepts@^1.3.4, accepts@~1.3.4, accepts@~1.3.5:
|
||||
accepts@^1.3.4, accepts@~1.3.5:
|
||||
version "1.3.5"
|
||||
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2"
|
||||
integrity sha1-63d99gEXI6OxTopywIBcjoZ0a9I=
|
||||
|
@ -1865,11 +1891,6 @@ array-flatten@1.1.1:
|
|||
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
|
||||
integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=
|
||||
|
||||
array-flatten@^2.1.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.1.tgz#426bb9da84090c1838d812c8150af20a8331e296"
|
||||
integrity sha1-Qmu52oQJDBg42BLIFQryCoMx4pY=
|
||||
|
||||
array-from@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/array-from/-/array-from-2.1.1.tgz#cfe9d8c26628b9dc5aecc62a9f5d8f1f352c1195"
|
||||
|
@ -2028,7 +2049,7 @@ async-limiter@~1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8"
|
||||
integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==
|
||||
|
||||
async@^1.4.0, async@^1.5.2, async@~1.5:
|
||||
async@^1.4.0, async@~1.5:
|
||||
version "1.5.2"
|
||||
resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
|
||||
integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=
|
||||
|
@ -3391,11 +3412,6 @@ base@^0.11.1:
|
|||
mixin-deep "^1.2.0"
|
||||
pascalcase "^0.1.1"
|
||||
|
||||
batch@0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16"
|
||||
integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=
|
||||
|
||||
bcrypt-pbkdf@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
|
||||
|
@ -3473,18 +3489,6 @@ body-parser@1.18.3:
|
|||
raw-body "2.3.3"
|
||||
type-is "~1.6.16"
|
||||
|
||||
bonjour@^3.5.0:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5"
|
||||
integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU=
|
||||
dependencies:
|
||||
array-flatten "^2.1.0"
|
||||
deep-equal "^1.0.1"
|
||||
dns-equal "^1.0.0"
|
||||
dns-txt "^2.0.2"
|
||||
multicast-dns "^6.0.1"
|
||||
multicast-dns-service-types "^1.1.0"
|
||||
|
||||
boolbase@^1.0.0, boolbase@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
|
||||
|
@ -3707,11 +3711,6 @@ buffer-from@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
|
||||
integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
|
||||
|
||||
buffer-indexof@^1.0.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c"
|
||||
integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==
|
||||
|
||||
buffer-xor@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9"
|
||||
|
@ -4099,7 +4098,7 @@ chokidar-cli@^1.2.1:
|
|||
lodash "4.17.10"
|
||||
yargs "12.0.1"
|
||||
|
||||
chokidar@2.0.4, chokidar@^2.0.0, chokidar@^2.0.2:
|
||||
chokidar@2.0.4, chokidar@^2.0.2:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26"
|
||||
integrity sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==
|
||||
|
@ -4487,26 +4486,6 @@ component-indexof@0.0.3:
|
|||
resolved "https://registry.yarnpkg.com/component-indexof/-/component-indexof-0.0.3.tgz#11d091312239eb8f32c8f25ae9cb002ffe8d3c24"
|
||||
integrity sha1-EdCRMSI5648yyPJa6csAL/6NPCQ=
|
||||
|
||||
compressible@~2.0.14:
|
||||
version "2.0.15"
|
||||
resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.15.tgz#857a9ab0a7e5a07d8d837ed43fe2defff64fe212"
|
||||
integrity sha512-4aE67DL33dSW9gw4CI2H/yTxqHLNcxp0yS6jB+4h+wr3e43+1z7vm0HU9qXOH8j+qjKuL8+UtkOxYQSMq60Ylw==
|
||||
dependencies:
|
||||
mime-db ">= 1.36.0 < 2"
|
||||
|
||||
compression@^1.5.2:
|
||||
version "1.7.3"
|
||||
resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.3.tgz#27e0e176aaf260f7f2c2813c3e440adb9f1993db"
|
||||
integrity sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==
|
||||
dependencies:
|
||||
accepts "~1.3.5"
|
||||
bytes "3.0.0"
|
||||
compressible "~2.0.14"
|
||||
debug "2.6.9"
|
||||
on-headers "~1.0.1"
|
||||
safe-buffer "5.1.2"
|
||||
vary "~1.1.2"
|
||||
|
||||
concat-map@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
|
@ -4556,11 +4535,6 @@ configstore@^3.1.2:
|
|||
write-file-atomic "^2.0.0"
|
||||
xdg-basedir "^3.0.0"
|
||||
|
||||
connect-history-api-fallback@^1.3.0:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz#b06873934bc5e344fef611a196a6faae0aee015a"
|
||||
integrity sha1-sGhzk0vF40T+9hGhlqb6rgruAVo=
|
||||
|
||||
connected-react-router@5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/connected-react-router/-/connected-react-router-5.0.1.tgz#8379854fad7e027b1e27652c00ad534f8ad244b3"
|
||||
|
@ -5249,14 +5223,6 @@ deepcopy@0.6.3:
|
|||
resolved "https://registry.yarnpkg.com/deepcopy/-/deepcopy-0.6.3.tgz#634780f2f8656ab771af8fa8431ed1ccee55c7b0"
|
||||
integrity sha1-Y0eA8vhlardxr4+oQx7RzO5Vx7A=
|
||||
|
||||
default-gateway@^2.6.0:
|
||||
version "2.7.2"
|
||||
resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-2.7.2.tgz#b7ef339e5e024b045467af403d50348db4642d0f"
|
||||
integrity sha512-lAc4i9QJR0YHSDFdzeBQKfZ1SRDG3hsJNEkrpcZa8QhBfidLAilT60BDEIVUUGqosFp425KOgB3uYqcnQrWafQ==
|
||||
dependencies:
|
||||
execa "^0.10.0"
|
||||
ip-regex "^2.1.0"
|
||||
|
||||
default-require-extensions@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8"
|
||||
|
@ -5307,18 +5273,6 @@ degenerator@^1.0.4:
|
|||
escodegen "1.x.x"
|
||||
esprima "3.x.x"
|
||||
|
||||
del@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/del/-/del-3.0.0.tgz#53ecf699ffcbcb39637691ab13baf160819766e5"
|
||||
integrity sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=
|
||||
dependencies:
|
||||
globby "^6.1.0"
|
||||
is-path-cwd "^1.0.0"
|
||||
is-path-in-cwd "^1.0.0"
|
||||
p-map "^1.1.1"
|
||||
pify "^3.0.0"
|
||||
rimraf "^2.2.8"
|
||||
|
||||
delayed-stream@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
||||
|
@ -5369,11 +5323,6 @@ detect-newline@^2.1.0:
|
|||
resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2"
|
||||
integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=
|
||||
|
||||
detect-node@^2.0.3:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c"
|
||||
integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==
|
||||
|
||||
detect-port-alt@1.1.6:
|
||||
version "1.1.6"
|
||||
resolved "https://registry.yarnpkg.com/detect-port-alt/-/detect-port-alt-1.1.6.tgz#24707deabe932d4a3cf621302027c2b266568275"
|
||||
|
@ -5422,31 +5371,11 @@ discontinuous-range@1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a"
|
||||
integrity sha1-44Mx8IRLukm5qctxx3FYWqsbxlo=
|
||||
|
||||
dns-equal@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d"
|
||||
integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0=
|
||||
|
||||
dns-packet@^1.3.1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.1.tgz#12aa426981075be500b910eedcd0b47dd7deda5a"
|
||||
integrity sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==
|
||||
dependencies:
|
||||
ip "^1.1.0"
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
dns-prefetch-control@0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/dns-prefetch-control/-/dns-prefetch-control-0.1.0.tgz#60ddb457774e178f1f9415f0cabb0e85b0b300b2"
|
||||
integrity sha1-YN20V3dOF48flBXwyrsOhbCzALI=
|
||||
|
||||
dns-txt@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6"
|
||||
integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=
|
||||
dependencies:
|
||||
buffer-indexof "^1.0.0"
|
||||
|
||||
dockerfile-ast@0.0.12:
|
||||
version "0.0.12"
|
||||
resolved "https://registry.yarnpkg.com/dockerfile-ast/-/dockerfile-ast-0.0.12.tgz#6f25f6ad55eeecdd297ab68b08be1b32e64b5aeb"
|
||||
|
@ -6220,13 +6149,6 @@ eventsource@0.1.6:
|
|||
dependencies:
|
||||
original ">=0.0.5"
|
||||
|
||||
eventsource@^1.0.7:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.0.7.tgz#8fbc72c93fcd34088090bc0a4e64f4b5cee6d8d0"
|
||||
integrity sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==
|
||||
dependencies:
|
||||
original "^1.0.0"
|
||||
|
||||
evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02"
|
||||
|
@ -6361,7 +6283,7 @@ express-http-context@1.2.0:
|
|||
dependencies:
|
||||
cls-hooked "^4.2.2"
|
||||
|
||||
express@4.16.4, express@^4.16.2, express@^4.16.3:
|
||||
express@4.16.4, express@^4.16.3:
|
||||
version "4.16.4"
|
||||
resolved "https://registry.yarnpkg.com/express/-/express-4.16.4.tgz#fddef61926109e24c515ea97fd2f1bdbf62df12e"
|
||||
integrity sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==
|
||||
|
@ -6528,14 +6450,7 @@ fastparse@^1.1.1:
|
|||
resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9"
|
||||
integrity sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==
|
||||
|
||||
faye-websocket@^0.10.0:
|
||||
version "0.10.0"
|
||||
resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4"
|
||||
integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=
|
||||
dependencies:
|
||||
websocket-driver ">=0.5.1"
|
||||
|
||||
faye-websocket@~0.11.0, faye-websocket@~0.11.1:
|
||||
faye-websocket@~0.11.0:
|
||||
version "0.11.1"
|
||||
resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.1.tgz#f0efe18c4f56e4f40afc7e06c719fd5ee6188f38"
|
||||
integrity sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=
|
||||
|
@ -7187,17 +7102,6 @@ globby@8.0.1, globby@^8.0.0:
|
|||
pify "^3.0.0"
|
||||
slash "^1.0.0"
|
||||
|
||||
globby@^6.1.0:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c"
|
||||
integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=
|
||||
dependencies:
|
||||
array-union "^1.0.1"
|
||||
glob "^7.0.3"
|
||||
object-assign "^4.0.1"
|
||||
pify "^2.0.0"
|
||||
pinkie-promise "^2.0.0"
|
||||
|
||||
globjoin@^0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/globjoin/-/globjoin-0.1.4.tgz#2f4494ac8919e3767c5cbb691e9f463324285d43"
|
||||
|
@ -7292,11 +7196,6 @@ gzip-size@^4.0.0:
|
|||
duplexer "^0.1.1"
|
||||
pify "^3.0.0"
|
||||
|
||||
handle-thing@^1.2.5:
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-1.2.5.tgz#fd7aad726bf1a5fd16dfc29b2f7a6601d27139c4"
|
||||
integrity sha1-/Xqtcmvxpf0W38KbL3pmAdJxOcQ=
|
||||
|
||||
handlebars@^4.0.3:
|
||||
version "4.0.12"
|
||||
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.12.tgz#2c15c8a96d46da5e266700518ba8cb8d919d5bc5"
|
||||
|
@ -7553,16 +7452,6 @@ hot-shots@5.9.2:
|
|||
resolved "https://registry.yarnpkg.com/hot-shots/-/hot-shots-5.9.2.tgz#1cff097706f40ba2c1350d4806deebbd16a5e8c8"
|
||||
integrity sha512-ruHZvHaxZRVUCoCleiwwCcjdr9A2/Y97C7oc9LpyMg9ae39blHvsJJQQ0QtMtxKX+i4lig/7/BqZBjUUZPUp3A==
|
||||
|
||||
hpack.js@^2.1.6:
|
||||
version "2.1.6"
|
||||
resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2"
|
||||
integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=
|
||||
dependencies:
|
||||
inherits "^2.0.1"
|
||||
obuf "^1.0.0"
|
||||
readable-stream "^2.0.1"
|
||||
wbuf "^1.1.0"
|
||||
|
||||
hpkp@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/hpkp/-/hpkp-2.0.0.tgz#10e142264e76215a5d30c44ec43de64dee6d1672"
|
||||
|
@ -7712,11 +7601,6 @@ http-cache-semantics@3.8.1:
|
|||
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2"
|
||||
integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==
|
||||
|
||||
http-deceiver@^1.2.7:
|
||||
version "1.2.7"
|
||||
resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87"
|
||||
integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=
|
||||
|
||||
http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3:
|
||||
version "1.6.3"
|
||||
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d"
|
||||
|
@ -7740,16 +7624,6 @@ http-proxy-agent@^2.1.0:
|
|||
agent-base "4"
|
||||
debug "3.1.0"
|
||||
|
||||
http-proxy-middleware@~0.18.0:
|
||||
version "0.18.0"
|
||||
resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.18.0.tgz#0987e6bb5a5606e5a69168d8f967a87f15dd8aab"
|
||||
integrity sha512-Fs25KVMPAIIcgjMZkVHJoKg9VcXcC1C8yb9JUgeDvVXY0S/zgVIhMb+qVswDIgtJe2DfckMSY2d6TuTEutlk6Q==
|
||||
dependencies:
|
||||
http-proxy "^1.16.2"
|
||||
is-glob "^4.0.0"
|
||||
lodash "^4.17.5"
|
||||
micromatch "^3.1.9"
|
||||
|
||||
http-proxy@^1.16.2:
|
||||
version "1.17.0"
|
||||
resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.17.0.tgz#7ad38494658f84605e2f6db4436df410f4e5be9a"
|
||||
|
@ -8032,14 +7906,6 @@ inquirer@6.2.0, inquirer@^6.1.0, inquirer@^6.2.0:
|
|||
strip-ansi "^4.0.0"
|
||||
through "^2.3.6"
|
||||
|
||||
internal-ip@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-3.0.1.tgz#df5c99876e1d2eb2ea2d74f520e3f669a00ece27"
|
||||
integrity sha512-NXXgESC2nNVtU+pqmC9e6R8B1GpKxzsAQhffvh5AL79qKnodd+L7tnEQmTiUAVngqLalPbSqRA7XGIEL5nCd0Q==
|
||||
dependencies:
|
||||
default-gateway "^2.6.0"
|
||||
ipaddr.js "^1.5.2"
|
||||
|
||||
interpret@^1.0.0, interpret@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614"
|
||||
|
@ -8080,12 +7946,7 @@ invert-kv@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02"
|
||||
integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==
|
||||
|
||||
ip-regex@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9"
|
||||
integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=
|
||||
|
||||
ip@^1.1.0, ip@^1.1.4, ip@^1.1.5:
|
||||
ip@^1.1.4, ip@^1.1.5:
|
||||
version "1.1.5"
|
||||
resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a"
|
||||
integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=
|
||||
|
@ -8095,11 +7956,6 @@ ipaddr.js@1.8.0:
|
|||
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.0.tgz#eaa33d6ddd7ace8f7f6fe0c9ca0440e706738b1e"
|
||||
integrity sha1-6qM9bd16zo9/b+DJygRA5wZzix4=
|
||||
|
||||
ipaddr.js@^1.5.2:
|
||||
version "1.8.1"
|
||||
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.1.tgz#fa4b79fa47fd3def5e3b159825161c0a519c9427"
|
||||
integrity sha1-+kt5+kf9Pe9eOxWYJRYcClGclCc=
|
||||
|
||||
is-absolute-url@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6"
|
||||
|
@ -8370,25 +8226,6 @@ is-object@^1.0.1:
|
|||
resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470"
|
||||
integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA=
|
||||
|
||||
is-path-cwd@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d"
|
||||
integrity sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=
|
||||
|
||||
is-path-in-cwd@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52"
|
||||
integrity sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==
|
||||
dependencies:
|
||||
is-path-inside "^1.0.0"
|
||||
|
||||
is-path-inside@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036"
|
||||
integrity sha1-jvW33lBDej/cprToZe96pVy0gDY=
|
||||
dependencies:
|
||||
path-is-inside "^1.0.1"
|
||||
|
||||
is-plain-obj@^1.0.0, is-plain-obj@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
|
||||
|
@ -9289,11 +9126,6 @@ keyv@3.0.0:
|
|||
dependencies:
|
||||
json-buffer "3.0.0"
|
||||
|
||||
killable@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892"
|
||||
integrity sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==
|
||||
|
||||
kind-of@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-2.0.1.tgz#018ec7a4ce7e3a86cb9141be519d24c8faa981b5"
|
||||
|
@ -9676,11 +9508,6 @@ log-symbols@^2.0.0:
|
|||
dependencies:
|
||||
chalk "^2.0.1"
|
||||
|
||||
loglevel@^1.4.1:
|
||||
version "1.6.1"
|
||||
resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa"
|
||||
integrity sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=
|
||||
|
||||
lolex@^2.3.2:
|
||||
version "2.7.5"
|
||||
resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.7.5.tgz#113001d56bfc7e02d56e36291cc5c413d1aa0733"
|
||||
|
@ -9984,7 +9811,7 @@ micromatch@^2.1.5, micromatch@^2.3.11:
|
|||
parse-glob "^3.0.4"
|
||||
regex-cache "^0.4.2"
|
||||
|
||||
micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8, micromatch@^3.1.9:
|
||||
micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8:
|
||||
version "3.1.10"
|
||||
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23"
|
||||
integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==
|
||||
|
@ -10011,12 +9838,12 @@ miller-rabin@^4.0.0:
|
|||
bn.js "^4.0.0"
|
||||
brorand "^1.0.1"
|
||||
|
||||
"mime-db@>= 1.36.0 < 2", mime-db@~1.37.0:
|
||||
mime-db@~1.37.0:
|
||||
version "1.37.0"
|
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8"
|
||||
integrity sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==
|
||||
|
||||
mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.18, mime-types@~2.1.19:
|
||||
mime-types@^2.1.12, mime-types@~2.1.18, mime-types@~2.1.19:
|
||||
version "2.1.21"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.21.tgz#28995aa1ecb770742fe6ae7e58f9181c744b3f96"
|
||||
integrity sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==
|
||||
|
@ -10179,7 +10006,7 @@ mixin-object@^2.0.1:
|
|||
for-in "^0.1.3"
|
||||
is-extendable "^0.1.1"
|
||||
|
||||
mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1:
|
||||
mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1:
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
|
||||
integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
|
||||
|
@ -10300,19 +10127,6 @@ ms@2.1.1, ms@^2.1.1:
|
|||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
|
||||
integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
|
||||
|
||||
multicast-dns-service-types@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901"
|
||||
integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=
|
||||
|
||||
multicast-dns@^6.0.1:
|
||||
version "6.2.3"
|
||||
resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229"
|
||||
integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==
|
||||
dependencies:
|
||||
dns-packet "^1.3.1"
|
||||
thunky "^1.0.2"
|
||||
|
||||
mute-stream@0.0.7:
|
||||
version "0.0.7"
|
||||
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
|
||||
|
@ -10462,11 +10276,6 @@ node-fetch@^2.2.0:
|
|||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.3.0.tgz#1a1d940bbfb916a1d3e0219f037e89e71f8c5fa5"
|
||||
integrity sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA==
|
||||
|
||||
node-forge@0.7.5:
|
||||
version "0.7.5"
|
||||
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df"
|
||||
integrity sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==
|
||||
|
||||
node-gyp@^3.6.2, node-gyp@^3.8.0:
|
||||
version "3.8.0"
|
||||
resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.8.0.tgz#540304261c330e80d0d5edce253a68cb3964218c"
|
||||
|
@ -10842,11 +10651,6 @@ object.values@^1.0.4:
|
|||
function-bind "^1.1.0"
|
||||
has "^1.0.1"
|
||||
|
||||
obuf@^1.0.0, obuf@^1.1.1:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e"
|
||||
integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==
|
||||
|
||||
on-finished@^2.3.0, on-finished@~2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
|
||||
|
@ -10880,7 +10684,7 @@ opn@5.2.0:
|
|||
dependencies:
|
||||
is-wsl "^1.1.0"
|
||||
|
||||
opn@5.4.0, opn@^5.1.0, opn@^5.2.0, opn@^5.3.0, opn@^5.4.0:
|
||||
opn@5.4.0, opn@^5.2.0, opn@^5.3.0, opn@^5.4.0:
|
||||
version "5.4.0"
|
||||
resolved "https://registry.yarnpkg.com/opn/-/opn-5.4.0.tgz#cb545e7aab78562beb11aa3bfabc7042e1761035"
|
||||
integrity sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw==
|
||||
|
@ -10915,7 +10719,7 @@ optionator@^0.8.1, optionator@^0.8.2:
|
|||
type-check "~0.3.2"
|
||||
wordwrap "~1.0.0"
|
||||
|
||||
original@>=0.0.5, original@^1.0.0:
|
||||
original@>=0.0.5:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f"
|
||||
integrity sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==
|
||||
|
@ -11026,11 +10830,6 @@ p-locate@^3.0.0:
|
|||
dependencies:
|
||||
p-limit "^2.0.0"
|
||||
|
||||
p-map@^1.1.1:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b"
|
||||
integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==
|
||||
|
||||
p-timeout@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038"
|
||||
|
@ -11234,7 +11033,7 @@ path-is-absolute@^1.0.0, path-is-absolute@^1.0.1:
|
|||
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
|
||||
|
||||
path-is-inside@^1.0.1, path-is-inside@^1.0.2:
|
||||
path-is-inside@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53"
|
||||
integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=
|
||||
|
@ -11486,15 +11285,6 @@ po2json@^0.4.5:
|
|||
gettext-parser "1.1.0"
|
||||
nomnom "1.8.1"
|
||||
|
||||
portfinder@^1.0.9:
|
||||
version "1.0.19"
|
||||
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.19.tgz#07e87914a55242dcda5b833d42f018d6875b595f"
|
||||
integrity sha512-23aeQKW9KgHe6citUrG3r9HjeX6vls0h713TAa+CwTKZwNIr/pD2ApaxYF4Um3ZZyq4ar+Siv3+fhoHaIwSOSw==
|
||||
dependencies:
|
||||
async "^1.5.2"
|
||||
debug "^2.2.0"
|
||||
mkdirp "0.5.x"
|
||||
|
||||
posix-character-classes@^0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
|
||||
|
@ -13105,7 +12895,7 @@ read-pkg@^4.0.1:
|
|||
parse-json "^4.0.0"
|
||||
pify "^3.0.0"
|
||||
|
||||
"readable-stream@1 || 2", readable-stream@2, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6:
|
||||
"readable-stream@1 || 2", readable-stream@2, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6:
|
||||
version "2.3.6"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
|
||||
integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==
|
||||
|
@ -13881,18 +13671,6 @@ secure-keys@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/secure-keys/-/secure-keys-1.0.0.tgz#f0c82d98a3b139a8776a8808050b824431087fca"
|
||||
integrity sha1-8MgtmKOxOah3aogIBQuCRDEIf8o=
|
||||
|
||||
select-hose@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
|
||||
integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=
|
||||
|
||||
selfsigned@^1.9.1:
|
||||
version "1.10.4"
|
||||
resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.4.tgz#cdd7eccfca4ed7635d47a08bf2d5d3074092e2cd"
|
||||
integrity sha512-9AukTiDmHXGXWtWjembZ5NDmVvP2695EtpgbCsxCa68w3c88B+alqbmZ4O3hZ4VWGXeGWzEVdvqgAJD8DQPCDw==
|
||||
dependencies:
|
||||
node-forge "0.7.5"
|
||||
|
||||
"semver@2 || 3 || 4 || 5", semver@^5.0.1, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0:
|
||||
version "5.6.0"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004"
|
||||
|
@ -13938,19 +13716,6 @@ serve-favicon@^2.4.5, serve-favicon@^2.5.0:
|
|||
parseurl "~1.3.2"
|
||||
safe-buffer "5.1.1"
|
||||
|
||||
serve-index@^1.7.2:
|
||||
version "1.9.1"
|
||||
resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239"
|
||||
integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=
|
||||
dependencies:
|
||||
accepts "~1.3.4"
|
||||
batch "0.6.1"
|
||||
debug "2.6.9"
|
||||
escape-html "~1.0.3"
|
||||
http-errors "~1.6.2"
|
||||
mime-types "~2.1.17"
|
||||
parseurl "~1.3.2"
|
||||
|
||||
serve-static@1.13.2:
|
||||
version "1.13.2"
|
||||
resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1"
|
||||
|
@ -14384,26 +14149,6 @@ sockjs-client@1.1.5:
|
|||
json3 "^3.3.2"
|
||||
url-parse "^1.1.8"
|
||||
|
||||
sockjs-client@1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.3.0.tgz#12fc9d6cb663da5739d3dc5fb6e8687da95cb177"
|
||||
integrity sha512-R9jxEzhnnrdxLCNln0xg5uGHqMnkhPSTzUZH2eXcR03S/On9Yvoq2wyUZILRUhZCNVu2PmwWVoyuiPz8th8zbg==
|
||||
dependencies:
|
||||
debug "^3.2.5"
|
||||
eventsource "^1.0.7"
|
||||
faye-websocket "~0.11.1"
|
||||
inherits "^2.0.3"
|
||||
json3 "^3.3.2"
|
||||
url-parse "^1.4.3"
|
||||
|
||||
sockjs@0.3.19:
|
||||
version "0.3.19"
|
||||
resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.19.tgz#d976bbe800af7bd20ae08598d582393508993c0d"
|
||||
integrity sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==
|
||||
dependencies:
|
||||
faye-websocket "^0.10.0"
|
||||
uuid "^3.0.1"
|
||||
|
||||
socks-proxy-agent@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-3.0.1.tgz#2eae7cf8e2a82d34565761539a7f9718c5617659"
|
||||
|
@ -14525,31 +14270,6 @@ spdx-license-ids@^3.0.0:
|
|||
resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.2.tgz#a59efc09784c2a5bada13cfeaf5c75dd214044d2"
|
||||
integrity sha512-qky9CVt0lVIECkEsYbNILVnPvycuEBkXoMFLRWsREkomQLevYhtRKC+R91a5TOAQ3bCMjikRwhyaRqj1VYatYg==
|
||||
|
||||
spdy-transport@^2.0.18:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-2.1.1.tgz#c54815d73858aadd06ce63001e7d25fa6441623b"
|
||||
integrity sha512-q7D8c148escoB3Z7ySCASadkegMmUZW8Wb/Q1u0/XBgDKMO880rLQDj8Twiew/tYi7ghemKUi/whSYOwE17f5Q==
|
||||
dependencies:
|
||||
debug "^2.6.8"
|
||||
detect-node "^2.0.3"
|
||||
hpack.js "^2.1.6"
|
||||
obuf "^1.1.1"
|
||||
readable-stream "^2.2.9"
|
||||
safe-buffer "^5.0.1"
|
||||
wbuf "^1.7.2"
|
||||
|
||||
spdy@^3.4.1:
|
||||
version "3.4.7"
|
||||
resolved "https://registry.yarnpkg.com/spdy/-/spdy-3.4.7.tgz#42ff41ece5cc0f99a3a6c28aabb73f5c3b03acbc"
|
||||
integrity sha1-Qv9B7OXMD5mjpsKKq7c/XDsDrLw=
|
||||
dependencies:
|
||||
debug "^2.6.8"
|
||||
handle-thing "^1.2.5"
|
||||
http-deceiver "^1.2.7"
|
||||
safe-buffer "^5.0.1"
|
||||
select-hose "^2.0.0"
|
||||
spdy-transport "^2.0.18"
|
||||
|
||||
specificity@^0.4.1:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/specificity/-/specificity-0.4.1.tgz#aab5e645012db08ba182e151165738d00887b019"
|
||||
|
@ -15024,7 +14744,7 @@ supports-color@^4.0.0, supports-color@^4.2.1, supports-color@^4.5.0:
|
|||
dependencies:
|
||||
has-flag "^2.0.0"
|
||||
|
||||
supports-color@^5.1.0, supports-color@^5.3.0, supports-color@^5.4.0, supports-color@^5.5.0:
|
||||
supports-color@^5.3.0, supports-color@^5.4.0, supports-color@^5.5.0:
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
|
||||
integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
|
||||
|
@ -15279,11 +14999,6 @@ thunkify@^2.1.2:
|
|||
resolved "https://registry.yarnpkg.com/thunkify/-/thunkify-2.1.2.tgz#faa0e9d230c51acc95ca13a361ac05ca7e04553d"
|
||||
integrity sha1-+qDp0jDFGsyVyhOjYawFyn4EVT0=
|
||||
|
||||
thunky@^1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.0.3.tgz#f5df732453407b09191dae73e2a8cc73f381a826"
|
||||
integrity sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow==
|
||||
|
||||
time-stamp@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-2.2.0.tgz#917e0a66905688790ec7bbbde04046259af83f57"
|
||||
|
@ -15992,13 +15707,6 @@ watchpack@^1.4.0, watchpack@^1.5.0:
|
|||
graceful-fs "^4.1.2"
|
||||
neo-async "^2.5.0"
|
||||
|
||||
wbuf@^1.1.0, wbuf@^1.7.2:
|
||||
version "1.7.3"
|
||||
resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df"
|
||||
integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==
|
||||
dependencies:
|
||||
minimalistic-assert "^1.0.0"
|
||||
|
||||
webidl-conversions@^4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"
|
||||
|
@ -16020,16 +15728,6 @@ webpack-cli@^3.1.2:
|
|||
v8-compile-cache "^2.0.2"
|
||||
yargs "^12.0.2"
|
||||
|
||||
webpack-dev-middleware@3.4.0, webpack-dev-middleware@^3.4.0:
|
||||
version "3.4.0"
|
||||
resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.4.0.tgz#1132fecc9026fd90f0ecedac5cbff75d1fb45890"
|
||||
integrity sha512-Q9Iyc0X9dP9bAsYskAVJ/hmIZZQwf/3Sy4xCAZgL5cUkjZmUZLt4l5HpbST/Pdgjn3u6pE7u5OdGd1apgzRujA==
|
||||
dependencies:
|
||||
memory-fs "~0.4.1"
|
||||
mime "^2.3.1"
|
||||
range-parser "^1.0.3"
|
||||
webpack-log "^2.0.0"
|
||||
|
||||
webpack-dev-middleware@^1.12.2:
|
||||
version "1.12.2"
|
||||
resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-1.12.2.tgz#f8fc1120ce3b4fc5680ceecb43d777966b21105e"
|
||||
|
@ -16041,39 +15739,15 @@ webpack-dev-middleware@^1.12.2:
|
|||
range-parser "^1.0.3"
|
||||
time-stamp "^2.0.0"
|
||||
|
||||
webpack-dev-server@^3.1.10:
|
||||
version "3.1.10"
|
||||
resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.1.10.tgz#507411bee727ee8d2fdffdc621b66a64ab3dea2b"
|
||||
integrity sha512-RqOAVjfqZJtQcB0LmrzJ5y4Jp78lv9CK0MZ1YJDTaTmedMZ9PU9FLMQNrMCfVu8hHzaVLVOJKBlGEHMN10z+ww==
|
||||
webpack-dev-middleware@^3.4.0:
|
||||
version "3.4.0"
|
||||
resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.4.0.tgz#1132fecc9026fd90f0ecedac5cbff75d1fb45890"
|
||||
integrity sha512-Q9Iyc0X9dP9bAsYskAVJ/hmIZZQwf/3Sy4xCAZgL5cUkjZmUZLt4l5HpbST/Pdgjn3u6pE7u5OdGd1apgzRujA==
|
||||
dependencies:
|
||||
ansi-html "0.0.7"
|
||||
bonjour "^3.5.0"
|
||||
chokidar "^2.0.0"
|
||||
compression "^1.5.2"
|
||||
connect-history-api-fallback "^1.3.0"
|
||||
debug "^3.1.0"
|
||||
del "^3.0.0"
|
||||
express "^4.16.2"
|
||||
html-entities "^1.2.0"
|
||||
http-proxy-middleware "~0.18.0"
|
||||
import-local "^2.0.0"
|
||||
internal-ip "^3.0.1"
|
||||
ip "^1.1.5"
|
||||
killable "^1.0.0"
|
||||
loglevel "^1.4.1"
|
||||
opn "^5.1.0"
|
||||
portfinder "^1.0.9"
|
||||
schema-utils "^1.0.0"
|
||||
selfsigned "^1.9.1"
|
||||
serve-index "^1.7.2"
|
||||
sockjs "0.3.19"
|
||||
sockjs-client "1.3.0"
|
||||
spdy "^3.4.1"
|
||||
strip-ansi "^3.0.0"
|
||||
supports-color "^5.1.0"
|
||||
webpack-dev-middleware "3.4.0"
|
||||
memory-fs "~0.4.1"
|
||||
mime "^2.3.1"
|
||||
range-parser "^1.0.3"
|
||||
webpack-log "^2.0.0"
|
||||
yargs "12.0.2"
|
||||
|
||||
webpack-hot-middleware@^2.22.1, webpack-hot-middleware@^2.24.3:
|
||||
version "2.24.3"
|
||||
|
@ -16411,7 +16085,6 @@ y18n@^3.2.0, y18n@^3.2.1:
|
|||
"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
|
||||
integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
|
||||
|
||||
yallist@^3.0.0, yallist@^3.0.2:
|
||||
version "3.0.3"
|
||||
|
@ -16472,24 +16145,6 @@ yargs@12.0.1:
|
|||
y18n "^3.2.1 || ^4.0.0"
|
||||
yargs-parser "^10.1.0"
|
||||
|
||||
yargs@12.0.2:
|
||||
version "12.0.2"
|
||||
resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.2.tgz#fe58234369392af33ecbef53819171eff0f5aadc"
|
||||
integrity sha512-e7SkEx6N6SIZ5c5H22RTZae61qtn3PYUE8JYbBFlK9sYmh3DMQ6E5ygtaG/2BW0JZi4WGgTR2IV5ChqlqrDGVQ==
|
||||
dependencies:
|
||||
cliui "^4.0.0"
|
||||
decamelize "^2.0.0"
|
||||
find-up "^3.0.0"
|
||||
get-caller-file "^1.0.1"
|
||||
os-locale "^3.0.0"
|
||||
require-directory "^2.1.1"
|
||||
require-main-filename "^1.0.1"
|
||||
set-blocking "^2.0.0"
|
||||
string-width "^2.0.0"
|
||||
which-module "^2.0.0"
|
||||
y18n "^3.2.1 || ^4.0.0"
|
||||
yargs-parser "^10.1.0"
|
||||
|
||||
yargs@^11.0.0:
|
||||
version "11.1.0"
|
||||
resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77"
|
||||
|
|
Загрузка…
Ссылка в новой задаче