Skip to content
This repository was archived by the owner on Apr 24, 2024. It is now read-only.

Commit 0420253

Browse files
committed
feat(cli): add skip-cleanup parameter
1 parent ffe355e commit 0420253

File tree

2 files changed

+134
-119
lines changed

2 files changed

+134
-119
lines changed

scripts/index.js

Lines changed: 131 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const {
1717
disableChunks,
1818
outputFilename,
1919
chunkFilename,
20+
skipCleanup,
2021
},
2122
} = require('../utils/cliHandler');
2223
const { getReactScriptsVersion, isEjected } = require('../utils');
@@ -42,135 +43,146 @@ const getClientEnvironment = isEjected
4243
: importCwd('react-scripts/config/env');
4344

4445
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(/webpackHotDevClient/));
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-
}
8846

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(/webpackHotDevClient/));
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+
}
10392

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+
}
110107

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+
}
119114

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+
});
122126

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+
});
124163

125-
fs.emptyDir(paths.appBuild)
126-
.then(() => {
127-
spinner.succeed();
164+
copyPublicFolder();
128165

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,
159170
});
160-
})
161-
.then(() => copyPublicFolder());
171+
}
162172

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+
}
169177

170-
function handleBuildPath(userBuildPath) {
171-
if (path.isAbsolute(userBuildPath)) {
172-
return userBuildPath;
178+
return path.join(process.cwd(), userBuildPath);
173179
}
174180

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+
}
176186
}
187+
188+
main();

utils/cliHandler.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ module.exports = meow(
5454
type: 'boolean',
5555
alias: 'v',
5656
},
57+
'skip-cleanup': {
58+
type: 'boolean',
59+
},
5760
},
5861
}
5962
);

0 commit comments

Comments
 (0)