@@ -16,12 +16,18 @@ var HtmlWebpackPlugin = require('html-webpack-plugin');
1616var ExtractTextPlugin = require ( 'extract-text-webpack-plugin' ) ;
1717var url = require ( 'url' ) ;
1818var paths = require ( './paths' ) ;
19- var env = require ( './env' ) ;
19+ var InterpolateHtmlPlugin = require ( '../scripts/utils/InterpolateHtmlPlugin' ) ;
20+ var getClientEnvironment = require ( '../scripts/utils/getClientEnvironment' ) ;
2021
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+ }
2531}
2632
2733// 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"') {
3036// We can't use a relative path in HTML because we don't want to load something
3137// like /todos/42/static/js/bundle.7289d.js. We have to know the root.
3238var 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.' ) ;
3754}
3855
3956// This is the production configuration.
@@ -139,21 +156,11 @@ module.exports = {
139156 // When you `import` an asset, you get its filename.
140157 {
141158 test : / \. ( i c o | j p g | j p e g | p n g | g i f | e o t | o t f | w e b p | s v g | t t f | w o f f | w o f f 2 ) ( \? .* ) ? $ / ,
142- exclude : / \/ f a v i c o n .i c o $ / ,
143159 loader : 'file' ,
144160 query : {
145161 name : 'static/media/[name].[hash:8].[ext]'
146162 }
147163 } ,
148- // A special case for favicon.ico to place it into build root directory.
149- {
150- test : / \/ f a v i c o n .i c o $ / ,
151- include : [ paths . appSrc ] ,
152- loader : 'file' ,
153- query : {
154- name : 'favicon.ico?[hash:8]'
155- }
156- } ,
157164 // "url" loader works just like "file" loader but it also embeds
158165 // assets smaller than specified size as data URLs to avoid requests.
159166 {
@@ -163,15 +170,6 @@ module.exports = {
163170 limit : 10000 ,
164171 name : 'static/media/[name].[hash:8].[ext]'
165172 }
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 : / \. h t m l $ / ,
171- loader : 'html' ,
172- query : {
173- attrs : [ 'link:href' ] ,
174- }
175173 }
176174 ]
177175 } ,
@@ -198,6 +196,13 @@ module.exports = {
198196 ] ;
199197 } ,
200198 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+ } ) ,
201206 // Generates an `index.html` file with the <script> injected.
202207 new HtmlWebpackPlugin ( {
203208 inject : true ,
@@ -216,7 +221,7 @@ module.exports = {
216221 }
217222 } ) ,
218223 // 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') { ... }.
220225 // It is absolutely essential that NODE_ENV was set to production here.
221226 // Otherwise React will be compiled in the very slow development mode.
222227 new webpack . DefinePlugin ( env ) ,
0 commit comments