Skip to content

Commit 707ee10

Browse files
committed
feat(deps): upstream merge create-react-app 0.9
1 parent 2b85cb6 commit 707ee10

10 files changed

+1152
-581
lines changed

config/env.js

+15-7
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,33 @@
44
var REACT_APP = /^REACT_APP_/i;
55

66
function getClientEnvironment(publicUrl) {
7-
var processEnv = Object
7+
var raw = Object
88
.keys(process.env)
99
.filter(key => REACT_APP.test(key))
1010
.reduce((env, key) => {
11-
env[key] = JSON.stringify(process.env[key]);
11+
env[key] = process.env[key];
1212
return env;
1313
}, {
1414
// Useful for determining whether we’re running in production mode.
1515
// Most importantly, it switches React into the correct mode.
16-
'NODE_ENV': JSON.stringify(
17-
process.env.NODE_ENV || 'development'
18-
),
16+
'NODE_ENV': process.env.NODE_ENV || 'development',
1917
// Useful for resolving the correct path to static assets in `public`.
2018
// For example, <img src={process.env.PUBLIC_URL + '/img/logo.png'} />.
2119
// This should only be used as an escape hatch. Normally you would put
2220
// images into the `src` and `import` them in code to get their paths.
23-
'PUBLIC_URL': JSON.stringify(publicUrl)
21+
'PUBLIC_URL': publicUrl
2422
});
25-
return {'process.env': processEnv};
23+
// Stringify all values so we can feed into Webpack DefinePlugin
24+
var stringified = {
25+
'process.env': Object
26+
.keys(raw)
27+
.reduce((env, key) => {
28+
env[key] = JSON.stringify(raw[key]);
29+
return env;
30+
}, {})
31+
};
32+
33+
return { raw, stringified };
2634
}
2735

2836
module.exports = getClientEnvironment;

config/jest/CSSStub.js

-1
This file was deleted.

config/jest/FileStub.js

-1
This file was deleted.

config/jest/cssTransform.js

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// This is a custom Jest transformer turning style imports into empty objects.
2+
// http://facebook.github.io/jest/docs/tutorial-webpack.html
3+
4+
module.exports = {
5+
process() {
6+
return 'module.exports = {};';
7+
},
8+
getCacheKey(fileData, filename) {
9+
// The output is always the same.
10+
return 'cssTransform';
11+
},
12+
};

config/jest/fileTransform.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
const path = require('path');
2+
3+
// This is a custom Jest transformer turning file imports into filenames.
4+
// http://facebook.github.io/jest/docs/tutorial-webpack.html
5+
6+
module.exports = {
7+
process(src, filename) {
8+
return 'module.exports = ' + JSON.stringify(path.basename(filename)) + ';';
9+
},
10+
};

config/paths.js

+35-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
var path = require('path');
22
var fs = require('fs');
3+
var url = require('url');
34

45
// Make sure any symlinks in the project folder are resolved:
56
// https://github.com/facebookincubator/create-react-app/issues/637
@@ -29,6 +30,37 @@ var nodePaths = (process.env.NODE_PATH || '')
2930
.filter(folder => !path.isAbsolute(folder))
3031
.map(resolveApp);
3132

