Skip to content

Commit e6d210a

Browse files
authored
feat: add --analyze flag (#1853)
* feat: add --analyze flag * fix: conlicts * tests: updates * chore: suggesion * fix: ci
1 parent 2b8415a commit e6d210a

File tree

11 files changed

+160
-17
lines changed

11 files changed

+160
-17
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@
131131
"ts-jest": "^25.5.1",
132132
"typescript": "^3.9.7",
133133
"webpack": "^4.44.2",
134+
"webpack-bundle-analyzer": "^3.9.0",
134135
"yeoman-test": "^2.7.0"
135136
}
136137
}

packages/webpack-cli/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ yarn add webpack-cli --dev
3636
### webpack 4
3737

3838
```
39+
--analyze It invokes webpack-bundle-analyzer plugin to get bundle information
3940
--entry string[] The entry point(s) of your application.
4041
-c, --config string[] Provide path to webpack configuration file(s)
4142
--config-name string[] Name of the configuration to use

packages/webpack-cli/__tests__/resolveAdvanced.test.js

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,31 @@ const resolveAdvanced = require('../lib/groups/resolveAdvanced');
33
const targetValues = ['web', 'webworker', 'node', 'async-node', 'node-webkit', 'electron-main', 'electron-renderer', 'electron-preload'];
44

55
describe('advanced options', function () {
6-
it('should load the HMR plugin', () => {
7-
const result = resolveAdvanced({
6+
it('should load the HMR plugin', async () => {
7+
const result = await resolveAdvanced({
88
hot: true,
99
});
1010
expect(result.options.plugins[0].constructor.name).toEqual('HotModuleReplacementPlugin');
1111
});
1212

13-
it('should load the prefetch plugin', () => {
14-
const result = resolveAdvanced({
13+
it('should load the prefetch plugin', async () => {
14+
const result = await resolveAdvanced({
1515
prefetch: 'url',
1616
});
1717
expect(result.options.plugins[0].constructor.name).toEqual('PrefetchPlugin');
1818
});
1919

20+
it('should load the webpack-bundle-analyzer plugin', async () => {
21+
const result = await resolveAdvanced({
22+
analyze: true,
23+
});
24+
expect(result.options.plugins[0].constructor.name).toEqual('BundleAnalyzerPlugin');
25+
});
26+
2027
{
2128
targetValues.map((option) => {
22-
it(`should handle ${option} option`, () => {
23-
const result = resolveAdvanced({
29+
it(`should handle ${option} option`, async () => {
30+
const result = await resolveAdvanced({
2431
target: option,
2532
});
2633
expect(result.options.target).toEqual(option);

packages/webpack-cli/lib/groups/resolveAdvanced.js

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1+
const { packageExists, promptInstallation } = require('@webpack-cli/package-utils');
2+
const { yellow } = require('colorette');
3+
const { error, info } = require('../utils/logger');
4+
15
/**
26
* Resolve advanced flags
37
* @param {args} args - Parsed args passed to CLI
48
*/
5-
const resolveAdvanced = (args) => {
6-
const { target, prefetch, hot } = args;
9+
const resolveAdvanced = async (args) => {
10+
const { target, prefetch, hot, analyze } = args;
711

812
const finalOptions = {
913
options: {},
@@ -28,6 +32,27 @@ const resolveAdvanced = (args) => {
2832
finalOptions.options.plugins = [prefetchVal];
2933
}
3034
}
35+
if (analyze) {
36+
if (packageExists('webpack-bundle-analyzer')) {
37+
// eslint-disable-next-line node/no-extraneous-require
38+
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
39+
const bundleAnalyzerVal = new BundleAnalyzerPlugin();
40+
if (finalOptions.options && finalOptions.options.plugins) {
41+
finalOptions.options.plugins.unshift(bundleAnalyzerVal);
42+
} else {
43+
finalOptions.options.plugins = [bundleAnalyzerVal];
44+
}
45+
} else {
46+
await promptInstallation('webpack-bundle-analyzer', () => {
47+
error(`It looks like ${yellow('webpack-bundle-analyzer')} is not installed.`);
48+
})
49+
.then(() => info(`${yellow('webpack-bundle-analyzer')} was installed sucessfully.`))
50+
.catch(() => {
51+
error(`Action Interrupted, Please try once again or install ${yellow('webpack-bundle-analyzer')} manually.`);
52+
process.exit(2);
53+
});
54+
}
55+
}
3156
if (target) {
3257
finalOptions.options.target = args.target;
3358
}

packages/webpack-cli/lib/utils/cli-flags.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -222,12 +222,13 @@ const core = [
222222
multiple: true,
223223
description: 'Name of the configuration to use',
224224
},
225-
/* {
226-
name: "analyze",
225+
{
226+
name: 'analyze',
227+
usage: '--analyze',
227228
type: Boolean,
228-
group: BASIC_GROUP,
229-
description: "analyze build for performance improvements"
230-
}, */
229+
multiple: false,
230+
description: 'It invokes webpack-bundle-analyzer plugin to get bundle information',
231+
},
231232
/* {
232233
name: "interactive",
233234
type: Boolean,

packages/webpack-cli/package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@
2323
"web"
2424
],
2525
"dependencies": {
26-
"@webpack-cli/package-utils": "^1.0.1-rc.0",
2726
"@webpack-cli/info": "^1.0.1-rc.0",
2827
"@webpack-cli/init": "^1.0.1-rc.0",
28+
"@webpack-cli/package-utils": "^1.0.1-rc.0",
2929
"@webpack-cli/serve": "^1.0.1-rc.0",
3030
"ansi-escapes": "^4.3.1",
3131
"colorette": "^1.2.1",
@@ -42,5 +42,10 @@
4242
"peerDependencies": {
4343
"webpack": "4.x.x || 5.x.x"
4444
},
45+
"peerDependenciesMeta": {
46+
"webpack-bundle-analyzer": {
47+
"optional": true
48+
}
49+
},
4550
"gitHead": "fb50f766851f500ca12867a2aa9de81fa6e368f9"
4651
}

test/analyze/analyze-flag.test.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
'use strict';
2+
3+
const { runWatch, isWindows } = require('../utils/test-utils');
4+
5+
describe('--analyze flag', () => {
6+
// TODO: fix timeout for windows CI
7+
if (isWindows) {
8+
it('TODO: Fix on windows', () => {
9+
expect(true).toBe(true);
10+
});
11+
return;
12+
}
13+
it('should load webpack-bundle-analyzer plugin with --analyze flag', async () => {
14+
const { stderr, stdout } = await runWatch({
15+
testCase: __dirname,
16+
args: ['--analyze'],
17+
setOutput: true,
18+
outputKillStr: 'main',
19+
});
20+
21+
expect(stderr).toBeFalsy();
22+
expect(stdout).toContain('BundleAnalyzerPlugin');
23+
expect(stdout).toContain('Webpack Bundle Analyzer is started at http://127.0.0.1:8888');
24+
});
25+
});

test/analyze/main.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
console.log('webpack-bundle-analyzer is installed');

test/analyze/webpack.config.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const WebpackCLITestPlugin = require('../utils/webpack-cli-test-plugin');
2+
3+
module.exports = {
4+
mode: 'development',
5+
entry: './main.js',
6+
plugins: [new WebpackCLITestPlugin(['plugins'], false)],
7+
};

test/utils/test-utils.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,8 @@ const hyphenToUpperCase = (name) => {
244244
});
245245
};
246246

247+
const isWindows = process.platform === 'win32';
248+
247249
module.exports = {
248250
run,
249251
runWatch,
@@ -256,4 +258,5 @@ module.exports = {
256258
runInfo,
257259
hyphenToUpperCase,
258260
isWebpack5,
261+
isWindows,
259262
};

0 commit comments

Comments
 (0)