@rushstack/rundown 1.1.9 → 1.1.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.
- package/LICENSE +24 -24
- package/README.md +230 -230
- package/bin/rundown +2 -2
- package/lib/LauncherTypes.js.map +1 -1
- package/lib/Rundown.js.map +1 -1
- package/lib/cli/BaseReportAction.js.map +1 -1
- package/lib/cli/InspectAction.js.map +1 -1
- package/lib/cli/RundownCommandLine.js.map +1 -1
- package/lib/cli/SnapshotAction.js.map +1 -1
- package/lib/launcher.js.map +1 -1
- package/lib/start.js.map +1 -1
- package/package.json +3 -3
package/LICENSE
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
@rushstack/rundown
|
|
2
|
-
|
|
3
|
-
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4
|
-
|
|
5
|
-
MIT License
|
|
6
|
-
|
|
7
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
|
8
|
-
a copy of this software and associated documentation files (the
|
|
9
|
-
"Software"), to deal in the Software without restriction, including
|
|
10
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
|
11
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
|
12
|
-
permit persons to whom the Software is furnished to do so, subject to
|
|
13
|
-
the following conditions:
|
|
14
|
-
|
|
15
|
-
The above copyright notice and this permission notice shall be
|
|
16
|
-
included in all copies or substantial portions of the Software.
|
|
17
|
-
|
|
18
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
19
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
20
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
21
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
22
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
23
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
24
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
1
|
+
@rushstack/rundown
|
|
2
|
+
|
|
3
|
+
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4
|
+
|
|
5
|
+
MIT License
|
|
6
|
+
|
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
8
|
+
a copy of this software and associated documentation files (the
|
|
9
|
+
"Software"), to deal in the Software without restriction, including
|
|
10
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
11
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
12
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
13
|
+
the following conditions:
|
|
14
|
+
|
|
15
|
+
The above copyright notice and this permission notice shall be
|
|
16
|
+
included in all copies or substantial portions of the Software.
|
|
17
|
+
|
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
19
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
20
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
21
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
22
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
23
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
24
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,230 +1,230 @@
|
|
|
1
|
-
# @rushstack/rundown
|
|
2
|
-
|
|
3
|
-
Slow startup times for Node.js commands or services? **Rundown** can invoke a Node.js process and:
|
|
4
|
-
|
|
5
|
-
1. **View imported files:** Intercept all `require()` calls and show which paths were loaded.
|
|
6
|
-
2. **Find culprits:** Show the chain for `require()` calls for each import, explaining why it was imported.
|
|
7
|
-
3. **Detect regressions over time:** Generate a concise "snapshot" report that can be committed to Git. Changes
|
|
8
|
-
to this file may indicate potential performance regressions.
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
## Installation
|
|
12
|
-
|
|
13
|
-
You can install this tool globally:
|
|
14
|
-
|
|
15
|
-
```shell
|
|
16
|
-
$ npm install --global @rushstack/rundown
|
|
17
|
-
|
|
18
|
-
# View command line help
|
|
19
|
-
$ rundown --help
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
If you will generate rundown snapshots during your build, it is recommended to install via `devDependencies`:
|
|
23
|
-
|
|
24
|
-
```shell
|
|
25
|
-
$ cd my-tool
|
|
26
|
-
$ npm install @rushstack/rundown --save-dev
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
## Viewing imported files
|
|
31
|
-
|
|
32
|
-
Suppose you maintain a small NPM project that is invoked as follows:
|
|
33
|
-
|
|
34
|
-
```shell
|
|
35
|
-
# The folder where your tool is developed
|
|
36
|
-
$ cd my-tool
|
|
37
|
-
|
|
38
|
-
# When you invoke "my-tool --my-option 123 --verbose" from the shell, let's suppose that it invokes
|
|
39
|
-
# this Node.js command:
|
|
40
|
-
$ node lib/start.js --my-option 123 --verbose
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
And suppose that your tool's startup time is rather slow, because the code calls `require()` to load many different
|
|
44
|
-
NPM packages. We can create a report to see all the imports:
|
|
45
|
-
|
|
46
|
-
```shell
|
|
47
|
-
# We use "--args" to pass the command-line arguments for "my-tool"
|
|
48
|
-
$ rundown inspect --script lib/start.js --args="--my-option 123 --verbose"
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
The report may look like this:
|
|
52
|
-
|
|
53
|
-
**rundown-inspect.log**
|
|
54
|
-
```
|
|
55
|
-
/path/to/my-tool/lib/start.js
|
|
56
|
-
/path/to/my-tool/node_modules/at-least-node/index.js
|
|
57
|
-
/path/to/my-tool/node_modules/fs-extra/lib/copy-sync/copy-sync.js
|
|
58
|
-
/path/to/my-tool/node_modules/fs-extra/lib/copy-sync/index.js
|
|
59
|
-
/path/to/my-tool/node_modules/fs-extra/lib/copy/copy.js
|
|
60
|
-
/path/to/my-tool/node_modules/fs-extra/lib/copy/index.js
|
|
61
|
-
/path/to/my-tool/node_modules/fs-extra/lib/empty/index.js
|
|
62
|
-
/path/to/my-tool/node_modules/fs-extra/lib/ensure/file.js
|
|
63
|
-
/path/to/my-tool/node_modules/fs-extra/lib/ensure/index.js
|
|
64
|
-
/path/to/my-tool/node_modules/fs-extra/lib/ensure/link.js
|
|
65
|
-
/path/to/my-tool/node_modules/fs-extra/lib/ensure/symlink-paths.js
|
|
66
|
-
/path/to/my-tool/node_modules/fs-extra/lib/ensure/symlink-type.js
|
|
67
|
-
/path/to/my-tool/node_modules/fs-extra/lib/ensure/symlink.js
|
|
68
|
-
/path/to/my-tool/node_modules/fs-extra/lib/fs/index.js
|
|
69
|
-
/path/to/my-tool/node_modules/fs-extra/lib/index.js
|
|
70
|
-
/path/to/my-tool/node_modules/fs-extra/lib/json/jsonfile.js
|
|
71
|
-
/path/to/my-tool/node_modules/fs-extra/lib/json/output-json-sync.js
|
|
72
|
-
/path/to/my-tool/node_modules/fs-extra/lib/json/output-json.js
|
|
73
|
-
/path/to/my-tool/node_modules/fs-extra/lib/mkdirs/index.js
|
|
74
|
-
/path/to/my-tool/node_modules/fs-extra/lib/mkdirs/make-dir.js
|
|
75
|
-
/path/to/my-tool/node_modules/fs-extra/lib/move-sync/index.js
|
|
76
|
-
/path/to/my-tool/node_modules/fs-extra/lib/move-sync/move-sync.js
|
|
77
|
-
/path/to/my-tool/node_modules/fs-extra/lib/move/index.js
|
|
78
|
-
/path/to/my-tool/node_modules/fs-extra/lib/move/move.js
|
|
79
|
-
/path/to/my-tool/node_modules/fs-extra/lib/output/index.js
|
|
80
|
-
/path/to/my-tool/node_modules/fs-extra/lib/path-exists/index.js
|
|
81
|
-
/path/to/my-tool/node_modules/fs-extra/lib/remove/index.js
|
|
82
|
-
/path/to/my-tool/node_modules/fs-extra/lib/remove/rimraf.js
|
|
83
|
-
/path/to/my-tool/node_modules/fs-extra/lib/util/stat.js
|
|
84
|
-
/path/to/my-tool/node_modules/fs-extra/lib/util/utimes.js
|
|
85
|
-
/path/to/my-tool/node_modules/graceful-fs/clone.js
|
|
86
|
-
/path/to/my-tool/node_modules/graceful-fs/graceful-fs.js
|
|
87
|
-
/path/to/my-tool/node_modules/graceful-fs/legacy-streams.js
|
|
88
|
-
/path/to/my-tool/node_modules/graceful-fs/polyfills.js
|
|
89
|
-
/path/to/my-tool/node_modules/jsonfile/index.js
|
|
90
|
-
/path/to/my-tool/node_modules/jsonfile/utils.js
|
|
91
|
-
/path/to/my-tool/node_modules/universalify/index.js
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
## Finding callers
|
|
95
|
-
|
|
96
|
-
To see how each file is imported, you can add the `--trace-imports` switch.
|
|
97
|
-
```shell
|
|
98
|
-
# We use "--args" to pass the command-line arguments for "my-tool"
|
|
99
|
-
$ rundown inspect --script lib/start.js --args="--my-option 123 --verbose" --trace-imports
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
The report now shows more detail:
|
|
103
|
-
|
|
104
|
-
**rundown-inspect.log**
|
|
105
|
-
```
|
|
106
|
-
. . .
|
|
107
|
-
/path/to/my-tool/node_modules/graceful-fs/legacy-streams.js
|
|
108
|
-
imported by /path/to/my-tool/node_modules/graceful-fs/graceful-fs.js
|
|
109
|
-
imported by /path/to/my-tool/node_modules/fs-extra/lib/fs/index.js
|
|
110
|
-
imported by /path/to/my-tool/node_modules/fs-extra/lib/index.js
|
|
111
|
-
imported by /path/to/my-tool/lib/start.js
|
|
112
|
-
imported by /rundown/lib/launcher.js
|
|
113
|
-
|
|
114
|
-
/path/to/my-tool/node_modules/graceful-fs/polyfills.js
|
|
115
|
-
imported by /path/to/my-tool/node_modules/graceful-fs/graceful-fs.js
|
|
116
|
-
imported by /path/to/my-tool/node_modules/fs-extra/lib/fs/index.js
|
|
117
|
-
imported by /path/to/my-tool/node_modules/fs-extra/lib/index.js
|
|
118
|
-
imported by /path/to/my-tool/lib/start.js
|
|
119
|
-
imported by rundown/lib/launcher.js
|
|
120
|
-
. . .
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
## Fixing problems
|
|
124
|
-
|
|
125
|
-
It may be the case that many of these imports are not actually used. You can avoid preloading them
|
|
126
|
-
by converting them to lazy imports using the `Import.lazy()` from
|
|
127
|
-
[@rushstack/node-core-library](https://www.npmjs.com/package/@rushstack/node-core-library)
|
|
128
|
-
or [import-lazy](https://www.npmjs.com/package/import-lazy).
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
## Generating a snapshot
|
|
132
|
-
|
|
133
|
-
To detect future regressions, use the `rundown snapshot` command to write a snapshot file:
|
|
134
|
-
|
|
135
|
-
```shell
|
|
136
|
-
# We use "--args" to pass the command-line arguments for "my-tool"
|
|
137
|
-
$ rundown snapshot --script lib/start.js --args="--my-option 123 --verbose"
|
|
138
|
-
|
|
139
|
-
# This file can be committed to Git to track regressions
|
|
140
|
-
$ git add rundown-snapshot.log
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
The snapshot file format eliminates spurious diffs, by showing only the names of the imported packages.
|
|
144
|
-
For local projects in a monorepo, it will show relative paths. Example output:
|
|
145
|
-
|
|
146
|
-
**rundown-snapshot.log**
|
|
147
|
-
```
|
|
148
|
-
../path/to/monorepo-sibling
|
|
149
|
-
at-least-node
|
|
150
|
-
fs-extra
|
|
151
|
-
graceful-fs
|
|
152
|
-
jsonfile
|
|
153
|
-
universalify
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
## Command-line reference
|
|
157
|
-
|
|
158
|
-
```
|
|
159
|
-
usage: rundown [-h] <command> ...
|
|
160
|
-
|
|
161
|
-
Detect load time regressions by running an app, tracing require() calls, and
|
|
162
|
-
generating a deterministic report
|
|
163
|
-
|
|
164
|
-
Positional arguments:
|
|
165
|
-
<command>
|
|
166
|
-
snapshot Invoke a Node.js script and generate a test snapshot
|
|
167
|
-
inspect Invoke a Node.js script and generate detailed diagnostic output
|
|
168
|
-
|
|
169
|
-
Optional arguments:
|
|
170
|
-
-h, --help Show this help message and exit.
|
|
171
|
-
|
|
172
|
-
For detailed help about a specific command, use: rundown <command> -h
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
```
|
|
176
|
-
usage: rundown snapshot [-h] -s PATH [-a STRING] [-q] [-i]
|
|
177
|
-
|
|
178
|
-
Invoke a Node.js script and generate a test snapshot. This command creates a
|
|
179
|
-
concise report that can be added to Git, so that its diff can be used to
|
|
180
|
-
detect performance regressions
|
|
181
|
-
|
|
182
|
-
Optional arguments:
|
|
183
|
-
-h, --help Show this help message and exit.
|
|
184
|
-
-s PATH, --script PATH
|
|
185
|
-
The path to a .js file that will be the entry point
|
|
186
|
-
for the target Node.js process
|
|
187
|
-
-a STRING, --args STRING
|
|
188
|
-
Specifies command-line arguments to be passed to the
|
|
189
|
-
target Node.js process. The value should be a single
|
|
190
|
-
text string delimited by spaces. Example: rundown
|
|
191
|
-
inspect --scripts ./example.js --args="--flag
|
|
192
|
-
--option=123"
|
|
193
|
-
-q, --quiet Suppress STDOUT/STDERR for the target Node.js process
|
|
194
|
-
-i, --ignore-exit-code
|
|
195
|
-
Do not report an error if the target Node.js process
|
|
196
|
-
returns a nonzero exit code
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
```
|
|
200
|
-
usage: rundown inspect [-h] -s PATH [-a STRING] [-q] [-i] [-t]
|
|
201
|
-
|
|
202
|
-
Invoke a Node.js script and generate detailed diagnostic output. This command
|
|
203
|
-
is used to inspect performance regressions.
|
|
204
|
-
|
|
205
|
-
Optional arguments:
|
|
206
|
-
-h, --help Show this help message and exit.
|
|
207
|
-
-s PATH, --script PATH
|
|
208
|
-
The path to a .js file that will be the entry point
|
|
209
|
-
for the target Node.js process
|
|
210
|
-
-a STRING, --args STRING
|
|
211
|
-
Specifies command-line arguments to be passed to the
|
|
212
|
-
target Node.js process. The value should be a single
|
|
213
|
-
text string delimited by spaces. Example: rundown
|
|
214
|
-
inspect --scripts ./example.js --args="--flag
|
|
215
|
-
--option=123"
|
|
216
|
-
-q, --quiet Suppress STDOUT/STDERR for the target Node.js process
|
|
217
|
-
-i, --ignore-exit-code
|
|
218
|
-
Do not report an error if the target Node.js process
|
|
219
|
-
returns a nonzero exit code
|
|
220
|
-
-t, --trace-imports Reports the call chain for each module path, showing
|
|
221
|
-
how it was imported
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
## Links
|
|
225
|
-
|
|
226
|
-
- [CHANGELOG.md](
|
|
227
|
-
https://github.com/microsoft/rushstack/blob/main/apps/rundown/CHANGELOG.md) - Find
|
|
228
|
-
out what's new in the latest version
|
|
229
|
-
|
|
230
|
-
Rundown is part of the [Rush Stack](https://rushstack.io/) family of projects.
|
|
1
|
+
# @rushstack/rundown
|
|
2
|
+
|
|
3
|
+
Slow startup times for Node.js commands or services? **Rundown** can invoke a Node.js process and:
|
|
4
|
+
|
|
5
|
+
1. **View imported files:** Intercept all `require()` calls and show which paths were loaded.
|
|
6
|
+
2. **Find culprits:** Show the chain for `require()` calls for each import, explaining why it was imported.
|
|
7
|
+
3. **Detect regressions over time:** Generate a concise "snapshot" report that can be committed to Git. Changes
|
|
8
|
+
to this file may indicate potential performance regressions.
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
You can install this tool globally:
|
|
14
|
+
|
|
15
|
+
```shell
|
|
16
|
+
$ npm install --global @rushstack/rundown
|
|
17
|
+
|
|
18
|
+
# View command line help
|
|
19
|
+
$ rundown --help
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
If you will generate rundown snapshots during your build, it is recommended to install via `devDependencies`:
|
|
23
|
+
|
|
24
|
+
```shell
|
|
25
|
+
$ cd my-tool
|
|
26
|
+
$ npm install @rushstack/rundown --save-dev
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
## Viewing imported files
|
|
31
|
+
|
|
32
|
+
Suppose you maintain a small NPM project that is invoked as follows:
|
|
33
|
+
|
|
34
|
+
```shell
|
|
35
|
+
# The folder where your tool is developed
|
|
36
|
+
$ cd my-tool
|
|
37
|
+
|
|
38
|
+
# When you invoke "my-tool --my-option 123 --verbose" from the shell, let's suppose that it invokes
|
|
39
|
+
# this Node.js command:
|
|
40
|
+
$ node lib/start.js --my-option 123 --verbose
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
And suppose that your tool's startup time is rather slow, because the code calls `require()` to load many different
|
|
44
|
+
NPM packages. We can create a report to see all the imports:
|
|
45
|
+
|
|
46
|
+
```shell
|
|
47
|
+
# We use "--args" to pass the command-line arguments for "my-tool"
|
|
48
|
+
$ rundown inspect --script lib/start.js --args="--my-option 123 --verbose"
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The report may look like this:
|
|
52
|
+
|
|
53
|
+
**rundown-inspect.log**
|
|
54
|
+
```
|
|
55
|
+
/path/to/my-tool/lib/start.js
|
|
56
|
+
/path/to/my-tool/node_modules/at-least-node/index.js
|
|
57
|
+
/path/to/my-tool/node_modules/fs-extra/lib/copy-sync/copy-sync.js
|
|
58
|
+
/path/to/my-tool/node_modules/fs-extra/lib/copy-sync/index.js
|
|
59
|
+
/path/to/my-tool/node_modules/fs-extra/lib/copy/copy.js
|
|
60
|
+
/path/to/my-tool/node_modules/fs-extra/lib/copy/index.js
|
|
61
|
+
/path/to/my-tool/node_modules/fs-extra/lib/empty/index.js
|
|
62
|
+
/path/to/my-tool/node_modules/fs-extra/lib/ensure/file.js
|
|
63
|
+
/path/to/my-tool/node_modules/fs-extra/lib/ensure/index.js
|
|
64
|
+
/path/to/my-tool/node_modules/fs-extra/lib/ensure/link.js
|
|
65
|
+
/path/to/my-tool/node_modules/fs-extra/lib/ensure/symlink-paths.js
|
|
66
|
+
/path/to/my-tool/node_modules/fs-extra/lib/ensure/symlink-type.js
|
|
67
|
+
/path/to/my-tool/node_modules/fs-extra/lib/ensure/symlink.js
|
|
68
|
+
/path/to/my-tool/node_modules/fs-extra/lib/fs/index.js
|
|
69
|
+
/path/to/my-tool/node_modules/fs-extra/lib/index.js
|
|
70
|
+
/path/to/my-tool/node_modules/fs-extra/lib/json/jsonfile.js
|
|
71
|
+
/path/to/my-tool/node_modules/fs-extra/lib/json/output-json-sync.js
|
|
72
|
+
/path/to/my-tool/node_modules/fs-extra/lib/json/output-json.js
|
|
73
|
+
/path/to/my-tool/node_modules/fs-extra/lib/mkdirs/index.js
|
|
74
|
+
/path/to/my-tool/node_modules/fs-extra/lib/mkdirs/make-dir.js
|
|
75
|
+
/path/to/my-tool/node_modules/fs-extra/lib/move-sync/index.js
|
|
76
|
+
/path/to/my-tool/node_modules/fs-extra/lib/move-sync/move-sync.js
|
|
77
|
+
/path/to/my-tool/node_modules/fs-extra/lib/move/index.js
|
|
78
|
+
/path/to/my-tool/node_modules/fs-extra/lib/move/move.js
|
|
79
|
+
/path/to/my-tool/node_modules/fs-extra/lib/output/index.js
|
|
80
|
+
/path/to/my-tool/node_modules/fs-extra/lib/path-exists/index.js
|
|
81
|
+
/path/to/my-tool/node_modules/fs-extra/lib/remove/index.js
|
|
82
|
+
/path/to/my-tool/node_modules/fs-extra/lib/remove/rimraf.js
|
|
83
|
+
/path/to/my-tool/node_modules/fs-extra/lib/util/stat.js
|
|
84
|
+
/path/to/my-tool/node_modules/fs-extra/lib/util/utimes.js
|
|
85
|
+
/path/to/my-tool/node_modules/graceful-fs/clone.js
|
|
86
|
+
/path/to/my-tool/node_modules/graceful-fs/graceful-fs.js
|
|
87
|
+
/path/to/my-tool/node_modules/graceful-fs/legacy-streams.js
|
|
88
|
+
/path/to/my-tool/node_modules/graceful-fs/polyfills.js
|
|
89
|
+
/path/to/my-tool/node_modules/jsonfile/index.js
|
|
90
|
+
/path/to/my-tool/node_modules/jsonfile/utils.js
|
|
91
|
+
/path/to/my-tool/node_modules/universalify/index.js
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Finding callers
|
|
95
|
+
|
|
96
|
+
To see how each file is imported, you can add the `--trace-imports` switch.
|
|
97
|
+
```shell
|
|
98
|
+
# We use "--args" to pass the command-line arguments for "my-tool"
|
|
99
|
+
$ rundown inspect --script lib/start.js --args="--my-option 123 --verbose" --trace-imports
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The report now shows more detail:
|
|
103
|
+
|
|
104
|
+
**rundown-inspect.log**
|
|
105
|
+
```
|
|
106
|
+
. . .
|
|
107
|
+
/path/to/my-tool/node_modules/graceful-fs/legacy-streams.js
|
|
108
|
+
imported by /path/to/my-tool/node_modules/graceful-fs/graceful-fs.js
|
|
109
|
+
imported by /path/to/my-tool/node_modules/fs-extra/lib/fs/index.js
|
|
110
|
+
imported by /path/to/my-tool/node_modules/fs-extra/lib/index.js
|
|
111
|
+
imported by /path/to/my-tool/lib/start.js
|
|
112
|
+
imported by /rundown/lib/launcher.js
|
|
113
|
+
|
|
114
|
+
/path/to/my-tool/node_modules/graceful-fs/polyfills.js
|
|
115
|
+
imported by /path/to/my-tool/node_modules/graceful-fs/graceful-fs.js
|
|
116
|
+
imported by /path/to/my-tool/node_modules/fs-extra/lib/fs/index.js
|
|
117
|
+
imported by /path/to/my-tool/node_modules/fs-extra/lib/index.js
|
|
118
|
+
imported by /path/to/my-tool/lib/start.js
|
|
119
|
+
imported by rundown/lib/launcher.js
|
|
120
|
+
. . .
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Fixing problems
|
|
124
|
+
|
|
125
|
+
It may be the case that many of these imports are not actually used. You can avoid preloading them
|
|
126
|
+
by converting them to lazy imports using the `Import.lazy()` from
|
|
127
|
+
[@rushstack/node-core-library](https://www.npmjs.com/package/@rushstack/node-core-library)
|
|
128
|
+
or [import-lazy](https://www.npmjs.com/package/import-lazy).
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
## Generating a snapshot
|
|
132
|
+
|
|
133
|
+
To detect future regressions, use the `rundown snapshot` command to write a snapshot file:
|
|
134
|
+
|
|
135
|
+
```shell
|
|
136
|
+
# We use "--args" to pass the command-line arguments for "my-tool"
|
|
137
|
+
$ rundown snapshot --script lib/start.js --args="--my-option 123 --verbose"
|
|
138
|
+
|
|
139
|
+
# This file can be committed to Git to track regressions
|
|
140
|
+
$ git add rundown-snapshot.log
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
The snapshot file format eliminates spurious diffs, by showing only the names of the imported packages.
|
|
144
|
+
For local projects in a monorepo, it will show relative paths. Example output:
|
|
145
|
+
|
|
146
|
+
**rundown-snapshot.log**
|
|
147
|
+
```
|
|
148
|
+
../path/to/monorepo-sibling
|
|
149
|
+
at-least-node
|
|
150
|
+
fs-extra
|
|
151
|
+
graceful-fs
|
|
152
|
+
jsonfile
|
|
153
|
+
universalify
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Command-line reference
|
|
157
|
+
|
|
158
|
+
```
|
|
159
|
+
usage: rundown [-h] <command> ...
|
|
160
|
+
|
|
161
|
+
Detect load time regressions by running an app, tracing require() calls, and
|
|
162
|
+
generating a deterministic report
|
|
163
|
+
|
|
164
|
+
Positional arguments:
|
|
165
|
+
<command>
|
|
166
|
+
snapshot Invoke a Node.js script and generate a test snapshot
|
|
167
|
+
inspect Invoke a Node.js script and generate detailed diagnostic output
|
|
168
|
+
|
|
169
|
+
Optional arguments:
|
|
170
|
+
-h, --help Show this help message and exit.
|
|
171
|
+
|
|
172
|
+
For detailed help about a specific command, use: rundown <command> -h
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
```
|
|
176
|
+
usage: rundown snapshot [-h] -s PATH [-a STRING] [-q] [-i]
|
|
177
|
+
|
|
178
|
+
Invoke a Node.js script and generate a test snapshot. This command creates a
|
|
179
|
+
concise report that can be added to Git, so that its diff can be used to
|
|
180
|
+
detect performance regressions
|
|
181
|
+
|
|
182
|
+
Optional arguments:
|
|
183
|
+
-h, --help Show this help message and exit.
|
|
184
|
+
-s PATH, --script PATH
|
|
185
|
+
The path to a .js file that will be the entry point
|
|
186
|
+
for the target Node.js process
|
|
187
|
+
-a STRING, --args STRING
|
|
188
|
+
Specifies command-line arguments to be passed to the
|
|
189
|
+
target Node.js process. The value should be a single
|
|
190
|
+
text string delimited by spaces. Example: rundown
|
|
191
|
+
inspect --scripts ./example.js --args="--flag
|
|
192
|
+
--option=123"
|
|
193
|
+
-q, --quiet Suppress STDOUT/STDERR for the target Node.js process
|
|
194
|
+
-i, --ignore-exit-code
|
|
195
|
+
Do not report an error if the target Node.js process
|
|
196
|
+
returns a nonzero exit code
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
usage: rundown inspect [-h] -s PATH [-a STRING] [-q] [-i] [-t]
|
|
201
|
+
|
|
202
|
+
Invoke a Node.js script and generate detailed diagnostic output. This command
|
|
203
|
+
is used to inspect performance regressions.
|
|
204
|
+
|
|
205
|
+
Optional arguments:
|
|
206
|
+
-h, --help Show this help message and exit.
|
|
207
|
+
-s PATH, --script PATH
|
|
208
|
+
The path to a .js file that will be the entry point
|
|
209
|
+
for the target Node.js process
|
|
210
|
+
-a STRING, --args STRING
|
|
211
|
+
Specifies command-line arguments to be passed to the
|
|
212
|
+
target Node.js process. The value should be a single
|
|
213
|
+
text string delimited by spaces. Example: rundown
|
|
214
|
+
inspect --scripts ./example.js --args="--flag
|
|
215
|
+
--option=123"
|
|
216
|
+
-q, --quiet Suppress STDOUT/STDERR for the target Node.js process
|
|
217
|
+
-i, --ignore-exit-code
|
|
218
|
+
Do not report an error if the target Node.js process
|
|
219
|
+
returns a nonzero exit code
|
|
220
|
+
-t, --trace-imports Reports the call chain for each module path, showing
|
|
221
|
+
how it was imported
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Links
|
|
225
|
+
|
|
226
|
+
- [CHANGELOG.md](
|
|
227
|
+
https://github.com/microsoft/rushstack/blob/main/apps/rundown/CHANGELOG.md) - Find
|
|
228
|
+
out what's new in the latest version
|
|
229
|
+
|
|
230
|
+
Rundown is part of the [Rush Stack](https://rushstack.io/) family of projects.
|
package/bin/rundown
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
require('../lib/start.js');
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
require('../lib/start.js');
|
package/lib/LauncherTypes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LauncherTypes.js","sourceRoot":"","sources":["../src/LauncherTypes.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nexport const enum LauncherAction {\n Snapshot = 'snapshot',\n Inspect = 'inspect'\n}\n\nexport interface IIpcTraceRecord {\n importedModule: string;\n callingModule: string;\n}\n\nexport interface IIpcTrace {\n id: 'trace';\n records: IIpcTraceRecord[];\n}\n\nexport interface IIpcDone {\n id: 'done';\n}\n\nexport type IpcMessage = IIpcTrace | IIpcDone;\n"]}
|
|
1
|
+
{"version":3,"file":"LauncherTypes.js","sourceRoot":"","sources":["../src/LauncherTypes.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\r\n// See LICENSE in the project root for license information.\r\n\r\nexport const enum LauncherAction {\r\n Snapshot = 'snapshot',\r\n Inspect = 'inspect'\r\n}\r\n\r\nexport interface IIpcTraceRecord {\r\n importedModule: string;\r\n callingModule: string;\r\n}\r\n\r\nexport interface IIpcTrace {\r\n id: 'trace';\r\n records: IIpcTraceRecord[];\r\n}\r\n\r\nexport interface IIpcDone {\r\n id: 'done';\r\n}\r\n\r\nexport type IpcMessage = IIpcTrace | IIpcDone;\r\n"]}
|
package/lib/Rundown.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Rundown.js","sourceRoot":"","sources":["../src/Rundown.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { FileSystem, PackageJsonLookup, Sort, Text } from '@rushstack/node-core-library';\nimport * as child_process from 'child_process';\nimport * as path from 'path';\nimport stringArgv from 'string-argv';\n\nimport type { IpcMessage } from './LauncherTypes';\n\nexport class Rundown {\n // Map from required path --> caller path\n private _importedModuleMap: Map<string, string> = new Map();\n\n public async invokeAsync(\n scriptPath: string,\n args: string | undefined,\n quiet: boolean,\n ignoreExitCode: boolean\n ): Promise<void> {\n if (!FileSystem.exists(scriptPath)) {\n throw new Error('The specified script path does not exist: ' + scriptPath);\n }\n const absoluteScriptPath: string = path.resolve(scriptPath);\n\n const expandedArgs: string[] = args === undefined ? [] : stringArgv(args);\n\n console.log('Starting process: ' + [absoluteScriptPath, ...expandedArgs].join(' '));\n console.log();\n\n // Example process.argv:\n // [\"path/to/launcher.js\", \"path/to/target-script.js\", \"first-target-arg\"]\n const nodeArgs: string[] = [path.join(__dirname, 'launcher.js'), absoluteScriptPath, ...expandedArgs];\n\n await this._spawnLauncherAsync(nodeArgs, quiet, ignoreExitCode);\n\n if (!quiet) {\n console.log();\n }\n }\n\n public writeSnapshotReport(): void {\n const reportPath: string = 'rundown-snapshot.log';\n console.log('Writing report file: ' + reportPath);\n\n const packageJsonLookup: PackageJsonLookup = new PackageJsonLookup();\n const importedPaths: string[] = [...this._importedModuleMap.keys()];\n const importedPackageFolders: Set<string> = new Set();\n\n for (const importedPath of importedPaths) {\n const importedPackageFolder: string | undefined =\n packageJsonLookup.tryGetPackageFolderFor(importedPath);\n if (importedPackageFolder) {\n if (/[\\\\/]node_modules[\\\\/]/i.test(importedPackageFolder)) {\n importedPackageFolders.add(path.basename(importedPackageFolder));\n } else {\n const relativePath: string = path.relative(process.cwd(), importedPackageFolder);\n importedPackageFolders.add(Text.replaceAll(relativePath, '\\\\', '/'));\n }\n } else {\n // If the importedPath does not belong to an NPM package, then rundown-snapshot.log can ignore it.\n // In other words, treat it the same way as the local project's source files.\n }\n }\n\n Sort.sortSet(importedPackageFolders);\n const data: string = [...importedPackageFolders].join('\\n') + '\\n';\n\n FileSystem.writeFile(reportPath, data);\n }\n\n public writeInspectReport(traceImports: boolean): void {\n const reportPath: string = 'rundown-inspect.log';\n console.log('Writing report file: ' + reportPath);\n\n const importedPaths: string[] = [...this._importedModuleMap.keys()];\n importedPaths.sort();\n\n let data: string = '';\n\n if (traceImports) {\n for (const importedPath of importedPaths) {\n data += importedPath + '\\n';\n\n let current: string = importedPath;\n const visited: Set<string> = new Set();\n for (;;) {\n const callerPath: string | undefined = this._importedModuleMap.get(current);\n if (!callerPath) {\n break;\n }\n if (visited.has(callerPath)) {\n break;\n }\n visited.add(callerPath);\n data += ' imported by ' + callerPath + '\\n';\n current = callerPath;\n }\n data += '\\n';\n }\n } else {\n data = importedPaths.join('\\n') + '\\n';\n }\n\n FileSystem.writeFile(reportPath, data);\n }\n\n private async _spawnLauncherAsync(\n nodeArgs: string[],\n quiet: boolean,\n ignoreExitCode: boolean\n ): Promise<void> {\n const childProcess: child_process.ChildProcess = child_process.spawn(process.execPath, nodeArgs, {\n stdio: quiet ? ['inherit', 'ignore', 'ignore', 'ipc'] : ['inherit', 'inherit', 'inherit', 'ipc']\n });\n\n let completedNormally: boolean = false;\n\n childProcess.on('message', (message: IpcMessage): void => {\n switch (message.id) {\n case 'trace':\n for (const record of message.records) {\n this._importedModuleMap.set(record.importedModule, record.callingModule);\n }\n break;\n case 'done':\n completedNormally = true;\n break;\n default:\n throw new Error('Unknown IPC message: ' + JSON.stringify(message));\n }\n });\n\n await new Promise<void>((resolve, reject) => {\n childProcess.on('exit', (code: number | null, signal: string | null): void => {\n if (code !== 0 && !ignoreExitCode) {\n reject(new Error('Child process terminated with exit code ' + code));\n } else if (!completedNormally) {\n reject(new Error('Child process terminated without completing IPC handshake'));\n } else {\n resolve();\n }\n });\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"Rundown.js","sourceRoot":"","sources":["../src/Rundown.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\r\n// See LICENSE in the project root for license information.\r\n\r\nimport { FileSystem, PackageJsonLookup, Sort, Text } from '@rushstack/node-core-library';\r\nimport * as child_process from 'child_process';\r\nimport * as path from 'path';\r\nimport stringArgv from 'string-argv';\r\n\r\nimport type { IpcMessage } from './LauncherTypes';\r\n\r\nexport class Rundown {\r\n // Map from required path --> caller path\r\n private _importedModuleMap: Map<string, string> = new Map();\r\n\r\n public async invokeAsync(\r\n scriptPath: string,\r\n args: string | undefined,\r\n quiet: boolean,\r\n ignoreExitCode: boolean\r\n ): Promise<void> {\r\n if (!FileSystem.exists(scriptPath)) {\r\n throw new Error('The specified script path does not exist: ' + scriptPath);\r\n }\r\n const absoluteScriptPath: string = path.resolve(scriptPath);\r\n\r\n const expandedArgs: string[] = args === undefined ? [] : stringArgv(args);\r\n\r\n console.log('Starting process: ' + [absoluteScriptPath, ...expandedArgs].join(' '));\r\n console.log();\r\n\r\n // Example process.argv:\r\n // [\"path/to/launcher.js\", \"path/to/target-script.js\", \"first-target-arg\"]\r\n const nodeArgs: string[] = [path.join(__dirname, 'launcher.js'), absoluteScriptPath, ...expandedArgs];\r\n\r\n await this._spawnLauncherAsync(nodeArgs, quiet, ignoreExitCode);\r\n\r\n if (!quiet) {\r\n console.log();\r\n }\r\n }\r\n\r\n public writeSnapshotReport(): void {\r\n const reportPath: string = 'rundown-snapshot.log';\r\n console.log('Writing report file: ' + reportPath);\r\n\r\n const packageJsonLookup: PackageJsonLookup = new PackageJsonLookup();\r\n const importedPaths: string[] = [...this._importedModuleMap.keys()];\r\n const importedPackageFolders: Set<string> = new Set();\r\n\r\n for (const importedPath of importedPaths) {\r\n const importedPackageFolder: string | undefined =\r\n packageJsonLookup.tryGetPackageFolderFor(importedPath);\r\n if (importedPackageFolder) {\r\n if (/[\\\\/]node_modules[\\\\/]/i.test(importedPackageFolder)) {\r\n importedPackageFolders.add(path.basename(importedPackageFolder));\r\n } else {\r\n const relativePath: string = path.relative(process.cwd(), importedPackageFolder);\r\n importedPackageFolders.add(Text.replaceAll(relativePath, '\\\\', '/'));\r\n }\r\n } else {\r\n // If the importedPath does not belong to an NPM package, then rundown-snapshot.log can ignore it.\r\n // In other words, treat it the same way as the local project's source files.\r\n }\r\n }\r\n\r\n Sort.sortSet(importedPackageFolders);\r\n const data: string = [...importedPackageFolders].join('\\n') + '\\n';\r\n\r\n FileSystem.writeFile(reportPath, data);\r\n }\r\n\r\n public writeInspectReport(traceImports: boolean): void {\r\n const reportPath: string = 'rundown-inspect.log';\r\n console.log('Writing report file: ' + reportPath);\r\n\r\n const importedPaths: string[] = [...this._importedModuleMap.keys()];\r\n importedPaths.sort();\r\n\r\n let data: string = '';\r\n\r\n if (traceImports) {\r\n for (const importedPath of importedPaths) {\r\n data += importedPath + '\\n';\r\n\r\n let current: string = importedPath;\r\n const visited: Set<string> = new Set();\r\n for (;;) {\r\n const callerPath: string | undefined = this._importedModuleMap.get(current);\r\n if (!callerPath) {\r\n break;\r\n }\r\n if (visited.has(callerPath)) {\r\n break;\r\n }\r\n visited.add(callerPath);\r\n data += ' imported by ' + callerPath + '\\n';\r\n current = callerPath;\r\n }\r\n data += '\\n';\r\n }\r\n } else {\r\n data = importedPaths.join('\\n') + '\\n';\r\n }\r\n\r\n FileSystem.writeFile(reportPath, data);\r\n }\r\n\r\n private async _spawnLauncherAsync(\r\n nodeArgs: string[],\r\n quiet: boolean,\r\n ignoreExitCode: boolean\r\n ): Promise<void> {\r\n const childProcess: child_process.ChildProcess = child_process.spawn(process.execPath, nodeArgs, {\r\n stdio: quiet ? ['inherit', 'ignore', 'ignore', 'ipc'] : ['inherit', 'inherit', 'inherit', 'ipc']\r\n });\r\n\r\n let completedNormally: boolean = false;\r\n\r\n childProcess.on('message', (message: IpcMessage): void => {\r\n switch (message.id) {\r\n case 'trace':\r\n for (const record of message.records) {\r\n this._importedModuleMap.set(record.importedModule, record.callingModule);\r\n }\r\n break;\r\n case 'done':\r\n completedNormally = true;\r\n break;\r\n default:\r\n throw new Error('Unknown IPC message: ' + JSON.stringify(message));\r\n }\r\n });\r\n\r\n await new Promise<void>((resolve, reject) => {\r\n childProcess.on('exit', (code: number | null, signal: string | null): void => {\r\n if (code !== 0 && !ignoreExitCode) {\r\n reject(new Error('Child process terminated with exit code ' + code));\r\n } else if (!completedNormally) {\r\n reject(new Error('Child process terminated without completing IPC handshake'));\r\n } else {\r\n resolve();\r\n }\r\n });\r\n });\r\n }\r\n}\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseReportAction.js","sourceRoot":"","sources":["../../src/cli/BaseReportAction.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D,4FAA4F;AAC5F,2DAA2D;AAE3D,gEAKoC;AAEpC,MAAsB,gBAAiB,SAAQ,mCAAiB;IAM9D,YAAmB,OAAkC;QACnD,KAAK,CAAC,OAAO,CAAC,CAAC;QAEf,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,qBAAqB,CAAC;YAChD,iBAAiB,EAAE,UAAU;YAC7B,kBAAkB,EAAE,IAAI;YACxB,YAAY,EAAE,MAAM;YACpB,WAAW,EAAE,oFAAoF;YACjG,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;QACH,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,qBAAqB,CAAC;YAC9C,iBAAiB,EAAE,QAAQ;YAC3B,kBAAkB,EAAE,IAAI;YACxB,YAAY,EAAE,QAAQ;YACtB,WAAW,EACT,yFAAyF;gBACzF,sDAAsD;gBACtD,+EAA+E;SAClF,CAAC,CAAC;QACH,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,mBAAmB,CAAC;YAC7C,iBAAiB,EAAE,SAAS;YAC5B,kBAAkB,EAAE,IAAI;YACxB,WAAW,EAAE,uDAAuD;SACrE,CAAC,CAAC;QACH,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC,mBAAmB,CAAC;YACtD,iBAAiB,EAAE,oBAAoB;YACvC,kBAAkB,EAAE,IAAI;YACxB,WAAW,EAAE,kFAAkF;SAChG,CAAC,CAAC;IACL,CAAC;CACF;AApCD,4CAoCC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\n// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport {\n CommandLineAction,\n type ICommandLineActionOptions,\n type CommandLineStringParameter,\n type CommandLineFlagParameter\n} from '@rushstack/ts-command-line';\n\nexport abstract class BaseReportAction extends CommandLineAction {\n protected readonly scriptParameter: CommandLineStringParameter;\n protected readonly argsParameter: CommandLineStringParameter;\n protected readonly quietParameter: CommandLineFlagParameter;\n protected readonly ignoreExitCodeParameter: CommandLineFlagParameter;\n\n public constructor(options: ICommandLineActionOptions) {\n super(options);\n\n this.scriptParameter = this.defineStringParameter({\n parameterLongName: '--script',\n parameterShortName: '-s',\n argumentName: 'PATH',\n description: 'The path to a .js file that will be the entry point for the target Node.js process',\n required: true\n });\n this.argsParameter = this.defineStringParameter({\n parameterLongName: '--args',\n parameterShortName: '-a',\n argumentName: 'STRING',\n description:\n 'Specifies command-line arguments to be passed to the target Node.js process. The value' +\n ' should be a single text string delimited by spaces.' +\n ' Example: rundown inspect --scripts ./example.js --args=\"--flag --option=123\"'\n });\n this.quietParameter = this.defineFlagParameter({\n parameterLongName: '--quiet',\n parameterShortName: '-q',\n description: 'Suppress STDOUT/STDERR for the target Node.js process'\n });\n this.ignoreExitCodeParameter = this.defineFlagParameter({\n parameterLongName: '--ignore-exit-code',\n parameterShortName: '-i',\n description: 'Do not report an error if the target Node.js process returns a nonzero exit code'\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"BaseReportAction.js","sourceRoot":"","sources":["../../src/cli/BaseReportAction.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D,4FAA4F;AAC5F,2DAA2D;AAE3D,gEAKoC;AAEpC,MAAsB,gBAAiB,SAAQ,mCAAiB;IAM9D,YAAmB,OAAkC;QACnD,KAAK,CAAC,OAAO,CAAC,CAAC;QAEf,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,qBAAqB,CAAC;YAChD,iBAAiB,EAAE,UAAU;YAC7B,kBAAkB,EAAE,IAAI;YACxB,YAAY,EAAE,MAAM;YACpB,WAAW,EAAE,oFAAoF;YACjG,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;QACH,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,qBAAqB,CAAC;YAC9C,iBAAiB,EAAE,QAAQ;YAC3B,kBAAkB,EAAE,IAAI;YACxB,YAAY,EAAE,QAAQ;YACtB,WAAW,EACT,yFAAyF;gBACzF,sDAAsD;gBACtD,+EAA+E;SAClF,CAAC,CAAC;QACH,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,mBAAmB,CAAC;YAC7C,iBAAiB,EAAE,SAAS;YAC5B,kBAAkB,EAAE,IAAI;YACxB,WAAW,EAAE,uDAAuD;SACrE,CAAC,CAAC;QACH,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC,mBAAmB,CAAC;YACtD,iBAAiB,EAAE,oBAAoB;YACvC,kBAAkB,EAAE,IAAI;YACxB,WAAW,EAAE,kFAAkF;SAChG,CAAC,CAAC;IACL,CAAC;CACF;AApCD,4CAoCC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\r\n// See LICENSE in the project root for license information.\r\n\r\n// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\r\n// See LICENSE in the project root for license information.\r\n\r\nimport {\r\n CommandLineAction,\r\n type ICommandLineActionOptions,\r\n type CommandLineStringParameter,\r\n type CommandLineFlagParameter\r\n} from '@rushstack/ts-command-line';\r\n\r\nexport abstract class BaseReportAction extends CommandLineAction {\r\n protected readonly scriptParameter: CommandLineStringParameter;\r\n protected readonly argsParameter: CommandLineStringParameter;\r\n protected readonly quietParameter: CommandLineFlagParameter;\r\n protected readonly ignoreExitCodeParameter: CommandLineFlagParameter;\r\n\r\n public constructor(options: ICommandLineActionOptions) {\r\n super(options);\r\n\r\n this.scriptParameter = this.defineStringParameter({\r\n parameterLongName: '--script',\r\n parameterShortName: '-s',\r\n argumentName: 'PATH',\r\n description: 'The path to a .js file that will be the entry point for the target Node.js process',\r\n required: true\r\n });\r\n this.argsParameter = this.defineStringParameter({\r\n parameterLongName: '--args',\r\n parameterShortName: '-a',\r\n argumentName: 'STRING',\r\n description:\r\n 'Specifies command-line arguments to be passed to the target Node.js process. The value' +\r\n ' should be a single text string delimited by spaces.' +\r\n ' Example: rundown inspect --scripts ./example.js --args=\"--flag --option=123\"'\r\n });\r\n this.quietParameter = this.defineFlagParameter({\r\n parameterLongName: '--quiet',\r\n parameterShortName: '-q',\r\n description: 'Suppress STDOUT/STDERR for the target Node.js process'\r\n });\r\n this.ignoreExitCodeParameter = this.defineFlagParameter({\r\n parameterLongName: '--ignore-exit-code',\r\n parameterShortName: '-i',\r\n description: 'Do not report an error if the target Node.js process returns a nonzero exit code'\r\n });\r\n }\r\n}\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InspectAction.js","sourceRoot":"","sources":["../../src/cli/InspectAction.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAI3D,yDAAsD;AACtD,wCAAqC;AAErC,MAAa,aAAc,SAAQ,mCAAgB;IAGjD;QACE,KAAK,CAAC;YACJ,UAAU,EAAE,SAAS;YACrB,OAAO,EAAE,iEAAiE;YAC1E,aAAa,EACX,wFAAwF;gBACxF,sCAAsC;SACzC,CAAC,CAAC;QAEH,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,mBAAmB,CAAC;YAC9C,iBAAiB,EAAE,iBAAiB;YACpC,kBAAkB,EAAE,IAAI;YACxB,WAAW,EAAE,0EAA0E;SACxF,CAAC,CAAC;IACL,CAAC;IAES,KAAK,CAAC,SAAS;QACvB,MAAM,OAAO,GAAY,IAAI,iBAAO,EAAE,CAAC;QACvC,MAAM,OAAO,CAAC,WAAW,CACvB,IAAI,CAAC,eAAe,CAAC,KAAM,EAC3B,IAAI,CAAC,aAAa,CAAC,KAAK,EACxB,IAAI,CAAC,cAAc,CAAC,KAAO,EAC3B,IAAI,CAAC,uBAAuB,CAAC,KAAO,CACrC,CAAC;QACF,OAAO,CAAC,kBAAkB,CAAC,IAAI,CAAC,eAAe,CAAC,KAAO,CAAC,CAAC;IAC3D,CAAC;CACF;AA7BD,sCA6BC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport type { CommandLineFlagParameter } from '@rushstack/ts-command-line';\n\nimport { BaseReportAction } from './BaseReportAction';\nimport { Rundown } from '../Rundown';\n\nexport class InspectAction extends BaseReportAction {\n private readonly _traceParameter: CommandLineFlagParameter;\n\n public constructor() {\n super({\n actionName: 'inspect',\n summary: 'Invoke a Node.js script and generate detailed diagnostic output',\n documentation:\n 'Invoke a Node.js script and generate detailed diagnostic output. This command is used' +\n ' to inspect performance regressions.'\n });\n\n this._traceParameter = this.defineFlagParameter({\n parameterLongName: '--trace-imports',\n parameterShortName: '-t',\n description: 'Reports the call chain for each module path, showing how it was imported'\n });\n }\n\n protected async onExecute(): Promise<void> {\n const rundown: Rundown = new Rundown();\n await rundown.invokeAsync(\n this.scriptParameter.value!,\n this.argsParameter.value,\n this.quietParameter.value!!,\n this.ignoreExitCodeParameter.value!!\n );\n rundown.writeInspectReport(this._traceParameter.value!!);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"InspectAction.js","sourceRoot":"","sources":["../../src/cli/InspectAction.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAI3D,yDAAsD;AACtD,wCAAqC;AAErC,MAAa,aAAc,SAAQ,mCAAgB;IAGjD;QACE,KAAK,CAAC;YACJ,UAAU,EAAE,SAAS;YACrB,OAAO,EAAE,iEAAiE;YAC1E,aAAa,EACX,wFAAwF;gBACxF,sCAAsC;SACzC,CAAC,CAAC;QAEH,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,mBAAmB,CAAC;YAC9C,iBAAiB,EAAE,iBAAiB;YACpC,kBAAkB,EAAE,IAAI;YACxB,WAAW,EAAE,0EAA0E;SACxF,CAAC,CAAC;IACL,CAAC;IAES,KAAK,CAAC,SAAS;QACvB,MAAM,OAAO,GAAY,IAAI,iBAAO,EAAE,CAAC;QACvC,MAAM,OAAO,CAAC,WAAW,CACvB,IAAI,CAAC,eAAe,CAAC,KAAM,EAC3B,IAAI,CAAC,aAAa,CAAC,KAAK,EACxB,IAAI,CAAC,cAAc,CAAC,KAAO,EAC3B,IAAI,CAAC,uBAAuB,CAAC,KAAO,CACrC,CAAC;QACF,OAAO,CAAC,kBAAkB,CAAC,IAAI,CAAC,eAAe,CAAC,KAAO,CAAC,CAAC;IAC3D,CAAC;CACF;AA7BD,sCA6BC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\r\n// See LICENSE in the project root for license information.\r\n\r\nimport type { CommandLineFlagParameter } from '@rushstack/ts-command-line';\r\n\r\nimport { BaseReportAction } from './BaseReportAction';\r\nimport { Rundown } from '../Rundown';\r\n\r\nexport class InspectAction extends BaseReportAction {\r\n private readonly _traceParameter: CommandLineFlagParameter;\r\n\r\n public constructor() {\r\n super({\r\n actionName: 'inspect',\r\n summary: 'Invoke a Node.js script and generate detailed diagnostic output',\r\n documentation:\r\n 'Invoke a Node.js script and generate detailed diagnostic output. This command is used' +\r\n ' to inspect performance regressions.'\r\n });\r\n\r\n this._traceParameter = this.defineFlagParameter({\r\n parameterLongName: '--trace-imports',\r\n parameterShortName: '-t',\r\n description: 'Reports the call chain for each module path, showing how it was imported'\r\n });\r\n }\r\n\r\n protected async onExecute(): Promise<void> {\r\n const rundown: Rundown = new Rundown();\r\n await rundown.invokeAsync(\r\n this.scriptParameter.value!,\r\n this.argsParameter.value,\r\n this.quietParameter.value!!,\r\n this.ignoreExitCodeParameter.value!!\r\n );\r\n rundown.writeInspectReport(this._traceParameter.value!!);\r\n }\r\n}\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RundownCommandLine.js","sourceRoot":"","sources":["../../src/cli/RundownCommandLine.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D,gEAA+D;AAE/D,qDAAkD;AAClD,mDAAgD;AAEhD,MAAa,kBAAmB,SAAQ,mCAAiB;IACvD;QACE,KAAK,CAAC;YACJ,YAAY,EAAE,SAAS;YACvB,eAAe,EACb,0EAA0E;gBAC1E,wCAAwC;SAC3C,CAAC,CAAC;QAEH,IAAI,CAAC,SAAS,CAAC,IAAI,+BAAc,EAAE,CAAC,CAAC;QACrC,IAAI,CAAC,SAAS,CAAC,IAAI,6BAAa,EAAE,CAAC,CAAC;IACtC,CAAC;CACF;AAZD,gDAYC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { CommandLineParser } from '@rushstack/ts-command-line';\n\nimport { SnapshotAction } from './SnapshotAction';\nimport { InspectAction } from './InspectAction';\n\nexport class RundownCommandLine extends CommandLineParser {\n public constructor() {\n super({\n toolFilename: 'rundown',\n toolDescription:\n 'Detect load time regressions by running an app, tracing require() calls,' +\n ' and generating a deterministic report'\n });\n\n this.addAction(new SnapshotAction());\n this.addAction(new InspectAction());\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"RundownCommandLine.js","sourceRoot":"","sources":["../../src/cli/RundownCommandLine.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D,gEAA+D;AAE/D,qDAAkD;AAClD,mDAAgD;AAEhD,MAAa,kBAAmB,SAAQ,mCAAiB;IACvD;QACE,KAAK,CAAC;YACJ,YAAY,EAAE,SAAS;YACvB,eAAe,EACb,0EAA0E;gBAC1E,wCAAwC;SAC3C,CAAC,CAAC;QAEH,IAAI,CAAC,SAAS,CAAC,IAAI,+BAAc,EAAE,CAAC,CAAC;QACrC,IAAI,CAAC,SAAS,CAAC,IAAI,6BAAa,EAAE,CAAC,CAAC;IACtC,CAAC;CACF;AAZD,gDAYC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\r\n// See LICENSE in the project root for license information.\r\n\r\nimport { CommandLineParser } from '@rushstack/ts-command-line';\r\n\r\nimport { SnapshotAction } from './SnapshotAction';\r\nimport { InspectAction } from './InspectAction';\r\n\r\nexport class RundownCommandLine extends CommandLineParser {\r\n public constructor() {\r\n super({\r\n toolFilename: 'rundown',\r\n toolDescription:\r\n 'Detect load time regressions by running an app, tracing require() calls,' +\r\n ' and generating a deterministic report'\r\n });\r\n\r\n this.addAction(new SnapshotAction());\r\n this.addAction(new InspectAction());\r\n }\r\n}\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SnapshotAction.js","sourceRoot":"","sources":["../../src/cli/SnapshotAction.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D,yDAAsD;AAEtD,wCAAqC;AAErC,MAAa,cAAe,SAAQ,mCAAgB;IAClD;QACE,KAAK,CAAC;YACJ,UAAU,EAAE,UAAU;YACtB,OAAO,EAAE,sDAAsD;YAC/D,aAAa,EACX,0GAA0G;gBAC1G,+EAA+E;SAClF,CAAC,CAAC;IACL,CAAC;IAES,KAAK,CAAC,SAAS;QACvB,MAAM,OAAO,GAAY,IAAI,iBAAO,EAAE,CAAC;QACvC,MAAM,OAAO,CAAC,WAAW,CACvB,IAAI,CAAC,eAAe,CAAC,KAAM,EAC3B,IAAI,CAAC,aAAa,CAAC,KAAK,EACxB,IAAI,CAAC,cAAc,CAAC,KAAO,EAC3B,IAAI,CAAC,uBAAuB,CAAC,KAAO,CACrC,CAAC;QACF,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAChC,CAAC;CACF;AArBD,wCAqBC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { BaseReportAction } from './BaseReportAction';\n\nimport { Rundown } from '../Rundown';\n\nexport class SnapshotAction extends BaseReportAction {\n public constructor() {\n super({\n actionName: 'snapshot',\n summary: 'Invoke a Node.js script and generate a test snapshot',\n documentation:\n 'Invoke a Node.js script and generate a test snapshot. This command creates a concise report that can be' +\n ' added to Git, so that its diff can be used to detect performance regressions'\n });\n }\n\n protected async onExecute(): Promise<void> {\n const rundown: Rundown = new Rundown();\n await rundown.invokeAsync(\n this.scriptParameter.value!,\n this.argsParameter.value,\n this.quietParameter.value!!,\n this.ignoreExitCodeParameter.value!!\n );\n rundown.writeSnapshotReport();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SnapshotAction.js","sourceRoot":"","sources":["../../src/cli/SnapshotAction.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D,yDAAsD;AAEtD,wCAAqC;AAErC,MAAa,cAAe,SAAQ,mCAAgB;IAClD;QACE,KAAK,CAAC;YACJ,UAAU,EAAE,UAAU;YACtB,OAAO,EAAE,sDAAsD;YAC/D,aAAa,EACX,0GAA0G;gBAC1G,+EAA+E;SAClF,CAAC,CAAC;IACL,CAAC;IAES,KAAK,CAAC,SAAS;QACvB,MAAM,OAAO,GAAY,IAAI,iBAAO,EAAE,CAAC;QACvC,MAAM,OAAO,CAAC,WAAW,CACvB,IAAI,CAAC,eAAe,CAAC,KAAM,EAC3B,IAAI,CAAC,aAAa,CAAC,KAAK,EACxB,IAAI,CAAC,cAAc,CAAC,KAAO,EAC3B,IAAI,CAAC,uBAAuB,CAAC,KAAO,CACrC,CAAC;QACF,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAChC,CAAC;CACF;AArBD,wCAqBC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\r\n// See LICENSE in the project root for license information.\r\n\r\nimport { BaseReportAction } from './BaseReportAction';\r\n\r\nimport { Rundown } from '../Rundown';\r\n\r\nexport class SnapshotAction extends BaseReportAction {\r\n public constructor() {\r\n super({\r\n actionName: 'snapshot',\r\n summary: 'Invoke a Node.js script and generate a test snapshot',\r\n documentation:\r\n 'Invoke a Node.js script and generate a test snapshot. This command creates a concise report that can be' +\r\n ' added to Git, so that its diff can be used to detect performance regressions'\r\n });\r\n }\r\n\r\n protected async onExecute(): Promise<void> {\r\n const rundown: Rundown = new Rundown();\r\n await rundown.invokeAsync(\r\n this.scriptParameter.value!,\r\n this.argsParameter.value,\r\n this.quietParameter.value!!,\r\n this.ignoreExitCodeParameter.value!!\r\n );\r\n rundown.writeSnapshotReport();\r\n }\r\n}\r\n"]}
|
package/lib/launcher.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"launcher.js","sourceRoot":"","sources":["../src/launcher.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport moduleApi = require('module');\nimport process from 'process';\n\nimport { LauncherAction } from './LauncherTypes'; // \"import type\" doesn't work with const enums\nimport type { IIpcTrace, IIpcDone, IIpcTraceRecord } from './LauncherTypes';\n\n// The _ipcTraceRecordsBatch will get transmitted when this many items are accumulated\nconst IPC_BATCH_SIZE: number = 300;\n\nclass Launcher {\n public action: LauncherAction = LauncherAction.Inspect;\n public targetScriptPathArg: string = '';\n public reportPath: string = '';\n private _importedModules: Set<unknown> = new Set();\n private _importedModulePaths: Set<string> = new Set();\n private _ipcTraceRecordsBatch: IIpcTraceRecord[] = [];\n\n public transformArgs(argv: ReadonlyArray<string>): string[] {\n let nodeArg: string;\n let remainderArgs: string[];\n\n // Example process.argv:\n // [\"path/to/node.exe\", \"path/to/launcher.js\", \"path/to/target-script.js\", \"first-target-arg\"]\n [nodeArg, , this.targetScriptPathArg, ...remainderArgs] = argv;\n\n // Example process.argv:\n // [\"path/to/node.exe\", \"path/to/target-script.js\", \"first-target-arg\"]\n return [nodeArg, this.targetScriptPathArg, ...remainderArgs];\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private static _copyProperties(dst: any, src: any): void {\n for (const prop of Object.keys(src)) {\n dst[prop] = src[prop];\n }\n }\n\n private _sendIpcTraceBatch(): void {\n if (this._ipcTraceRecordsBatch.length > 0) {\n const batch: IIpcTraceRecord[] = [...this._ipcTraceRecordsBatch];\n this._ipcTraceRecordsBatch.length = 0;\n\n process.send!({\n id: 'trace',\n records: batch\n } as IIpcTrace);\n }\n }\n\n /**\n * Synchronously delay for the specified time interval.\n */\n private static _delayMs(milliseconds: number): void {\n Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, milliseconds);\n }\n\n public installHook(): void {\n const realRequire: NodeJS.Require = moduleApi.Module.prototype.require;\n\n const importedModules: Set<unknown> = this._importedModules; // for closure\n const importedModulePaths: Set<string> = this._importedModulePaths; // for closure\n const ipcTraceRecordsBatch: IIpcTraceRecord[] = this._ipcTraceRecordsBatch; // for closure\n const sendIpcTraceBatch: () => void = this._sendIpcTraceBatch.bind(this); // for closure\n\n function hookedRequire(this: NodeModule, moduleName: string): unknown {\n // NOTE: The \"this\" pointer is the calling NodeModule, so we rely on closure\n // variable here.\n const callingModuleInfo: NodeModule = this;\n\n // Paranoidly use \"arguments\" in case some implementor passes additional undocumented arguments\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const importedModule: unknown = (realRequire as any).apply(callingModuleInfo, arguments);\n\n if (!importedModules.has(importedModule)) {\n importedModules.add(importedModule);\n\n // Find the info for the imported module\n let importedModuleInfo: NodeModule | undefined = undefined;\n const children: NodeModule[] = callingModuleInfo.children || [];\n for (const child of children) {\n if (child.exports === importedModule) {\n importedModuleInfo = child;\n break;\n }\n }\n\n if (importedModuleInfo === undefined) {\n // It's a built-in module like \"os\"\n } else {\n if (!importedModuleInfo.filename) {\n throw new Error('Missing filename for ' + moduleName);\n }\n\n if (!importedModulePaths.has(importedModuleInfo.filename)) {\n importedModulePaths.add(importedModuleInfo.filename);\n ipcTraceRecordsBatch.push({\n importedModule: importedModuleInfo.filename,\n callingModule: callingModuleInfo.filename\n });\n if (ipcTraceRecordsBatch.length >= IPC_BATCH_SIZE) {\n sendIpcTraceBatch();\n }\n }\n }\n }\n\n return importedModule;\n }\n\n moduleApi.Module.prototype.require = hookedRequire as NodeJS.Require;\n Launcher._copyProperties(hookedRequire, realRequire);\n\n process.on('exit', () => {\n this._sendIpcTraceBatch();\n process.send!({\n id: 'done'\n } as IIpcDone);\n\n // The Node.js \"exit\" event is synchronous, and the process will terminate as soon as this function returns.\n // To avoid a race condition, allow some time for IPC messages to be transmitted to the parent process.\n // TODO: There should be a way to eliminate this delay by intercepting earlier in the shutdown sequence,\n // but it needs to consider every way that Node.js can exit.\n Launcher._delayMs(500);\n });\n }\n}\n\nif (!process.send) {\n throw new Error('launcher.js must be invoked via IPC');\n}\n\nconst launcher: Launcher = new Launcher();\n\nconst originalArgv: ReadonlyArray<string> = [...process.argv];\nprocess.argv.length = 0;\nprocess.argv.push(...launcher.transformArgs(originalArgv));\n\nlauncher.installHook();\n\n// Start the app\nrequire(launcher.targetScriptPathArg);\n"]}
|
|
1
|
+
{"version":3,"file":"launcher.js","sourceRoot":"","sources":["../src/launcher.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\r\n// See LICENSE in the project root for license information.\r\n\r\nimport moduleApi = require('module');\r\nimport process from 'process';\r\n\r\nimport { LauncherAction } from './LauncherTypes'; // \"import type\" doesn't work with const enums\r\nimport type { IIpcTrace, IIpcDone, IIpcTraceRecord } from './LauncherTypes';\r\n\r\n// The _ipcTraceRecordsBatch will get transmitted when this many items are accumulated\r\nconst IPC_BATCH_SIZE: number = 300;\r\n\r\nclass Launcher {\r\n public action: LauncherAction = LauncherAction.Inspect;\r\n public targetScriptPathArg: string = '';\r\n public reportPath: string = '';\r\n private _importedModules: Set<unknown> = new Set();\r\n private _importedModulePaths: Set<string> = new Set();\r\n private _ipcTraceRecordsBatch: IIpcTraceRecord[] = [];\r\n\r\n public transformArgs(argv: ReadonlyArray<string>): string[] {\r\n let nodeArg: string;\r\n let remainderArgs: string[];\r\n\r\n // Example process.argv:\r\n // [\"path/to/node.exe\", \"path/to/launcher.js\", \"path/to/target-script.js\", \"first-target-arg\"]\r\n [nodeArg, , this.targetScriptPathArg, ...remainderArgs] = argv;\r\n\r\n // Example process.argv:\r\n // [\"path/to/node.exe\", \"path/to/target-script.js\", \"first-target-arg\"]\r\n return [nodeArg, this.targetScriptPathArg, ...remainderArgs];\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n private static _copyProperties(dst: any, src: any): void {\r\n for (const prop of Object.keys(src)) {\r\n dst[prop] = src[prop];\r\n }\r\n }\r\n\r\n private _sendIpcTraceBatch(): void {\r\n if (this._ipcTraceRecordsBatch.length > 0) {\r\n const batch: IIpcTraceRecord[] = [...this._ipcTraceRecordsBatch];\r\n this._ipcTraceRecordsBatch.length = 0;\r\n\r\n process.send!({\r\n id: 'trace',\r\n records: batch\r\n } as IIpcTrace);\r\n }\r\n }\r\n\r\n /**\r\n * Synchronously delay for the specified time interval.\r\n */\r\n private static _delayMs(milliseconds: number): void {\r\n Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, milliseconds);\r\n }\r\n\r\n public installHook(): void {\r\n const realRequire: NodeJS.Require = moduleApi.Module.prototype.require;\r\n\r\n const importedModules: Set<unknown> = this._importedModules; // for closure\r\n const importedModulePaths: Set<string> = this._importedModulePaths; // for closure\r\n const ipcTraceRecordsBatch: IIpcTraceRecord[] = this._ipcTraceRecordsBatch; // for closure\r\n const sendIpcTraceBatch: () => void = this._sendIpcTraceBatch.bind(this); // for closure\r\n\r\n function hookedRequire(this: NodeModule, moduleName: string): unknown {\r\n // NOTE: The \"this\" pointer is the calling NodeModule, so we rely on closure\r\n // variable here.\r\n const callingModuleInfo: NodeModule = this;\r\n\r\n // Paranoidly use \"arguments\" in case some implementor passes additional undocumented arguments\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const importedModule: unknown = (realRequire as any).apply(callingModuleInfo, arguments);\r\n\r\n if (!importedModules.has(importedModule)) {\r\n importedModules.add(importedModule);\r\n\r\n // Find the info for the imported module\r\n let importedModuleInfo: NodeModule | undefined = undefined;\r\n const children: NodeModule[] = callingModuleInfo.children || [];\r\n for (const child of children) {\r\n if (child.exports === importedModule) {\r\n importedModuleInfo = child;\r\n break;\r\n }\r\n }\r\n\r\n if (importedModuleInfo === undefined) {\r\n // It's a built-in module like \"os\"\r\n } else {\r\n if (!importedModuleInfo.filename) {\r\n throw new Error('Missing filename for ' + moduleName);\r\n }\r\n\r\n if (!importedModulePaths.has(importedModuleInfo.filename)) {\r\n importedModulePaths.add(importedModuleInfo.filename);\r\n ipcTraceRecordsBatch.push({\r\n importedModule: importedModuleInfo.filename,\r\n callingModule: callingModuleInfo.filename\r\n });\r\n if (ipcTraceRecordsBatch.length >= IPC_BATCH_SIZE) {\r\n sendIpcTraceBatch();\r\n }\r\n }\r\n }\r\n }\r\n\r\n return importedModule;\r\n }\r\n\r\n moduleApi.Module.prototype.require = hookedRequire as NodeJS.Require;\r\n Launcher._copyProperties(hookedRequire, realRequire);\r\n\r\n process.on('exit', () => {\r\n this._sendIpcTraceBatch();\r\n process.send!({\r\n id: 'done'\r\n } as IIpcDone);\r\n\r\n // The Node.js \"exit\" event is synchronous, and the process will terminate as soon as this function returns.\r\n // To avoid a race condition, allow some time for IPC messages to be transmitted to the parent process.\r\n // TODO: There should be a way to eliminate this delay by intercepting earlier in the shutdown sequence,\r\n // but it needs to consider every way that Node.js can exit.\r\n Launcher._delayMs(500);\r\n });\r\n }\r\n}\r\n\r\nif (!process.send) {\r\n throw new Error('launcher.js must be invoked via IPC');\r\n}\r\n\r\nconst launcher: Launcher = new Launcher();\r\n\r\nconst originalArgv: ReadonlyArray<string> = [...process.argv];\r\nprocess.argv.length = 0;\r\nprocess.argv.push(...launcher.transformArgs(originalArgv));\r\n\r\nlauncher.installHook();\r\n\r\n// Start the app\r\nrequire(launcher.targetScriptPathArg);\r\n"]}
|
package/lib/start.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start.js","sourceRoot":"","sources":["../src/start.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;AAE3D,oEAAiE;AAEjE,iEAA8D;AAE9D,MAAM,WAAW,GAAW,qCAAiB,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC;AAEpF,OAAO,CAAC,GAAG,EAAE,CAAC;AACd,OAAO,CAAC,GAAG,CAAC,WAAW,WAAW,yBAAyB,CAAC,CAAC;AAC7D,OAAO,CAAC,GAAG,EAAE,CAAC;AAEd,MAAM,WAAW,GAAuB,IAAI,uCAAkB,EAAE,CAAC;AACjE,WAAW,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACpC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { PackageJsonLookup } from '@rushstack/node-core-library';\n\nimport { RundownCommandLine } from './cli/RundownCommandLine';\n\nconst toolVersion: string = PackageJsonLookup.loadOwnPackageJson(__dirname).version;\n\nconsole.log();\nconsole.log(`Rundown ${toolVersion} - https://rushstack.io`);\nconsole.log();\n\nconst commandLine: RundownCommandLine = new RundownCommandLine();\ncommandLine.execute().catch((error) => {\n console.error(error);\n});\n"]}
|
|
1
|
+
{"version":3,"file":"start.js","sourceRoot":"","sources":["../src/start.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;AAE3D,oEAAiE;AAEjE,iEAA8D;AAE9D,MAAM,WAAW,GAAW,qCAAiB,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC;AAEpF,OAAO,CAAC,GAAG,EAAE,CAAC;AACd,OAAO,CAAC,GAAG,CAAC,WAAW,WAAW,yBAAyB,CAAC,CAAC;AAC7D,OAAO,CAAC,GAAG,EAAE,CAAC;AAEd,MAAM,WAAW,GAAuB,IAAI,uCAAkB,EAAE,CAAC;AACjE,WAAW,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACpC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\r\n// See LICENSE in the project root for license information.\r\n\r\nimport { PackageJsonLookup } from '@rushstack/node-core-library';\r\n\r\nimport { RundownCommandLine } from './cli/RundownCommandLine';\r\n\r\nconst toolVersion: string = PackageJsonLookup.loadOwnPackageJson(__dirname).version;\r\n\r\nconsole.log();\r\nconsole.log(`Rundown ${toolVersion} - https://rushstack.io`);\r\nconsole.log();\r\n\r\nconst commandLine: RundownCommandLine = new RundownCommandLine();\r\ncommandLine.execute().catch((error) => {\r\n console.error(error);\r\n});\r\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rushstack/rundown",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.10",
|
|
4
4
|
"description": "Detect load time regressions by running an app, tracing require() calls, and generating a deterministic report",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -19,10 +19,10 @@
|
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"string-argv": "~0.3.1",
|
|
21
21
|
"@rushstack/node-core-library": "3.61.0",
|
|
22
|
-
"@rushstack/ts-command-line": "4.
|
|
22
|
+
"@rushstack/ts-command-line": "4.17.0"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@rushstack/heft": "0.
|
|
25
|
+
"@rushstack/heft": "0.63.0",
|
|
26
26
|
"local-node-rig": "1.0.0"
|
|
27
27
|
},
|
|
28
28
|
"scripts": {
|