react-native-bundle-discovery 2.6.0 → 2.7.0-rc.0
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.
- package/README.md +168 -117
- package/dist/index.d.ts +262 -0
- package/dist/index.js +731 -0
- package/package.json +21 -10
- package/index.js +0 -301
- package/packageMetadata.js +0 -155
- package/parseUtils.js +0 -615
- package/webpack.js +0 -373
package/README.md
CHANGED
|
@@ -1,72 +1,92 @@
|
|
|
1
1
|
# react-native-bundle-discovery
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/react-native-bundle-discovery)
|
|
4
|
+
[](https://www.npmtrends.com/react-native-bundle-discovery)
|
|
5
|
+
[](https://www.npmjs.com/package/react-native-bundle-discovery)
|
|
6
|
+
|
|
7
|
+
Visualize and analyze the JS bundle of your React Native app. Find heavy packages, duplicates and deprecated
|
|
8
|
+
dependencies, inspect every module, and catch bundle size regressions in CI.
|
|
9
|
+
|
|
10
|
+
<img width="800" alt="Bundle Discovery UI" src="./assets/img.png" />
|
|
11
|
+
|
|
12
|
+
## Contents
|
|
13
|
+
|
|
14
|
+
- [Features](#features)
|
|
15
|
+
- [Packages](#packages)
|
|
16
|
+
- [Quick start](#quick-start)
|
|
17
|
+
- [Other setups](#other-setups)
|
|
18
|
+
- [Usage](#usage)
|
|
19
|
+
- [UI](#ui)
|
|
20
|
+
- [CLI](#cli)
|
|
21
|
+
- [Bundle size checks in CI](#bundle-size-checks-in-ci)
|
|
22
|
+
- [API](#api)
|
|
23
|
+
- [`createSerializer`](#createserializeroptions)
|
|
24
|
+
- [`createResolveRequest`](#createresolverequestoptions)
|
|
25
|
+
- [Similar projects](#similar-projects)
|
|
26
|
+
- [Support the project](#support-the-project)
|
|
27
|
+
- [License](#license)
|
|
28
|
+
|
|
29
|
+
## Features
|
|
30
|
+
|
|
31
|
+
- 📊 Interactive UI to explore packages, modules and their source/bundled code
|
|
32
|
+
- 💡 Optimization recommendations (duplicates, deprecated / outdated / dev-only packages, and more)
|
|
33
|
+
- 🔍 CLI to list the heaviest packages and modules
|
|
34
|
+
- 🆚 Compare two reports and fail CI on bundle size regressions
|
|
35
|
+
- 🧩 Works with Metro, [Re.Pack](./Re.Pack.md) and [React Native DevTools](./packages/rozenite-plugin/README.md) (via Rozenite)
|
|
36
|
+
|
|
37
|
+
## Packages
|
|
38
|
+
|
|
39
|
+
| Package | What it does | Required |
|
|
40
|
+
| ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------- | -------- |
|
|
41
|
+
| `react-native-bundle-discovery` | Generates a JSON report (`metro-stats.json`) of your bundle | ✅ Yes |
|
|
42
|
+
| `react-native-bundle-discovery-ui` | Shows the report in the browser | Optional |
|
|
43
|
+
| `react-native-bundle-discovery-cli` | Analyzes and compares reports in the terminal / CI | Optional |
|
|
44
|
+
| [`react-native-bundle-discovery-rozenite-plugin`](./packages/rozenite-plugin/README.md) | Shows the UI inside [React Native DevTools](https://reactnative.dev/docs/react-native-devtools) | Optional |
|
|
45
|
+
|
|
46
|
+
## Quick start
|
|
47
|
+
|
|
48
|
+
This setup is for a standard **Metro** project.
|
|
49
|
+
Using Re.Pack or Rozenite? See [Other setups](#other-setups).
|
|
50
|
+
|
|
51
|
+
> [!TIP]
|
|
52
|
+
> **Using an AI coding agent?** Skip the manual steps below. Point your agent (Claude Code, Cursor, Codex, etc.)
|
|
53
|
+
> at the [`setup-react-native-bundle-discovery`](./skills/setup-react-native-bundle-discovery/SKILL.md) skill.
|
|
54
|
+
> It installs the package and sets up Metro or Re.Pack for you:
|
|
28
55
|
>
|
|
29
|
-
>
|
|
56
|
+
> ```bash
|
|
57
|
+
> npx skills add retyui/react-native-bundle-discovery
|
|
58
|
+
> ```
|
|
30
59
|
|
|
31
|
-
|
|
60
|
+
### 1. Install
|
|
32
61
|
|
|
33
62
|
```bash
|
|
34
|
-
yarn add -D react-native-bundle-discovery
|
|
35
|
-
yarn add -D react-native-bundle-discovery-ui
|
|
36
|
-
yarn add -D react-native-bundle-discovery-cli
|
|
63
|
+
yarn add -D react-native-bundle-discovery # required: generates the report
|
|
64
|
+
yarn add -D react-native-bundle-discovery-ui # optional: browser UI
|
|
65
|
+
yarn add -D react-native-bundle-discovery-cli # optional: CLI
|
|
37
66
|
```
|
|
38
67
|
|
|
39
|
-
|
|
68
|
+
### 2. Configure Metro
|
|
40
69
|
|
|
41
70
|
```diff
|
|
42
71
|
// metro.config.js
|
|
43
|
-
const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
|
|
44
|
-
+const {createSerializer} = require('react-native-bundle-discovery');
|
|
45
|
-
|
|
46
|
-
+const mySerializer = createSerializer({
|
|
47
|
-
+ includeCode: true, // Useful if you want to compare source/bundle code (but a report file will be larger)
|
|
48
|
-
+ projectRoot: __dirname,
|
|
49
|
-
+ //^^^ ⚠️ WARNING: In a monorepo setup, this should point to the monorepo root,
|
|
50
|
-
+ // not the individual package directory.
|
|
51
|
-
+});
|
|
72
|
+
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
|
|
73
|
+
+const { createSerializer } = require('react-native-bundle-discovery');
|
|
52
74
|
|
|
53
75
|
-const config = {};
|
|
54
76
|
+const config = {
|
|
55
|
-
serializer: {
|
|
56
|
-
|
|
77
|
+
+ serializer: {
|
|
78
|
+
+ customSerializer: createSerializer({
|
|
79
|
+
+ projectRoot: __dirname, // ⚠️ In a monorepo, use the monorepo root instead
|
|
80
|
+
+ }),
|
|
81
|
+
+ },
|
|
82
|
+
+};
|
|
57
83
|
|
|
58
84
|
module.exports = mergeConfig(getDefaultConfig(__dirname), config);
|
|
59
85
|
```
|
|
60
86
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
See: [_rozenite/README.md](_rozenite/README.md)
|
|
64
|
-
|
|
65
|
-
---
|
|
87
|
+
See all options in [`createSerializer`](#createserializeroptions).
|
|
66
88
|
|
|
67
|
-
### 3. Build
|
|
68
|
-
|
|
69
|
-
For example, for iOS you can run the following command, and it will generate the `metro-stats.json` file in the root of your project:
|
|
89
|
+
### 3. Build a release bundle
|
|
70
90
|
|
|
71
91
|
```bash
|
|
72
92
|
npx react-native bundle \
|
|
@@ -77,122 +97,153 @@ npx react-native bundle \
|
|
|
77
97
|
--assets-dest ios/assets
|
|
78
98
|
```
|
|
79
99
|
|
|
80
|
-
|
|
100
|
+
This writes `metro-stats.json` to your project root.
|
|
101
|
+
|
|
102
|
+
### 4. Explore the report
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
npx react-native-bundle-discovery-ui metro-stats.json # open in the browser
|
|
106
|
+
npx react-native-bundle-discovery-cli metro-stats.json # get recommendations in the terminal
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Other setups
|
|
110
|
+
|
|
111
|
+
| Setup | Guide |
|
|
112
|
+
| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
|
|
113
|
+
| Re.Pack (Rspack / Webpack) | [Re.Pack.md](./Re.Pack.md) |
|
|
114
|
+
| React Native DevTools | [Rozenite plugin](./packages/rozenite-plugin/README.md) |
|
|
115
|
+
| AI coding agent | Point your agent at the [`setup-react-native-bundle-discovery`](./skills/setup-react-native-bundle-discovery/SKILL.md) skill |
|
|
81
116
|
|
|
82
|
-
|
|
117
|
+
## Usage
|
|
83
118
|
|
|
84
|
-
|
|
119
|
+
### UI
|
|
120
|
+
|
|
121
|
+
Requires `react-native-bundle-discovery-ui`.
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# Start a local server (default port: 8079)
|
|
125
|
+
npx react-native-bundle-discovery-ui metro-stats.json [--port <port>]
|
|
126
|
+
|
|
127
|
+
# Build a static HTML report (default output: .bundle-discovery)
|
|
128
|
+
npx react-native-bundle-discovery-ui build metro-stats.json [--output <path>]
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### CLI
|
|
132
|
+
|
|
133
|
+
Requires `react-native-bundle-discovery-cli`. Run any command with `--help` to see all options.
|
|
134
|
+
|
|
135
|
+
| Command | Description |
|
|
136
|
+
| ---------- | --------------------------------------------- |
|
|
137
|
+
| _(none)_ | Show recommended optimizations for the bundle |
|
|
138
|
+
| `packages` | List all packages in the bundle |
|
|
139
|
+
| `modules` | List the heaviest modules |
|
|
140
|
+
| `compare` | Compare two reports |
|
|
85
141
|
|
|
86
142
|
```bash
|
|
87
|
-
#
|
|
143
|
+
# Recommended optimizations
|
|
88
144
|
npx react-native-bundle-discovery-cli metro-stats.json
|
|
89
145
|
|
|
90
|
-
#
|
|
146
|
+
# All packages
|
|
91
147
|
npx react-native-bundle-discovery-cli packages metro-stats.json [--sort size|name] [--format json|table|default]
|
|
92
148
|
|
|
93
|
-
#
|
|
94
|
-
# --filter accepts plain text (case-insensitive) or a regexp
|
|
149
|
+
# Heaviest modules (default --limit: 50, use 0 to show all)
|
|
150
|
+
# --filter accepts plain text (case-insensitive) or a regexp, e.g. --filter '/\.json/i'
|
|
95
151
|
npx react-native-bundle-discovery-cli modules metro-stats.json [--limit 50] [--filter <text|/regexp/>] [--sort size|name] [--format json|table|default]
|
|
96
152
|
|
|
97
|
-
#
|
|
153
|
+
# Diff two reports: total size, added/removed/changed modules and packages,
|
|
98
154
|
# version changes, new duplicates and new deprecated packages
|
|
99
155
|
npx react-native-bundle-discovery-cli compare --before main-stats.json --after pr-stats.json [--limit 50] [--format json|markdown|default]
|
|
100
156
|
```
|
|
101
157
|
|
|
102
|
-
|
|
158
|
+
### Bundle size checks in CI
|
|
159
|
+
|
|
160
|
+
`compare` exits with code `1` when any check fails:
|
|
103
161
|
|
|
104
|
-
|
|
162
|
+
| Option | Fails when | Example |
|
|
163
|
+
| -------------------- | ------------------------------------------------------------- | ------------------------------- |
|
|
164
|
+
| `--fail-on-increase` | The bundle grows more than the limit (bytes or % of "before") | `50KB`, `0.5MB`, `51200`, `5%` |
|
|
165
|
+
| `--max-size` | The "after" bundle is bigger than the limit | `3MB` |
|
|
166
|
+
| `--fail-on` | New duplicate and/or deprecated packages appear | `new-duplicates,new-deprecated` |
|
|
105
167
|
|
|
106
168
|
```bash
|
|
107
|
-
# --fail-on-increase: max growth, in bytes (50KB, 0.5MB, 51200) or percent of the "before" size (5%)
|
|
108
|
-
# --max-size: absolute limit for the "after" bundle
|
|
109
|
-
# --fail-on: fail when new duplicate or new deprecated packages appear
|
|
110
169
|
npx react-native-bundle-discovery-cli compare --before main-stats.json --after pr-stats.json \
|
|
111
170
|
--fail-on-increase 50KB \
|
|
112
171
|
--max-size 3MB \
|
|
113
172
|
--fail-on new-duplicates,new-deprecated
|
|
114
173
|
```
|
|
115
174
|
|
|
116
|
-
|
|
117
|
-
|
|
175
|
+
**GitHub Actions** works out of the box: the markdown report is added to the job summary and failed checks
|
|
176
|
+
are shown as error annotations.
|
|
118
177
|
|
|
119
178
|
```yaml
|
|
120
|
-
- run: npx react-native-bundle-discovery-cli compare --before main-
|
|
179
|
+
- run: npx react-native-bundle-discovery-cli compare --before main-stats.json --after pr-stats.json --fail-on-increase 5%
|
|
121
180
|
```
|
|
122
181
|
|
|
123
|
-
|
|
182
|
+
To post the report as a PR comment, use `--format markdown`.
|
|
124
183
|
|
|
125
|
-
|
|
184
|
+
## API
|
|
126
185
|
|
|
127
|
-
|
|
128
|
-
# Start server to view the report in the browser (default port: 8079)
|
|
129
|
-
npx react-native-bundle-discovery-ui metro-stats.json [--port <port>]
|
|
130
|
-
|
|
131
|
-
# Build the report into a static HTML file
|
|
132
|
-
npx react-native-bundle-discovery-ui build metro-stats.json
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
---
|
|
186
|
+
Exported from `react-native-bundle-discovery`.
|
|
136
187
|
|
|
137
|
-
### `
|
|
188
|
+
### `createSerializer(options)`
|
|
138
189
|
|
|
139
|
-
|
|
190
|
+
Creates a Metro serializer that writes the JSON report. Use it as `serializer.customSerializer` (see [Quick start](#2-configure-metro)).
|
|
140
191
|
|
|
141
|
-
|
|
|
142
|
-
|
|
|
143
|
-
|
|
|
144
|
-
|
|
|
145
|
-
|
|
|
146
|
-
|
|
|
192
|
+
| Option | Type | Default | Description |
|
|
193
|
+
| ----------------------- | ---------- | -------------------------------- | ----------------------------------------------------------------------------------------- |
|
|
194
|
+
| `projectRoot` | `string` | **Required** | Project root. ⚠️ In a monorepo, use the monorepo root, not the app package directory. |
|
|
195
|
+
| `outputJsonPath` | `string` | `<projectRoot>/metro-stats.json` | Where to save the report. |
|
|
196
|
+
| `includeCode` | `boolean` | `true` | Include source and bundled code of each module in the report (larger file). |
|
|
197
|
+
| `includeEnvs` | `string[]` | `[]` | Names of environment variables to include in the report. |
|
|
198
|
+
| `fetchPackagesMetadata` | `boolean` | `true` | Fetch package metadata (publish date, deprecation, latest version) from the npm registry. |
|
|
199
|
+
| `silent` | `boolean` | `false` | Disable log output. |
|
|
200
|
+
| `serializer` | `Function` | Metro default serializer | Custom serializer to wrap. |
|
|
147
201
|
|
|
148
|
-
|
|
202
|
+
> [!WARNING]
|
|
203
|
+
> With `includeCode: true` (the default) the report **contains your source code**.
|
|
204
|
+
> If your code is proprietary, be careful who you share the report with.
|
|
149
205
|
|
|
150
|
-
|
|
206
|
+
### `createResolveRequest(options)`
|
|
151
207
|
|
|
152
|
-
|
|
208
|
+
Creates a Metro `resolveRequest` that removes unnecessary React Native modules from **release** bundles
|
|
209
|
+
(dev builds are not affected). The CLI recommends these options when they apply to your bundle.
|
|
153
210
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
| Prop | Default value | Description |
|
|
159
|
-
| ------------------------------ | ------------- | ----------------------------------------------------------------------------------------------------------------------------- |
|
|
160
|
-
| removePromisePolyfill: boolean | `false` | Remove the Promise polyfill as Hermes provide own impl. (issue: [#57702](https://github.com/react/react-native/issues/57702)) |
|
|
161
|
-
| removeUTFSequence: boolean | `false` | Remove useless undocumented RN module. |
|
|
162
|
-
|
|
163
|
-
Helper that creates a custom resolve request function to filter out unnecessary modules from the bundle.
|
|
164
|
-
You can get recommendations during the analysis of the bundle report using the CLI tool.
|
|
211
|
+
| Option | Type | Default | Description |
|
|
212
|
+
| ------------------- | --------- | ------- | -------------------------------------------------------------------------------- |
|
|
213
|
+
| `removeUTFSequence` | `boolean` | `false` | Remove the unused `react-native/Libraries/UTFSequence.js` module. |
|
|
214
|
+
| `removeNewRenderer` | `boolean` | `false` | Remove the Fabric renderer. Enable only if the New Architecture is **disabled**. |
|
|
165
215
|
|
|
166
216
|
```js
|
|
167
217
|
// metro.config.js
|
|
168
218
|
const { createResolveRequest } = require("react-native-bundle-discovery");
|
|
169
|
-
|
|
170
|
-
removePromisePolyfill: true,
|
|
171
|
-
removeUTFSequence: true,
|
|
172
|
-
});
|
|
219
|
+
|
|
173
220
|
const config = {
|
|
174
221
|
resolver: {
|
|
175
|
-
resolveRequest
|
|
222
|
+
resolveRequest: createResolveRequest({
|
|
223
|
+
removeUTFSequence: true,
|
|
224
|
+
}),
|
|
176
225
|
},
|
|
177
226
|
};
|
|
178
227
|
```
|
|
179
228
|
|
|
180
|
-
|
|
229
|
+
## Similar projects
|
|
181
230
|
|
|
182
|
-
|
|
231
|
+
- [expo-atlas](https://github.com/expo/atlas)
|
|
232
|
+
- [expo-atlas-without-expo](https://github.com/v3ron/expo-atlas-without-expo)
|
|
233
|
+
- [react-native-bundle-visualizer](https://github.com/callstack/react-native-bundle-visualizer)
|
|
234
|
+
- [webpack-bundle-analyzer](https://github.com/webpack-contrib/webpack-bundle-analyzer)
|
|
235
|
+
- [bundle-stats](https://github.com/relative-ci/bundle-stats/tree/master/packages/cli#readme)
|
|
236
|
+
- [statoscope](https://github.com/statoscope/statoscope)
|
|
183
237
|
|
|
184
|
-
|
|
238
|
+
Built with [Discovery.js](https://github.com/discoveryjs/discovery)
|
|
239
|
+
([views showcase](https://discoveryjs.github.io/discovery/#views-showcase),
|
|
240
|
+
[Jora syntax](https://discoveryjs.github.io/jora/#article:jora-syntax-operators)).
|
|
185
241
|
|
|
186
|
-
|
|
242
|
+
## Support the project
|
|
187
243
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
- [react-native-bundle-visualizer](https://github.com/callstack/react-native-bundle-visualizer) [](https://www.npmtrends.com/react-native-bundle-visualizer)[](https://packagephobia.com/result?p=react-native-bundle-visualizer)
|
|
191
|
-
- [webpack-bundle-analyzer](https://github.com/webpack-contrib/webpack-bundle-analyzer) [](https://www.npmtrends.com/webpack-bundle-analyzer)[](https://packagephobia.com/result?p=webpack-bundle-analyzer)
|
|
192
|
-
- [bundle-stats](https://github.com/relative-ci/bundle-stats/tree/master/packages/cli#readme) [](https://www.npmtrends.com/bundle-stats)[](https://packagephobia.com/result?p=bundle-stats)
|
|
193
|
-
- [statoscope](https://github.com/statoscope/statoscope) [](https://www.npmtrends.com/@statoscope/cli)[](https://packagephobia.com/result?p=@statoscope/cli)
|
|
244
|
+
Become a financial contributor on [OpenCollective](https://opencollective.com/react-native-bundle-discovery)
|
|
245
|
+
or [GitHub Sponsors](https://github.com/sponsors/retyui).
|
|
194
246
|
|
|
195
|
-
|
|
247
|
+
## License
|
|
196
248
|
|
|
197
|
-
|
|
198
|
-
- Jora syntax: https://discoveryjs.github.io/jora/#article:jora-syntax-operators
|
|
249
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import { Buffer } from "node:buffer";
|
|
2
|
+
//#region src/types.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Shape of the `metro-stats.json` report.
|
|
5
|
+
* Mirrors the report types of the (private) monorepo `shared` package; kept local so the
|
|
6
|
+
* published `.d.ts` is self-contained.
|
|
7
|
+
*/
|
|
8
|
+
interface PackageMetadata {
|
|
9
|
+
createdAt: string | null;
|
|
10
|
+
deprecated: string | false;
|
|
11
|
+
isLatest: boolean;
|
|
12
|
+
latestVersion: string | null;
|
|
13
|
+
}
|
|
14
|
+
interface SizeInfo {
|
|
15
|
+
sizeInBytes: number;
|
|
16
|
+
}
|
|
17
|
+
interface CodeInfo extends SizeInfo {
|
|
18
|
+
code: string;
|
|
19
|
+
lineCount: number;
|
|
20
|
+
}
|
|
21
|
+
interface ReportPackage {
|
|
22
|
+
name: string;
|
|
23
|
+
absolutePath: string;
|
|
24
|
+
version: string;
|
|
25
|
+
metadata?: PackageMetadata | null;
|
|
26
|
+
}
|
|
27
|
+
interface ReportModuleDependency {
|
|
28
|
+
absolutePath: string;
|
|
29
|
+
name: string;
|
|
30
|
+
}
|
|
31
|
+
interface ReportModule {
|
|
32
|
+
path: string;
|
|
33
|
+
source: CodeInfo;
|
|
34
|
+
output: CodeInfo;
|
|
35
|
+
dependencies: ReportModuleDependency[];
|
|
36
|
+
}
|
|
37
|
+
interface TransformOptions {
|
|
38
|
+
customTransformOptions?: Record<string, unknown>;
|
|
39
|
+
dev: boolean;
|
|
40
|
+
minify: boolean;
|
|
41
|
+
platform: string;
|
|
42
|
+
type?: string;
|
|
43
|
+
unstable_transformProfile?: string;
|
|
44
|
+
[key: string]: unknown;
|
|
45
|
+
}
|
|
46
|
+
//#endregion
|
|
47
|
+
//#region src/parseUtils.d.ts
|
|
48
|
+
type Modules = Record<string, string>;
|
|
49
|
+
interface ParseBundleOptions {
|
|
50
|
+
sourceType?: "script" | "module";
|
|
51
|
+
expectedModuleIds?: (string | number)[];
|
|
52
|
+
}
|
|
53
|
+
declare function parseBundle(bundlePath: string, opts?: ParseBundleOptions): {
|
|
54
|
+
modules: Modules;
|
|
55
|
+
src: string;
|
|
56
|
+
runtimeSrc: string;
|
|
57
|
+
};
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region src/webpack.d.ts
|
|
60
|
+
/** Options passed to `stats.toJson()` (https://webpack.js.org/configuration/stats/) */
|
|
61
|
+
type StatsOptions = Record<string, unknown>;
|
|
62
|
+
/** Minimal shape of the (normalized) Webpack/Rspack compiler options used by the plugin */
|
|
63
|
+
interface CompilerOptions {
|
|
64
|
+
context?: string;
|
|
65
|
+
mode?: string;
|
|
66
|
+
name?: string;
|
|
67
|
+
output: {
|
|
68
|
+
path?: string;
|
|
69
|
+
};
|
|
70
|
+
optimization?: {
|
|
71
|
+
minimize?: boolean;
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/** Minimal shape of a Webpack/Rspack `Stats` object */
|
|
75
|
+
interface Stats {
|
|
76
|
+
toJson(options: StatsOptions): unknown;
|
|
77
|
+
}
|
|
78
|
+
/** Minimal shape of a Webpack/Rspack `Compiler` */
|
|
79
|
+
interface Compiler {
|
|
80
|
+
options: CompilerOptions;
|
|
81
|
+
hooks: {
|
|
82
|
+
done: {
|
|
83
|
+
tap(name: string, callback: (stats: Stats) => void): void;
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
interface StatsReason {
|
|
88
|
+
type?: string;
|
|
89
|
+
modulePath?: string;
|
|
90
|
+
moduleNameForCondition?: string;
|
|
91
|
+
resolvedModule?: string;
|
|
92
|
+
moduleIdentifier?: string;
|
|
93
|
+
userRequest?: string;
|
|
94
|
+
}
|
|
95
|
+
interface StatsModule {
|
|
96
|
+
id?: string | number;
|
|
97
|
+
type?: string;
|
|
98
|
+
path?: string;
|
|
99
|
+
identifier?: string;
|
|
100
|
+
nameForCondition?: string;
|
|
101
|
+
source?: string;
|
|
102
|
+
size?: number;
|
|
103
|
+
reasons?: StatsReason[];
|
|
104
|
+
}
|
|
105
|
+
interface StatsAsset {
|
|
106
|
+
name: string;
|
|
107
|
+
info: {
|
|
108
|
+
javascriptModule?: boolean;
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
interface StatsJson {
|
|
112
|
+
builtAt?: number;
|
|
113
|
+
assets: StatsAsset[];
|
|
114
|
+
modules: StatsModule[];
|
|
115
|
+
}
|
|
116
|
+
type ParsedBundle = ReturnType<typeof parseBundle>;
|
|
117
|
+
interface WebpackReport {
|
|
118
|
+
kind: "webpack";
|
|
119
|
+
date: number;
|
|
120
|
+
entryPoint: string;
|
|
121
|
+
rootFolder: string;
|
|
122
|
+
transformOptions: TransformOptions;
|
|
123
|
+
modules: ReportModule[];
|
|
124
|
+
packages: ReportPackage[];
|
|
125
|
+
}
|
|
126
|
+
interface BundleDiscoveryPluginOptions {
|
|
127
|
+
/** Output file name (resolved against the compiler `context`). Defaults to `"metro-stats.json"`. */
|
|
128
|
+
filename?: string;
|
|
129
|
+
/** Extra options passed to `stats.toJson()`. */
|
|
130
|
+
options?: StatsOptions;
|
|
131
|
+
/** Whether the plugin is enabled. Defaults to `true`. */
|
|
132
|
+
enabled?: boolean;
|
|
133
|
+
/** Whether to fetch packages metadata (publish date, deprecation, latest version) from the npm registry. Defaults to `true`. */
|
|
134
|
+
fetchPackagesMetadata?: boolean;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Simple Webpack/Rspack plugin
|
|
138
|
+
* to adapt stats object https://webpack.js.org/api/stats/
|
|
139
|
+
* to metro-stats.json format used by `react-native-bundle-discovery`
|
|
140
|
+
*/
|
|
141
|
+
export declare class BundleDiscoveryPlugin {
|
|
142
|
+
options: StatsOptions | undefined;
|
|
143
|
+
filename: string;
|
|
144
|
+
enabled: boolean;
|
|
145
|
+
fetchPackagesMetadata: boolean;
|
|
146
|
+
constructor({ filename, options, enabled, fetchPackagesMetadata }?: BundleDiscoveryPluginOptions);
|
|
147
|
+
extractSizesFromJsBundle(statAsset: StatsAsset, options: CompilerOptions): ParsedBundle | null;
|
|
148
|
+
apply(compiler: Compiler): void;
|
|
149
|
+
writeReport(statsJson: WebpackReport, outputPath: string): Promise<void>;
|
|
150
|
+
readSource(filePath: string): CodeInfo;
|
|
151
|
+
getPkgVersionFromPath(path: string): string | null;
|
|
152
|
+
getPackages(statsJson: StatsJson): ReportPackage[];
|
|
153
|
+
getEntryFile(statsJson: StatsJson, rootFolder: string): string;
|
|
154
|
+
getModuleOutput(mdl: StatsModule, bundleModules: ParsedBundle | null): CodeInfo;
|
|
155
|
+
formatStat(statsJson: StatsJson, bundleModules: ParsedBundle | null, compilerOptions: CompilerOptions): WebpackReport;
|
|
156
|
+
buildImportsMapFromReasons(statsJson: StatsJson, compilerOptions: CompilerOptions): Map<string, ReportModuleDependency[]>;
|
|
157
|
+
findCommonRoot(paths: string[]): string;
|
|
158
|
+
}
|
|
159
|
+
//#endregion
|
|
160
|
+
//#region src/index.d.ts
|
|
161
|
+
/** Minimal shape of a Metro module (`Module` from `metro/src/DeltaBundler/types`) */
|
|
162
|
+
interface MetroModule {
|
|
163
|
+
path: string;
|
|
164
|
+
getSource(): Buffer;
|
|
165
|
+
output: ReadonlyArray<{
|
|
166
|
+
data: {
|
|
167
|
+
code: string;
|
|
168
|
+
lineCount: number;
|
|
169
|
+
};
|
|
170
|
+
}>;
|
|
171
|
+
dependencies?: Map<string, {
|
|
172
|
+
absolutePath?: string | null;
|
|
173
|
+
data: {
|
|
174
|
+
name: string;
|
|
175
|
+
};
|
|
176
|
+
}>;
|
|
177
|
+
}
|
|
178
|
+
/** Minimal shape of a Metro graph (`ReadOnlyGraph` from `metro/src/DeltaBundler/types`) */
|
|
179
|
+
interface MetroGraph {
|
|
180
|
+
dependencies: Map<string, MetroModule>;
|
|
181
|
+
transformOptions: TransformOptions;
|
|
182
|
+
}
|
|
183
|
+
/** Minimal shape of Metro serializer options */
|
|
184
|
+
interface MetroSerializerOptions {
|
|
185
|
+
processModuleFilter?: (module: MetroModule) => boolean;
|
|
186
|
+
sentryBundleCallback?: (bundle: unknown) => unknown;
|
|
187
|
+
[key: string]: unknown;
|
|
188
|
+
}
|
|
189
|
+
type MetroSerializerResult = string | {
|
|
190
|
+
code: string;
|
|
191
|
+
map: string;
|
|
192
|
+
} | Promise<string | {
|
|
193
|
+
code: string;
|
|
194
|
+
map: string;
|
|
195
|
+
}>;
|
|
196
|
+
type MetroSerializer = (entryPoint: string, preModules: ReadonlyArray<MetroModule>, graph: MetroGraph, options: MetroSerializerOptions) => MetroSerializerResult;
|
|
197
|
+
interface CreateSerializerOptions {
|
|
198
|
+
/** A custom serializer function. If not provided, a default serializer is used. */
|
|
199
|
+
serializer?: MetroSerializer;
|
|
200
|
+
/** The root directory of the project. Must exist. */
|
|
201
|
+
projectRoot: string;
|
|
202
|
+
/** The path where the JSON report will be saved. Defaults to "metro-stats.json" in the project root. */
|
|
203
|
+
outputJsonPath?: string;
|
|
204
|
+
/** Whether to include the source and output code in the JSON report. Defaults to `true`. */
|
|
205
|
+
includeCode?: boolean;
|
|
206
|
+
/** Whether to suppress log messages. Defaults to `false`. */
|
|
207
|
+
silent?: boolean;
|
|
208
|
+
/** A list of environment variable names to include in the JSON report. Defaults to `[]`. */
|
|
209
|
+
includeEnvs?: string[];
|
|
210
|
+
/** Whether to fetch packages metadata (publish date, deprecation, latest version) from the npm registry. Defaults to `true`. */
|
|
211
|
+
fetchPackagesMetadata?: boolean;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Creates a custom serializer function for Metro bundler, which generates a JSON report
|
|
215
|
+
* and optionally modifies the serialization process.
|
|
216
|
+
*
|
|
217
|
+
* @param options - Configuration options for the serializer.
|
|
218
|
+
* @returns A custom serializer function to be used by Metro.
|
|
219
|
+
* @throws Throws an error if the project root does not exist.
|
|
220
|
+
*/
|
|
221
|
+
declare function createSerializer({ serializer, projectRoot, outputJsonPath, includeCode, silent, includeEnvs, fetchPackagesMetadata }?: CreateSerializerOptions): MetroSerializer;
|
|
222
|
+
/** Minimal shape of a Metro resolution result */
|
|
223
|
+
type MetroResolution = {
|
|
224
|
+
type: string;
|
|
225
|
+
filePath?: string;
|
|
226
|
+
};
|
|
227
|
+
/** Minimal shape of a Metro resolution context */
|
|
228
|
+
interface MetroResolutionContext {
|
|
229
|
+
dev: boolean;
|
|
230
|
+
resolveRequest(context: MetroResolutionContext, moduleName: string, platform: string | null): MetroResolution;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Usage:
|
|
234
|
+
*
|
|
235
|
+
* ```js
|
|
236
|
+
* // metro.config.js
|
|
237
|
+
* const { createResolveRequest } = require("react-native-bundle-discovery");
|
|
238
|
+
* const resolveRequest = createResolveRequest({
|
|
239
|
+
* removePromisePolyfill: true,
|
|
240
|
+
* });
|
|
241
|
+
* const config = {
|
|
242
|
+
* resolver: {
|
|
243
|
+
* resolveRequest,
|
|
244
|
+
* },
|
|
245
|
+
* };
|
|
246
|
+
* ```
|
|
247
|
+
*/
|
|
248
|
+
declare const createResolveRequest: ({ removeNewRenderer, removeUTFSequence }?: {
|
|
249
|
+
removeNewRenderer?: boolean;
|
|
250
|
+
removeUTFSequence?: boolean;
|
|
251
|
+
}) => (context: MetroResolutionContext, moduleName: string, platform: string | null) => MetroResolution;
|
|
252
|
+
/**
|
|
253
|
+
* @deprecated Use `createResolveRequest` instead.
|
|
254
|
+
*/
|
|
255
|
+
declare const createProcessModuleFilter: ({ removePromisePolyfill, removeUTFSequence }?: {
|
|
256
|
+
removePromisePolyfill?: boolean;
|
|
257
|
+
removeUTFSequence?: boolean;
|
|
258
|
+
}) => (module: {
|
|
259
|
+
path: string;
|
|
260
|
+
}) => boolean;
|
|
261
|
+
//#endregion
|
|
262
|
+
export { createProcessModuleFilter, createResolveRequest, createSerializer };
|