@jsenv/file-size-impact 11.0.0 → 12.1.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/index.js CHANGED
@@ -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 { getFileSizeReport } from "./src/getFileSizeReport.js"
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,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/file-size-impact",
3
- "version": "11.0.0",
3
+ "version": "12.1.0",
4
4
  "description": "Add files size impact into pull requests",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -11,8 +11,7 @@
11
11
  "node": ">=14.17.0"
12
12
  },
13
13
  "publishConfig": {
14
- "access": "public",
15
- "registry": "https://registry.npmjs.org"
14
+ "access": "public"
16
15
  },
17
16
  "type": "module",
18
17
  "exports": {
@@ -28,7 +27,7 @@
28
27
  "scripts": {
29
28
  "eslint-check": "node ./node_modules/eslint/bin/eslint.js . --ext=.js,.mjs",
30
29
  "generate-importmap": "node ./script/importmap/generate_importmap.mjs",
31
- "measure-file-sizes": "node ./script/file_size/generate_file_size_report.mjs --local",
30
+ "measure-file-sizes": "node ./script/file_size/generate_file_size_report.mjs --log",
32
31
  "generate-comment-snapshot-file": "node ./test/comment/generate_comment_snapshot_file.mjs",
33
32
  "test": "node ./script/test/test.mjs",
34
33
  "test-with-coverage": "npm run test -- --coverage",
@@ -39,9 +38,10 @@
39
38
  "postpublish": "node ./script/publish/restore_postinstall.mjs"
40
39
  },
41
40
  "dependencies": {
41
+ "@jsenv/dynamic-import-worker": "1.0.0",
42
+ "@jsenv/filesystem": "2.3.1",
42
43
  "@jsenv/github-pull-request-impact": "1.6.4",
43
44
  "@jsenv/logger": "4.0.1",
44
- "@jsenv/filesystem": "2.2.0",
45
45
  "pretty-bytes": "5.6.0"
46
46
  },
47
47
  "devDependencies": {
@@ -50,7 +50,7 @@
50
50
  "@jsenv/assert": "2.3.2",
51
51
  "@jsenv/cancellation": "3.0.0",
52
52
  "@jsenv/codecov-upload": "3.5.0",
53
- "@jsenv/core": "23.0.2",
53
+ "@jsenv/core": "23.0.5",
54
54
  "@jsenv/eslint-config": "16.0.8",
55
55
  "@jsenv/filesystem": "2.2.0",
56
56
  "@jsenv/github-release-package": "1.2.3",
package/readme.md CHANGED
@@ -9,17 +9,29 @@
9
9
 
10
10
  # Pull request comment
11
11
 
12
- This section shows pull request comment and how to read _group summary_ and _size impact_ sections.
12
+ This section shows pull request comment and how to read it.
13
13
 
14
- ![legend of pull request comment](./docs/comment-legend.png)
14
+ ![legend of pull request comment](./docs/comment_legend.png)
15
15
 
16
- "_critical files (1/2)_" is a group summary, it translates into the following sentence:
16
+ ## group summary
17
17
 
18
- > "There is a group of files named **critical files** and pull request impacts **1** out of **2** files in this group."
18
+ "_remaining files (+4.71%)_" is a group summary, it translates into the following sentence:
19
19
 
20
- "_127.83KB (+6.84KB / +5.65%)_" is a size impact, it translates into the following sentence:
20
+ > "There is a group of files named **remaining files** and pull request has an overall impact of +4.71% on these files."
21
21
 
22
- > "The size after merge is **127.83KB** and pull request adds **6.84KB** representing an increase of **5.65%** of the size before merge."
22
+ ## size impact
23
+
24
+ "_21.6 kB (+4.11 kB / +23.55%)_" is a size impact, it translates into the following sentence:
25
+
26
+ > "The size after merge is **21.6 kB**. Pull request adds **4.11 kB** representing an increase of **23.55%** of the size before merge."
27
+
28
+ ## Unmodified row
29
+
30
+ Unmodified row is the sum of all files in a group that are not impacted by changes in the pull request.
31
+
32
+ ## Total row
33
+
34
+ Total row is the sum of all files in a group.
23
35
 
24
36
  # Installation
25
37
 
@@ -32,22 +44,25 @@ npm install --save-dev @jsenv/file-size-impact
32
44
  _generate_file_size_report.mjs_
33
45
 
34
46
  ```js
35
- import { getFileSizeReport } from "@jsenv/file-size-impact"
36
-
37
- export const generateFileSizeReport = async () => {
38
- return getFileSizeReport({
39
- projectDirectoryUrl: new URL("./", import.meta.url),
40
- trackingConfig: {
41
- dist: {
42
- "./dist/**/*": true,
43
- "./dist/**/*.map": false,
44
- },
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,
45
56
  },
46
- })
47
- }
57
+ },
58
+ })
48
59
  ```
49
60
 
50
- At this stage, you could generate a file size report on your machine. For an example, see [script/file_size/generate_file_size_report.mjs#L14](./script/file_size/generate_file_size_report.mjs#L14).
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
+ ```
51
66
 
52
67
  Now it's time to configure a workflow to compare file size reports before and after merging a pull request.
53
68
 
@@ -164,14 +179,14 @@ In order to analyse the impact of a pull request on file size the following step
164
179
  7. Analyse differences between the two file size reports
165
180
  8. Post or update comment in the pull request
166
181
 
167
- # getFileSizeReport
182
+ # generateFileSizeReport
168
183
 
169
- _getFileSizeReport_ is an async function scanning filesystem to compute a list of file sizes and return these infos into an object.
184
+ _generateFileSizeReport_ is an async function scanning filesystem to compute a list of file sizes and return these infos into an object.
170
185
 
171
186
  ```js
172
- import { getFileSizeReport, raw, gzip } from "@jsenv/file-size-impact"
187
+ import { generateFileSizeReport, raw, gzip } from "@jsenv/file-size-impact"
173
188
 
174
- const fileSizeReport = await getFileSizeReport({
189
+ const fileSizeReport = await generateFileSizeReport({
175
190
  projectDirectoryUrl: new URL("./", import.meta.url),
176
191
  trackingConfig: {
177
192
  dist: {
@@ -192,9 +207,9 @@ _trackingConfig_ values are objects associating a pattern to a value. This objec
192
207
  For example you can create two groups named _"critical files"_ and _"remaining files"_ like this:
193
208
 
194
209
  ```js
195
- import { getFileSizeReport } from "@jsenv/file-size-impact"
210
+ import { generateFileSizeReport } from "@jsenv/file-size-impact"
196
211
 
197
- await getFileSizeReport({
212
+ await generateFileSizeReport({
198
213
  trackingConfig: {
199
214
  "critical files": {
200
215
  "./dist/main.js": true,
@@ -210,7 +225,7 @@ await getFileSizeReport({
210
225
  })
211
226
  ```
212
227
 
213
- ![screenshot of pull request comment where groups are highlighted](./docs/group-highlighted.png)
228
+ ![screenshot of pull request comment where groups are highlighted](./docs/comment_group_highlighted.png)
214
229
 
215
230
  ## transformations
216
231
 
@@ -219,23 +234,23 @@ _transformations_ parameter is an object used to transform files content before
219
234
  You can use this parameter to track file size after gzip compression.
220
235
 
221
236
  ```js
222
- import { getFileSizeReport, raw, gzip, brotli } from "@jsenv/file-size-impact"
237
+ import { generateFileSizeReport, raw, gzip, brotli } from "@jsenv/file-size-impact"
223
238
 
224
- await getFileSizeReport({
239
+ await generateFileSizeReport({
225
240
  transformations: { raw, gzip, brotli },
226
241
  })
227
242
  ```
228
243
 
229
- ![screenshot of pull request comment with gzip and brotli](./docs/comment-compression.png)
244
+ ![screenshot of pull request comment with gzip and brotli](./docs/comment_compression.png)
230
245
 
231
246
  _raw_, _gzip_ and _brotli_ compression can be enabled this way.
232
247
 
233
248
  It's also possible to control compression level.
234
249
 
235
250
  ```js
236
- import { getFileSizeReport, raw, gzip } from "@jsenv/file-size-impact"
251
+ import { generateFileSizeReport, raw, gzip } from "@jsenv/file-size-impact"
237
252
 
238
- await getFileSizeReport({
253
+ await generateFileSizeReport({
239
254
  transformations: {
240
255
  raw,
241
256
  gzip7: (buffer) => gzip(buffer, { level: 7 }),
@@ -247,9 +262,9 @@ await getFileSizeReport({
247
262
  Finally _transformations_ can be used to add custom _transformations_.
248
263
 
249
264
  ```js
250
- import { getFileSizeReport, raw, gzip, brotli } from "@jsenv/file-size-impact"
265
+ import { generateFileSizeReport, raw, gzip, brotli } from "@jsenv/file-size-impact"
251
266
 
252
- await getFileSizeReport({
267
+ await generateFileSizeReport({
253
268
  transformations: {
254
269
  raw,
255
270
  trim: (buffer) => String(buffer).trim(),
@@ -346,7 +361,7 @@ _filesOrdering_ parameter is a string used to decide the order of the files disp
346
361
 
347
362
  _runLink_ parameter allow to put a link to the workflow run in the generated comment body. It is used to indicates where file size impact was runned.
348
363
 
349
- ![screenshot of pull request comment where runlink is highlighted](./docs/runlink-highlighted.png)
364
+ ![screenshot of pull request comment where runlink is highlighted](./docs/comment_run_link_highlighted.png)
350
365
 
351
366
  This parameter is returned by [readGitHubWorkflowEnv](#readGitHubWorkflowEnv) meaning it comes for free inside a GitHub workflow.
352
367
 
@@ -363,6 +378,12 @@ await reportFileSizeImpact({
363
378
  })
364
379
  ```
365
380
 
381
+ # commitInGeneratedByInfo
382
+
383
+ _commitInGeneratedByInfo_ parameter is a boolean controlling if a link to the commit where size impact was performed appears in the comment. This parameter is optional and enabled by default.
384
+
385
+ ![screenshot of pull request comment where link to commit is highlighted](./docs/comment_commit_link_highlighted.png)
386
+
366
387
  # readGitHubWorkflowEnv
367
388
 
368
389
  _readGitHubWorkflowEnv_ is a function meant to be runned inside a GitHub workflow. It returns an object meant to be forwarded to [reportFileSizeImpact](#reportFileSizeImpact).
@@ -10,9 +10,11 @@ import {
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 getFileSizeReport = async ({
15
+ export const generateFileSizeReport = async ({
15
16
  cancellationToken,
17
+ log,
16
18
  logLevel,
17
19
  projectDirectoryUrl,
18
20
  trackingConfig = jsenvTrackingConfig,
@@ -60,6 +62,10 @@ export const getFileSizeReport = async ({
60
62
  groups,
61
63
  }
62
64
 
65
+ if (log) {
66
+ logger.info(formatFileSizeReportForLog(fileSizeReport))
67
+ }
68
+
63
69
  return fileSizeReport
64
70
  }
65
71
 
@@ -1,4 +1,6 @@
1
- import { resolveUrl, comparePathnames, urlToRelativeUrl } from "@jsenv/filesystem"
1
+ import { comparePathnames } from "@jsenv/filesystem"
2
+
3
+ import { manifestToMappings } from "./manifest.js"
2
4
 
3
5
  export const compareTwoFileSizeReports = ({
4
6
  afterMergeFileSizeReport,
@@ -146,31 +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
151
  const manifestKeyFromRelativeUrl = (relativeUrl, mappings) => {
175
152
  return Object.keys(mappings).find((keyCandidate) => {
176
153
  return mappings[keyCandidate] === relativeUrl
@@ -1,23 +1,26 @@
1
- import { formatSize } from "./internal/formatSize.js"
1
+ import { formatSize } from "./formatSize.js"
2
+ import { manifestToMappings } from "./manifest.js"
2
3
 
3
- export const logFileSizeReport = (fileSizeReport) => {
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 = mappings[fileRelativeUrl] || 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 `${fileRelativeUrl}: ${formatSize(sizeMap[sizeNames[0]])}`
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 `${fileRelativeUrl}: { ${sizesFormatted.join(`, `)} }`
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
- console.log(message)
38
+ return message
36
39
  }
@@ -108,7 +108,13 @@ export const jsenvCommentParameters = {
108
108
  const formatSizeImpactAsPercentage = ({ sizeBeforeMerge, sizeAfterMerge }) => {
109
109
  const sizeDiff = sizeAfterMerge - sizeBeforeMerge
110
110
  const sizeDiffRatio =
111
- sizeBeforeMerge === 0 ? 1 : sizeAfterMerge === 0 ? -1 : sizeDiff / sizeBeforeMerge
111
+ sizeDiff === 0
112
+ ? 0
113
+ : sizeBeforeMerge === 0
114
+ ? 1
115
+ : sizeAfterMerge === 0
116
+ ? -1
117
+ : sizeDiff / sizeBeforeMerge
112
118
  const sizeDiffAsPercentage = sizeDiffRatio * 100
113
119
  const sizeDiffAsPercentageFormatted = `${sizeDiffAsPercentage < 0 ? `-` : "+"}${Math.abs(
114
120
  limitDecimals(sizeDiffAsPercentage, 2),
@@ -0,0 +1,26 @@
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/"
@@ -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"
1
+ import { assertAndNormalizeDirectoryUrl, resolveUrl } from "@jsenv/filesystem"
9
2
  import { commentGitHubPullRequestImpact } from "@jsenv/github-pull-request-impact"
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
- fileSizeModulePath,
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.
@@ -59,14 +48,13 @@ export const reportFileSizeImpact = async ({
59
48
  throw new TypeError(`buildCommand must be a string but received ${buildCommand}`)
60
49
  }
61
50
 
62
- if (typeof fileSizeModulePath !== "string") {
63
- throw new TypeError(`fileSizeModulePath must be a string but received ${fileSizeModulePath}`)
51
+ if (typeof fileSizeReportModulePath !== "string") {
52
+ throw new TypeError(
53
+ `fileSizeReportModulePath must be a string but received ${fileSizeReportModulePath}`,
54
+ )
64
55
  }
65
56
  projectDirectoryUrl = assertAndNormalizeDirectoryUrl(projectDirectoryUrl)
66
- const fileSizeModuleUrl = isFileSystemPath(fileSizeModulePath)
67
- ? fileSystemPathToUrl(fileSizeModulePath)
68
- : resolveUrl(fileSizeModulePath, projectDirectoryUrl)
69
- const workerFilePath = urlToFileSystemPath(workerFileUrl)
57
+ const fileSizeReportModuleUrl = resolveUrl(fileSizeReportModulePath, projectDirectoryUrl)
70
58
 
71
59
  return commentGitHubPullRequestImpact({
72
60
  logLevel,
@@ -83,14 +71,7 @@ export const reportFileSizeImpact = async ({
83
71
  collectInfo: async ({ execCommandInProjectDirectory }) => {
84
72
  if (installCommand) await execCommandInProjectDirectory(installCommand)
85
73
  if (buildCommand) await execCommandInProjectDirectory(buildCommand)
86
-
87
- const worker = new Worker(workerFilePath)
88
- const { fileSizeReport } = await new Promise((resolve, reject) => {
89
- worker.postMessage({ fileSizeModuleUrl })
90
- worker.on("message", resolve)
91
- worker.on("error", reject)
92
- })
93
-
74
+ const fileSizeReport = await importOneExportFromFile(fileSizeReportModuleUrl)
94
75
  return { version: 1, data: fileSizeReport }
95
76
  },
96
77
  commentIdentifier: `<!-- Generated by @jsenv/file-size-impact -->`,
@@ -1,17 +0,0 @@
1
- import { parentPort } from "node:worker_threads"
2
-
3
- parentPort.on("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
- })