@@ -17,6 +17,7 @@ const {
17
17
disableChunks,
18
18
outputFilename,
19
19
chunkFilename,
20
+ skipCleanup,
20
21
} ,
21
22
} = require ( '../utils/cliHandler' ) ;
22
23
const { getReactScriptsVersion, isEjected } = require ( '../utils' ) ;
@@ -42,135 +43,146 @@ const getClientEnvironment = isEjected
42
43
: importCwd ( 'react-scripts/config/env' ) ;
43
44
44
45
console . log ( ) ;
45
- const spinner = ora ( 'Update webpack configuration' ) . start ( ) ;
46
-
47
- // we need to set the public_url ourselves because in dev mode
48
- // it is supposed to always be an empty string as they are using
49
- // the in-memory development server to serve the content
50
- const env = getClientEnvironment ( process . env . PUBLIC_URL || '' ) ; // eslint-disable-line no-process-env
51
-
52
- /**
53
- * We need to update the webpack dev config in order to remove the use of webpack devserver
54
- */
55
- config . entry = config . entry . filter ( fileName => ! fileName . match ( / w e b p a c k H o t D e v C l i e n t / ) ) ;
56
- config . plugins = config . plugins . filter (
57
- plugin => ! ( plugin instanceof webpack . HotModuleReplacementPlugin )
58
- ) ;
59
-
60
- /**
61
- * We also need to update the path where the different files get generated.
62
- */
63
- const resolvedBuildPath = buildPath ? handleBuildPath ( buildPath ) : paths . appBuild ; // resolve the build path
64
-
65
- // update the paths in config
66
- config . output . path = resolvedBuildPath ;
67
- config . output . publicPath = publicPath || '' ;
68
-
69
- // Grab output names from cli args, otherwise use some default naming.
70
- const fileNameToUse = outputFilename || `js/bundle.js` ;
71
- const chunkNameToUse = chunkFilename || `js/[name].chunk.js` ;
72
- // If cli user adds .js, respect that, otherwise we add it ourself
73
- config . output . filename = fileNameToUse . slice ( - 3 ) !== '.js' ? `${ fileNameToUse } .js` : fileNameToUse ;
74
- config . output . chunkFilename =
75
- chunkNameToUse . slice ( - 3 ) !== '.js' ? `${ chunkNameToUse } .js` : chunkNameToUse ;
76
-
77
- if ( disableChunks ) {
78
- assert ( major >= 2 , 'Split chunks optimization is only available in react-scripts >= 2.0.0' ) ;
79
- // disable code-splitting/chunks
80
- config . optimization . runtimeChunk = false ;
81
-
82
- config . optimization . splitChunks = {
83
- cacheGroups : {
84
- default : false ,
85
- } ,
86
- } ;
87
- }
88
46
89
- // update media path destination
90
- if ( major >= 2 ) {
91
- // 2.0.0 => 2
92
- // 2.0.1 => 3
93
- // 2.0.2 => 3
94
- // 2.0.3 => 3
95
- // 2.0.4 to 3.0.0 => 2
96
- const oneOfIndex = concatenatedVersion === 200 || concatenatedVersion >= 204 ? 2 : 3 ;
97
- config . module . rules [ oneOfIndex ] . oneOf [ 0 ] . options . name = `media/[name].[hash:8].[ext]` ;
98
- config . module . rules [ oneOfIndex ] . oneOf [ 7 ] . options . name = `media/[name].[hash:8].[ext]` ;
99
- } else {
100
- config . module . rules [ 1 ] . oneOf [ 0 ] . options . name = `media/[name].[hash:8].[ext]` ;
101
- config . module . rules [ 1 ] . oneOf [ 3 ] . options . name = `media/[name].[hash:8].[ext]` ;
102
- }
47
+ async function main ( ) {
48
+ const spinner = ora ( 'Update webpack configuration' ) . start ( ) ;
49
+
50
+ // we need to set the public_url ourselves because in dev mode
51
+ // it is supposed to always be an empty string as they are using
52
+ // the in-memory development server to serve the content
53
+ const env = getClientEnvironment ( process . env . PUBLIC_URL || '' ) ; // eslint-disable-line no-process-env
54
+
55
+ /**
56
+ * We need to update the webpack dev config in order to remove the use of webpack devserver
57
+ */
58
+ config . entry = config . entry . filter ( fileName => ! fileName . match ( / w e b p a c k H o t D e v C l i e n t / ) ) ;
59
+ config . plugins = config . plugins . filter (
60
+ plugin => ! ( plugin instanceof webpack . HotModuleReplacementPlugin )
61
+ ) ;
62
+
63
+ /**
64
+ * We also need to update the path where the different files get generated.
65
+ */
66
+ const resolvedBuildPath = buildPath ? handleBuildPath ( buildPath ) : paths . appBuild ; // resolve the build path
67
+
68
+ // update the paths in config
69
+ config . output . path = resolvedBuildPath ;
70
+ config . output . publicPath = publicPath || '' ;
71
+
72
+ // Grab output names from cli args, otherwise use some default naming.
73
+ const fileNameToUse = outputFilename || `js/bundle.js` ;
74
+ const chunkNameToUse = chunkFilename || `js/[name].chunk.js` ;
75
+ // If cli user adds .js, respect that, otherwise we add it ourself
76
+ config . output . filename =
77
+ fileNameToUse . slice ( - 3 ) !== '.js' ? `${ fileNameToUse } .js` : fileNameToUse ;
78
+ config . output . chunkFilename =
79
+ chunkNameToUse . slice ( - 3 ) !== '.js' ? `${ chunkNameToUse } .js` : chunkNameToUse ;
80
+
81
+ if ( disableChunks ) {
82
+ assert ( major >= 2 , 'Split chunks optimization is only available in react-scripts >= 2.0.0' ) ;
83
+ // disable code-splitting/chunks
84
+ config . optimization . runtimeChunk = false ;
85
+
86
+ config . optimization . splitChunks = {
87
+ cacheGroups : {
88
+ default : false ,
89
+ } ,
90
+ } ;
91
+ }
103
92
104
- let htmlPluginIndex = 1 ;
105
- let interpolateHtmlPluginIndex = 0 ;
106
- if ( major >= 2 ) {
107
- htmlPluginIndex = 0 ;
108
- interpolateHtmlPluginIndex = 1 ;
109
- }
93
+ // update media path destination
94
+ if ( major >= 2 ) {
95
+ // 2.0.0 => 2
96
+ // 2.0.1 => 3
97
+ // 2.0.2 => 3
98
+ // 2.0.3 => 3
99
+ // 2.0.4 to 3.0.0 => 2
100
+ const oneOfIndex = concatenatedVersion === 200 || concatenatedVersion >= 204 ? 2 : 3 ;
101
+ config . module . rules [ oneOfIndex ] . oneOf [ 0 ] . options . name = `media/[name].[hash:8].[ext]` ;
102
+ config . module . rules [ oneOfIndex ] . oneOf [ 7 ] . options . name = `media/[name].[hash:8].[ext]` ;
103
+ } else {
104
+ config . module . rules [ 1 ] . oneOf [ 0 ] . options . name = `media/[name].[hash:8].[ext]` ;
105
+ config . module . rules [ 1 ] . oneOf [ 3 ] . options . name = `media/[name].[hash:8].[ext]` ;
106
+ }
110
107
111
- // we need to override the InterpolateHtmlPlugin because in dev mod
112
- // they don't provide it the PUBLIC_URL env
113
- config . plugins [ interpolateHtmlPluginIndex ] = new InterpolateHtmlPlugin ( HtmlWebpackPlugin , env . raw ) ;
114
- config . plugins [ htmlPluginIndex ] = new HtmlWebpackPlugin ( {
115
- inject : true ,
116
- template : paths . appHtml ,
117
- filename : 'index.html' ,
118
- } ) ;
108
+ let htmlPluginIndex = 1 ;
109
+ let interpolateHtmlPluginIndex = 0 ;
110
+ if ( major >= 2 ) {
111
+ htmlPluginIndex = 0 ;
112
+ interpolateHtmlPluginIndex = 1 ;
113
+ }
119
114
120
- spinner . succeed ( ) ;
121
- spinner . start ( 'Clear destination folder' ) ;
115
+ // we need to override the InterpolateHtmlPlugin because in dev mod
116
+ // they don't provide it the PUBLIC_URL env
117
+ config . plugins [ interpolateHtmlPluginIndex ] = new InterpolateHtmlPlugin (
118
+ HtmlWebpackPlugin ,
119
+ env . raw
120
+ ) ;
121
+ config . plugins [ htmlPluginIndex ] = new HtmlWebpackPlugin ( {
122
+ inject : true ,
123
+ template : paths . appHtml ,
124
+ filename : 'index.html' ,
125
+ } ) ;
122
126
123
- let inProgress = false ;
127
+ spinner . succeed ( ) ;
128
+
129
+ skipCleanup || ( await clearDestinationFolder ( ) ) ;
130
+ let inProgress = false ;
131
+
132
+ await new Promise ( ( resolve , reject ) => {
133
+ const webpackCompiler = webpack ( config ) ;
134
+ new webpack . ProgressPlugin ( ( ) => {
135
+ if ( ! inProgress ) {
136
+ spinner . start ( 'Start webpack watch' ) ;
137
+ inProgress = true ;
138
+ }
139
+ } ) . apply ( webpackCompiler ) ;
140
+
141
+ webpackCompiler . watch ( { } , ( err , stats ) => {
142
+ if ( err ) {
143
+ return reject ( err ) ;
144
+ }
145
+
146
+ spinner . succeed ( ) ;
147
+ inProgress = false ;
148
+
149
+ if ( verbose ) {
150
+ console . log ( ) ;
151
+ console . log (
152
+ stats . toString ( {
153
+ chunks : false ,
154
+ colors : true ,
155
+ } )
156
+ ) ;
157
+ console . log ( ) ;
158
+ }
159
+
160
+ return resolve ( ) ;
161
+ } ) ;
162
+ } ) ;
124
163
125
- fs . emptyDir ( paths . appBuild )
126
- . then ( ( ) => {
127
- spinner . succeed ( ) ;
164
+ copyPublicFolder ( ) ;
128
165
129
- return new Promise ( ( resolve , reject ) => {
130
- const webpackCompiler = webpack ( config ) ;
131
- new webpack . ProgressPlugin ( ( ) => {
132
- if ( ! inProgress ) {
133
- spinner . start ( 'Start webpack watch' ) ;
134
- inProgress = true ;
135
- }
136
- } ) . apply ( webpackCompiler ) ;
137
-
138
- webpackCompiler . watch ( { } , ( err , stats ) => {
139
- if ( err ) {
140
- return reject ( err ) ;
141
- }
142
-
143
- spinner . succeed ( ) ;
144
- inProgress = false ;
145
-
146
- if ( verbose ) {
147
- console . log ( ) ;
148
- console . log (
149
- stats . toString ( {
150
- chunks : false ,
151
- colors : true ,
152
- } )
153
- ) ;
154
- console . log ( ) ;
155
- }
156
-
157
- return resolve ( ) ;
158
- } ) ;
166
+ function copyPublicFolder ( ) {
167
+ return fs . copy ( paths . appPublic , resolvedBuildPath , {
168
+ dereference : true ,
169
+ filter : file => file !== paths . appHtml ,
159
170
} ) ;
160
- } )
161
- . then ( ( ) => copyPublicFolder ( ) ) ;
171
+ }
162
172
163
- function copyPublicFolder ( ) {
164
- return fs . copy ( paths . appPublic , resolvedBuildPath , {
165
- dereference : true ,
166
- filter : file => file !== paths . appHtml ,
167
- } ) ;
168
- }
173
+ function handleBuildPath ( userBuildPath ) {
174
+ if ( path . isAbsolute ( userBuildPath ) ) {
175
+ return userBuildPath ;
176
+ }
169
177
170
- function handleBuildPath ( userBuildPath ) {
171
- if ( path . isAbsolute ( userBuildPath ) ) {
172
- return userBuildPath ;
178
+ return path . join ( process . cwd ( ) , userBuildPath ) ;
173
179
}
174
180
175
- return path . join ( process . cwd ( ) , userBuildPath ) ;
181
+ async function clearDestinationFolder ( ) {
182
+ spinner . start ( 'Clear destination folder' ) ;
183
+ await fs . emptyDir ( paths . appBuild ) ;
184
+ spinner . succeed ( ) ;
185
+ }
176
186
}
187
+
188
+ main ( ) ;
0 commit comments