33+
var envPublicUrl = process.env.PUBLIC_URL;
34+
35+
function ensureSlash(path, needsSlash) {
36+
var hasSlash = path.endsWith('/');
37+
if (hasSlash && !needsSlash) {
38+
return path.substr(path, path.length - 1);
39+
} else if (!hasSlash && needsSlash) {
40+
return path + '/';
41+
} else {
42+
return path;
43+
}
44+
}
45+
46+
function getPublicUrl(appPackageJson) {
47+
return envPublicUrl || require(appPackageJson).homepage;
48+
}
49+
50+
// We use `PUBLIC_URL` environment variable or "homepage" field to infer
51+
// "public path" at which the app is served.
52+
// Webpack needs to know it to put the right <script> hrefs into HTML even in
53+
// single-page apps that may serve index.html for nested URLs like /todos/42.
54+
// We can't use a relative path in HTML because we don't want to load something
55+
// like /todos/42/static/js/bundle.7289d.js. We have to know the root.
56+
function getServedPath(appPackageJson) {
57+
var publicUrl = getPublicUrl(appPackageJson);
58+
var servedUrl = envPublicUrl || (
59+
publicUrl ? url.parse(publicUrl).pathname : '/'
60+
);
61+
return ensureSlash(servedUrl, true);
62+
}
63+
3264
// config after eject: we're in ./config/
3365
module.exports = {
3466
appBuild: resolveApp('build'),
@@ -41,5 +73,7 @@ module.exports = {
4173
testsSetup: resolveApp('src/setupTests.js'),
4274
appNodeModules: resolveApp('node_modules'),
4375
ownNodeModules: resolveApp('node_modules'),
44-
nodePaths: nodePaths
76+
nodePaths: nodePaths,
77+
publicUrl: getPublicUrl(resolveApp('package.json')),
78+
servedPath: getServedPath(resolveApp('package.json'))
4579
};

config/webpack.config.dev.js

+24-29
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ var WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeMod
77
var getClientEnvironment = require('./env');
88
var paths = require('./paths');
99

10+
11+
1012
// Webpack uses `publicPath` to determine where the app is being served from.
1113
// In development, we always serve from the root. This makes config easier.
1214
var publicPath = '/';
@@ -89,27 +91,22 @@ module.exports = {
8991
}
9092
],
9193
loaders: [
92-
// Default loader: load all assets that are not handled
93-
// by other loaders with the url loader.
94-
// Note: This list needs to be updated with every change of extensions
95-
// the other loaders match.
96-
// E.g., when adding a loader for a new supported file extension,
97-
// we need to add the supported extension to this loader too.
98-
// Add one new line in `exclude` for each loader.
99-
//
100-
// "file" loader makes sure those assets get served by WebpackDevServer.
101-
// When you `import` an asset, you get its (virtual) filename.
102-
// In production, they would get copied to the `build` folder.
103-
// "url" loader works like "file" loader except that it embeds assets
104-
// smaller than specified limit in bytes as data URLs to avoid requests.
105-
// A missing `test` is equivalent to a match.
94+
// ** ADDING/UPDATING LOADERS **
95+
// The "url" loader handles all assets unless explicitly excluded.
96+
// The `exclude` list *must* be updated with every change to loader extensions.
97+
// When adding a new loader, you must add its `test`
98+
// as a new entry in the `exclude` list for "url" loader.
99+
100+
// "url" loader embeds assets smaller than specified size as data URLs to avoid requests.
101+
// Otherwise, it acts like the "file" loader..
106102
{
107103
exclude: [
108104
/\.html$/,
109105
/\.(js|jsx)$/,
110-
/\.less$/,
111106
/\.css$/,
112-
/\.json$/
107+
/\.json$/,
108+
/\.svg$/,
109+
/\.less$/
113110
],
114111
loader: 'url',
115112
query: {
@@ -139,14 +136,6 @@ module.exports = {
139136
test: /\.css$/,
140137
loader: 'style!css?importLoaders=1!postcss'
141138
},
142-
{
143-
test: /\.less$/,
144-
loader: 'style!css!less!postcss'
145-
},
146-
{
147-
test: /\.scss$/,
148-
loader: 'style!css!sass!postcss'
149-
},
150139
// JSON is not enabled by default in Webpack but both Node and Browserify
151140
// allow it implicitly so we also enable it.
152141
{
@@ -160,7 +149,15 @@ module.exports = {
160149
query: {
161150
name: 'static/media/[name].[hash:8].[ext]'
162151
}
163-
}
152+
},
153+
{
154+
test: /\.less$/,
155+
loader: 'style!css!less!postcss'
156+
},
157+
{
158+
test: /\.scss$/,
159+
loader: 'style!css!sass!postcss'
160+
},
164161
]
165162
},
166163

@@ -181,17 +178,15 @@ module.exports = {
181178
// Makes the public URL available as %PUBLIC_URL% in index.html, e.g.:
182179
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
183180
// In development, this will be an empty string.
184-
new InterpolateHtmlPlugin({
185-
PUBLIC_URL: publicUrl
186-
}),
181+
new InterpolateHtmlPlugin(env.raw),
187182
// Generates an `index.html` file with the <script> injected.
188183
new HtmlWebpackPlugin({
189184
inject: true,
190185
template: paths.appHtml,
191186
}),
192187
// Makes some environment variables available to the JS code, for example:
193188
// if (process.env.NODE_ENV === 'development') { ... }. See `./env.js`.
194-
new webpack.DefinePlugin(env),
189+
new webpack.DefinePlugin(env.stringified),
195190
// This is necessary to emit hot updates (currently CSS only):
196191
new webpack.HotModuleReplacementPlugin(),
197192
// Watcher doesn't work well if you mistype casing in a path so we use

config/webpack.config.prod.js

+48-49
Original file line numberDiff line numberDiff line change
@@ -8,40 +8,40 @@ var url = require('url');
88
var paths = require('./paths');
99
var getClientEnvironment = require('./env');
1010

11-
function ensureSlash(path, needsSlash) {
12-
var hasSlash = path.endsWith('/');
13-
if (hasSlash && !needsSlash) {
14-
return path.substr(path, path.length - 1);
15-
} else if (!hasSlash && needsSlash) {
16-
return path + '/';
17-
} else {
18-
return path;
19-
}
20-
}
2111

22-
// We use "homepage" field to infer "public path" at which the app is served.
23-
// Webpack needs to know it to put the right <script> hrefs into HTML even in
24-
// single-page apps that may serve index.html for nested URLs like /todos/42.
25-
// We can't use a relative path in HTML because we don't want to load something
26-
// like /todos/42/static/js/bundle.7289d.js. We have to know the root.
27-
var homepagePath = require(paths.appPackageJson).homepage;
28-
var homepagePathname = homepagePath ? url.parse(homepagePath).pathname : '/';
12+
2913
// Webpack uses `publicPath` to determine where the app is being served from.
3014
// It requires a trailing slash, or the file assets will get an incorrect path.
31-
var publicPath = ensureSlash(homepagePathname, true);
15+
var publicPath = paths.servedPath;
16+
// Some apps do not use client-side routing with pushState.
17+
// For these, "homepage" can be set to "." to enable relative asset paths.
18+
var shouldUseRelativeAssetPaths = publicPath === './';
3219
// `publicUrl` is just like `publicPath`, but we will provide it to our app
3320
// as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
34-
// Omit trailing slash as %PUBLIC_PATH%/xyz looks better than %PUBLIC_PATH%xyz.
35-
var publicUrl = ensureSlash(homepagePathname, false);
21+
// Omit trailing slash as %PUBLIC_URL%/xyz looks better than %PUBLIC_URL%xyz.
22+
var publicUrl = publicPath.slice(0, -1);
3623
// Get environment variables to inject into our app.
3724
var env = getClientEnvironment(publicUrl);
3825

3926
// Assert this just to be safe.
4027
// Development builds of React are slow and not intended for production.
41-
if (env['process.env'].NODE_ENV !== '"production"') {
28+
if (env.stringified['process.env'].NODE_ENV !== '"production"') {
4229
throw new Error('Production builds must have NODE_ENV=production.');
4330
}
4431

32+
// Note: defined here because it will be used more than once.
33+
const cssFilename = 'static/css/[name].[contenthash:8].css';
34+
35+
// ExtractTextPlugin expects the build output to be flat.
36+
// (See https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/27)
37+
// However, our output is structured with css, js and media folders.
38+
// To have this structure working with relative paths, we have to use custom options.
39+
const extractTextPluginOptions = shouldUseRelativeAssetPaths
40+
// Making sure that the publicPath goes back to to build folder.
41+
? { publicPath: Array(cssFilename.split('/').length).join('../') }
42+
: undefined;
43+
44+
4545
// This is the production configuration.
4646
// It compiles slowly and is focused on producing a fast and minimal bundle.
4747
// The development configuration is different and lives in a separate file.
@@ -97,25 +97,22 @@ module.exports = {
9797
}
9898
],
9999
loaders: [
100-
// Default loader: load all assets that are not handled
101-
// by other loaders with the url loader.
102-
// Note: This list needs to be updated with every change of extensions
103-
// the other loaders match.
104-
// E.g., when adding a loader for a new supported file extension,
105-
// we need to add the supported extension to this loader too.
106-
// Add one new line in `exclude` for each loader.
107-
//
108-
// "file" loader makes sure those assets end up in the `build` folder.
109-
// When you `import` an asset, you get its filename.
110-
// "url" loader works just like "file" loader but it also embeds
111-
// assets smaller than specified size as data URLs to avoid requests.
100+
// ** ADDING/UPDATING LOADERS **
101+
// The "url" loader handles all assets unless explicitly excluded.
102+
// The `exclude` list *must* be updated with every change to loader extensions.
103+
// When adding a new loader, you must add its `test`
104+
// as a new entry in the `exclude` list in the "url" loader.
105+
106+
// "url" loader embeds assets smaller than specified size as data URLs to avoid requests.
107+
// Otherwise, it acts like the "file" loader.
112108
{
113109
exclude: [
114110
/\.html$/,
115111
/\.(js|jsx)$/,
116-
/\.less$/,
117112
/\.css$/,
118-
/\.json$/
113+
/\.json$/,
114+
/\.svg$/,
115+
/\.less$/
119116
],
120117
loader: 'url',
121118
query: {
@@ -144,17 +141,13 @@ module.exports = {
144141
// in the main CSS file.
145142
{
146143
test: /\.css$/,
147-
loader: ExtractTextPlugin.extract('style', 'css?importLoaders=1!postcss')
144+
loader: ExtractTextPlugin.extract(
145+
'style',
146+
'css?importLoaders=1!postcss',
147+
extractTextPluginOptions
148+
)
148149
// Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
149150
},
150-
{
151-
test: /\.less$/,
152-
loader: ExtractTextPlugin.extract('style', 'css?-autoprefixer!less!postcss')
153-
},
154-
{
155-
test: /\.scss$/,
156-
loader: ExtractTextPlugin.extract('style', 'css?-autoprefixer!sass!postcss')
157-
},
158151
// JSON is not enabled by default in Webpack but both Node and Browserify
159152
// allow it implicitly so we also enable it.
160153
{
@@ -168,6 +161,14 @@ module.exports = {
168161
query: {
169162
name: 'static/media/[name].[hash:8].[ext]'
170163
}
164+
},
165+
{
166+
test: /\.less$/,
167+
loader: ExtractTextPlugin.extract('style', 'css?-autoprefixer!less!postcss')
168+
},
169+
{
170+
test: /\.scss$/,
171+
loader: ExtractTextPlugin.extract('style', 'css?-autoprefixer!sass!postcss')
171172
}
172173
]
173174
},
@@ -190,9 +191,7 @@ module.exports = {
190191
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
191192
// In production, it will be an empty string unless you specify "homepage"
192193
// in `package.json`, in which case it will be the pathname of that URL.
193-
new InterpolateHtmlPlugin({
194-
PUBLIC_URL: publicUrl
195-
}),
194+
new InterpolateHtmlPlugin(env.raw),
196195
// Generates an `index.html` file with the <script> injected.
197196
new HtmlWebpackPlugin({
198197
inject: true,
@@ -214,7 +213,7 @@ module.exports = {
214213
// if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
215214
// It is absolutely essential that NODE_ENV was set to production here.
216215
// Otherwise React will be compiled in the very slow development mode.
217-
new webpack.DefinePlugin(env),
216+
new webpack.DefinePlugin(env.stringified),
218217
// This helps ensure the builds are consistent if source hasn't changed:
219218
new webpack.optimize.OccurrenceOrderPlugin(),
220219
// Try to dedupe duplicated modules, if any:
@@ -234,7 +233,7 @@ module.exports = {
234233
}
235234
}),
236235
// Note: this won't work without ExtractTextPlugin.extract(..) in `loaders`.
237-
new ExtractTextPlugin('static/css/[name].[contenthash:8].css'),
236+
new ExtractTextPlugin(cssFilename),
238237
// Generate a manifest file which contains a mapping of all asset filenames
239238
// to their corresponding output file so that tools can pick it up without
240239
// having to parse `index.html`.

0 commit comments

Comments
 (0)