@atlaspack/reporter-bundle-analyzer 2.12.1-canary.3354

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ function _assert() {
8
+ const data = _interopRequireDefault(require("assert"));
9
+ _assert = function () {
10
+ return data;
11
+ };
12
+ return data;
13
+ }
14
+ function _plugin() {
15
+ const data = require("@atlaspack/plugin");
16
+ _plugin = function () {
17
+ return data;
18
+ };
19
+ return data;
20
+ }
21
+ function _utils() {
22
+ const data = require("@atlaspack/utils");
23
+ _utils = function () {
24
+ return data;
25
+ };
26
+ return data;
27
+ }
28
+ function _path() {
29
+ const data = _interopRequireDefault(require("path"));
30
+ _path = function () {
31
+ return data;
32
+ };
33
+ return data;
34
+ }
35
+ function _nullthrows() {
36
+ const data = _interopRequireDefault(require("nullthrows"));
37
+ _nullthrows = function () {
38
+ return data;
39
+ };
40
+ return data;
41
+ }
42
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
43
+ var _default = exports.default = new (_plugin().Reporter)({
44
+ async report({
45
+ event,
46
+ options
47
+ }) {
48
+ if (event.type !== 'buildSuccess') {
49
+ return;
50
+ }
51
+ let bundlesByTarget = new (_utils().DefaultMap)(() => []);
52
+ for (let bundle of event.bundleGraph.getBundles()) {
53
+ bundlesByTarget.get(bundle.target.name).push(bundle);
54
+ }
55
+ let reportsDir = _path().default.join(options.projectRoot, 'atlaspack-bundle-reports');
56
+ await options.outputFS.mkdirp(reportsDir);
57
+ await Promise.all([...bundlesByTarget.entries()].map(async ([targetName, bundles]) => {
58
+ return options.outputFS.writeFile(_path().default.join(reportsDir, `${targetName}.html`), `
59
+ <html>
60
+ <head>
61
+ <meta charset="utf-8">
62
+ <title>📦Atlaspack Bundle Analyzer | ${targetName}</title>
63
+ <style>
64
+ body {
65
+ margin: 0;
66
+ }
67
+
68
+ .tooltip {
69
+ background-color: rgba(255, 255, 255, 0.7);
70
+ left: 0;
71
+ padding: 20px;
72
+ pointer-events: none;
73
+ position: absolute;
74
+ top: 0;
75
+ transform: translate3d(0, 0, 0);
76
+ }
77
+
78
+ .tooltip-content {
79
+ font-family: monospace;
80
+ }
81
+
82
+ .tooltip-content dl div {
83
+ display: flex;
84
+ }
85
+
86
+ .tooltip-title {
87
+ font-size: 18px;
88
+ }
89
+ </style>
90
+ <script>
91
+ ${await options.inputFS.readFile(_path().default.resolve(__dirname, '../client/vendor/foamtree/carrotsearch.foamtree.js'), 'utf8')}
92
+ </script>
93
+ <script id="bundle-data" type="application/json">
94
+ ${JSON.stringify(await getBundleData(bundles, options))}
95
+ </script>
96
+ </head>
97
+ <body>
98
+ <script>
99
+ ${await options.inputFS.readFile(_path().default.resolve(__dirname, '../client/index.js'), 'utf8')}
100
+ </script>
101
+ </body>
102
+ </html>
103
+ `);
104
+ }));
105
+ }
106
+ });
107
+ async function getBundleData(bundles, options) {
108
+ let groups = await Promise.all(bundles.map(bundle => getBundleNode(bundle, options)));
109
+ return {
110
+ groups
111
+ };
112
+ }
113
+ let createMap = () => new (_utils().DefaultMap)(() => createMap());
114
+ async function getBundleNode(bundle, options) {
115
+ let buildMetrics = await (0, _utils().generateBuildMetrics)([bundle], options.outputFS, options.projectRoot);
116
+ let bundleData = buildMetrics.bundles[0];
117
+ let dirMap = createMap();
118
+ for (let asset of bundleData.assets) {
119
+ let relativePath = _path().default.relative(options.projectRoot, asset.filePath);
120
+ let parts = relativePath.split(_path().default.sep);
121
+ let dirs = parts.slice(0, parts.length - 1);
122
+ let basename = _path().default.basename(asset.filePath);
123
+ let map = dirMap;
124
+ for (let dir of dirs) {
125
+ (0, _assert().default)(map instanceof _utils().DefaultMap);
126
+ map = map.get(dir);
127
+ }
128
+ (0, _assert().default)(map instanceof _utils().DefaultMap);
129
+ map.set(basename, {
130
+ basename,
131
+ size: asset.size
132
+ });
133
+ }
134
+ return {
135
+ label: _path().default.relative(options.projectRoot, bundle.filePath),
136
+ weight: bundle.stats.size,
137
+ groups: generateGroups(dirMap)
138
+ };
139
+ }
140
+ function generateGroups(dirMap) {
141
+ let groups = [];
142
+ for (let [directoryName, contents] of dirMap) {
143
+ if (contents instanceof _utils().DefaultMap) {
144
+ let childrenGroups = generateGroups(contents);
145
+ if (childrenGroups.length === 1) {
146
+ let firstChild = childrenGroups[0];
147
+ groups.push({
148
+ ...firstChild,
149
+ label: _path().default.join(directoryName, firstChild.label)
150
+ });
151
+ } else {
152
+ groups.push({
153
+ label: directoryName,
154
+ weight: childrenGroups.reduce((acc, g) => acc + (0, _nullthrows().default)(g.weight), 0),
155
+ groups: childrenGroups
156
+ });
157
+ }
158
+ } else {
159
+ // file
160
+ groups.push({
161
+ label: contents.basename === '' ? 'Code from unknown source files' : contents.basename,
162
+ weight: contents.size
163
+ });
164
+ }
165
+ }
166
+ return groups;
167
+ }
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@atlaspack/reporter-bundle-analyzer",
3
+ "version": "2.12.1-canary.3354+7bb54d46a",
4
+ "license": "MIT",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/atlassian-labs/atlaspack.git"
11
+ },
12
+ "main": "lib/BundleAnalyzerReporter.js",
13
+ "source": "src/BundleAnalyzerReporter.js",
14
+ "engines": {
15
+ "node": ">= 16.0.0",
16
+ "atlaspack": "2.12.1-canary.3354+7bb54d46a"
17
+ },
18
+ "dependencies": {
19
+ "@atlaspack/plugin": "2.12.1-canary.3354+7bb54d46a",
20
+ "@atlaspack/utils": "2.12.1-canary.3354+7bb54d46a",
21
+ "nullthrows": "^1.1.1"
22
+ },
23
+ "devDependencies": {
24
+ "@atlaspack/types": "2.12.1-canary.3354+7bb54d46a"
25
+ },
26
+ "gitHead": "7bb54d46a00c5ba9cdbc2ee426dcbe82c8d79a3e"
27
+ }
@@ -0,0 +1,192 @@
1
+ // @flow strict-local
2
+
3
+ import type {FilePath, PackagedBundle, PluginOptions} from '@atlaspack/types';
4
+
5
+ import invariant from 'assert';
6
+ import {Reporter} from '@atlaspack/plugin';
7
+ import {DefaultMap, generateBuildMetrics} from '@atlaspack/utils';
8
+ import path from 'path';
9
+ import nullthrows from 'nullthrows';
10
+
11
+ export default (new Reporter({
12
+ async report({event, options}) {
13
+ if (event.type !== 'buildSuccess') {
14
+ return;
15
+ }
16
+
17
+ let bundlesByTarget: DefaultMap<
18
+ string /* target name */,
19
+ Array<PackagedBundle>,
20
+ > = new DefaultMap(() => []);
21
+ for (let bundle of event.bundleGraph.getBundles()) {
22
+ bundlesByTarget.get(bundle.target.name).push(bundle);
23
+ }
24
+
25
+ let reportsDir = path.join(options.projectRoot, 'atlaspack-bundle-reports');
26
+ await options.outputFS.mkdirp(reportsDir);
27
+
28
+ await Promise.all(
29
+ [...bundlesByTarget.entries()].map(async ([targetName, bundles]) => {
30
+ return options.outputFS.writeFile(
31
+ path.join(reportsDir, `${targetName}.html`),
32
+ `
33
+ <html>
34
+ <head>
35
+ <meta charset="utf-8">
36
+ <title>📦Atlaspack Bundle Analyzer | ${targetName}</title>
37
+ <style>
38
+ body {
39
+ margin: 0;
40
+ }
41
+
42
+ .tooltip {
43
+ background-color: rgba(255, 255, 255, 0.7);
44
+ left: 0;
45
+ padding: 20px;
46
+ pointer-events: none;
47
+ position: absolute;
48
+ top: 0;
49
+ transform: translate3d(0, 0, 0);
50
+ }
51
+
52
+ .tooltip-content {
53
+ font-family: monospace;
54
+ }
55
+
56
+ .tooltip-content dl div {
57
+ display: flex;
58
+ }
59
+
60
+ .tooltip-title {
61
+ font-size: 18px;
62
+ }
63
+ </style>
64
+ <script>
65
+ ${await options.inputFS.readFile(
66
+ path.resolve(
67
+ __dirname,
68
+ '../client/vendor/foamtree/carrotsearch.foamtree.js',
69
+ ),
70
+ 'utf8',
71
+ )}
72
+ </script>
73
+ <script id="bundle-data" type="application/json">
74
+ ${JSON.stringify(await getBundleData(bundles, options))}
75
+ </script>
76
+ </head>
77
+ <body>
78
+ <script>
79
+ ${await options.inputFS.readFile(
80
+ path.resolve(__dirname, '../client/index.js'),
81
+ 'utf8',
82
+ )}
83
+ </script>
84
+ </body>
85
+ </html>
86
+ `,
87
+ );
88
+ }),
89
+ );
90
+ },
91
+ }): Reporter);
92
+
93
+ type BundleData = {|
94
+ groups: Array<Group>,
95
+ |};
96
+
97
+ async function getBundleData(
98
+ bundles: Array<PackagedBundle>,
99
+ options: PluginOptions,
100
+ ): Promise<BundleData> {
101
+ let groups = await Promise.all(
102
+ bundles.map(bundle => getBundleNode(bundle, options)),
103
+ );
104
+ return {
105
+ groups,
106
+ };
107
+ }
108
+
109
+ type File = {|
110
+ basename: string,
111
+ size: number,
112
+ |};
113
+ type DirMapValue = File | DirMap;
114
+ type DirMap = DefaultMap<FilePath, DirMapValue>;
115
+ let createMap: () => DirMap = () => new DefaultMap(() => createMap());
116
+
117
+ async function getBundleNode(bundle: PackagedBundle, options: PluginOptions) {
118
+ let buildMetrics = await generateBuildMetrics(
119
+ [bundle],
120
+ options.outputFS,
121
+ options.projectRoot,
122
+ );
123
+ let bundleData = buildMetrics.bundles[0];
124
+ let dirMap = createMap();
125
+ for (let asset of bundleData.assets) {
126
+ let relativePath = path.relative(options.projectRoot, asset.filePath);
127
+ let parts = relativePath.split(path.sep);
128
+ let dirs = parts.slice(0, parts.length - 1);
129
+ let basename = path.basename(asset.filePath);
130
+
131
+ let map = dirMap;
132
+ for (let dir of dirs) {
133
+ invariant(map instanceof DefaultMap);
134
+ map = map.get(dir);
135
+ }
136
+
137
+ invariant(map instanceof DefaultMap);
138
+ map.set(basename, {
139
+ basename,
140
+ size: asset.size,
141
+ });
142
+ }
143
+
144
+ return {
145
+ label: path.relative(options.projectRoot, bundle.filePath),
146
+ weight: bundle.stats.size,
147
+ groups: generateGroups(dirMap),
148
+ };
149
+ }
150
+
151
+ type Group = {|
152
+ label: string,
153
+ weight: number,
154
+ groups?: Array<Group>,
155
+ |};
156
+
157
+ function generateGroups(dirMap: DirMap): Array<Group> {
158
+ let groups = [];
159
+
160
+ for (let [directoryName, contents] of dirMap) {
161
+ if (contents instanceof DefaultMap) {
162
+ let childrenGroups = generateGroups(contents);
163
+ if (childrenGroups.length === 1) {
164
+ let firstChild = childrenGroups[0];
165
+ groups.push({
166
+ ...firstChild,
167
+ label: path.join(directoryName, firstChild.label),
168
+ });
169
+ } else {
170
+ groups.push({
171
+ label: directoryName,
172
+ weight: childrenGroups.reduce(
173
+ (acc, g) => acc + nullthrows(g.weight),
174
+ 0,
175
+ ),
176
+ groups: childrenGroups,
177
+ });
178
+ }
179
+ } else {
180
+ // file
181
+ groups.push({
182
+ label:
183
+ contents.basename === ''
184
+ ? 'Code from unknown source files'
185
+ : contents.basename,
186
+ weight: contents.size,
187
+ });
188
+ }
189
+ }
190
+
191
+ return groups;
192
+ }