react-native-bundle-discovery 1.0.0-rc.10

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,194 @@
1
+ const {
2
+ metadata,
3
+ getModulesTree,
4
+ getPackage,
5
+ getPackageList,
6
+ } = require("./_common");
7
+
8
+ const topMetaData = [
9
+ metadata.platform,
10
+ metadata.size,
11
+ metadata.source_code_size,
12
+ metadata.node_modules_size,
13
+ metadata.is_dev,
14
+ metadata.is_minified,
15
+ ];
16
+
17
+ const TABS = {
18
+ TREEMAP_FOAMTREE: "treemap-foamtree",
19
+ MODULES: "modules",
20
+ PACKAGES: "packages",
21
+ DUPLICATES: "duplicates",
22
+ };
23
+
24
+ function parseHashRef(url = window.location.href) {
25
+ return new URL(url).hash.split(":")?.[1];
26
+ }
27
+
28
+ discovery.page.define("default", [
29
+ ...topMetaData,
30
+
31
+ {
32
+ view: "tabs",
33
+ name: "mainTabs",
34
+ className: "main-tabs",
35
+ value: parseHashRef() ?? TABS.TREEMAP_FOAMTREE,
36
+ tabs: [
37
+ {
38
+ value: TABS.TREEMAP_FOAMTREE,
39
+ text: "Treemap chart",
40
+ className: `main-tabs-${TABS.TREEMAP_FOAMTREE}`,
41
+ },
42
+ {
43
+ value: TABS.PACKAGES,
44
+ className: `main-tabs-${TABS.PACKAGES}`,
45
+ content: [
46
+ "text:'Packages '",
47
+ `pill-badge: modules.filter(=> path has "node_modules").group(=> path.getModulesName(), => 0).size()`,
48
+ ],
49
+ },
50
+ {
51
+ value: TABS.MODULES,
52
+ className: `main-tabs-${TABS.MODULES}`,
53
+ content: ["text:'Modules '", "pill-badge: modules.size()"],
54
+ },
55
+ {
56
+ value: TABS.DUPLICATES,
57
+ className: `main-tabs-${TABS.DUPLICATES}`,
58
+ content: [
59
+ "text:'Duplicate modules '",
60
+ "pill-badge: modules.filter(=> duplicates).size()",
61
+ ],
62
+ },
63
+ ],
64
+ content: {
65
+ view: "switch",
66
+ context(data, context) {
67
+ // FIXME - common nobody handle navigation in such way :(
68
+ const isHashChangeEvent = new Error("").stack.includes("Promise.all");
69
+ discovery.overridePageHashStateWithAnchor({
70
+ id: "default",
71
+ ref: isHashChangeEvent ? discovery.pageRef : context.mainTabs,
72
+ });
73
+ discovery.cancelScheduledRender();
74
+
75
+ const id = discovery.pageRef ?? TABS.TREEMAP_FOAMTREE;
76
+
77
+ setTimeout(() => {
78
+ discovery.dom.root
79
+ .querySelectorAll(".main-tabs>div>.onclick")
80
+ .forEach((e) => e.classList.remove("active"));
81
+ discovery.dom.root
82
+ .querySelectorAll(`.main-tabs .main-tabs-${id}`)
83
+ .forEach((e) => e.classList.add("active"));
84
+ }, 50);
85
+
86
+ return {
87
+ ...context,
88
+ id,
89
+ };
90
+ },
91
+ content: [
92
+ {
93
+ when: `#.id="${TABS.TREEMAP_FOAMTREE}"`,
94
+ content: {
95
+ view: "content-filter",
96
+ name: "filterByPathStr",
97
+ debounce: 300,
98
+ className: "foamtree-filter",
99
+ content: {
100
+ view: "foamtree",
101
+ data: `
102
+ $root: $.rootFolder;
103
+ $applyFilter: => #.filterByPathStr ? $.modules.filter(=> $.path ~= #.filterByPathStr) : $.modules;
104
+ $dataObject: $.$applyFilter()
105
+ .map(=> {path, size: $.output.sizeInBytes})
106
+ .transformFilesList($root, "foamtree");
107
+
108
+ {
109
+ options: {
110
+ dataObject: $dataObject,
111
+ descriptionGroupSize: 0.05,
112
+ descriptionGroupMinHeight: 30,
113
+ }
114
+ }
115
+ `,
116
+ },
117
+ },
118
+ },
119
+ {
120
+ when: `#.id="${TABS.MODULES}"`,
121
+ content: getModulesTree({
122
+ limit: 200,
123
+ data: `
124
+ $entryPoint: $.entryPointPath;
125
+ $totalSize: modules.sum(=>output.sizeInBytes);
126
+ $toModule: => {
127
+ ext: $.path.getFileExtension(),
128
+ name: $.path,
129
+ size: $.output.sizeInBytes.formatBytes(),
130
+ percent: ($.output.sizeInBytes / $totalSize).percent(3),
131
+ };
132
+ modules.map(=> {
133
+ ...$.$toModule(),
134
+ isEntry: $.isEntry,
135
+ reasons: $.dependents.map(=> $.$toModule()),
136
+ duplicates: $.duplicates.map(=> $.$toModule()),
137
+ })
138
+ `,
139
+ }),
140
+ },
141
+ {
142
+ when: `#.id="${TABS.PACKAGES}"`,
143
+ content: [
144
+ {
145
+ view: "content-filter",
146
+ data: `${getPackage(`modules.filter(=> path has "node_modules")`)}.sort(pkgInstances desc, size desc)`,
147
+ name: "filterByPathStr",
148
+ content: getPackageList({
149
+ showCopiesBadge: true,
150
+ expanded: false,
151
+ limit: 200,
152
+ subLimit: 50,
153
+ data: ".[pkgName ~= #.filterByPathStr]",
154
+ itemPkgName: {
155
+ view: "link",
156
+ content: "text-match",
157
+ data: `{
158
+ href: pkgName.pageLink("package", {}),
159
+ text: pkgName,
160
+ match: #.filterByPathStr
161
+ }`,
162
+ },
163
+ }),
164
+ },
165
+ ],
166
+ },
167
+ {
168
+ when: `#.id="${TABS.DUPLICATES}"`,
169
+ content: getModulesTree({
170
+ data: `
171
+ // values
172
+ $duplicatesOnly: modules.filter(=> duplicates);
173
+ $totalSize: $duplicatesOnly.sum(=>output.sizeInBytes);
174
+ $toModule: => {
175
+ ext: $.path.getFileExtension(),
176
+ name: $.path,
177
+ size: $.output.sizeInBytes.formatBytes(),
178
+ percent: ($.output.sizeInBytes / $totalSize).percent(3),
179
+ };
180
+ // return
181
+ $duplicatesOnly.map(=> {
182
+ ...$.$toModule(),
183
+ reasons: $.dependents.map(=> $.$toModule()),
184
+ duplicates: $.duplicates.map(=> $.$toModule()),
185
+ })
186
+ `,
187
+ }),
188
+ },
189
+ ],
190
+ },
191
+ },
192
+
193
+ // END
194
+ ]);
@@ -0,0 +1,296 @@
1
+ const {
2
+ getModulesTree,
3
+ getTreeModule,
4
+ getCopyToClipboardButton,
5
+ } = require("./_common");
6
+
7
+ function getMetroWarn({ when, href, linkText, content }) {
8
+ return {
9
+ view: "alert-warning",
10
+ when,
11
+ className: "m-v-8",
12
+ content: [
13
+ ...content,
14
+ {
15
+ view: "link",
16
+ data: {
17
+ external: true,
18
+ href,
19
+ text: linkText,
20
+ },
21
+ },
22
+ ],
23
+ };
24
+ }
25
+
26
+ discovery.page.define("module", {
27
+ view: "context",
28
+ data: `{
29
+ $currentModule: $.modules.[path = #.id].pick(0);
30
+ ...$,
31
+ currentModule: $currentModule,
32
+ isEntry: $currentModule.isEntry,
33
+ isInjectedByMetro: $currentModule.path = '__prelude__' or $currentModule.path has '@react-native/js-polyfills',
34
+ }`,
35
+ content: [
36
+ {
37
+ view: "h2",
38
+ content: [
39
+ //
40
+ 'text: "Module: "',
41
+ "text: $.currentModule.path",
42
+ getCopyToClipboardButton({
43
+ textToCopy: `$.currentModule.path`,
44
+ className: "m-l-0_5em",
45
+ }),
46
+ ],
47
+ },
48
+
49
+ {
50
+ view: "tabs",
51
+ name: "tabs",
52
+ // value: "networkGraph", //FIXME
53
+ tabs: [
54
+ {
55
+ value: "mcontent",
56
+ text: "Module content",
57
+ },
58
+ {
59
+ value: "networkGraph",
60
+ when: "not isInjectedByMetro and not isEntry",
61
+ text: "Imported by modules",
62
+ },
63
+ {
64
+ value: "mduplicates",
65
+ when: "not isInjectedByMetro and not isEntry and currentModule.duplicates",
66
+ text: "Duplicates",
67
+ },
68
+ ],
69
+ content: {
70
+ view: "switch",
71
+ content: [
72
+ {
73
+ when: '#.tabs="mcontent"',
74
+ content: [
75
+ getMetroWarn({
76
+ when: "$.currentModule.path = '__prelude__'",
77
+ content: [
78
+ "html: '<b>__prelude__</b>'",
79
+ "text: ' is a special runtime code that was generated by the Metro bundler, see: '",
80
+ ],
81
+ href: "https://github.com/facebook/metro/blob/f595e9e1c9021ad372b489be8958cc298eb1e0d9/packages/metro/src/lib/getPreludeCode.js#L25-L33",
82
+ linkText: "getPreludeCode.js",
83
+ }),
84
+ getMetroWarn({
85
+ when: "$.currentModule.path has '@react-native/js-polyfills'",
86
+ content: [
87
+ "html: '<b>@react-native/js-polyfills/*</b>'",
88
+ "text: ' is a special package that was injected by the Metro bundler, see: '",
89
+ ],
90
+ href: "https://github.com/facebook/react-native/blob/198c6fc81cda67a46fff457cc39eb2a297eddc01/packages/metro-config/src/index.flow.js#L61",
91
+ linkText: "rn/metro-config/index.js",
92
+ }),
93
+ getMetroWarn({
94
+ when: "$.currentModule.path has 'metro-runtime'",
95
+ content: [
96
+ "html: '<b>metro-runtime/*</b>'",
97
+ "text: ' is a special package that was injected by the Metro bundler, see: '",
98
+ ],
99
+ href: "https://github.com/facebook/metro/blob/f595e9e1c9021ad372b489be8958cc298eb1e0d9/packages/metro-config/src/defaults/defaults.js#L61-L63",
100
+ linkText: "metro-config/index.js",
101
+ }),
102
+ {
103
+ view: "hstack",
104
+ className: "flex-no-wrap",
105
+ content: [
106
+ {
107
+ view: "block",
108
+ className: "width-50p",
109
+ content: [
110
+ "h5: 'Source'",
111
+ {
112
+ view: "source",
113
+ syntax: "ts",
114
+ source: "=$.currentModule.source.code",
115
+ },
116
+ ],
117
+ },
118
+ {
119
+ view: "block",
120
+ className: "width-50p",
121
+ content: [
122
+ "h5: 'Output'",
123
+ {
124
+ view: "source",
125
+ syntax: "ts",
126
+ source: "=$.currentModule.output.code",
127
+ },
128
+ ],
129
+ },
130
+ ],
131
+ },
132
+ ],
133
+ },
134
+ {
135
+ when: '#.tabs="networkGraph"',
136
+ content: {
137
+ view: "context",
138
+ context: `{ ...#, maxParentDepth: $.currentModule.getBestNetworkGraphSize() }`,
139
+ modifiers: [
140
+ "html: '<br/>'",
141
+ "text:'Max parent depth: '",
142
+ {
143
+ view: "input",
144
+ name: "maxParentDepth",
145
+ className: "inline-block",
146
+ htmlType: "number",
147
+ htmlMin: 1,
148
+ htmlMax: 10,
149
+ },
150
+ ],
151
+ content: [
152
+ {
153
+ view: "context",
154
+ data: `{
155
+ // Vars
156
+ $tmp: $.currentModule.getNetworkGraph({ maxParentDepth: #.maxParentDepth });
157
+ $limit: 150;
158
+ // Return data
159
+ currentModule: $.currentModule,
160
+ entryPointPath: $tmp.entryPointPath,
161
+ limit: $limit,
162
+ data: $tmp.data,
163
+ isGraphTooBig: $tmp.data.size() > $limit,
164
+ }`,
165
+ content: [
166
+ // TODO use for debugging
167
+ // {
168
+ // view: "struct",
169
+ // expanded: 2,
170
+ // },
171
+ {
172
+ when: "isGraphTooBig",
173
+ view: "block",
174
+ className: "m-v-8",
175
+ content: [
176
+ {
177
+ view: "alert-warning",
178
+ data: '"Amount of dependencies "+$.data.size()+" (limit: "+$.limit+") are too big to display as a graph :("',
179
+ },
180
+ ],
181
+ },
182
+ {
183
+ view: "hstack",
184
+ className: "flex-no-wrap two-column",
185
+ content: [
186
+ {
187
+ when: "not isGraphTooBig",
188
+ view: "highcharts",
189
+ data: `{
190
+ options: {
191
+ chart: {
192
+ type: "networkgraph",
193
+ height: "500px",
194
+ },
195
+ title: {
196
+ text: "Import Dependency Graph",
197
+ align: "left",
198
+ },
199
+ subtitle: {
200
+ text: "It shows which modules import this file (Red - current module, Gold - entry point)",
201
+ align: "left",
202
+ },
203
+ plotOptions: {
204
+ networkgraph: {
205
+ keys: ["from", "to"],
206
+ layoutAlgorithm: {
207
+ enableSimulation: true,
208
+ friction: -0.9,
209
+ gravitationalConstant: 0.06,
210
+ },
211
+ },
212
+ },
213
+ series: [
214
+ {
215
+ accessibility: {
216
+ enabled: false,
217
+ },
218
+ dataLabels: {
219
+ enabled: true,
220
+ linkFormat: "",
221
+ style: {
222
+ fontSize: "0.8em",
223
+ fontWeight: "normal",
224
+ },
225
+ },
226
+ id: "lang-tree",
227
+ data: $.data,
228
+ nodes:[
229
+ { id: $.currentModule.path, marker: { radius: 15, fillColor: 'red' }, },
230
+ { id: $.entryPointPath, marker: { radius: 15, fillColor: 'gold' } }
231
+ ].filter(=> id),
232
+ },
233
+ ],
234
+ },
235
+ }`,
236
+ },
237
+
238
+ {
239
+ view: "block",
240
+ content: [
241
+ "h4: 'Modules that import this file: ' + $.currentModule.path",
242
+ {
243
+ view: "list",
244
+ data: `
245
+ $totalSize: modules.sum(=>output.sizeInBytes);
246
+ $toModule: => {
247
+ $deepIdx: $$ + 1;
248
+ ext: $.path.getFileExtension(),
249
+ name: $.path,
250
+ size: $.output.sizeInBytes.formatBytes(),
251
+ percent: ($.output.sizeInBytes / $totalSize).percent(3),
252
+ children: $deepIdx < 2 ? $.dependents.map(=> $.$toModule()) : null,
253
+ };
254
+ $.currentModule.dependents.map(=> $.$toModule(0))
255
+ `,
256
+ emptyText: "⚠️ No importing modules found",
257
+ item: {
258
+ view: "tree",
259
+ expanded: false,
260
+ itemConfig: {
261
+ content: getTreeModule({
262
+ hasTextMatch: true,
263
+ }),
264
+ children: `$.children`,
265
+ },
266
+ },
267
+ },
268
+ ],
269
+ },
270
+ ],
271
+ },
272
+ ],
273
+ },
274
+ ],
275
+ },
276
+ },
277
+ {
278
+ when: '#.tabs="mduplicates"',
279
+ content: getModulesTree({
280
+ data: `
281
+ $totalSize: modules.sum(=>output.sizeInBytes);
282
+ $toModule: => {
283
+ ext: $.path.getFileExtension(),
284
+ name: $.path,
285
+ size: $.output.sizeInBytes.formatBytes(),
286
+ percent: ($.output.sizeInBytes / $totalSize).percent(3),
287
+ };
288
+ currentModule.duplicates.map(=> $.$toModule())
289
+ `,
290
+ }),
291
+ },
292
+ ],
293
+ },
294
+ },
295
+ ],
296
+ });
@@ -0,0 +1,150 @@
1
+ const { externalLinkHtml } = require("./_common.js");
2
+ const {
3
+ getTreeModule,
4
+ getPackage,
5
+ getPackageList,
6
+ getCopyToClipboardButton,
7
+ } = require("./_common");
8
+
9
+ discovery.page.define("package", {
10
+ view: "context",
11
+ data: `
12
+ // Tmp variables
13
+ $currentPkgName: #.id;
14
+ ${getPackage(`$pkg: modules.filter(=> path has "node_modules" and path has $currentPkgName)`)}[0];
15
+ $copies: $pkg.pkgInstances.size() - 1;
16
+ $ver: $pkg.pkgInstances[0].version;
17
+
18
+ // Return value
19
+ {
20
+ ...$,
21
+ currentPkgHasCopies: $copies > 0,
22
+ currentPkgCopiesCount: $copies,
23
+ currentPkgVersion: $ver,
24
+ currentPkgWithUniqVer: $pkg.pkgName + ($copies = 0 ? '@' + $ver : ''),
25
+ currentPkgWithUniqVerNpm: $pkg.pkgName + ($copies = 0 ? '/v/' + $ver : ''),
26
+ currentPkg: $pkg,
27
+ }
28
+ `,
29
+ content: [
30
+ // TODO uncomment for debugging
31
+ // {
32
+ // view: "struct",
33
+ // data: "$.currentPkg",
34
+ // },
35
+
36
+ {
37
+ view: "block",
38
+ content: [
39
+ {
40
+ view: "h1",
41
+ className: "inline-block no-margin",
42
+ content: `badge: {
43
+ text: $.currentPkgWithUniqVer,
44
+ color: "#fffb5a",
45
+ }`,
46
+ },
47
+ {
48
+ when: "$.currentPkgCopiesCount > 0",
49
+ view: "h2",
50
+ className: "inline-block no-margin",
51
+ content: [
52
+ `badge: {
53
+ text: '+' + $.currentPkgCopiesCount,
54
+ postfix: $.currentPkgCopiesCount = 1 ? 'copy' : 'copies',
55
+ color: "rgba(255, 0, 0, 0.35)"
56
+ }`,
57
+ ],
58
+ },
59
+ getCopyToClipboardButton({
60
+ textToCopy: `$.currentPkg.pkgName`,
61
+ className: "m-l-0_5em",
62
+ }),
63
+ ],
64
+ },
65
+
66
+ "html: '<br>'",
67
+
68
+ {
69
+ view: "block",
70
+ content: [
71
+ "text: 'Links: '",
72
+ {
73
+ view: "link",
74
+ external: true,
75
+ data: `{ href: "https://www.npmjs.com/package/" + currentPkgWithUniqVerNpm }`,
76
+ content: [
77
+ "text: 'npmjs.com'",
78
+ `html: '<span class="my-icon-inline my-icon-12">${externalLinkHtml}</span>'`,
79
+ ],
80
+ },
81
+ "text: ' '",
82
+ {
83
+ view: "link",
84
+ external: true,
85
+ data: `{ href: "https://bundlephobia.com/package/" + currentPkgWithUniqVer }`,
86
+ content: [
87
+ "text: 'bundlephobia.com'",
88
+ `html: '<span class="my-icon-inline my-icon-12">${externalLinkHtml}</span>'`,
89
+ ],
90
+ },
91
+ "text: ' '",
92
+ {
93
+ view: "link",
94
+ external: true,
95
+ data: `{ href: "https://packagephobia.com/result?p=" + currentPkgWithUniqVer }`,
96
+ content: [
97
+ "text: 'packagephobia.com'",
98
+ `html: '<span class="my-icon-inline my-icon-12">${externalLinkHtml}</span>'`,
99
+ ],
100
+ },
101
+ ],
102
+ },
103
+
104
+ "html: '<hr>'",
105
+
106
+ {
107
+ view: "block",
108
+ content: getPackageList({
109
+ data: "$.currentPkg",
110
+ itemPkgName: "text: pkgName",
111
+ showCopiesBadge: false,
112
+ expanded: true,
113
+ }),
114
+
115
+ /*[
116
+ {
117
+ view: "list",
118
+ data: "$.currentPkg",
119
+ item: {
120
+ view: "tree",
121
+ expanded: true,
122
+ itemConfig: {
123
+ content: [
124
+ "text: pkgName",
125
+ "text: ' '",
126
+ "pill-badge:{ text: size.formatBytes(), color: 'rgba(120, 177, 9, 0.35)' }",
127
+ ],
128
+ children: `$.pkgInstances`,
129
+ itemConfig: {
130
+ view: "tree-leaf",
131
+ content: [
132
+ //
133
+ "text:pkgName",
134
+ "text:' '",
135
+ "pill-badge:{ text: 'v' + version, color: '#0af' }",
136
+ "pill-badge:{ text: size.formatBytes(), color: 'rgba(120, 177, 9, 0.35)' }",
137
+ ],
138
+ children: `$.modules`,
139
+ itemConfig: {
140
+ view: "tree-leaf",
141
+ content: getTreeModule({ hasPercent: false }),
142
+ },
143
+ },
144
+ },
145
+ },
146
+ },
147
+ ]*/
148
+ },
149
+ ],
150
+ });