Skip to content

Commit cf6d197

Browse files
committed
3.4.0 Add Dev Utils and Error Overlay for compares
1 parent 23fb1d9 commit cf6d197

File tree

120 files changed

+91568
-595
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

120 files changed

+91568
-595
lines changed

packages/create-react-app/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "create-react-app",
3-
"version": "3.3.1",
3+
"version": "3.4.0",
44
"keywords": [
55
"react"
66
],

packages/create-react-app/yarn.lock.cached

Lines changed: 499 additions & 594 deletions
Large diffs are not rendered by default.
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
/**
2+
* Copyright (c) 2015-present, Facebook, Inc.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
'use strict';
9+
10+
var fs = require('fs');
11+
var path = require('path');
12+
var chalk = require('chalk');
13+
var filesize = require('filesize');
14+
var recursive = require('recursive-readdir');
15+
var stripAnsi = require('strip-ansi');
16+
var gzipSize = require('gzip-size').sync;
17+
18+
function canReadAsset(asset) {
19+
return (
20+
/\.(js|css)$/.test(asset) &&
21+
!/service-worker\.js/.test(asset) &&
22+
!/precache-manifest\.[0-9a-f]+\.js/.test(asset)
23+
);
24+
}
25+
26+
// Prints a detailed summary of build files.
27+
function printFileSizesAfterBuild(
28+
webpackStats,
29+
previousSizeMap,
30+
buildFolder,
31+
maxBundleGzipSize,
32+
maxChunkGzipSize
33+
) {
34+
var root = previousSizeMap.root;
35+
var sizes = previousSizeMap.sizes;
36+
var assets = (webpackStats.stats || [webpackStats])
37+
.map(stats =>
38+
stats
39+
.toJson({ all: false, assets: true })
40+
.assets.filter(asset => canReadAsset(asset.name))
41+
.map(asset => {
42+
var fileContents = fs.readFileSync(path.join(root, asset.name));
43+
var size = gzipSize(fileContents);
44+
var previousSize = sizes[removeFileNameHash(root, asset.name)];
45+
var difference = getDifferenceLabel(size, previousSize);
46+
return {
47+
folder: path.join(
48+
path.basename(buildFolder),
49+
path.dirname(asset.name)
50+
),
51+
name: path.basename(asset.name),
52+
size: size,
53+
sizeLabel:
54+
filesize(size) + (difference ? ' (' + difference + ')' : ''),
55+
};
56+
})
57+
)
58+
.reduce((single, all) => all.concat(single), []);
59+
assets.sort((a, b) => b.size - a.size);
60+
var longestSizeLabelLength = Math.max.apply(
61+
null,
62+
assets.map(a => stripAnsi(a.sizeLabel).length)
63+
);
64+
var suggestBundleSplitting = false;
65+
assets.forEach(asset => {
66+
var sizeLabel = asset.sizeLabel;
67+
var sizeLength = stripAnsi(sizeLabel).length;
68+
if (sizeLength < longestSizeLabelLength) {
69+
var rightPadding = ' '.repeat(longestSizeLabelLength - sizeLength);
70+
sizeLabel += rightPadding;
71+
}
72+
var isMainBundle = asset.name.indexOf('main.') === 0;
73+
var maxRecommendedSize = isMainBundle
74+
? maxBundleGzipSize
75+
: maxChunkGzipSize;
76+
var isLarge = maxRecommendedSize && asset.size > maxRecommendedSize;
77+
if (isLarge && path.extname(asset.name) === '.js') {
78+
suggestBundleSplitting = true;
79+
}
80+
console.log(
81+
' ' +
82+
(isLarge ? chalk.yellow(sizeLabel) : sizeLabel) +
83+
' ' +
84+
chalk.dim(asset.folder + path.sep) +
85+
chalk.cyan(asset.name)
86+
);
87+
});
88+
if (suggestBundleSplitting) {
89+
console.log();
90+
console.log(
91+
chalk.yellow('The bundle size is significantly larger than recommended.')
92+
);
93+
console.log(
94+
chalk.yellow(
95+
'Consider reducing it with code splitting: https://goo.gl/9VhYWB'
96+
)
97+
);
98+
console.log(
99+
chalk.yellow(
100+
'You can also analyze the project dependencies: https://goo.gl/LeUzfb'
101+
)
102+
);
103+
}
104+
}
105+
106+
function removeFileNameHash(buildFolder, fileName) {
107+
return fileName
108+
.replace(buildFolder, '')
109+
.replace(/\\/g, '/')
110+
.replace(
111+
/\/?(.*)(\.[0-9a-f]+)(\.chunk)?(\.js|\.css)/,
112+
(match, p1, p2, p3, p4) => p1 + p4
113+
);
114+
}
115+
116+
// Input: 1024, 2048
117+
// Output: "(+1 KB)"
118+
function getDifferenceLabel(currentSize, previousSize) {
119+
var FIFTY_KILOBYTES = 1024 * 50;
120+
var difference = currentSize - previousSize;
121+
var fileSize = !Number.isNaN(difference) ? filesize(difference) : 0;
122+
if (difference >= FIFTY_KILOBYTES) {
123+
return chalk.red('+' + fileSize);
124+
} else if (difference < FIFTY_KILOBYTES && difference > 0) {
125+
return chalk.yellow('+' + fileSize);
126+
} else if (difference < 0) {
127+
return chalk.green(fileSize);
128+
} else {
129+
return '';
130+
}
131+
}
132+
133+
function measureFileSizesBeforeBuild(buildFolder) {
134+
return new Promise(resolve => {
135+
recursive(buildFolder, (err, fileNames) => {
136+
var sizes;
137+
if (!err && fileNames) {
138+
sizes = fileNames.filter(canReadAsset).reduce((memo, fileName) => {
139+
var contents = fs.readFileSync(fileName);
140+
var key = removeFileNameHash(buildFolder, fileName);
141+
memo[key] = gzipSize(contents);
142+
return memo;
143+
}, {});
144+
}
145+
resolve({
146+
root: buildFolder,
147+
sizes: sizes || {},
148+
});
149+
});
150+
});
151+
}
152+
153+
module.exports = {
154+
measureFileSizesBeforeBuild: measureFileSizesBeforeBuild,
155+
printFileSizesAfterBuild: printFileSizesAfterBuild,
156+
};
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* Copyright (c) 2015-present, Facebook, Inc.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
'use strict';
9+
10+
var ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
11+
12+
module.exports = ForkTsCheckerWebpackPlugin;
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/**
2+
* Copyright (c) 2015-present, Facebook, Inc.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
'use strict';
9+
10+
class InlineChunkHtmlPlugin {
11+
constructor(htmlWebpackPlugin, tests) {
12+
this.htmlWebpackPlugin = htmlWebpackPlugin;
13+
this.tests = tests;
14+
}
15+
16+
getInlinedTag(publicPath, assets, tag) {
17+
if (tag.tagName !== 'script' || !(tag.attributes && tag.attributes.src)) {
18+
return tag;
19+
}
20+
const scriptName = publicPath
21+
? tag.attributes.src.replace(publicPath, '')
22+
: tag.attributes.src;
23+
if (!this.tests.some(test => scriptName.match(test))) {
24+
return tag;
25+
}
26+
const asset = assets[scriptName];
27+
if (asset == null) {
28+
return tag;
29+
}
30+
return { tagName: 'script', innerHTML: asset.source(), closeTag: true };
31+
}
32+
33+
apply(compiler) {
34+
let publicPath = compiler.options.output.publicPath || '';
35+
if (publicPath && !publicPath.endsWith('/')) {
36+
publicPath += '/';
37+
}
38+
39+
compiler.hooks.compilation.tap('InlineChunkHtmlPlugin', compilation => {
40+
const tagFunction = tag =>
41+
this.getInlinedTag(publicPath, compilation.assets, tag);
42+
43+
const hooks = this.htmlWebpackPlugin.getHooks(compilation);
44+
hooks.alterAssetTagGroups.tap('InlineChunkHtmlPlugin', assets => {
45+
assets.headTags = assets.headTags.map(tagFunction);
46+
assets.bodyTags = assets.bodyTags.map(tagFunction);
47+
});
48+
49+
// Still emit the runtime chunk for users who do not use our generated
50+
// index.html file.
51+
// hooks.afterEmit.tap('InlineChunkHtmlPlugin', () => {
52+
// Object.keys(compilation.assets).forEach(assetName => {
53+
// if (this.tests.some(test => assetName.match(test))) {
54+
// delete compilation.assets[assetName];
55+
// }
56+
// });
57+
// });
58+
});
59+
}
60+
}
61+
62+
module.exports = InlineChunkHtmlPlugin;
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* Copyright (c) 2015-present, Facebook, Inc.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
// This Webpack plugin lets us interpolate custom variables into `index.html`.
9+
// Usage: `new InterpolateHtmlPlugin(HtmlWebpackPlugin, { 'MY_VARIABLE': 42 })`
10+
// Then, you can use %MY_VARIABLE% in your `index.html`.
11+
12+
// It works in tandem with HtmlWebpackPlugin.
13+
// Learn more about creating plugins like this:
14+
// https://github.com/ampedandwired/html-webpack-plugin#events
15+
16+
'use strict';
17+
const escapeStringRegexp = require('escape-string-regexp');
18+
19+
class InterpolateHtmlPlugin {
20+
constructor(htmlWebpackPlugin, replacements) {
21+
this.htmlWebpackPlugin = htmlWebpackPlugin;
22+
this.replacements = replacements;
23+
}
24+
25+
apply(compiler) {
26+
compiler.hooks.compilation.tap('InterpolateHtmlPlugin', compilation => {
27+
this.htmlWebpackPlugin
28+
.getHooks(compilation)
29+
.afterTemplateExecution.tap('InterpolateHtmlPlugin', data => {
30+
// Run HTML through a series of user-specified string replacements.
31+
Object.keys(this.replacements).forEach(key => {
32+
const value = this.replacements[key];
33+
data.html = data.html.replace(
34+
new RegExp('%' + escapeStringRegexp(key) + '%', 'g'),
35+
value
36+
);
37+
});
38+
});
39+
});
40+
}
41+
}
42+
43+
module.exports = InterpolateHtmlPlugin;

packages/react-dev-utils/LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2013-present, Facebook, Inc.
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

0 commit comments

Comments
 (0)