From b2576c0c1f41450cc39d4aad30d76f49140a0478 Mon Sep 17 00:00:00 2001 From: fengmk2 Date: Thu, 14 Sep 2023 14:13:04 +0800 Subject: [PATCH] feat: use tshy to support commonjs and esm both (#468) https://isaacs.github.io/tshy/ --- .gitignore | 2 ++ package.json | 42 ++++++++++++++++++------------- scripts/build_test.js | 15 +++++++++++ scripts/esm_import_fix.js | 31 ----------------------- scripts/replace_urllib_version.js | 4 +-- settings.json | 10 -------- src/HttpClient.ts | 12 ++++----- src/Request.ts | 2 +- src/cjs/package.json | 3 --- src/diagnosticsChannel.ts | 4 +-- src/esm/package.json | 3 --- src/index.ts | 10 ++++---- src/utils.ts | 2 +- test/fixtures/ts-esm/package.json | 5 +++- test/fixtures/ts/package.json | 5 +++- tsconfig.build.cjs.json | 6 ----- tsconfig.build.esm.json | 7 ------ tsconfig.json | 4 +-- 18 files changed, 68 insertions(+), 99 deletions(-) create mode 100644 scripts/build_test.js delete mode 100644 scripts/esm_import_fix.js delete mode 100644 settings.json delete mode 100644 src/cjs/package.json delete mode 100644 src/esm/package.json delete mode 100644 tsconfig.build.cjs.json delete mode 100644 tsconfig.build.esm.json diff --git a/.gitignore b/.gitignore index 0e3c17b1..9e5122da 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,6 @@ src/**/*.d.ts !src/formstream.d.ts .DS_Store test/fixtures/ts/*.js +test/fixtures/ts-esm/*.js .eslintcache +.tshy/ diff --git a/package.json b/package.json index 55b4421a..22de8475 100644 --- a/package.json +++ b/package.json @@ -19,21 +19,28 @@ "author": "fengmk2 (https://github.com/fengmk2)", "homepage": "https://github.com/node-modules/urllib", "type": "module", + "tshy": { + "exports": { + ".": "./src/index.ts", + "./package.json": "./package.json" + } + }, "exports": { ".": { "import": { - "types": "./src/esm/index.d.ts", - "default": "./src/esm/index.js" + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" }, "require": { - "types": "./src/cjs/index.d.ts", - "default": "./src/cjs/index.js" + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" } - } + }, + "./package.json": "./package.json" }, - "types": "./src/esm/index.d.ts", - "main": "./src/cjs/index.js", + "typings": "./dist/commonjs/index.d.ts", "files": [ + "dist", "src" ], "repository": { @@ -43,24 +50,22 @@ "scripts": { "lint": "eslint src test --ext .ts --cache", "prebuild": "npm run clean", - "build": "tsc --version && npm run build:cjs && npm run build:esm && npm run build:version", - "postbuild": "rm -rf src/*.tsbuildinfo", - "build:cjs": "tsc -p ./tsconfig.build.cjs.json", - "build:esm": "tsc -p ./tsconfig.build.esm.json && node ./scripts/esm_import_fix.js", + "build": "tsc --version && tshy && npm run build:version", + "postbuild": "rm -rf *.tsbuildinfo", "build:version": "node ./scripts/replace_urllib_version.js", "build:cjs:test": "cd test/cjs && rm -rf node_modules && npm link ../.. && node index.js", "build:esm:test": "cd test/esm && rm -rf node_modules && npm link ../.. && node index.js", "build:mts:test": "cd test/mts && rm -rf node_modules && npm link ../.. && tsc", "build:test": "npm run build && npm run build:cjs:test && npm run build:esm:test && npm run build:mts:test && npm run test-tsc", - "test-tsc": "npm run test-tsc:cjs", - "test-tsc:cjs": "tsc -p ./test/fixtures/ts/tsconfig.json", - "test-tsc:esm": "tsc -p ./test/fixtures/ts-esm/tsconfig.json", + "test-tsc": "npm run test-tsc:cjs && npm run test-tsc:esm", + "test-tsc:cjs": "cd test/fixtures/ts && rm -rf node_modules && npm link ../../.. && npm run build", + "test-tsc:esm": "cd test/fixtures/ts-esm && rm -rf node_modules && npm link ../../.. && npm run build", "test": "npm run lint && vitest run", "test-keepalive": "cross-env TEST_KEEPALIVE_COUNT=50 vitest run --test-timeout 180000 keep-alive-header.test.ts", "cov": "vitest run --coverage", - "ci": "npm run lint && npm run cov && npm run build:test", + "ci": "npm run lint && npm run cov && node scripts/build_test.js", "contributor": "git-contributor", - "clean": "rm -rf src/*.tsbuildinfo src/cjs/*.ts src/cjs/*.js src/esm/*.ts src/esm/*.js", + "clean": "rm -rf dist", "prepublishOnly": "npm run build" }, "dependencies": { @@ -76,6 +81,8 @@ "ylru": "^1.3.2" }, "devDependencies": { + "@tsconfig/node18": "^18.2.1", + "@tsconfig/strictest": "^2.0.2", "@types/busboy": "^1.5.0", "@types/default-user-agent": "^1.0.0", "@types/mime-types": "^2.1.1", @@ -85,8 +92,6 @@ "@types/selfsigned": "^2.0.1", "@types/tar-stream": "^2.2.2", "@vitest/coverage-v8": "^0.32.0", - "@tsconfig/node18": "^18.2.1", - "@tsconfig/strictest": "^2.0.2", "busboy": "^1.6.0", "cross-env": "^7.0.3", "eslint": "^8.25.0", @@ -96,6 +101,7 @@ "proxy": "^1.0.2", "selfsigned": "^2.0.1", "tar-stream": "^2.2.0", + "tshy": "^1.0.0-3", "typescript": "^5.0.4", "vitest": "^0.32.0" }, diff --git a/scripts/build_test.js b/scripts/build_test.js new file mode 100644 index 00000000..d2b06180 --- /dev/null +++ b/scripts/build_test.js @@ -0,0 +1,15 @@ +import { execSync } from 'child_process'; + +function main() { + if (process.version.startsWith('v14.')) { + console.log(`ignore build:test on Node.js ${process.version}`); + return; + } + const cwd = process.cwd() + execSync('npm run build:test', { + cwd, + stdio: [ 'inherit', 'inherit', 'inherit' ], + }); +} + +main(); diff --git a/scripts/esm_import_fix.js b/scripts/esm_import_fix.js deleted file mode 100644 index c7faf251..00000000 --- a/scripts/esm_import_fix.js +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env node - -import fs from 'fs/promises'; -import path from 'path'; - -async function main() { - const root = path.join(process.cwd(), 'src/esm'); - const files = await fs.readdir(root); - for (const name of files) { - if (!name.endsWith('.js') && !name.endsWith('.d.ts')) continue; - const file = path.join(root, name); - const content = await fs.readFile(file, 'utf-8'); - // replace "from './HttpClient'" to "from './HttpClient.js'" - const newContent = content.replace(/ from \'(\.\/[^\.\']+?)\'/g, (match, p1) => { - const after = ` from '${p1}.js'`; - console.log('[%s] %s => %s', file, match, after); - return after; - }).replace(/import\(\"(\.\/[^\.\"]+?)\"\)/g, (match, p1) => { - // import("./Response") => import("./Response.js") - const after = `import("${p1}.js")`; - console.log('[%s] %s => %s', file, match, after); - return after; - }); - if (newContent !== content) { - await fs.writeFile(file, newContent); - console.log('ESM import fix on %s', file); - } - } -} - -main(); diff --git a/scripts/replace_urllib_version.js b/scripts/replace_urllib_version.js index 31807981..0efb7b02 100644 --- a/scripts/replace_urllib_version.js +++ b/scripts/replace_urllib_version.js @@ -7,8 +7,8 @@ async function main() { const root = process.cwd(); const pkg = JSON.parse(await fs.readFile(path.join(root, 'package.json'))); const files = [ - path.join(root, 'src/cjs/HttpClient.js'), - path.join(root, 'src/esm/HttpClient.js'), + path.join(root, 'dist/commonjs/HttpClient.js'), + path.join(root, 'dist/esm/HttpClient.js'), ]; for (const file of files) { const content = await fs.readFile(file, 'utf-8'); diff --git a/settings.json b/settings.json deleted file mode 100644 index 5bc5afc4..00000000 --- a/settings.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "eslint.validate": [ - "javascript", - "javascriptreact", - { - "language": "typescript", - "autoFix": true - } - ] -} diff --git a/src/HttpClient.ts b/src/HttpClient.ts index e8a428c3..72d87368 100644 --- a/src/HttpClient.ts +++ b/src/HttpClient.ts @@ -30,12 +30,12 @@ import qs from 'qs'; import pump from 'pump'; // Compatible with old style formstream import FormStream from 'formstream'; -import { HttpAgent, CheckAddressFunction } from './HttpAgent'; -import { RequestURL, RequestOptions, HttpMethod, RequestMeta } from './Request'; -import { RawResponseWithMeta, HttpClientResponse, SocketInfo } from './Response'; -import { parseJSON, sleep, digestAuthHeader, globalId, performanceTime, isReadable } from './utils'; -import symbols from './symbols'; -import { initDiagnosticsChannel } from './diagnosticsChannel'; +import { HttpAgent, CheckAddressFunction } from './HttpAgent.js'; +import { RequestURL, RequestOptions, HttpMethod, RequestMeta } from './Request.js'; +import { RawResponseWithMeta, HttpClientResponse, SocketInfo } from './Response.js'; +import { parseJSON, sleep, digestAuthHeader, globalId, performanceTime, isReadable } from './utils.js'; +import symbols from './symbols.js'; +import { initDiagnosticsChannel } from './diagnosticsChannel.js'; type Exists = T extends undefined ? never : T; type UndiciRequestOption = Exists[1]>; diff --git a/src/Request.ts b/src/Request.ts index aa907903..f46ae745 100644 --- a/src/Request.ts +++ b/src/Request.ts @@ -3,7 +3,7 @@ import type { IncomingHttpHeaders } from 'node:http'; import type { Dispatcher } from 'undici'; import type { HttpClientResponse, -} from './Response'; +} from './Response.js'; export type HttpMethod = Dispatcher.HttpMethod; diff --git a/src/cjs/package.json b/src/cjs/package.json deleted file mode 100644 index 5bbefffb..00000000 --- a/src/cjs/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "commonjs" -} diff --git a/src/diagnosticsChannel.ts b/src/diagnosticsChannel.ts index 41ceb55c..dea9e80c 100644 --- a/src/diagnosticsChannel.ts +++ b/src/diagnosticsChannel.ts @@ -3,8 +3,8 @@ import { performance } from 'node:perf_hooks'; import { debuglog } from 'node:util'; import { Socket } from 'node:net'; import { DiagnosticsChannel } from 'undici'; -import symbols from './symbols'; -import { globalId, performanceTime } from './utils'; +import symbols from './symbols.js'; +import { globalId, performanceTime } from './utils.js'; const debug = debuglog('urllib:DiagnosticsChannel'); let initedDiagnosticsChannel = false; diff --git a/src/esm/package.json b/src/esm/package.json deleted file mode 100644 index 3dbc1ca5..00000000 --- a/src/esm/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "module" -} diff --git a/src/index.ts b/src/index.ts index 61769e4e..5ca86270 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,6 @@ import LRU from 'ylru'; -import { HttpClient, HEADER_USER_AGENT } from './HttpClient'; -import { RequestOptions, RequestURL } from './Request'; +import { HttpClient, HEADER_USER_AGENT } from './HttpClient.js'; +import { RequestOptions, RequestURL } from './Request.js'; let httpclient: HttpClient; const domainSocketHttpclients = new LRU(50); @@ -39,14 +39,14 @@ export { export { HttpClient, HttpClient as HttpClient2, HEADER_USER_AGENT as USER_AGENT, RequestDiagnosticsMessage, ResponseDiagnosticsMessage, -} from './HttpClient'; +} from './HttpClient.js'; // RequestOptions2 is keep compatible with urlib@2 RequestOptions2 export { RequestOptions, RequestOptions as RequestOptions2, RequestURL, HttpMethod, FixJSONCtlCharsHandler, FixJSONCtlChars, -} from './Request'; +} from './Request.js'; -export { SocketInfo, Timing, RawResponseWithMeta, HttpClientResponse } from './Response'; +export { SocketInfo, Timing, RawResponseWithMeta, HttpClientResponse } from './Response.js'; export default { request, diff --git a/src/utils.ts b/src/utils.ts index 2e12c7ac..bde49674 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,7 +1,7 @@ import { randomBytes, createHash } from 'node:crypto'; import { Readable } from 'node:stream'; import { performance } from 'node:perf_hooks'; -import { FixJSONCtlChars } from './Request'; +import type { FixJSONCtlChars } from './Request.js'; const JSONCtlCharsMap = { '"': '\\"', // \u0022 diff --git a/test/fixtures/ts-esm/package.json b/test/fixtures/ts-esm/package.json index d8e3fe76..20db7b51 100644 --- a/test/fixtures/ts-esm/package.json +++ b/test/fixtures/ts-esm/package.json @@ -1,4 +1,7 @@ { "name": "ts-esm-demo", - "type": "module" + "type": "module", + "scripts": { + "build": "tsc && node hello.js" + } } diff --git a/test/fixtures/ts/package.json b/test/fixtures/ts/package.json index 20e6ebf5..23607c7a 100644 --- a/test/fixtures/ts/package.json +++ b/test/fixtures/ts/package.json @@ -1,3 +1,6 @@ { - "name": "ts-cjs-demo" + "name": "ts-cjs-demo", + "scripts": { + "build": "tsc && node hello.js" + } } diff --git a/tsconfig.build.cjs.json b/tsconfig.build.cjs.json deleted file mode 100644 index e737e1ba..00000000 --- a/tsconfig.build.cjs.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "./src/cjs", - } -} diff --git a/tsconfig.build.esm.json b/tsconfig.build.esm.json deleted file mode 100644 index 3660e9f3..00000000 --- a/tsconfig.build.esm.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "module": "ESNext", - "outDir": "./src/esm", - } -} diff --git a/tsconfig.json b/tsconfig.json index 8ab89bd6..51c9027f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,8 +7,8 @@ "emitDecoratorMetadata": true, "experimentalDecorators": true, "importHelpers": false, - "module": "CommonJS", - "moduleResolution": "Node", + "module": "NodeNext", + "moduleResolution": "NodeNext", "newLine": "LF", "checkJs": false, "allowJs": true,