@jsenv/file-size-impact 11.0.2 → 12.1.2
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 → LICENSE} +0 -0
- package/{index.js → main.js} +2 -4
- package/package.json +22 -31
- package/readme.md +28 -25
- package/src/brotliTransformation.js +8 -3
- package/src/{getFileSizeReport.js → generateFileSizeReport.js} +46 -19
- package/src/gzipTransformation.js +5 -2
- package/src/internal/applyTrackingConfig.js +9 -5
- package/src/internal/compareTwoFileSizeReports.js +3 -32
- package/src/{logFileSizeReport.js → internal/formatFileSizeReportForLog.js} +9 -6
- package/src/internal/formatSize.js +1 -1
- package/src/internal/manifest.js +32 -0
- package/src/reportFileSizeImpact.js +20 -30
- package/src/internal/worker_generating_file_size_report.js +0 -17
package/{license → LICENSE}
RENAMED
|
File without changes
|
package/{index.js → main.js}
RENAMED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
export { readGitHubWorkflowEnv } from "@jsenv/github-pull-request-impact"
|
|
2
|
-
|
|
3
1
|
export { jsenvTrackingConfig } from "./src/jsenvTrackingConfig.js"
|
|
4
2
|
export { transform as raw } from "./src/rawTransformation.js"
|
|
5
3
|
export { transform as gzip } from "./src/gzipTransformation.js"
|
|
6
4
|
export { transform as brotli } from "./src/brotliTransformation.js"
|
|
5
|
+
export { generateFileSizeReport } from "./src/generateFileSizeReport.js"
|
|
7
6
|
|
|
8
|
-
export {
|
|
9
|
-
export { logFileSizeReport } from "./src/logFileSizeReport.js"
|
|
7
|
+
export { readGitHubWorkflowEnv } from "@jsenv/github-pull-request-impact"
|
|
10
8
|
export { reportFileSizeImpact } from "./src/reportFileSizeImpact.js"
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/file-size-impact",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "12.1.2",
|
|
4
4
|
"description": "Add files size impact into pull requests",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
|
-
"url": "https://github.com/jsenv/
|
|
8
|
+
"url": "https://github.com/jsenv/workflow",
|
|
9
|
+
"directory": "packages/jsenv-file-size-impact"
|
|
9
10
|
},
|
|
10
11
|
"engines": {
|
|
11
12
|
"node": ">=14.17.0"
|
|
@@ -17,49 +18,39 @@
|
|
|
17
18
|
"type": "module",
|
|
18
19
|
"exports": {
|
|
19
20
|
".": {
|
|
20
|
-
"import": "./
|
|
21
|
+
"import": "./main.js"
|
|
21
22
|
},
|
|
22
23
|
"./*": "./*"
|
|
23
24
|
},
|
|
25
|
+
"main": "./main.js",
|
|
24
26
|
"files": [
|
|
25
27
|
"/src/",
|
|
26
|
-
"/
|
|
28
|
+
"/main.js"
|
|
27
29
|
],
|
|
28
30
|
"scripts": {
|
|
29
|
-
"eslint
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"generate-comment-snapshot-file": "node ./test/comment/generate_comment_snapshot_file.mjs",
|
|
31
|
+
"eslint": "npx eslint . --ext=.js,.mjs",
|
|
32
|
+
"importmap": "node ./script/importmap/importmap.mjs",
|
|
33
|
+
"snapshot": "node ./test/comment/generate_comment_snapshot_file.mjs",
|
|
33
34
|
"test": "node ./script/test/test.mjs",
|
|
34
35
|
"test-with-coverage": "npm run test -- --coverage",
|
|
35
|
-
"
|
|
36
|
-
"prettier
|
|
37
|
-
"prettier-check": "npm run prettier-format -- --dry-run",
|
|
38
|
-
"prepublishOnly": "node ./script/publish/remove_postinstall.mjs",
|
|
39
|
-
"postpublish": "node ./script/publish/restore_postinstall.mjs"
|
|
36
|
+
"file-size": "node ./script/file_size/file_size.mjs --log",
|
|
37
|
+
"prettier": "prettier --write ."
|
|
40
38
|
},
|
|
41
39
|
"dependencies": {
|
|
42
|
-
"@jsenv/
|
|
40
|
+
"@jsenv/dynamic-import-worker": "1.0.0",
|
|
41
|
+
"@jsenv/filesystem": "2.7.1",
|
|
42
|
+
"@jsenv/github-pull-request-impact": "1.6.6",
|
|
43
43
|
"@jsenv/logger": "4.0.1",
|
|
44
|
-
"@jsenv/filesystem": "2.2.0",
|
|
45
44
|
"pretty-bytes": "5.6.0"
|
|
46
45
|
},
|
|
47
46
|
"devDependencies": {
|
|
48
|
-
"@
|
|
49
|
-
"@
|
|
50
|
-
"@jsenv/
|
|
51
|
-
"@jsenv/
|
|
52
|
-
"@jsenv/
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"@jsenv/github-release-package": "1.2.3",
|
|
57
|
-
"@jsenv/importmap-eslint-resolver": "5.1.2",
|
|
58
|
-
"@jsenv/importmap-node-module": "2.4.1",
|
|
59
|
-
"@jsenv/package-publish": "1.6.2",
|
|
60
|
-
"@jsenv/prettier-check-project": "5.6.1",
|
|
61
|
-
"eslint": "7.32.0",
|
|
62
|
-
"eslint-plugin-import": "2.25.2",
|
|
63
|
-
"prettier": "2.4.1"
|
|
47
|
+
"@jsenv/assert": "2.4.1",
|
|
48
|
+
"@jsenv/core": "25.3.0",
|
|
49
|
+
"@jsenv/eslint-config": "16.0.9",
|
|
50
|
+
"@jsenv/importmap-eslint-resolver": "5.2.5",
|
|
51
|
+
"@jsenv/importmap-node-module": "5.1.3",
|
|
52
|
+
"eslint": "8.7.0",
|
|
53
|
+
"eslint-plugin-import": "2.25.4",
|
|
54
|
+
"prettier": "2.5.1"
|
|
64
55
|
}
|
|
65
56
|
}
|
package/readme.md
CHANGED
|
@@ -44,22 +44,25 @@ npm install --save-dev @jsenv/file-size-impact
|
|
|
44
44
|
_generate_file_size_report.mjs_
|
|
45
45
|
|
|
46
46
|
```js
|
|
47
|
-
import {
|
|
48
|
-
|
|
49
|
-
export const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
},
|
|
47
|
+
import { generateFileSizeReport } from "@jsenv/file-size-impact"
|
|
48
|
+
|
|
49
|
+
export const filesizeReport = await generateFileSizeReport({
|
|
50
|
+
log: process.argv.includes("--log"),
|
|
51
|
+
projectDirectoryUrl: new URL("./", import.meta.url),
|
|
52
|
+
trackingConfig: {
|
|
53
|
+
dist: {
|
|
54
|
+
"./dist/**/*": true,
|
|
55
|
+
"./dist/**/*.map": false,
|
|
57
56
|
},
|
|
58
|
-
}
|
|
59
|
-
}
|
|
57
|
+
},
|
|
58
|
+
})
|
|
60
59
|
```
|
|
61
60
|
|
|
62
|
-
At this stage, you could generate a file size report on your machine
|
|
61
|
+
At this stage, you could generate a file size report on your machine with the following command.
|
|
62
|
+
|
|
63
|
+
```console
|
|
64
|
+
node ./generate_file_size_report.mjs --log
|
|
65
|
+
```
|
|
63
66
|
|
|
64
67
|
Now it's time to configure a workflow to compare file size reports before and after merging a pull request.
|
|
65
68
|
|
|
@@ -176,14 +179,14 @@ In order to analyse the impact of a pull request on file size the following step
|
|
|
176
179
|
7. Analyse differences between the two file size reports
|
|
177
180
|
8. Post or update comment in the pull request
|
|
178
181
|
|
|
179
|
-
#
|
|
182
|
+
# generateFileSizeReport
|
|
180
183
|
|
|
181
|
-
|
|
184
|
+
_generateFileSizeReport_ is an async function scanning filesystem to compute a list of file sizes and return these infos into an object.
|
|
182
185
|
|
|
183
186
|
```js
|
|
184
|
-
import {
|
|
187
|
+
import { generateFileSizeReport, raw, gzip } from "@jsenv/file-size-impact"
|
|
185
188
|
|
|
186
|
-
const fileSizeReport = await
|
|
189
|
+
const fileSizeReport = await generateFileSizeReport({
|
|
187
190
|
projectDirectoryUrl: new URL("./", import.meta.url),
|
|
188
191
|
trackingConfig: {
|
|
189
192
|
dist: {
|
|
@@ -204,9 +207,9 @@ _trackingConfig_ values are objects associating a pattern to a value. This objec
|
|
|
204
207
|
For example you can create two groups named _"critical files"_ and _"remaining files"_ like this:
|
|
205
208
|
|
|
206
209
|
```js
|
|
207
|
-
import {
|
|
210
|
+
import { generateFileSizeReport } from "@jsenv/file-size-impact"
|
|
208
211
|
|
|
209
|
-
await
|
|
212
|
+
await generateFileSizeReport({
|
|
210
213
|
trackingConfig: {
|
|
211
214
|
"critical files": {
|
|
212
215
|
"./dist/main.js": true,
|
|
@@ -231,9 +234,9 @@ _transformations_ parameter is an object used to transform files content before
|
|
|
231
234
|
You can use this parameter to track file size after gzip compression.
|
|
232
235
|
|
|
233
236
|
```js
|
|
234
|
-
import {
|
|
237
|
+
import { generateFileSizeReport, raw, gzip, brotli } from "@jsenv/file-size-impact"
|
|
235
238
|
|
|
236
|
-
await
|
|
239
|
+
await generateFileSizeReport({
|
|
237
240
|
transformations: { raw, gzip, brotli },
|
|
238
241
|
})
|
|
239
242
|
```
|
|
@@ -245,9 +248,9 @@ _raw_, _gzip_ and _brotli_ compression can be enabled this way.
|
|
|
245
248
|
It's also possible to control compression level.
|
|
246
249
|
|
|
247
250
|
```js
|
|
248
|
-
import {
|
|
251
|
+
import { generateFileSizeReport, raw, gzip } from "@jsenv/file-size-impact"
|
|
249
252
|
|
|
250
|
-
await
|
|
253
|
+
await generateFileSizeReport({
|
|
251
254
|
transformations: {
|
|
252
255
|
raw,
|
|
253
256
|
gzip7: (buffer) => gzip(buffer, { level: 7 }),
|
|
@@ -259,9 +262,9 @@ await getFileSizeReport({
|
|
|
259
262
|
Finally _transformations_ can be used to add custom _transformations_.
|
|
260
263
|
|
|
261
264
|
```js
|
|
262
|
-
import {
|
|
265
|
+
import { generateFileSizeReport, raw, gzip, brotli } from "@jsenv/file-size-impact"
|
|
263
266
|
|
|
264
|
-
await
|
|
267
|
+
await generateFileSizeReport({
|
|
265
268
|
transformations: {
|
|
266
269
|
raw,
|
|
267
270
|
trim: (buffer) => String(buffer).trim(),
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import { brotliCompress, constants } from "zlib"
|
|
1
|
+
import { brotliCompress, constants } from "node:zlib"
|
|
2
2
|
|
|
3
3
|
export const name = "brotli"
|
|
4
4
|
|
|
5
5
|
export const transform = (
|
|
6
6
|
value,
|
|
7
|
-
{
|
|
7
|
+
{
|
|
8
|
+
quality = constants.BROTLI_MAX_QUALITY,
|
|
9
|
+
size = Buffer.from(value).length,
|
|
10
|
+
...rest
|
|
11
|
+
} = {},
|
|
8
12
|
) => {
|
|
9
13
|
return new Promise((resolve, reject) => {
|
|
10
14
|
brotliCompress(
|
|
@@ -12,7 +16,8 @@ export const transform = (
|
|
|
12
16
|
{
|
|
13
17
|
params: {
|
|
14
18
|
[constants.BROTLI_PARAM_QUALITY]: quality,
|
|
15
|
-
[constants.BROTLI_PARAM_SIZE_HINT]:
|
|
19
|
+
[constants.BROTLI_PARAM_SIZE_HINT]:
|
|
20
|
+
typeof size === "number" ? size : 0,
|
|
16
21
|
...rest,
|
|
17
22
|
},
|
|
18
23
|
},
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { createDetailedMessage, createLogger } from "@jsenv/logger"
|
|
2
1
|
import {
|
|
3
2
|
assertAndNormalizeDirectoryUrl,
|
|
4
3
|
bufferToEtag,
|
|
@@ -6,13 +5,16 @@ import {
|
|
|
6
5
|
readFile,
|
|
7
6
|
urlToFileSystemPath,
|
|
8
7
|
} from "@jsenv/filesystem"
|
|
8
|
+
import { createDetailedMessage, createLogger } from "@jsenv/logger"
|
|
9
9
|
|
|
10
10
|
import { transform as rawTransform } from "./rawTransformation.js"
|
|
11
11
|
import { jsenvTrackingConfig } from "./jsenvTrackingConfig.js"
|
|
12
12
|
import { applyTrackingConfig } from "./internal/applyTrackingConfig.js"
|
|
13
|
+
import { formatFileSizeReportForLog } from "./internal/formatFileSizeReportForLog.js"
|
|
13
14
|
|
|
14
|
-
export const
|
|
15
|
+
export const generateFileSizeReport = async ({
|
|
15
16
|
cancellationToken,
|
|
17
|
+
log,
|
|
16
18
|
logLevel,
|
|
17
19
|
projectDirectoryUrl,
|
|
18
20
|
trackingConfig = jsenvTrackingConfig,
|
|
@@ -45,12 +47,15 @@ export const getFileSizeReport = async ({
|
|
|
45
47
|
await Promise.all(
|
|
46
48
|
groupNames.map(async (groupName) => {
|
|
47
49
|
const groupTrackingResult = groupTrackingResults[groupName]
|
|
48
|
-
const groupReport = await groupTrackingResultToGroupReport(
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
const groupReport = await groupTrackingResultToGroupReport(
|
|
51
|
+
groupTrackingResult,
|
|
52
|
+
{
|
|
53
|
+
logger,
|
|
54
|
+
projectDirectoryUrl,
|
|
55
|
+
tracking: trackingConfig[groupName],
|
|
56
|
+
transformations,
|
|
57
|
+
},
|
|
58
|
+
)
|
|
54
59
|
groups[groupName] = groupReport
|
|
55
60
|
}),
|
|
56
61
|
)
|
|
@@ -60,6 +65,10 @@ export const getFileSizeReport = async ({
|
|
|
60
65
|
groups,
|
|
61
66
|
}
|
|
62
67
|
|
|
68
|
+
if (log) {
|
|
69
|
+
logger.info(formatFileSizeReportForLog(fileSizeReport))
|
|
70
|
+
}
|
|
71
|
+
|
|
63
72
|
return fileSizeReport
|
|
64
73
|
}
|
|
65
74
|
|
|
@@ -72,18 +81,26 @@ const groupTrackingResultToGroupReport = async (
|
|
|
72
81
|
const manifestRelativeUrls = Object.keys(manifestMetaMap)
|
|
73
82
|
await Promise.all(
|
|
74
83
|
manifestRelativeUrls.map(async (manifestRelativeUrl) => {
|
|
75
|
-
const manifestFileUrl = resolveUrl(
|
|
76
|
-
|
|
84
|
+
const manifestFileUrl = resolveUrl(
|
|
85
|
+
manifestRelativeUrl,
|
|
86
|
+
projectDirectoryUrl,
|
|
87
|
+
)
|
|
88
|
+
const manifestFileContent = await readFile(manifestFileUrl, {
|
|
89
|
+
as: "string",
|
|
90
|
+
})
|
|
77
91
|
let manifest
|
|
78
92
|
try {
|
|
79
93
|
manifest = JSON.parse(manifestFileContent)
|
|
80
94
|
} catch (e) {
|
|
81
95
|
if (e.name === "SyntaxError") {
|
|
82
96
|
logger.error(
|
|
83
|
-
createDetailedMessage(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
97
|
+
createDetailedMessage(
|
|
98
|
+
`JSON.parse error while trying to parse a manifest file`,
|
|
99
|
+
{
|
|
100
|
+
"error stack": e.stack,
|
|
101
|
+
"manifest file": urlToFileSystemPath(manifestFileUrl),
|
|
102
|
+
},
|
|
103
|
+
),
|
|
87
104
|
)
|
|
88
105
|
return
|
|
89
106
|
}
|
|
@@ -103,7 +120,11 @@ const groupTrackingResultToGroupReport = async (
|
|
|
103
120
|
const fileUrl = resolveUrl(fileRelativeUrl, projectDirectoryUrl)
|
|
104
121
|
const fileContent = await readFile(fileUrl)
|
|
105
122
|
const fileBuffer = Buffer.from(fileContent)
|
|
106
|
-
const sizeMap = await getFileSizeMap(fileBuffer, {
|
|
123
|
+
const sizeMap = await getFileSizeMap(fileBuffer, {
|
|
124
|
+
transformations,
|
|
125
|
+
logger,
|
|
126
|
+
fileUrl,
|
|
127
|
+
})
|
|
107
128
|
const hash = bufferToEtag(fileBuffer)
|
|
108
129
|
fileMap[fileRelativeUrl] = {
|
|
109
130
|
sizeMap,
|
|
@@ -119,7 +140,10 @@ const groupTrackingResultToGroupReport = async (
|
|
|
119
140
|
}
|
|
120
141
|
}
|
|
121
142
|
|
|
122
|
-
const getFileSizeMap = async (
|
|
143
|
+
const getFileSizeMap = async (
|
|
144
|
+
fileBuffer,
|
|
145
|
+
{ transformations, logger, fileUrl },
|
|
146
|
+
) => {
|
|
123
147
|
const sizeMap = {}
|
|
124
148
|
await Object.keys(transformations).reduce(async (previous, sizeName) => {
|
|
125
149
|
await previous
|
|
@@ -129,9 +153,12 @@ const getFileSizeMap = async (fileBuffer, { transformations, logger, fileUrl })
|
|
|
129
153
|
sizeMap[sizeName] = Buffer.from(transformResult).length
|
|
130
154
|
} catch (e) {
|
|
131
155
|
logger.error(
|
|
132
|
-
createDetailedMessage(
|
|
133
|
-
|
|
134
|
-
|
|
156
|
+
createDetailedMessage(
|
|
157
|
+
`error while transforming ${fileUrl} with ${sizeName}`,
|
|
158
|
+
{
|
|
159
|
+
"error stack": e.stack,
|
|
160
|
+
},
|
|
161
|
+
),
|
|
135
162
|
)
|
|
136
163
|
sizeMap[sizeName] = "error"
|
|
137
164
|
}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import { gzip, constants } from "zlib"
|
|
1
|
+
import { gzip, constants } from "node:zlib"
|
|
2
2
|
|
|
3
3
|
export const name = "gzip"
|
|
4
4
|
|
|
5
|
-
export const transform = (
|
|
5
|
+
export const transform = (
|
|
6
|
+
value,
|
|
7
|
+
{ level = constants.Z_MAX_LEVEL, ...rest } = {},
|
|
8
|
+
) => {
|
|
6
9
|
return new Promise((resolve, reject) => {
|
|
7
10
|
gzip(value, { level, ...rest }, (error, buffer) => {
|
|
8
11
|
if (error) {
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
urlToFileSystemPath,
|
|
3
|
+
collectDirectoryMatchReport,
|
|
4
|
+
} from "@jsenv/filesystem"
|
|
3
5
|
|
|
4
6
|
export const applyTrackingConfig = async (
|
|
5
7
|
trackingConfig,
|
|
6
|
-
{
|
|
8
|
+
{ projectDirectoryUrl, manifestConfig },
|
|
7
9
|
) => {
|
|
8
10
|
const result = {}
|
|
9
11
|
const trackingNames = Object.keys(trackingConfig)
|
|
@@ -19,13 +21,15 @@ export const applyTrackingConfig = async (
|
|
|
19
21
|
manifestConfig,
|
|
20
22
|
})
|
|
21
23
|
result[trackingName] = groupTrackingResult
|
|
22
|
-
cancellationToken.throwIfRequested()
|
|
23
24
|
}),
|
|
24
25
|
)
|
|
25
26
|
return result
|
|
26
27
|
}
|
|
27
28
|
|
|
28
|
-
const applyTracking = async (
|
|
29
|
+
const applyTracking = async (
|
|
30
|
+
tracking,
|
|
31
|
+
{ projectDirectoryUrl, manifestConfig },
|
|
32
|
+
) => {
|
|
29
33
|
const structuredMetaMap = {
|
|
30
34
|
track: tracking,
|
|
31
35
|
...(manifestConfig ? { manifest: manifestConfig } : {}),
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { comparePathnames } from "@jsenv/filesystem"
|
|
2
|
+
|
|
3
|
+
import { manifestToMappings, manifestKeyFromRelativeUrl } from "./manifest.js"
|
|
2
4
|
|
|
3
5
|
export const compareTwoFileSizeReports = ({
|
|
4
6
|
afterMergeFileSizeReport,
|
|
@@ -146,37 +148,6 @@ const compareTwoGroups = (beforeMergeGroup, afterMergeGroup) => {
|
|
|
146
148
|
}
|
|
147
149
|
}
|
|
148
150
|
|
|
149
|
-
const ABSTRACT_DIRECTORY_URL = "file:///directory/"
|
|
150
|
-
|
|
151
|
-
const manifestToMappings = (manifestMap) => {
|
|
152
|
-
const mappings = {}
|
|
153
|
-
Object.keys(manifestMap).forEach((manifestRelativeUrl) => {
|
|
154
|
-
const manifest = manifestMap[manifestRelativeUrl]
|
|
155
|
-
const manifestAbstractUrl = resolveUrl(manifestRelativeUrl, ABSTRACT_DIRECTORY_URL)
|
|
156
|
-
Object.keys(manifest).forEach((manifestKey) => {
|
|
157
|
-
const manifestValue = manifest[manifestKey]
|
|
158
|
-
const manifestKeyAsAbstractUrl = resolveUrl(manifestKey, manifestAbstractUrl)
|
|
159
|
-
const manifestValueAsAbstractUrl = resolveUrl(manifestValue, manifestAbstractUrl)
|
|
160
|
-
const manifestKeyAsRelativeUrl = urlToRelativeUrl(
|
|
161
|
-
manifestKeyAsAbstractUrl,
|
|
162
|
-
ABSTRACT_DIRECTORY_URL,
|
|
163
|
-
)
|
|
164
|
-
const manifestValueAsRelativeUrl = urlToRelativeUrl(
|
|
165
|
-
manifestValueAsAbstractUrl,
|
|
166
|
-
ABSTRACT_DIRECTORY_URL,
|
|
167
|
-
)
|
|
168
|
-
mappings[manifestKeyAsRelativeUrl] = manifestValueAsRelativeUrl
|
|
169
|
-
})
|
|
170
|
-
})
|
|
171
|
-
return mappings
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
const manifestKeyFromRelativeUrl = (relativeUrl, mappings) => {
|
|
175
|
-
return Object.keys(mappings).find((keyCandidate) => {
|
|
176
|
-
return mappings[keyCandidate] === relativeUrl
|
|
177
|
-
})
|
|
178
|
-
}
|
|
179
|
-
|
|
180
151
|
const sortFileStructure = (fileStructure) => {
|
|
181
152
|
const relativeUrlSortedArray = Object.keys(fileStructure).sort(comparePathnames)
|
|
182
153
|
const fileStructureSorted = {}
|
|
@@ -1,23 +1,26 @@
|
|
|
1
|
-
import { formatSize } from "./
|
|
1
|
+
import { formatSize } from "./formatSize.js"
|
|
2
|
+
import { manifestToMappings, manifestKeyFromRelativeUrl } from "./manifest.js"
|
|
2
3
|
|
|
3
|
-
export const
|
|
4
|
+
export const formatFileSizeReportForLog = (fileSizeReport) => {
|
|
4
5
|
const { groups } = fileSizeReport
|
|
5
6
|
|
|
6
7
|
const groupMessages = Object.keys(groups).map((groupName) => {
|
|
7
|
-
const { fileMap } = groups[groupName]
|
|
8
|
+
const { fileMap, manifestMap } = groups[groupName]
|
|
8
9
|
|
|
10
|
+
const mappings = manifestToMappings(manifestMap)
|
|
9
11
|
const fileMessages = Object.keys(fileMap).map((fileRelativeUrl) => {
|
|
12
|
+
const fileDisplayed = manifestKeyFromRelativeUrl(fileRelativeUrl, mappings) || fileRelativeUrl
|
|
10
13
|
const file = fileMap[fileRelativeUrl]
|
|
11
14
|
const { sizeMap } = file
|
|
12
15
|
const sizeNames = Object.keys(sizeMap)
|
|
13
16
|
if (sizeNames.length === 1) {
|
|
14
|
-
return `${
|
|
17
|
+
return `${fileDisplayed}: ${formatSize(sizeMap[sizeNames[0]])}`
|
|
15
18
|
}
|
|
16
19
|
|
|
17
20
|
const sizesFormatted = sizeNames.map((sizeName) => {
|
|
18
21
|
return `${sizeName}: ${formatSize(sizeMap[sizeName])}`
|
|
19
22
|
})
|
|
20
|
-
return `${
|
|
23
|
+
return `${fileDisplayed}: { ${sizesFormatted.join(`, `)} }`
|
|
21
24
|
})
|
|
22
25
|
|
|
23
26
|
return `${groupName}
|
|
@@ -32,5 +35,5 @@ ${groupMessages.join(`
|
|
|
32
35
|
`)}
|
|
33
36
|
`
|
|
34
37
|
|
|
35
|
-
|
|
38
|
+
return message
|
|
36
39
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { resolveUrl, urlToRelativeUrl } from "@jsenv/filesystem"
|
|
2
|
+
|
|
3
|
+
export const manifestToMappings = (manifestMap) => {
|
|
4
|
+
const mappings = {}
|
|
5
|
+
Object.keys(manifestMap).forEach((manifestRelativeUrl) => {
|
|
6
|
+
const manifest = manifestMap[manifestRelativeUrl]
|
|
7
|
+
const manifestAbstractUrl = resolveUrl(manifestRelativeUrl, ABSTRACT_DIRECTORY_URL)
|
|
8
|
+
Object.keys(manifest).forEach((manifestKey) => {
|
|
9
|
+
const manifestValue = manifest[manifestKey]
|
|
10
|
+
const manifestKeyAsAbstractUrl = resolveUrl(manifestKey, manifestAbstractUrl)
|
|
11
|
+
const manifestValueAsAbstractUrl = resolveUrl(manifestValue, manifestAbstractUrl)
|
|
12
|
+
const manifestKeyAsRelativeUrl = urlToRelativeUrl(
|
|
13
|
+
manifestKeyAsAbstractUrl,
|
|
14
|
+
ABSTRACT_DIRECTORY_URL,
|
|
15
|
+
)
|
|
16
|
+
const manifestValueAsRelativeUrl = urlToRelativeUrl(
|
|
17
|
+
manifestValueAsAbstractUrl,
|
|
18
|
+
ABSTRACT_DIRECTORY_URL,
|
|
19
|
+
)
|
|
20
|
+
mappings[manifestKeyAsRelativeUrl] = manifestValueAsRelativeUrl
|
|
21
|
+
})
|
|
22
|
+
})
|
|
23
|
+
return mappings
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const ABSTRACT_DIRECTORY_URL = "file:///directory/"
|
|
27
|
+
|
|
28
|
+
export const manifestKeyFromRelativeUrl = (relativeUrl, mappings) => {
|
|
29
|
+
return Object.keys(mappings).find((keyCandidate) => {
|
|
30
|
+
return mappings[keyCandidate] === relativeUrl
|
|
31
|
+
})
|
|
32
|
+
}
|
|
@@ -1,21 +1,10 @@
|
|
|
1
|
-
import { Worker } from "node:worker_threads"
|
|
2
|
-
import {
|
|
3
|
-
assertAndNormalizeDirectoryUrl,
|
|
4
|
-
fileSystemPathToUrl,
|
|
5
|
-
isFileSystemPath,
|
|
6
|
-
resolveUrl,
|
|
7
|
-
urlToFileSystemPath,
|
|
8
|
-
} from "@jsenv/filesystem"
|
|
9
1
|
import { commentGitHubPullRequestImpact } from "@jsenv/github-pull-request-impact"
|
|
2
|
+
import { assertAndNormalizeDirectoryUrl, resolveUrl } from "@jsenv/filesystem"
|
|
3
|
+
import { importOneExportFromFile } from "@jsenv/dynamic-import-worker"
|
|
10
4
|
|
|
11
5
|
import { formatComment } from "./internal/formatComment.js"
|
|
12
6
|
import { jsenvCommentParameters } from "./internal/jsenvCommentParameters.js"
|
|
13
7
|
|
|
14
|
-
const workerFileUrl = resolveUrl(
|
|
15
|
-
"./internal/worker_generating_file_size_report.js",
|
|
16
|
-
import.meta.url,
|
|
17
|
-
)
|
|
18
|
-
|
|
19
8
|
export const reportFileSizeImpact = async ({
|
|
20
9
|
logLevel,
|
|
21
10
|
commandLogs,
|
|
@@ -29,7 +18,7 @@ export const reportFileSizeImpact = async ({
|
|
|
29
18
|
pullRequestNumber,
|
|
30
19
|
installCommand = "npm install",
|
|
31
20
|
buildCommand = "npm run-script build",
|
|
32
|
-
|
|
21
|
+
fileSizeReportModulePath,
|
|
33
22
|
|
|
34
23
|
// We could just to ...jsenvCommentParameters but explicitely passing params
|
|
35
24
|
// helps autocompletion in vscode for dev using the function.
|
|
@@ -50,23 +39,29 @@ export const reportFileSizeImpact = async ({
|
|
|
50
39
|
if (installCommand === null) {
|
|
51
40
|
// a null installCommand means there is no need to install anything
|
|
52
41
|
} else if (typeof installCommand !== "string") {
|
|
53
|
-
throw new TypeError(
|
|
42
|
+
throw new TypeError(
|
|
43
|
+
`installCommand must be a string but received ${installCommand}`,
|
|
44
|
+
)
|
|
54
45
|
}
|
|
55
46
|
|
|
56
47
|
if (buildCommand === null) {
|
|
57
48
|
// a null buildCommand means there is no need to build anything
|
|
58
49
|
} else if (typeof buildCommand !== "string") {
|
|
59
|
-
throw new TypeError(
|
|
50
|
+
throw new TypeError(
|
|
51
|
+
`buildCommand must be a string but received ${buildCommand}`,
|
|
52
|
+
)
|
|
60
53
|
}
|
|
61
54
|
|
|
62
|
-
if (typeof
|
|
63
|
-
throw new TypeError(
|
|
55
|
+
if (typeof fileSizeReportModulePath !== "string") {
|
|
56
|
+
throw new TypeError(
|
|
57
|
+
`fileSizeReportModulePath must be a string but received ${fileSizeReportModulePath}`,
|
|
58
|
+
)
|
|
64
59
|
}
|
|
65
60
|
projectDirectoryUrl = assertAndNormalizeDirectoryUrl(projectDirectoryUrl)
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
61
|
+
const fileSizeReportModuleUrl = resolveUrl(
|
|
62
|
+
fileSizeReportModulePath,
|
|
63
|
+
projectDirectoryUrl,
|
|
64
|
+
)
|
|
70
65
|
|
|
71
66
|
return commentGitHubPullRequestImpact({
|
|
72
67
|
logLevel,
|
|
@@ -83,14 +78,9 @@ export const reportFileSizeImpact = async ({
|
|
|
83
78
|
collectInfo: async ({ execCommandInProjectDirectory }) => {
|
|
84
79
|
if (installCommand) await execCommandInProjectDirectory(installCommand)
|
|
85
80
|
if (buildCommand) await execCommandInProjectDirectory(buildCommand)
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
worker.postMessage({ fileSizeModuleUrl })
|
|
90
|
-
worker.on("message", resolve)
|
|
91
|
-
worker.on("error", reject)
|
|
92
|
-
})
|
|
93
|
-
|
|
81
|
+
const fileSizeReport = await importOneExportFromFile(
|
|
82
|
+
fileSizeReportModuleUrl,
|
|
83
|
+
)
|
|
94
84
|
return { version: 1, data: fileSizeReport }
|
|
95
85
|
},
|
|
96
86
|
commentIdentifier: `<!-- Generated by @jsenv/file-size-impact -->`,
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { parentPort } from "node:worker_threads"
|
|
2
|
-
|
|
3
|
-
parentPort.once("message", async ({ fileSizeModuleUrl }) => {
|
|
4
|
-
const { generateFileSizeReport } = await import(fileSizeModuleUrl)
|
|
5
|
-
|
|
6
|
-
if (typeof generateFileSizeReport !== "function") {
|
|
7
|
-
throw new TypeError(
|
|
8
|
-
`generateFileSizeReport export must be a function, got ${generateFileSizeReport}`,
|
|
9
|
-
)
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const fileSizeReport = await generateFileSizeReport()
|
|
13
|
-
|
|
14
|
-
parentPort.postMessage({
|
|
15
|
-
fileSizeReport,
|
|
16
|
-
})
|
|
17
|
-
})
|