1
+ // @remove -on-eject-begin
2
+ /**
3
+ * Copyright (c) 2015-present, Facebook, Inc.
4
+ * All rights reserved.
5
+ *
6
+ * This source code is licensed under the BSD-style license found in the
7
+ * LICENSE file in the root directory of this source tree. An additional grant
8
+ * of patent rights can be found in the PATENTS file in the same directory.
9
+ */
10
+ // @remove -on-eject-end
11
+ "use strict"
12
+ var autoprefixer = require ( 'autoprefixer' ) ;
13
+ var webpack = require ( 'webpack' ) ;
14
+ var HtmlWebpackPlugin = require ( 'html-webpack-plugin' ) ;
15
+ var ExtractTextPlugin = require ( 'extract-text-webpack-plugin' ) ;
16
+ var ManifestPlugin = require ( 'webpack-manifest-plugin' ) ;
17
+ var InterpolateHtmlPlugin = require ( 'react-dev-utils/InterpolateHtmlPlugin' ) ;
18
+ var paths = require ( './paths' ) ;
19
+ var getClientEnvironment = require ( './env' ) ;
20
+ var isProduction = require ( 'react-dev-utils/isProduction' ) ;
21
+
22
+ // @remove -on-eject-begin
23
+ // `path` is not used after eject - see https://github.com/facebookincubator/create-react-app/issues/1174
24
+ var path = require ( 'path' ) ;
25
+ // @remove -on-eject-end
26
+
27
+ // Webpack uses `publicPath` to determine where the app is being served from.
28
+ // It requires a trailing slash, or the file assets will get an incorrect path.
29
+ var publicPath = paths . servedPath ;
30
+ // Some apps do not use client-side routing with pushState.
31
+ // For these, "homepage" can be set to "." to enable relative asset paths.
32
+ var shouldUseRelativeAssetPaths = publicPath === './' ;
33
+ // `publicUrl` is just like `publicPath`, but we will provide it to our app
34
+ // as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
35
+ // Omit trailing slash as %PUBLIC_URL%/xyz looks better than %PUBLIC_URL%xyz.
36
+ var publicUrl = publicPath . slice ( 0 , - 1 ) ;
37
+ // Get environment variables to inject into our app.
38
+ var env = getClientEnvironment ( publicUrl ) ;
39
+
40
+ // Fall back to development if not production
41
+ if ( env . stringified [ 'process.env' ] . NODE_ENV !== '"production"' ) {
42
+ process . env . NODE_ENV = 'development' ;
43
+ }
44
+
45
+ // Note: defined here because it will be used more than once.
46
+ const cssFilename = 'static/css/' +
47
+ process . env . NODE_ENV +
48
+ '.[name].[contenthash:8].css' ;
49
+
50
+ // ExtractTextPlugin expects the build output to be flat.
51
+ // (See https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/27)
52
+ // However, our output is structured with css, js and media folders.
53
+ // To have this structure working with relative paths, we have to use custom options.
54
+ const extractTextPluginOptions = shouldUseRelativeAssetPaths
55
+ ? // Making sure that the publicPath goes back to to build folder.
56
+ { publicPath : Array ( cssFilename . split ( '/' ) . length ) . join ( '../' ) }
57
+ : { } ;
58
+
59
+ // This is the watching configuration.
60
+ // It defaults to development mode for quick iteration
61
+ module . exports = {
62
+ watch : true ,
63
+ context : paths . appSrc ,
64
+ devtool : isProduction ( ) ? 'source-map' : 'cheap-module-source-map' ,
65
+ // There are no support for live reloading changes in this mode
66
+ entry : [ require . resolve ( './polyfills' ) , paths . appIndexJs ] ,
67
+ output : {
68
+ // The build folder.
69
+ path : paths . appBuild ,
70
+ // Generated JS file names (with nested folders).
71
+ // There will be one main bundle, and one file per asynchronous chunk.
72
+ // We don't currently advertise code splitting but Webpack supports it.
73
+ // There's prefix in the filename to identify which NODE_ENV generated this build
74
+ filename : 'static/js/' + process . env . NODE_ENV + '.[name].[chunkhash:8].js' ,
75
+ chunkFilename : (
76
+ 'static/js/' + process . env . NODE_ENV + '.[name].[chunkhash:8].chunk.js'
77
+ ) ,
78
+ // We inferred the "public path" (such as / or /my-project) from homepage.
79
+ publicPath : publicPath
80
+ } ,
81
+ resolve : {
82
+ // This allows you to set a fallback for where Webpack should look for modules.
83
+ // We read `NODE_PATH` environment variable in `paths.js` and pass paths here.
84
+ // We placed these paths second because we want `node_modules` to "win"
85
+ // if there are any conflicts. This matches Node resolution mechanism.
86
+ // https://github.com/facebookincubator/create-react-app/issues/253
87
+ modules : [ 'node_modules' ] . concat ( paths . nodePaths ) ,
88
+ // These are the reasonable defaults supported by the Node ecosystem.
89
+ // We also include JSX as a common component filename extension to support
90
+ // some tools, although we do not recommend using it, see:
91
+ // https://github.com/facebookincubator/create-react-app/issues/290
92
+ extensions : [ '.js' , '.json' , '.jsx' ] ,
93
+ alias : {
94
+ // Support React Native Web
95
+ // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
96
+ 'react-native' : 'react-native-web'
97
+ }
98
+ } ,
99
+ // @remove -on-eject-begin
100
+ // Resolve loaders (webpack plugins for CSS, images, transpilation) from the
101
+ // directory of `react-scripts` itself rather than the project directory.
102
+ resolveLoader : {
103
+ modules : [
104
+ paths . ownNodeModules ,
105
+ // Lerna hoists everything, so we need to look in our app directory
106
+ paths . appNodeModules
107
+ ]
108
+ } ,
109
+ // @remove -on-eject-end
110
+ // This part is essentially the same as production configuration, but it remove
111
+ // the minification on development
112
+ module : {
113
+ rules : [
114
+ // Disable require.ensure as it's not a standard language feature.
115
+ { parser : { requireEnsure : false } } ,
116
+ // First, run the linter.
117
+ // It's important to do this before Babel processes the JS.
118
+ {
119
+ test : / \. ( j s | j s x ) $ / ,
120
+ enforce : 'pre' ,
121
+ use : [
122
+ {
123
+ // @remove -on-eject-begin
124
+ // Point ESLint to our predefined config.
125
+ options : {
126
+ // TODO: consider separate config for production,
127
+ // e.g. to enable no-console and no-debugger only in production.
128
+ configFile : path . join ( __dirname , '../.eslintrc' ) ,
129
+ useEslintrc : false
130
+ } ,
131
+ // @remove -on-eject-end
132
+ loader : 'eslint-loader'
133
+ }
134
+ ] ,
135
+ include : paths . appSrc
136
+ } ,
137
+ // ** ADDING/UPDATING LOADERS **
138
+ // The "url" loader handles all assets unless explicitly excluded.
139
+ // The `exclude` list *must* be updated with every change to loader extensions.
140
+ // When adding a new loader, you must add its `test`
141
+ // as a new entry in the `exclude` list in the "url" loader.
142
+
143
+ // "url" loader embeds assets smaller than specified size as data URLs to avoid requests.
144
+ // Otherwise, it acts like the "file" loader.
145
+ {
146
+ exclude : [ / \. h t m l $ / , / \. ( j s | j s x ) $ / , / \. c s s $ / , / \. j s o n $ / , / \. s v g $ / ] ,
147
+ loader : 'url-loader' ,
148
+ options : {
149
+ limit : 10000 ,
150
+ name : (
151
+ 'static/media/' + process . env . NODE_ENV + '.[name].[hash:8].[ext]'
152
+ )
153
+ }
154
+ } ,
155
+ // Process JS with Babel.
156
+ {
157
+ test : / \. ( j s | j s x ) $ / ,
158
+ include : paths . appSrc ,
159
+ loader : 'babel-loader' ,
160
+ // @remove -on-eject-begin
161
+ options : {
162
+ babelrc : false ,
163
+ presets : [ require . resolve ( 'babel-preset-react-app' ) ]
164
+ }
165
+
166
+ // @remove -on-eject-end
167
+ } ,
168
+ // The notation here is somewhat confusing.
169
+ // "postcss" loader applies autoprefixer to our CSS.
170
+ // "css" loader resolves paths in CSS and adds assets as dependencies.
171
+ // "style" loader normally turns CSS into JS modules injecting <style>,
172
+ // but unlike in development configuration, we do something different.
173
+ // `ExtractTextPlugin` first applies the "postcss" and "css" loaders
174
+ // (second argument), then grabs the result CSS and puts it into a
175
+ // separate file in our build process. This way we actually ship
176
+ // a single CSS file in production instead of JS code injecting <style>
177
+ // tags. If you use code splitting, however, any async bundles will still
178
+ // use the "style" loader inside the async code so CSS from them won't be
179
+ // in the main CSS file.
180
+ {
181
+ test : / \. c s s $ / ,
182
+ loader : ExtractTextPlugin . extract (
183
+ Object . assign (
184
+ {
185
+ fallback : 'style-loader' ,
186
+ use : [
187
+ {
188
+ loader : 'css-loader' ,
189
+ options : {
190
+ importLoaders : 1
191
+ }
192
+ } ,
193
+ {
194
+ loader : 'postcss-loader' ,
195
+ options : {
196
+ ident : 'postcss' , // https://webpack.js.org/guides/migrating/#complex-options
197
+ plugins : function ( ) {
198
+ return [
199
+ autoprefixer ( {
200
+ browsers : [
201
+ '>1%' ,
202
+ 'last 4 versions' ,
203
+ 'Firefox ESR' ,
204
+ 'not ie < 9' // React doesn't support IE8 anyway
205
+ ]
206
+ } )
207
+ ] ;
208
+ }
209
+ }
210
+ }
211
+ ]
212
+ } ,
213
+ extractTextPluginOptions
214
+ )
215
+ )
216
+
217
+ // Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
218
+ } ,
219
+ // "file" loader for svg
220
+ {
221
+ test : / \. s v g $ / ,
222
+ loader : 'file-loader' ,
223
+ options : {
224
+ name : (
225
+ 'static/media/' + process . env . NODE_ENV + '.[name].[hash:8].[ext]'
226
+ )
227
+ }
228
+ }
229
+ // ** STOP ** Are you adding a new loader?
230
+ // Remember to add the new extension(s) to the "url" loader exclusion list.
231
+ ]
232
+ } ,
233
+ plugins : [
234
+ // Makes some environment variables available in index.html.
235
+ // The public URL is available as %PUBLIC_URL% in index.html, e.g.:
236
+ // <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
237
+ // In production, it will be an empty string unless you specify "homepage"
238
+ // in `package.json`, in which case it will be the pathname of that URL.
239
+ new InterpolateHtmlPlugin ( env . raw ) ,
240
+ // Generates an `index.html` file with the <script> injected.
241
+ new HtmlWebpackPlugin ( {
242
+ inject : true ,
243
+ template : paths . appHtml ,
244
+ minify : (
245
+ isProduction ( )
246
+ ? // Minify the code if in production.
247
+ {
248
+ removeComments : true ,
249
+ collapseWhitespace : true ,
250
+ removeRedundantAttributes : true ,
251
+ useShortDoctype : true ,
252
+ removeEmptyAttributes : true ,
253
+ removeStyleLinkTypeAttributes : true ,
254
+ keepClosingSlash : true ,
255
+ minifyJS : true ,
256
+ minifyCSS : true ,
257
+ minifyURLs : true
258
+ }
259
+ : false
260
+ )
261
+ } ) ,
262
+ // Makes some environment variables available to the JS code, for example:
263
+ // if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
264
+ // It is absolutely essential that NODE_ENV was set to production here.
265
+ // Otherwise React will be compiled in the very slow development mode.
266
+ new webpack . DefinePlugin ( env . stringified ) ,
267
+ // Minify js if in production.
268
+ isProduction ( )
269
+ ? new webpack . optimize . UglifyJsPlugin ( {
270
+ compress : {
271
+ screw_ie8 : true , // React doesn't support IE8
272
+ warnings : false
273
+ } ,
274
+ mangle : {
275
+ screw_ie8 : true
276
+ } ,
277
+ output : {
278
+ comments : false ,
279
+ screw_ie8 : true
280
+ } ,
281
+ sourceMap : true
282
+ } )
283
+ : false ,
284
+ // Note: this won't work without ExtractTextPlugin.extract(..) in `loaders`.
285
+ new ExtractTextPlugin ( {
286
+ filename : cssFilename
287
+ } ) ,
288
+ // Generate a manifest file which contains a mapping of all asset filenames
289
+ // to their corresponding output file so that tools can pick it up without
290
+ // having to parse `index.html`.
291
+ // We also read this file to delete stale files in build folder
292
+ new ManifestPlugin ( {
293
+ fileName : 'asset-manifest.json'
294
+ } )
295
+ ] . filter ( Boolean ) , // remove falsy plugin on development
296
+ // Some libraries import Node modules but don't use them in the browser.
297
+ // Tell Webpack to provide empty mocks for them so importing them works.
298
+ node : {
299
+ fs : 'empty' ,
300
+ net : 'empty' ,
301
+ tls : 'empty'
302
+ }
303
+ } ;
0 commit comments