Skip to content

Commit

Permalink
fix(build): remove private fields (#3514)
Browse files Browse the repository at this point in the history
* fix(build): remove private fields

* chore: format scripts

* test: add test code

* reduce package.json diff

* feat(build): add progress for removing private fields

* feat: rename `scripts` to `build`
  • Loading branch information
nakasyou authored Oct 15, 2024
1 parent aa50e0a commit 6cf01e5
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 13 deletions.
30 changes: 26 additions & 4 deletions build.ts → build/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
Copyright (c) 2022 Taishi Naritomi
*/

import { exec } from 'child_process'
import fs from 'fs'
/// <reference types="bun-types/bun" />

import fs, { write } from 'fs'
import path from 'path'
import arg from 'arg'
import { build } from 'esbuild'
import type { Plugin, PluginBuild, BuildOptions } from 'esbuild'
import glob from 'glob'
import * as glob from 'glob'
import { removePrivateFields } from './remove-private-fields'
import { $, stdout } from 'bun'

const args = arg({
'--watch': Boolean,
Expand Down Expand Up @@ -81,4 +84,23 @@ const esmBuild = () =>

Promise.all([esmBuild(), cjsBuild()])

exec(`tsc ${isWatch ? '-w' : ''} --emitDeclarationOnly --declaration --project tsconfig.build.json`)
await $`tsc ${
isWatch ? '-w' : ''
} --emitDeclarationOnly --declaration --project tsconfig.build.json`.nothrow()

// Remove #private fields
const dtsEntries = glob.globSync('./dist/types/**/*.d.ts')
const writer = stdout.writer()
writer.write('\n')
let lastOutputLength = 0
for (let i = 0; i < dtsEntries.length; i++) {
const entry = dtsEntries[i]

const message = `Removing private fields(${i}/${dtsEntries.length}): ${entry}`
writer.write(`\r${' '.repeat(lastOutputLength)}`)
lastOutputLength = message.length
writer.write(`\r${message}`)

fs.writeFileSync(entry, removePrivateFields(entry))
}
writer.write('\n')
21 changes: 21 additions & 0 deletions build/remove-private-fields.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/// <reference types="vitest/globals" />

import { removePrivateFields } from './remove-private-fields'
import fs from 'node:fs/promises'
import path from 'node:path'
import os from 'node:os'

describe('removePrivateFields', () => {
it('Works', async () => {
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'removePrivateFields'))
const tsPath = path.join(tmpDir, 'class.ts')
await fs.writeFile(tsPath, 'class X { #private: number = 0; a: number = 0 }')
expect(removePrivateFields(tsPath)).toBe(`class X {
a: number = 0;
}
`)
})
it('Should throw error when path does not exist', () => {
expect(() => removePrivateFields('./unknown.ts')).toThrowError(Error)
})
})
52 changes: 52 additions & 0 deletions build/remove-private-fields.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import * as ts from 'typescript'

const removePrivateTransformer = <T extends ts.Node>(ctx: ts.TransformationContext) => {
const visit: ts.Visitor = (node) => {
if (ts.isClassDeclaration(node)) {
const newMembers = node.members.filter((elem) => {
if (ts.isPropertyDeclaration(elem) || ts.isMethodDeclaration(elem)) {
for (const modifier of elem.modifiers ?? []) {
if (modifier.kind === ts.SyntaxKind.PrivateKeyword) {
return false
}
}
}
if (elem.name && ts.isPrivateIdentifier(elem.name)) {
return false
}
return true
})
return ts.factory.createClassDeclaration(
node.modifiers,
node.name,
node.typeParameters,
node.heritageClauses,
newMembers
)
}
return ts.visitEachChild(node, visit, ctx)
}

return (node: T) => {
const visited = ts.visitNode(node, visit)
if (!visited) {
throw new Error('The result visited is undefined.')
}
return visited
}
}

export const removePrivateFields = (tsPath: string) => {
const program = ts.createProgram([tsPath], {
target: ts.ScriptTarget.ESNext,
module: ts.ModuleKind.ESNext,
})
const file = program.getSourceFile(tsPath)

const transformed = ts.transform(file!, [removePrivateTransformer])
const printer = ts.createPrinter()
const transformedSourceFile = transformed.transformed[0] as ts.SourceFile
const code = printer.printFile(transformedSourceFile)
transformed.dispose()
return code
}
Binary file modified bun.lockb
Binary file not shown.
13 changes: 7 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@
"test:all": "bun run test && bun test:deno && bun test:bun && bun test:fastly && bun test:node && bun test:workerd && bun test:lambda && bun test:lambda-edge",
"lint": "eslint src runtime-tests",
"lint:fix": "eslint src runtime-tests --fix",
"format": "prettier --check --cache \"src/**/*.{js,ts,tsx}\" \"runtime-tests/**/*.{js,ts,tsx}\"",
"format:fix": "prettier --write --cache --cache-strategy metadata \"src/**/*.{js,ts,tsx}\" \"runtime-tests/**/*.{js,ts,tsx}\"",
"copy:package.cjs.json": "cp ./package.cjs.json ./dist/cjs/package.json && cp ./package.cjs.json ./dist/types/package.json ",
"build": "bun run --shell bun remove-dist && bun ./build.ts && bun run copy:package.cjs.json",
"format": "prettier --check --cache \"src/**/*.{js,ts,tsx}\" \"runtime-tests/**/*.{js,ts,tsx}\" \"build/**/*.{js,ts,tsx}\"",
"format:fix": "prettier --write --cache --cache-strategy metadata \"src/**/*.{js,ts,tsx}\" \"runtime-tests/**/*.{js,ts,tsx}\" \"build/**/*.{js,ts,tsx}\"",
"copy:package.cjs.json": "cp ./package.cjs.json ./dist/cjs/package.json && cp ./package.cjs.json ./dist/types/package.json",
"build": "bun run --shell bun remove-dist && bun ./build/build.ts && bun run copy:package.cjs.json",
"postbuild": "publint",
"watch": "bun run --shell bun remove-dist && bun ./build.ts --watch && bun run copy:package.cjs.json",
"watch": "bun run --shell bun remove-dist && bun ./build/build.ts --watch && bun run copy:package.cjs.json",
"coverage": "vitest --run --coverage",
"prerelease": "bun test:deno && bun run build",
"release": "np",
Expand Down Expand Up @@ -626,9 +626,10 @@
"@types/supertest": "^2.0.12",
"@vitest/coverage-v8": "^2.0.5",
"arg": "^5.0.2",
"bun-types": "^1.1.30",
"esbuild": "^0.15.12",
"eslint": "^9.10.0",
"glob": "7.2.3",
"glob": "^11.0.0",
"jsdom": "^22.1.0",
"msw": "^2.3.0",
"np": "7.7.0",
Expand Down
2 changes: 1 addition & 1 deletion vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default defineConfig({
},
test: {
globals: true,
include: ['**/src/**/(*.)+(spec|test).+(ts|tsx|js)'],
include: ['**/src/**/(*.)+(spec|test).+(ts|tsx|js)', '**/scripts/**/(*.)+(spec|test).+(ts|tsx|js)'],
exclude: [...configDefaults.exclude, '**/sandbox/**', '**/*.case.test.+(ts|tsx|js)'],
setupFiles: ['./.vitest.config/setup-vitest.ts'],
coverage: {
Expand Down
65 changes: 63 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
# bun ./bun.lockb --hash: 229521234768470F-a4cd9955ab6a6ada-9D052F6AF60C5C4D-0bfb97a3d93af742
# bun ./bun.lockb --hash: 77B78F6BF9FCD5E8-99bd6727146efa0f-3A60C19E44E6AEA6-b935857e930aa307


"@ampproject/remapping@^2.3.0":
Expand Down Expand Up @@ -1210,6 +1210,13 @@
dependencies:
undici-types "~5.26.4"

"@types/node@~20.12.8":
version "20.12.14"
resolved "https://registry.npmjs.org/@types/node/-/node-20.12.14.tgz"
integrity sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg==
dependencies:
undici-types "~5.26.4"

"@types/node@*", "@types/node@^22.5.5":
version "22.6.1"
resolved "https://registry.npmjs.org/@types/node/-/node-22.6.1.tgz"
Expand Down Expand Up @@ -1273,6 +1280,13 @@
resolved "https://registry.npmjs.org/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz"
integrity sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==

"@types/ws@~8.5.10":
version "8.5.12"
resolved "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz"
integrity sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==
dependencies:
"@types/node" "*"

"@typescript-eslint/eslint-plugin@^8.7.0":
version "8.7.0"
resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.7.0.tgz"
Expand Down Expand Up @@ -1721,6 +1735,14 @@ builtins@^1.0.3:
resolved "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz"
integrity sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==

bun-types@^1.1.30:
version "1.1.30"
resolved "https://registry.npmjs.org/bun-types/-/bun-types-1.1.30.tgz"
integrity sha512-mGh7NLisOXskBU62DxLS+/nwmLlCYHYAkCzdo4DZ9+fzrpP41hAdOqaN4DO6tQfenHb4pYb0/shw29k4/6I2yQ==
dependencies:
"@types/ws" "~8.5.10"
"@types/node" "~20.12.8"

cac@^6.7.14:
version "6.7.14"
resolved "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz"
Expand Down Expand Up @@ -3088,7 +3110,7 @@ github-url-from-git@^1.5.0:
resolved "https://registry.npmjs.org/github-url-from-git/-/github-url-from-git-1.5.0.tgz"
integrity sha512-WWOec4aRI7YAykQ9+BHmzjyNlkfJFG8QLXnDTsLz/kZefq7qkzdfo4p6fkYYMIq1aj+gZcQs/1HQhQh3DPPxlQ==

glob@7.2.3, glob@^7.1.3:
glob@^7.1.3:
version "7.2.3"
resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz"
integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
Expand Down Expand Up @@ -3123,6 +3145,18 @@ glob@^10.4.1:
foreground-child "^3.1.0"
package-json-from-dist "^1.0.0"

glob@^11.0.0:
version "11.0.0"
resolved "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz"
integrity sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==
dependencies:
minipass "^7.1.2"
jackspeak "^4.0.1"
minimatch "^10.0.0"
path-scurry "^2.0.0"
foreground-child "^3.1.0"
package-json-from-dist "^1.0.0"

glob-parent@^5.1.2, glob-parent@~5.1.2:
version "5.1.2"
resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz"
Expand Down Expand Up @@ -3765,6 +3799,13 @@ jackspeak@^3.1.2:
optionalDependencies:
"@pkgjs/parseargs" "^0.11.0"

jackspeak@^4.0.1:
version "4.0.2"
resolved "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.2.tgz"
integrity sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==
dependencies:
"@isaacs/cliui" "^8.0.2"

js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
Expand Down Expand Up @@ -4024,6 +4065,11 @@ lru-cache@^10.2.0:
resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz"
integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==

lru-cache@^11.0.0:
version "11.0.1"
resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.1.tgz"
integrity sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ==

magic-string@^0.25.3:
version "0.25.9"
resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz"
Expand Down Expand Up @@ -4221,6 +4267,13 @@ minimatch@^9.0.3, minimatch@^9.0.4, minimatch@^9.0.5:
dependencies:
brace-expansion "^2.0.1"

minimatch@^10.0.0:
version "10.0.1"
resolved "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz"
integrity sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==
dependencies:
brace-expansion "^2.0.1"

minimist@^1.2.0:
version "1.2.8"
resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz"
Expand Down Expand Up @@ -4748,6 +4801,14 @@ path-scurry@^1.11.1:
minipass "^5.0.0 || ^6.0.2 || ^7.0.0"
lru-cache "^10.2.0"

path-scurry@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz"
integrity sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==
dependencies:
lru-cache "^11.0.0"
minipass "^7.1.2"

path-to-regexp@^6.2.0, path-to-regexp@^6.3.0:
version "6.3.0"
resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz"
Expand Down

0 comments on commit 6cf01e5

Please sign in to comment.