@@ -16,12 +16,18 @@ var HtmlWebpackPlugin = require('html-webpack-plugin');
16
16
var ExtractTextPlugin = require('extract-text-webpack-plugin');
17
17
var url = require('url');
18
18
var paths = require('./paths');
19
- var env = require('./env');
19
+ var InterpolateHtmlPlugin = require('../scripts/utils/InterpolateHtmlPlugin');
20
+ var getClientEnvironment = require('../scripts/utils/getClientEnvironment');
20
21
21
- // Assert this just to be safe.
22
- // Development builds of React are slow and not intended for production.
23
- if (env['process.env.NODE_ENV'] !== '"production"') {
24
- throw new Error('Production builds must have NODE_ENV=production.');
22
+ function ensureSlash(path, needsSlash) {
23
+ var hasSlash = path.endsWith('/');
24
+ if (hasSlash && !needsSlash) {
25
+ return path.substr(path, path.length - 1);
26
+ } else if (!hasSlash && needsSlash) {
27
+ return path + '/';
28
+ } else {
29
+ return path;
30
+ }
25
31
}
26
32
27
33
// We use "homepage" field to infer "public path" at which the app is served.
@@ -30,10 +36,21 @@ if (env['process.env.NODE_ENV'] !== '"production"') {
30
36
// We can't use a relative path in HTML because we don't want to load something
31
37
// like /todos/42/static/js/bundle.7289d.js. We have to know the root.
32
38
var homepagePath = require(paths.appPackageJson).homepage;
33
- var publicPath = homepagePath ? url.parse(homepagePath).pathname : '/';
34
- if (!publicPath.endsWith('/')) {
35
- // If we don't do this, file assets will get incorrect paths.
36
- publicPath += '/';
39
+ var homepagePathname = homepagePath ? url.parse(homepagePath).pathname : '/';
40
+ // Webpack uses `publicPath` to determine where the app is being served from.
41
+ // It requires a trailing slash, or the file assets will get an incorrect path.
42
+ var publicPath = ensureSlash(homepagePathname, true);
43
+ // `publicUrl` is just like `publicPath`, but we will provide it to our app
44
+ // as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
45
+ // Omit trailing shlash as %PUBLIC_PATH%/xyz looks better than %PUBLIC_PATH%xyz.
46
+ var publicUrl = ensureSlash(homepagePathname, false);
47
+ // Get enrivonment variables to inject into our app.
48
+ var env = getClientEnvironment(publicUrl);
49
+
50
+ // Assert this just to be safe.
51
+ // Development builds of React are slow and not intended for production.
52
+ if (env['process.env.NODE_ENV'] !== '"production"') {
53
+ throw new Error('Production builds must have NODE_ENV=production.');
37
54
}
38
55
39
56
// This is the production configuration.
@@ -139,21 +156,11 @@ module.exports = {
139
156
// When you `import` an asset, you get its filename.
140
157
{
141
158
test: /\.(ico|jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2)(\?.*)?$/,
142
- exclude: /\/favicon.ico$/,
143
159
loader: 'file',
144
160
query: {
145
161
name: 'static/media/[name].[hash:8].[ext]'
146
162
}
147
163
},
148
- // A special case for favicon.ico to place it into build root directory.
149
- {
150
- test: /\/favicon.ico$/,
151
- include: [paths.appSrc],
152
- loader: 'file',
153
- query: {
154
- name: 'favicon.ico?[hash:8]'
155
- }
156
- },
157
164
// "url" loader works just like "file" loader but it also embeds
158
165
// assets smaller than specified size as data URLs to avoid requests.
159
166
{
@@ -163,15 +170,6 @@ module.exports = {
163
170
limit: 10000,
164
171
name: 'static/media/[name].[hash:8].[ext]'
165
172
}
166
- },
167
- // "html" loader is used to process template page (index.html) to resolve
168
- // resources linked with <link href="./relative/path"> HTML tags.
169
- {
170
- test: /\.html$/,
171
- loader: 'html',
172
- query: {
173
- attrs: ['link:href'],
174
- }
175
173
}
176
174
]
177
175
},
@@ -198,6 +196,13 @@ module.exports = {
198
196
];
199
197
},
200
198
plugins: [
199
+ // Makes the public URL available as %PUBLIC_URL% in index.html, e.g.:
200
+ // <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
201
+ // In production, it will be an empty string unless you specify "homepage"
202
+ // in `package.json`, in which case it will be the pathname of that URL.
203
+ new InterpolateHtmlPlugin({
204
+ PUBLIC_URL: publicUrl
205
+ }),
201
206
// Generates an `index.html` file with the <script> injected.
202
207
new HtmlWebpackPlugin({
203
208
inject: true,
@@ -216,7 +221,7 @@ module.exports = {
216
221
}
217
222
}),
218
223
// Makes some environment variables available to the JS code, for example:
219
- // if (process.env.NODE_ENV === 'production') { ... }. See `env.js`.
224
+ // if (process.env.NODE_ENV === 'production') { ... }.
220
225
// It is absolutely essential that NODE_ENV was set to production here.
221
226
// Otherwise React will be compiled in the very slow development mode.
222
227
new webpack.DefinePlugin(env),
0 commit comments