@checkdigit/typescript-config 3.3.0-PR.34-c87d → 3.4.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/package.json
CHANGED
@@ -1 +1,196 @@
|
|
1
|
-
{
|
1
|
+
{
|
2
|
+
"name": "@checkdigit/typescript-config",
|
3
|
+
"version": "3.4.0",
|
4
|
+
"description": "Check Digit standard Typescript configuration",
|
5
|
+
"prettier": "@checkdigit/prettier-config",
|
6
|
+
"engines": {
|
7
|
+
"node": ">=16"
|
8
|
+
},
|
9
|
+
"bin": {
|
10
|
+
"builder": "./bin/builder.mjs"
|
11
|
+
},
|
12
|
+
"peerDependencies": {
|
13
|
+
"@types/node": ">=16",
|
14
|
+
"esbuild": "0.17.19",
|
15
|
+
"typescript": ">=5.0.4 <5.1"
|
16
|
+
},
|
17
|
+
"repository": {
|
18
|
+
"type": "git",
|
19
|
+
"url": "git+https://github.com/checkdigit/typescript-config.git"
|
20
|
+
},
|
21
|
+
"author": "Check Digit, LLC",
|
22
|
+
"license": "MIT",
|
23
|
+
"bugs": {
|
24
|
+
"url": "https://github.com/checkdigit/typescript-config/issues"
|
25
|
+
},
|
26
|
+
"homepage": "https://github.com/checkdigit/typescript-config#readme",
|
27
|
+
"scripts": {
|
28
|
+
"preversion": "npm test",
|
29
|
+
"postversion": "git push && git push --tags",
|
30
|
+
"prepare": "npm run build-builder",
|
31
|
+
"lint:fix": "eslint -f unix --ext .ts,.mts src --fix",
|
32
|
+
"lint": "eslint -f unix --ext .ts,.mts src",
|
33
|
+
"prettier": "prettier --ignore-path .gitignore --list-different .",
|
34
|
+
"prettier:fix": "prettier --ignore-path .gitignore --write .",
|
35
|
+
"test": "npm run ci:compile && npm run ci:test && npm run ci:lint && npm run ci:style",
|
36
|
+
"build-builder": "esbuild src/builder/index.mts --bundle --platform=node --format=esm --external:typescript --external:esbuild --outfile=build-builder/builder.mjs && mkdir -p bin && { echo '#!/usr/bin/env node'; cat build-builder/builder.mjs; } > bin/builder.mjs && chmod +x bin/builder.mjs",
|
37
|
+
"build-cjs": "rimraf build-cjs && npx builder --type=commonjs --outDir=build-cjs",
|
38
|
+
"build-cjs-bundle": "rimraf build-cjs-bundle && npx builder --type=commonjs --entryPoint=test/index.test.ts --outDir=build-cjs-bundle --outFile=test/index.test.cjs --minify --sourceMap",
|
39
|
+
"build-cjs-bundle-no-external": "rimraf build-cjs-bundle-no-external && npx builder --type=commonjs --external=./node_modules/* --entryPoint=test/index.test.ts --outDir=build-cjs-bundle-no-external --outFile=test/index.test.cjs",
|
40
|
+
"build-esm": "rimraf build-esm && npx builder --type=module --outDir=build-esm",
|
41
|
+
"build-esm-bundle": "rimraf build-esm-bundle && npx builder --type=module --outDir=build-esm-bundle --entryPoint=test/index.test.ts --outFile=test/index.test.mjs",
|
42
|
+
"build-esm-bundle-no-external": "rimraf build-esm-bundle-no-external && npx builder --type=module --external=./node_modules/* --outDir=build-esm-bundle-no-external --entryPoint=test/index.test.ts --outFile=test/index.test.mjs --minify",
|
43
|
+
"test-jest-esm": "NODE_OPTIONS=\"--experimental-vm-modules\" jest --coverage=false src/*.mts src/*/*.mts src/*/*/*.mts",
|
44
|
+
"test-jest-cjs": "jest --coverage=false src/*.ts src/*/*.ts src/*/*/*.ts",
|
45
|
+
"test-cjs": "node --test build-cjs/test/index.test.cjs",
|
46
|
+
"test-cjs-bundle": "node --test build-cjs-bundle/test/index.test.cjs",
|
47
|
+
"test-cjs-bundle-no-external": "node --test build-cjs-bundle-no-external/test/index.test.cjs",
|
48
|
+
"test-esm": "node --test build-esm/test/index.test.mjs",
|
49
|
+
"test-esm-bundle": "echo \"node --test build-esm-bundle/test/index.test.mjs\"",
|
50
|
+
"test-esm-bundle-no-external": "node --test build-esm-bundle-no-external/test/index.test.mjs",
|
51
|
+
"ci:test": "npm run test-jest-cjs && npm run test-jest-esm && npm run test-cjs && npm run test-cjs-bundle && npm run test-cjs-bundle-no-external && npm run test-esm && npm run test-esm-bundle && npm run test-esm-bundle-no-external",
|
52
|
+
"ci:compile": "npm run build-builder && npm run build-cjs && npm run build-cjs-bundle && npm run build-cjs-bundle-no-external && npm run build-esm && npm run build-esm-bundle && npm run build-esm-bundle-no-external",
|
53
|
+
"ci:lint": "npm run lint",
|
54
|
+
"ci:style": "npm run prettier"
|
55
|
+
},
|
56
|
+
"devDependencies": {
|
57
|
+
"@checkdigit/prettier-config": "^3.4.0",
|
58
|
+
"@types/debug": "^4.1.7",
|
59
|
+
"@types/jest": "^29.5.1",
|
60
|
+
"@types/uuid": "^9.0.1",
|
61
|
+
"@typescript-eslint/eslint-plugin": "^5.59.6",
|
62
|
+
"@typescript-eslint/parser": "^5.59.6",
|
63
|
+
"debug": "^4.3.4",
|
64
|
+
"eslint": "^8.40.0",
|
65
|
+
"eslint-config-prettier": "^8.8.0",
|
66
|
+
"get-port": "^6.1.2",
|
67
|
+
"got": "^11.8.6",
|
68
|
+
"jest": "^29.5.0",
|
69
|
+
"rimraf": "^5.0.1",
|
70
|
+
"ts-jest": "^29.1.0",
|
71
|
+
"uuid": "^9.0.0"
|
72
|
+
},
|
73
|
+
"eslintConfig": {
|
74
|
+
"parser": "@typescript-eslint/parser",
|
75
|
+
"plugins": [
|
76
|
+
"@typescript-eslint"
|
77
|
+
],
|
78
|
+
"parserOptions": {
|
79
|
+
"project": "./tsconfig.json"
|
80
|
+
},
|
81
|
+
"extends": [
|
82
|
+
"eslint:all",
|
83
|
+
"plugin:@typescript-eslint/recommended",
|
84
|
+
"plugin:@typescript-eslint/recommended-requiring-type-checking",
|
85
|
+
"plugin:@typescript-eslint/strict",
|
86
|
+
"prettier"
|
87
|
+
],
|
88
|
+
"rules": {
|
89
|
+
"@typescript-eslint/non-nullable-type-assertion-style": "error",
|
90
|
+
"capitalized-comments": "off",
|
91
|
+
"one-var": "off",
|
92
|
+
"sort-keys": "off",
|
93
|
+
"sort-imports": "off",
|
94
|
+
"func-style": [
|
95
|
+
"error",
|
96
|
+
"declaration",
|
97
|
+
{
|
98
|
+
"allowArrowFunctions": true
|
99
|
+
}
|
100
|
+
],
|
101
|
+
"no-magic-numbers": [
|
102
|
+
"error",
|
103
|
+
{
|
104
|
+
"ignore": [
|
105
|
+
0,
|
106
|
+
1,
|
107
|
+
2
|
108
|
+
]
|
109
|
+
}
|
110
|
+
],
|
111
|
+
"no-undefined": "off",
|
112
|
+
"no-ternary": "off"
|
113
|
+
},
|
114
|
+
"overrides": [
|
115
|
+
{
|
116
|
+
"files": [
|
117
|
+
"*.spec.mts",
|
118
|
+
"*.test.mts",
|
119
|
+
"*.spec.ts",
|
120
|
+
"*.test.ts"
|
121
|
+
],
|
122
|
+
"rules": {
|
123
|
+
"@typescript-eslint/non-nullable-type-assertion-style": "off",
|
124
|
+
"@typescript-eslint/ban-types": "off",
|
125
|
+
"@typescript-eslint/require-await": "off",
|
126
|
+
"@typescript-eslint/consistent-type-definitions": "off",
|
127
|
+
"@typescript-eslint/ban-ts-comment": "off",
|
128
|
+
"@typescript-eslint/no-unnecessary-condition": "off",
|
129
|
+
"@typescript-eslint/consistent-indexed-object-style": "off",
|
130
|
+
"@typescript-eslint/no-unused-vars": "off",
|
131
|
+
"@typescript-eslint/no-unsafe-member-access": "off",
|
132
|
+
"line-comment-position": "off",
|
133
|
+
"no-inline-comments": "off",
|
134
|
+
"no-param-reassign": "off",
|
135
|
+
"id-length": "off",
|
136
|
+
"no-magic-numbers": "off",
|
137
|
+
"func-names": "off",
|
138
|
+
"no-duplicate-imports": "off",
|
139
|
+
"symbol-description": "off",
|
140
|
+
"no-invalid-this": "off",
|
141
|
+
"max-lines-per-function": "off",
|
142
|
+
"max-lines": "off",
|
143
|
+
"max-statements": "off",
|
144
|
+
"no-await-in-loop": "off"
|
145
|
+
}
|
146
|
+
}
|
147
|
+
]
|
148
|
+
},
|
149
|
+
"jest": {
|
150
|
+
"moduleFileExtensions": [
|
151
|
+
"js",
|
152
|
+
"mjs",
|
153
|
+
"cjs",
|
154
|
+
"ts",
|
155
|
+
"mts",
|
156
|
+
"json",
|
157
|
+
"node"
|
158
|
+
],
|
159
|
+
"extensionsToTreatAsEsm": [
|
160
|
+
".mts"
|
161
|
+
],
|
162
|
+
"transform": {
|
163
|
+
"^.+\\.mts$": [
|
164
|
+
"ts-jest",
|
165
|
+
{
|
166
|
+
"isolatedModules": true,
|
167
|
+
"diagnostics": false,
|
168
|
+
"useESM": true
|
169
|
+
}
|
170
|
+
],
|
171
|
+
"^.+\\.ts$": [
|
172
|
+
"ts-jest",
|
173
|
+
{
|
174
|
+
"isolatedModules": true,
|
175
|
+
"diagnostics": false,
|
176
|
+
"useESM": false
|
177
|
+
}
|
178
|
+
]
|
179
|
+
},
|
180
|
+
"collectCoverageFrom": [
|
181
|
+
"<rootDir>/src/**",
|
182
|
+
"!<rootDir>/src/**/*.spec.mts",
|
183
|
+
"!<rootDir>/src/**/*.test.mts",
|
184
|
+
"!<rootDir>/src/**/*.spec.ts",
|
185
|
+
"!<rootDir>/src/**/*.test.ts"
|
186
|
+
],
|
187
|
+
"testMatch": [
|
188
|
+
"<rootDir>/src/**/*.spec.ts",
|
189
|
+
"<rootDir>/src/**/*.spec.mts"
|
190
|
+
]
|
191
|
+
},
|
192
|
+
"files": [
|
193
|
+
"tsconfig.json",
|
194
|
+
"SECURITY.md"
|
195
|
+
]
|
196
|
+
}
|
package/src/builder/builder.mts
DELETED
@@ -1,229 +0,0 @@
|
|
1
|
-
// builder/builder.mts
|
2
|
-
|
3
|
-
import { strict as assert } from 'node:assert';
|
4
|
-
import { promises as fs } from 'node:fs';
|
5
|
-
import path from 'node:path';
|
6
|
-
import typescript from 'typescript';
|
7
|
-
|
8
|
-
import { PluginBuild, build } from 'esbuild';
|
9
|
-
|
10
|
-
export interface BuilderOptions {
|
11
|
-
/**
|
12
|
-
* whether to produce ESM or CommonJS code
|
13
|
-
*/
|
14
|
-
type: 'module' | 'commonjs';
|
15
|
-
|
16
|
-
/**
|
17
|
-
* the entry point for the bundle, relative to the inDir. if not provided, the files in the inDir will be processed
|
18
|
-
* as individual unbundled files
|
19
|
-
*/
|
20
|
-
entryPoint?: string | undefined;
|
21
|
-
|
22
|
-
/**
|
23
|
-
* source code
|
24
|
-
*/
|
25
|
-
inDir: string;
|
26
|
-
|
27
|
-
/**
|
28
|
-
* build directory
|
29
|
-
*/
|
30
|
-
outDir: string;
|
31
|
-
|
32
|
-
/**
|
33
|
-
* build file, relative to the outDir
|
34
|
-
*/
|
35
|
-
outFile?: string | undefined;
|
36
|
-
|
37
|
-
/**
|
38
|
-
* external modules to exclude from the bundle
|
39
|
-
*/
|
40
|
-
external?: string[] | undefined;
|
41
|
-
|
42
|
-
/**
|
43
|
-
* whether to minify output
|
44
|
-
*/
|
45
|
-
minify?: boolean | undefined;
|
46
|
-
|
47
|
-
/**
|
48
|
-
* whether to include sourcemap
|
49
|
-
*/
|
50
|
-
sourceMap?: boolean | undefined;
|
51
|
-
}
|
52
|
-
|
53
|
-
/**
|
54
|
-
* Recursively obtains all files in a directory
|
55
|
-
* @param {string} directory
|
56
|
-
* @returns {Promise<string[]>}
|
57
|
-
*/
|
58
|
-
async function getFiles(directory: string): Promise<string[]> {
|
59
|
-
const entries = await fs.readdir(directory, { withFileTypes: true });
|
60
|
-
const files = await Promise.all(
|
61
|
-
entries.map((entry) => {
|
62
|
-
const result = path.resolve(directory, entry.name);
|
63
|
-
return entry.isDirectory() ? getFiles(result) : result;
|
64
|
-
})
|
65
|
-
);
|
66
|
-
return files.flat();
|
67
|
-
}
|
68
|
-
|
69
|
-
function excludeSourceMaps(filter: RegExp) {
|
70
|
-
return (pluginBuild: PluginBuild) => {
|
71
|
-
// ignore source maps for any Javascript file that matches filter
|
72
|
-
pluginBuild.onLoad({ filter }, async (args) => {
|
73
|
-
if (args.path.endsWith('.js') || args.path.endsWith('.mjs') || args.path.endsWith('.cjs')) {
|
74
|
-
return {
|
75
|
-
contents: `${await fs.readFile(
|
76
|
-
args.path,
|
77
|
-
'utf8'
|
78
|
-
)}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIiJdLCJtYXBwaW5ncyI6IkEifQ==`,
|
79
|
-
loader: 'default',
|
80
|
-
};
|
81
|
-
}
|
82
|
-
return undefined;
|
83
|
-
});
|
84
|
-
};
|
85
|
-
}
|
86
|
-
|
87
|
-
function resolveTypescriptPaths(type: 'module' | 'commonjs') {
|
88
|
-
const extension = type === 'module' ? 'mjs' : 'cjs';
|
89
|
-
return (pluginBuild: PluginBuild) => {
|
90
|
-
// rewrite paths based on standard node resolution
|
91
|
-
pluginBuild.onResolve({ filter: /.*/u }, async (resolved) => {
|
92
|
-
if (resolved.kind === 'entry-point' || !resolved.path.startsWith('.') || resolved.path.endsWith('.js')) {
|
93
|
-
return { external: resolved.kind !== 'entry-point' };
|
94
|
-
}
|
95
|
-
let isDirectory = false;
|
96
|
-
try {
|
97
|
-
const stats = await fs.lstat(path.join(resolved.resolveDir, resolved.path));
|
98
|
-
isDirectory = stats.isDirectory();
|
99
|
-
} catch {
|
100
|
-
// do nothing
|
101
|
-
}
|
102
|
-
let newPath = resolved.path;
|
103
|
-
newPath += isDirectory ? `/index.${extension}` : `.${extension}`;
|
104
|
-
return { path: newPath, external: true };
|
105
|
-
});
|
106
|
-
};
|
107
|
-
}
|
108
|
-
|
109
|
-
// eslint-disable-next-line func-names,max-lines-per-function,max-statements
|
110
|
-
export default async function ({
|
111
|
-
type,
|
112
|
-
entryPoint,
|
113
|
-
inDir,
|
114
|
-
outDir,
|
115
|
-
outFile,
|
116
|
-
external = [],
|
117
|
-
minify = false,
|
118
|
-
sourceMap,
|
119
|
-
}: BuilderOptions): Promise<string[]> {
|
120
|
-
const messages: string[] = [];
|
121
|
-
|
122
|
-
assert.ok(
|
123
|
-
(entryPoint === undefined && outFile === undefined) || (entryPoint !== undefined && outFile !== undefined),
|
124
|
-
'entryPoint and outFile must both be provided'
|
125
|
-
);
|
126
|
-
|
127
|
-
/**
|
128
|
-
* Emit declarations using typescript compiler
|
129
|
-
*/
|
130
|
-
const allSourceFiles = await getFiles(inDir);
|
131
|
-
const productionSourceFiles =
|
132
|
-
entryPoint === undefined ? allSourceFiles.filter((file) => file.endsWith('.ts')) : [path.join(inDir, entryPoint)];
|
133
|
-
|
134
|
-
const program = typescript.createProgram(productionSourceFiles, {
|
135
|
-
module: typescript.ModuleKind.ESNext,
|
136
|
-
moduleResolution: typescript.ModuleResolutionKind.Bundler,
|
137
|
-
target: typescript.ScriptTarget.ESNext,
|
138
|
-
declaration: true,
|
139
|
-
noEmitOnError: true,
|
140
|
-
emitDeclarationOnly: true,
|
141
|
-
rootDir: inDir,
|
142
|
-
outDir,
|
143
|
-
noLib: false,
|
144
|
-
skipLibCheck: true,
|
145
|
-
strict: true,
|
146
|
-
preserveConstEnums: true,
|
147
|
-
noImplicitReturns: true,
|
148
|
-
noUnusedLocals: true,
|
149
|
-
noUnusedParameters: true,
|
150
|
-
alwaysStrict: true,
|
151
|
-
verbatimModuleSyntax: false,
|
152
|
-
noFallthroughCasesInSwitch: true,
|
153
|
-
forceConsistentCasingInFileNames: true,
|
154
|
-
emitDecoratorMetadata: true,
|
155
|
-
experimentalDecorators: true,
|
156
|
-
resolveJsonModule: true,
|
157
|
-
esModuleInterop: true,
|
158
|
-
noUncheckedIndexedAccess: true,
|
159
|
-
noPropertyAccessFromIndexSignature: true,
|
160
|
-
allowUnusedLabels: false,
|
161
|
-
allowUnreachableCode: false,
|
162
|
-
noImplicitOverride: true,
|
163
|
-
useUnknownInCatchVariables: true,
|
164
|
-
exactOptionalPropertyTypes: true,
|
165
|
-
});
|
166
|
-
const emitResult = program.emit();
|
167
|
-
const allDiagnostics = typescript.sortAndDeduplicateDiagnostics([
|
168
|
-
...typescript.getPreEmitDiagnostics(program),
|
169
|
-
...emitResult.diagnostics,
|
170
|
-
]);
|
171
|
-
for (const diagnostic of allDiagnostics) {
|
172
|
-
if (diagnostic.file) {
|
173
|
-
assert.ok(diagnostic.start !== undefined);
|
174
|
-
const { line, character } = typescript.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start);
|
175
|
-
const message = typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
|
176
|
-
messages.push(`tsc: ${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
|
177
|
-
} else {
|
178
|
-
// eslint-disable-next-line no-console
|
179
|
-
messages.push(`tsc: ${typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n')}`);
|
180
|
-
}
|
181
|
-
}
|
182
|
-
if (emitResult.emitSkipped) {
|
183
|
-
throw new Error(`TypeScript compilation failed ${JSON.stringify(messages)}`);
|
184
|
-
}
|
185
|
-
|
186
|
-
/**
|
187
|
-
* Emit ESM javascript using esbuild
|
188
|
-
*/
|
189
|
-
const buildResult = await build({
|
190
|
-
entryPoints: productionSourceFiles,
|
191
|
-
bundle: true,
|
192
|
-
minify,
|
193
|
-
platform: 'node',
|
194
|
-
format: type === 'module' ? 'esm' : 'cjs',
|
195
|
-
sourcesContent: false,
|
196
|
-
sourcemap: sourceMap ? 'inline' : false,
|
197
|
-
...(outFile === undefined
|
198
|
-
? {
|
199
|
-
// individual files
|
200
|
-
outdir: outDir,
|
201
|
-
outExtension: { '.js': type === 'module' ? '.mjs' : '.cjs' },
|
202
|
-
plugins: [
|
203
|
-
{
|
204
|
-
name: 'resolve-typescript-paths',
|
205
|
-
setup: resolveTypescriptPaths(type),
|
206
|
-
},
|
207
|
-
],
|
208
|
-
}
|
209
|
-
: {
|
210
|
-
// bundling
|
211
|
-
outfile: path.join(outDir, outFile),
|
212
|
-
legalComments: 'none',
|
213
|
-
external,
|
214
|
-
plugins: [
|
215
|
-
{
|
216
|
-
name: 'exclude-source-maps',
|
217
|
-
setup: excludeSourceMaps(/node_modules/u),
|
218
|
-
},
|
219
|
-
],
|
220
|
-
}),
|
221
|
-
});
|
222
|
-
|
223
|
-
messages.push(...buildResult.errors.map((error) => `esbuild error: ${error.text}`));
|
224
|
-
messages.push(...buildResult.warnings.map((warning) => `esbuild warning: ${warning.text}`));
|
225
|
-
if (messages.length > 0) {
|
226
|
-
throw new Error(`esbuild failed ${JSON.stringify(messages)}`);
|
227
|
-
}
|
228
|
-
return messages;
|
229
|
-
}
|
@@ -1,484 +0,0 @@
|
|
1
|
-
// builder/builder.spec.mts
|
2
|
-
|
3
|
-
import { strict as assert } from 'node:assert';
|
4
|
-
import { promises as fs } from 'node:fs';
|
5
|
-
import { createRequire } from 'node:module';
|
6
|
-
import os from 'node:os';
|
7
|
-
import path from 'node:path';
|
8
|
-
|
9
|
-
import { v4 as uuid } from 'uuid';
|
10
|
-
|
11
|
-
// @ts-expect-error
|
12
|
-
import builder from './builder.mts';
|
13
|
-
|
14
|
-
const require = createRequire(import.meta.url);
|
15
|
-
|
16
|
-
const singleModule = {
|
17
|
-
[`index.ts`]: `export const hello = 'world';`,
|
18
|
-
};
|
19
|
-
|
20
|
-
const twoModules = {
|
21
|
-
[`index.ts`]: `import { hello } from './thing';\nexport default hello + 'world';\n`,
|
22
|
-
[`thing.ts`]: `export const hello = 'world';`,
|
23
|
-
};
|
24
|
-
|
25
|
-
const exportDefaultFunctionModule = {
|
26
|
-
[`index.ts`]: `export default function () { return 'hello world' }\n`,
|
27
|
-
};
|
28
|
-
|
29
|
-
const importExternalModule = {
|
30
|
-
[`index.ts`]: `
|
31
|
-
import { hello as test } from 'test-esm-module';
|
32
|
-
import util from 'node:util';
|
33
|
-
export const hello = { test, message: util.format('hello %s', 'world') };
|
34
|
-
`,
|
35
|
-
};
|
36
|
-
|
37
|
-
const testNodeModules = {
|
38
|
-
[`test-cjs-module`]: {
|
39
|
-
source: {
|
40
|
-
[`index.js`]: `module.exports.goodbye = 'world';`,
|
41
|
-
[`index.d.ts`]: `export declare const goodbye = "world";\n`,
|
42
|
-
},
|
43
|
-
},
|
44
|
-
[`test-esm-module`]: {
|
45
|
-
type: 'module',
|
46
|
-
source: {
|
47
|
-
[`index.js`]: `export const hello = 'world';`,
|
48
|
-
[`index.d.ts`]: `export declare const hello = "world";\n`,
|
49
|
-
},
|
50
|
-
},
|
51
|
-
} as const;
|
52
|
-
|
53
|
-
interface NodeModule {
|
54
|
-
[name: string]: {
|
55
|
-
type?: 'module' | 'commonjs';
|
56
|
-
source: {
|
57
|
-
[file: string]: string;
|
58
|
-
};
|
59
|
-
};
|
60
|
-
}
|
61
|
-
|
62
|
-
async function writeNodeModules(directory: string, nodeModules: NodeModule) {
|
63
|
-
const nodeModulesDirectory = path.join(directory, 'node_modules');
|
64
|
-
for (const [name, nodeModule] of Object.entries(nodeModules)) {
|
65
|
-
const nodeModuleDirectory = path.join(nodeModulesDirectory, name);
|
66
|
-
await fs.mkdir(nodeModuleDirectory, { recursive: true });
|
67
|
-
await fs.writeFile(
|
68
|
-
path.join(nodeModuleDirectory, 'package.json'),
|
69
|
-
JSON.stringify({
|
70
|
-
type: nodeModule.type ?? 'commonjs',
|
71
|
-
})
|
72
|
-
);
|
73
|
-
for (const [file, content] of Object.entries(nodeModule.source)) {
|
74
|
-
await fs.writeFile(path.join(nodeModuleDirectory, file), content);
|
75
|
-
}
|
76
|
-
}
|
77
|
-
}
|
78
|
-
|
79
|
-
async function write(directory: string, files: Record<string, string>): Promise<void> {
|
80
|
-
await fs.mkdir(directory, { recursive: true });
|
81
|
-
await Promise.all(Object.entries(files).map(([name, content]) => fs.writeFile(path.join(directory, name), content)));
|
82
|
-
}
|
83
|
-
|
84
|
-
async function read(dir: string): Promise<Record<string, string>> {
|
85
|
-
const files = await fs.readdir(dir);
|
86
|
-
return Object.fromEntries(
|
87
|
-
await Promise.all(
|
88
|
-
files.map(async (name) => [
|
89
|
-
name,
|
90
|
-
(
|
91
|
-
await fs.readFile(path.join(dir, name), 'utf-8')
|
92
|
-
)
|
93
|
-
.split('\n')
|
94
|
-
.filter((line) => !line.startsWith('//'))
|
95
|
-
.join('\n'),
|
96
|
-
])
|
97
|
-
)
|
98
|
-
) as Record<string, string>;
|
99
|
-
}
|
100
|
-
|
101
|
-
describe('test builder', () => {
|
102
|
-
it('should not build bad code', async () => {
|
103
|
-
const id = uuid();
|
104
|
-
const inDir = path.join(os.tmpdir(), `in-dir-${id}`);
|
105
|
-
const outDir = path.join(os.tmpdir(), `out-dir-${id}`);
|
106
|
-
await write(inDir, { 'index.ts': 'bad code' });
|
107
|
-
await assert.rejects(builder({ type: 'module', inDir, outDir }), {
|
108
|
-
message: `TypeScript compilation failed ${JSON.stringify([
|
109
|
-
`tsc: ${inDir}/index.ts (1,1): Unexpected keyword or identifier.`,
|
110
|
-
`tsc: ${inDir}/index.ts (1,1): Cannot find name 'bad'.`,
|
111
|
-
`tsc: ${inDir}/index.ts (1,5): Cannot find name 'code'.`,
|
112
|
-
])}`,
|
113
|
-
});
|
114
|
-
await assert.rejects(read(outDir), {
|
115
|
-
message: `ENOENT: no such file or directory, scandir '${outDir}'`,
|
116
|
-
});
|
117
|
-
});
|
118
|
-
|
119
|
-
it('should not build from bad directory', async () => {
|
120
|
-
const id = uuid();
|
121
|
-
const inDir = path.join(os.tmpdir(), `in-dir-${id}`);
|
122
|
-
const outDir = path.join(os.tmpdir(), `out-dir-${id}`);
|
123
|
-
await assert.rejects(builder({ type: 'module', inDir, outDir }), {
|
124
|
-
message: `ENOENT: no such file or directory, scandir '${inDir}'`,
|
125
|
-
});
|
126
|
-
await assert.rejects(read(outDir), {
|
127
|
-
message: `ENOENT: no such file or directory, scandir '${outDir}'`,
|
128
|
-
});
|
129
|
-
});
|
130
|
-
|
131
|
-
it('should build from empty directory, but not create output directory', async () => {
|
132
|
-
const id = uuid();
|
133
|
-
const inDir = path.join(os.tmpdir(), `in-dir-${id}`);
|
134
|
-
const outDir = path.join(os.tmpdir(), `out-dir-${id}`);
|
135
|
-
await write(inDir, {});
|
136
|
-
assert.deepEqual(await builder({ type: 'module', inDir, outDir }), []);
|
137
|
-
await assert.rejects(read(outDir), {
|
138
|
-
message: `ENOENT: no such file or directory, scandir '${outDir}'`,
|
139
|
-
});
|
140
|
-
});
|
141
|
-
|
142
|
-
it('should build a single ESM module', async () => {
|
143
|
-
const id = uuid();
|
144
|
-
const inDir = path.join(os.tmpdir(), `in-dir-${id}`, 'src');
|
145
|
-
const outDir = path.join(os.tmpdir(), `out-dir-${id}`, 'build');
|
146
|
-
await write(inDir, singleModule);
|
147
|
-
assert.deepEqual(await builder({ type: 'module', inDir, outDir }), []);
|
148
|
-
assert.deepEqual(await read(outDir), {
|
149
|
-
'index.d.ts': 'export declare const hello = "world";\n',
|
150
|
-
'index.mjs': 'var hello = "world";\nexport {\n hello\n};\n',
|
151
|
-
});
|
152
|
-
|
153
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
154
|
-
const output = await import(path.join(outDir, 'index.mjs'));
|
155
|
-
assert.equal(output.hello, 'world');
|
156
|
-
});
|
157
|
-
|
158
|
-
it('should minify a single ESM module', async () => {
|
159
|
-
const id = uuid();
|
160
|
-
const inDir = path.join(os.tmpdir(), `in-dir-${id}`, 'src');
|
161
|
-
const outDir = path.join(os.tmpdir(), `out-dir-${id}`, 'build');
|
162
|
-
await write(inDir, singleModule);
|
163
|
-
assert.deepEqual(await builder({ type: 'module', inDir, outDir, minify: true }), []);
|
164
|
-
assert.deepEqual(await read(outDir), {
|
165
|
-
'index.d.ts': 'export declare const hello = "world";\n',
|
166
|
-
'index.mjs': 'var o="world";export{o as hello};\n',
|
167
|
-
});
|
168
|
-
|
169
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
170
|
-
const output = await import(path.join(outDir, 'index.mjs'));
|
171
|
-
assert.equal(output.hello, 'world');
|
172
|
-
});
|
173
|
-
|
174
|
-
it('should build a single ESM module that exports function as default', async () => {
|
175
|
-
const id = uuid();
|
176
|
-
const inDir = path.join(os.tmpdir(), `in-dir-${id}`, 'src');
|
177
|
-
const outDir = path.join(os.tmpdir(), `out-dir-${id}`, 'build');
|
178
|
-
await write(inDir, exportDefaultFunctionModule);
|
179
|
-
assert.deepEqual(await builder({ type: 'module', inDir, outDir }), []);
|
180
|
-
assert.deepEqual(await read(outDir), {
|
181
|
-
'index.d.ts': 'export default function (): string;\n',
|
182
|
-
'index.mjs':
|
183
|
-
'function src_default() {\n' +
|
184
|
-
' return "hello world";\n' +
|
185
|
-
'}\n' +
|
186
|
-
'export {\n' +
|
187
|
-
' src_default as default\n' +
|
188
|
-
'};\n',
|
189
|
-
});
|
190
|
-
|
191
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
192
|
-
const output = await import(path.join(outDir, 'index.mjs'));
|
193
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
194
|
-
assert.equal(output.default(), 'hello world');
|
195
|
-
});
|
196
|
-
|
197
|
-
it('should build a single CJS module that exports function as default', async () => {
|
198
|
-
const id = uuid();
|
199
|
-
const inDir = path.join(os.tmpdir(), `in-dir-${id}`, 'src');
|
200
|
-
const outDir = path.join(os.tmpdir(), `out-dir-${id}`, 'build');
|
201
|
-
await write(inDir, exportDefaultFunctionModule);
|
202
|
-
assert.deepEqual(await builder({ type: 'commonjs', inDir, outDir }), []);
|
203
|
-
assert.deepEqual(await read(outDir), {
|
204
|
-
'index.cjs':
|
205
|
-
'var __defProp = Object.defineProperty;\n' +
|
206
|
-
'var __getOwnPropDesc = Object.getOwnPropertyDescriptor;\n' +
|
207
|
-
'var __getOwnPropNames = Object.getOwnPropertyNames;\n' +
|
208
|
-
'var __hasOwnProp = Object.prototype.hasOwnProperty;\n' +
|
209
|
-
'var __export = (target, all) => {\n' +
|
210
|
-
' for (var name in all)\n' +
|
211
|
-
' __defProp(target, name, { get: all[name], enumerable: true });\n' +
|
212
|
-
'};\n' +
|
213
|
-
'var __copyProps = (to, from, except, desc) => {\n' +
|
214
|
-
' if (from && typeof from === "object" || typeof from === "function") {\n' +
|
215
|
-
' for (let key of __getOwnPropNames(from))\n' +
|
216
|
-
' if (!__hasOwnProp.call(to, key) && key !== except)\n' +
|
217
|
-
' __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n' +
|
218
|
-
' }\n' +
|
219
|
-
' return to;\n' +
|
220
|
-
'};\n' +
|
221
|
-
'var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);\n' +
|
222
|
-
'\n' +
|
223
|
-
'var src_exports = {};\n' +
|
224
|
-
'__export(src_exports, {\n' +
|
225
|
-
' default: () => src_default\n' +
|
226
|
-
'});\n' +
|
227
|
-
'module.exports = __toCommonJS(src_exports);\n' +
|
228
|
-
'function src_default() {\n' +
|
229
|
-
' return "hello world";\n' +
|
230
|
-
'}\n',
|
231
|
-
'index.d.ts': 'export default function (): string;\n',
|
232
|
-
});
|
233
|
-
|
234
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
235
|
-
const output = require(path.join(outDir, 'index.cjs'));
|
236
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
237
|
-
assert.equal(output.default(), 'hello world');
|
238
|
-
});
|
239
|
-
|
240
|
-
it('should build an ESM module that imports a second ESM module', async () => {
|
241
|
-
const id = uuid();
|
242
|
-
const inDir = path.join(os.tmpdir(), `in-dir-${id}`, 'src');
|
243
|
-
const outDir = path.join(os.tmpdir(), `out-dir-${id}`, 'build');
|
244
|
-
await write(inDir, twoModules);
|
245
|
-
assert.deepEqual(await builder({ type: 'module', inDir, outDir }), []);
|
246
|
-
assert.deepEqual(await read(outDir), {
|
247
|
-
'index.d.ts': 'declare const _default: string;\nexport default _default;\n',
|
248
|
-
'index.mjs':
|
249
|
-
'import { hello } from "./thing.mjs";\n' +
|
250
|
-
'var src_default = hello + "world";\n' +
|
251
|
-
'export {\n' +
|
252
|
-
' src_default as default\n' +
|
253
|
-
'};\n',
|
254
|
-
'thing.d.ts': 'export declare const hello = "world";\n',
|
255
|
-
'thing.mjs': 'var hello = "world";\nexport {\n hello\n};\n',
|
256
|
-
});
|
257
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
258
|
-
const output = await import(path.join(outDir, 'index.mjs'));
|
259
|
-
assert.equal(output.default, 'worldworld');
|
260
|
-
});
|
261
|
-
|
262
|
-
it('should build a single CJS module', async () => {
|
263
|
-
const id = uuid();
|
264
|
-
const inDir = path.join(os.tmpdir(), `in-dir-${id}`, 'src');
|
265
|
-
const outDir = path.join(os.tmpdir(), `out-dir-${id}`, 'build');
|
266
|
-
await write(inDir, singleModule);
|
267
|
-
assert.deepEqual(await builder({ type: 'commonjs', inDir, outDir }), []);
|
268
|
-
assert.deepEqual(await read(outDir), {
|
269
|
-
'index.d.ts': 'export declare const hello = "world";\n',
|
270
|
-
'index.cjs':
|
271
|
-
'var __defProp = Object.defineProperty;\n' +
|
272
|
-
'var __getOwnPropDesc = Object.getOwnPropertyDescriptor;\n' +
|
273
|
-
'var __getOwnPropNames = Object.getOwnPropertyNames;\n' +
|
274
|
-
'var __hasOwnProp = Object.prototype.hasOwnProperty;\n' +
|
275
|
-
'var __export = (target, all) => {\n' +
|
276
|
-
' for (var name in all)\n' +
|
277
|
-
' __defProp(target, name, { get: all[name], enumerable: true });\n' +
|
278
|
-
'};\n' +
|
279
|
-
'var __copyProps = (to, from, except, desc) => {\n' +
|
280
|
-
' if (from && typeof from === "object" || typeof from === "function") {\n' +
|
281
|
-
' for (let key of __getOwnPropNames(from))\n' +
|
282
|
-
' if (!__hasOwnProp.call(to, key) && key !== except)\n' +
|
283
|
-
' __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n' +
|
284
|
-
' }\n' +
|
285
|
-
' return to;\n' +
|
286
|
-
'};\n' +
|
287
|
-
'var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);\n' +
|
288
|
-
'\n' +
|
289
|
-
'var src_exports = {};\n' +
|
290
|
-
'__export(src_exports, {\n' +
|
291
|
-
' hello: () => hello\n' +
|
292
|
-
'});\n' +
|
293
|
-
'module.exports = __toCommonJS(src_exports);\n' +
|
294
|
-
'var hello = "world";\n' +
|
295
|
-
'0 && (module.exports = {\n' +
|
296
|
-
' hello\n' +
|
297
|
-
'});\n',
|
298
|
-
});
|
299
|
-
});
|
300
|
-
|
301
|
-
it('should build a CJS module that requires a second CJS module', async () => {
|
302
|
-
const id = uuid();
|
303
|
-
const inDir = path.join(os.tmpdir(), `in-dir-${id}`, 'src');
|
304
|
-
const outDir = path.join(os.tmpdir(), `out-dir-${id}`, 'build');
|
305
|
-
await write(inDir, twoModules);
|
306
|
-
assert.deepEqual(await builder({ type: 'commonjs', inDir, outDir }), []);
|
307
|
-
assert.deepEqual(await read(outDir), {
|
308
|
-
'index.cjs':
|
309
|
-
'var __defProp = Object.defineProperty;\n' +
|
310
|
-
'var __getOwnPropDesc = Object.getOwnPropertyDescriptor;\n' +
|
311
|
-
'var __getOwnPropNames = Object.getOwnPropertyNames;\n' +
|
312
|
-
'var __hasOwnProp = Object.prototype.hasOwnProperty;\n' +
|
313
|
-
'var __export = (target, all) => {\n' +
|
314
|
-
' for (var name in all)\n' +
|
315
|
-
' __defProp(target, name, { get: all[name], enumerable: true });\n' +
|
316
|
-
'};\n' +
|
317
|
-
'var __copyProps = (to, from, except, desc) => {\n' +
|
318
|
-
' if (from && typeof from === "object" || typeof from === "function") {\n' +
|
319
|
-
' for (let key of __getOwnPropNames(from))\n' +
|
320
|
-
' if (!__hasOwnProp.call(to, key) && key !== except)\n' +
|
321
|
-
' __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n' +
|
322
|
-
' }\n' +
|
323
|
-
' return to;\n' +
|
324
|
-
'};\n' +
|
325
|
-
'var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);\n' +
|
326
|
-
'\n' +
|
327
|
-
'var src_exports = {};\n' +
|
328
|
-
'__export(src_exports, {\n' +
|
329
|
-
' default: () => src_default\n' +
|
330
|
-
'});\n' +
|
331
|
-
'module.exports = __toCommonJS(src_exports);\n' +
|
332
|
-
'var import_thing = require("./thing.cjs");\n' +
|
333
|
-
'var src_default = import_thing.hello + "world";\n',
|
334
|
-
'index.d.ts': 'declare const _default: string;\nexport default _default;\n',
|
335
|
-
'thing.cjs':
|
336
|
-
'var __defProp = Object.defineProperty;\n' +
|
337
|
-
'var __getOwnPropDesc = Object.getOwnPropertyDescriptor;\n' +
|
338
|
-
'var __getOwnPropNames = Object.getOwnPropertyNames;\n' +
|
339
|
-
'var __hasOwnProp = Object.prototype.hasOwnProperty;\n' +
|
340
|
-
'var __export = (target, all) => {\n' +
|
341
|
-
' for (var name in all)\n' +
|
342
|
-
' __defProp(target, name, { get: all[name], enumerable: true });\n' +
|
343
|
-
'};\n' +
|
344
|
-
'var __copyProps = (to, from, except, desc) => {\n' +
|
345
|
-
' if (from && typeof from === "object" || typeof from === "function") {\n' +
|
346
|
-
' for (let key of __getOwnPropNames(from))\n' +
|
347
|
-
' if (!__hasOwnProp.call(to, key) && key !== except)\n' +
|
348
|
-
' __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n' +
|
349
|
-
' }\n' +
|
350
|
-
' return to;\n' +
|
351
|
-
'};\n' +
|
352
|
-
'var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);\n' +
|
353
|
-
'\n' +
|
354
|
-
'var thing_exports = {};\n' +
|
355
|
-
'__export(thing_exports, {\n' +
|
356
|
-
' hello: () => hello\n' +
|
357
|
-
'});\n' +
|
358
|
-
'module.exports = __toCommonJS(thing_exports);\n' +
|
359
|
-
'var hello = "world";\n' +
|
360
|
-
'0 && (module.exports = {\n' +
|
361
|
-
' hello\n' +
|
362
|
-
'});\n',
|
363
|
-
'thing.d.ts': 'export declare const hello = "world";\n',
|
364
|
-
});
|
365
|
-
|
366
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
367
|
-
const output1 = require(path.join(outDir, 'index.cjs'));
|
368
|
-
assert.equal(output1.default, 'worldworld');
|
369
|
-
|
370
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
371
|
-
const output2 = await import(path.join(outDir, 'index.cjs'));
|
372
|
-
assert.equal(output2.default.default, 'worldworld');
|
373
|
-
});
|
374
|
-
|
375
|
-
it('should bundle an ESM module that imports a second ESM module', async () => {
|
376
|
-
const id = uuid();
|
377
|
-
const inDir = path.join(os.tmpdir(), `in-dir-${id}`, 'src');
|
378
|
-
const outDir = path.join(os.tmpdir(), `out-dir-${id}`, 'build');
|
379
|
-
await write(inDir, twoModules);
|
380
|
-
assert.deepEqual(
|
381
|
-
await builder({ type: 'module', entryPoint: 'index.ts', outFile: 'index.mjs', inDir, outDir }),
|
382
|
-
[]
|
383
|
-
);
|
384
|
-
assert.deepEqual(await read(outDir), {
|
385
|
-
'index.d.ts': 'declare const _default: string;\nexport default _default;\n',
|
386
|
-
'index.mjs':
|
387
|
-
'var hello = "world";\n' +
|
388
|
-
'\n' +
|
389
|
-
'var src_default = hello + "world";\n' +
|
390
|
-
'export {\n' +
|
391
|
-
' src_default as default\n' +
|
392
|
-
'};\n',
|
393
|
-
'thing.d.ts': 'export declare const hello = "world";\n',
|
394
|
-
});
|
395
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
396
|
-
const output = await import(path.join(outDir, 'index.mjs'));
|
397
|
-
assert.equal(output.default, 'worldworld');
|
398
|
-
});
|
399
|
-
|
400
|
-
it('should bundle an ESM module that imports external modules', async () => {
|
401
|
-
const id = uuid();
|
402
|
-
const moduleDir = path.join(os.tmpdir(), `in-dir-${id}`);
|
403
|
-
const inDir = path.join(moduleDir, 'src');
|
404
|
-
const outDir = path.join(os.tmpdir(), `out-dir-${id}`, 'build');
|
405
|
-
await write(inDir, importExternalModule);
|
406
|
-
await writeNodeModules(moduleDir, testNodeModules);
|
407
|
-
assert.deepEqual(
|
408
|
-
await builder({ type: 'module', entryPoint: 'index.ts', outFile: 'index.mjs', inDir, outDir }),
|
409
|
-
[]
|
410
|
-
);
|
411
|
-
assert.deepEqual(await read(outDir), {
|
412
|
-
'index.d.ts': 'export declare const hello: {\n test: string;\n message: string;\n};\n',
|
413
|
-
'index.mjs':
|
414
|
-
'var hello = "world";\n' +
|
415
|
-
'\n' +
|
416
|
-
'import util from "node:util";\n' +
|
417
|
-
'var hello2 = { test: hello, message: util.format("hello %s", "world") };\n' +
|
418
|
-
'export {\n' +
|
419
|
-
' hello2 as hello\n' +
|
420
|
-
'};\n',
|
421
|
-
});
|
422
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
423
|
-
const output = await import(path.join(outDir, 'index.mjs'));
|
424
|
-
assert.deepEqual(output.hello, {
|
425
|
-
message: 'hello world',
|
426
|
-
test: 'world',
|
427
|
-
});
|
428
|
-
});
|
429
|
-
|
430
|
-
it('should bundle an ESM module that imports external modules, but excludes them', async () => {
|
431
|
-
const id = uuid();
|
432
|
-
const moduleDir = path.join(os.tmpdir(), `in-dir-${id}`);
|
433
|
-
const inDir = path.join(moduleDir, 'src');
|
434
|
-
const outDir = path.join(os.tmpdir(), `out-dir-${id}`, 'build');
|
435
|
-
await write(inDir, importExternalModule);
|
436
|
-
await writeNodeModules(moduleDir, testNodeModules);
|
437
|
-
assert.deepEqual(
|
438
|
-
await builder({
|
439
|
-
type: 'module',
|
440
|
-
entryPoint: 'index.ts',
|
441
|
-
outFile: 'index.mjs',
|
442
|
-
inDir,
|
443
|
-
outDir,
|
444
|
-
external: ['*'],
|
445
|
-
}),
|
446
|
-
[]
|
447
|
-
);
|
448
|
-
assert.deepEqual(await read(outDir), {
|
449
|
-
'index.d.ts': 'export declare const hello: {\n test: string;\n message: string;\n};\n',
|
450
|
-
'index.mjs':
|
451
|
-
'import { hello as test } from "test-esm-module";\n' +
|
452
|
-
'import util from "node:util";\n' +
|
453
|
-
'var hello = { test, message: util.format("hello %s", "world") };\n' +
|
454
|
-
'export {\n' +
|
455
|
-
' hello\n' +
|
456
|
-
'};\n',
|
457
|
-
});
|
458
|
-
});
|
459
|
-
|
460
|
-
it('should bundle a commonjs module that imports external ESM modules', async () => {
|
461
|
-
const id = uuid();
|
462
|
-
const moduleDir = path.join(os.tmpdir(), `in-dir-${id}`);
|
463
|
-
const inDir = path.join(moduleDir, 'src');
|
464
|
-
const outDir = path.join(os.tmpdir(), `out-dir-${id}`, 'build');
|
465
|
-
await write(inDir, importExternalModule);
|
466
|
-
await writeNodeModules(moduleDir, testNodeModules);
|
467
|
-
assert.deepEqual(
|
468
|
-
await builder({
|
469
|
-
type: 'commonjs',
|
470
|
-
entryPoint: 'index.ts',
|
471
|
-
outFile: 'index.cjs',
|
472
|
-
inDir,
|
473
|
-
outDir,
|
474
|
-
}),
|
475
|
-
[]
|
476
|
-
);
|
477
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
478
|
-
const output = require(path.join(outDir, 'index.cjs'));
|
479
|
-
assert.deepEqual(output.hello, {
|
480
|
-
message: 'hello world',
|
481
|
-
test: 'world',
|
482
|
-
});
|
483
|
-
});
|
484
|
-
});
|
package/src/builder/index.mts
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
// builder/index.mts
|
2
|
-
|
3
|
-
import { strict as assert } from 'node:assert';
|
4
|
-
import path from 'node:path';
|
5
|
-
import { parseArgs } from 'node:util';
|
6
|
-
|
7
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
8
|
-
// @ts-expect-error
|
9
|
-
import builder from './builder.mts';
|
10
|
-
|
11
|
-
const {
|
12
|
-
values: { type, inDir, outDir, entryPoint, outFile, external, minify, sourceMap },
|
13
|
-
} = parseArgs({
|
14
|
-
options: {
|
15
|
-
type: { type: 'string', short: 't', default: 'module' },
|
16
|
-
inDir: { type: 'string', short: 'i', default: 'src' },
|
17
|
-
outDir: { type: 'string', short: 'o', default: 'build' },
|
18
|
-
entryPoint: { type: 'string', short: 'e', default: undefined },
|
19
|
-
outFile: { type: 'string', short: 'f', default: undefined },
|
20
|
-
external: { type: 'string', short: 'x', multiple: true, default: [] },
|
21
|
-
minify: { type: 'boolean', short: 'm', default: false },
|
22
|
-
sourceMap: { type: 'boolean', short: 's', default: false },
|
23
|
-
},
|
24
|
-
});
|
25
|
-
|
26
|
-
assert.ok(type === 'module' || type === 'commonjs', 'type must be module or commonjs');
|
27
|
-
assert.ok(inDir !== undefined, 'inDir is required');
|
28
|
-
assert.ok(outDir !== undefined, 'outDir is required');
|
29
|
-
|
30
|
-
const messages = await builder({
|
31
|
-
type,
|
32
|
-
inDir: path.join(process.cwd(), inDir),
|
33
|
-
outDir: path.join(process.cwd(), outDir),
|
34
|
-
entryPoint,
|
35
|
-
outFile,
|
36
|
-
external,
|
37
|
-
minify,
|
38
|
-
sourceMap,
|
39
|
-
});
|
40
|
-
if (messages.length > 0) {
|
41
|
-
// eslint-disable-next-line no-console
|
42
|
-
console.warn(JSON.stringify(messages, undefined, 2));
|
43
|
-
process.exit(1);
|
44
|
-
}
|
@@ -1,27 +0,0 @@
|
|
1
|
-
// typescript-5.0-esm.spec.mts
|
2
|
-
|
3
|
-
import { strict as assert } from 'node:assert';
|
4
|
-
|
5
|
-
import getPort from 'get-port'; // ESM version of get-port
|
6
|
-
import debug from 'debug';
|
7
|
-
|
8
|
-
describe('typescript-5.0 ESM', () => {
|
9
|
-
it('"this" is undefined', () => {
|
10
|
-
assert.ok(typeof this === 'undefined');
|
11
|
-
});
|
12
|
-
|
13
|
-
it('works with CJS modules', async () => {
|
14
|
-
assert.ok(typeof debug === 'function');
|
15
|
-
const log = debug('typescript-5.0-esm.spec.mts:test');
|
16
|
-
assert.ok(typeof log === 'function');
|
17
|
-
log.enabled = true;
|
18
|
-
log('hello');
|
19
|
-
debug.enable('typescript-5.0-esm.spec.mts:test');
|
20
|
-
assert.ok(!debug.enabled('test'));
|
21
|
-
assert.ok(debug.enabled('typescript-5.0-esm.spec.mts:test'));
|
22
|
-
});
|
23
|
-
|
24
|
-
it('works with ESM modules', async () => {
|
25
|
-
assert.equal(typeof (await getPort()), 'number');
|
26
|
-
});
|
27
|
-
});
|