@checkdigit/typescript-config 3.3.0-PR.30-d5d5 → 3.3.0-PR.30-9280
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/README.md +1 -0
- package/bin/builder.mjs +33 -8
- package/package.json +1 -1
- package/src/builder/builder.mts +34 -4
- package/src/builder/builder.spec.mts +16 -0
- package/src/builder/index.mts +3 -1
package/README.md
CHANGED
@@ -33,6 +33,7 @@ types, and `esbuild` for generating code.
|
|
33
33
|
- `--outFile` the output file, relative to `--outDir`. This is provided for single-file bundles, along with `--entryPoint`.
|
34
34
|
- `--external` external modules to exclude from the bundle. Built-in `node` modules are automatically excluded.
|
35
35
|
A wildcard `*` can be used to exclude multiple external modules.
|
36
|
+
- `--minify` whether to minify the output.
|
36
37
|
|
37
38
|
#### Examples
|
38
39
|
|
package/bin/builder.mjs
CHANGED
@@ -20,7 +20,19 @@ async function getFiles(directory) {
|
|
20
20
|
);
|
21
21
|
return files.flat();
|
22
22
|
}
|
23
|
-
function
|
23
|
+
function excludeSourceMaps(filter) {
|
24
|
+
return (pluginBuild) => {
|
25
|
+
pluginBuild.onLoad({ filter }, async (args) => ({
|
26
|
+
contents: `${await fs.readFile(
|
27
|
+
args.path,
|
28
|
+
"utf8"
|
29
|
+
)}
|
30
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIiJdLCJtYXBwaW5ncyI6IkEifQ==`,
|
31
|
+
loader: "default"
|
32
|
+
}));
|
33
|
+
};
|
34
|
+
}
|
35
|
+
function resolveTypescriptPaths(type2) {
|
24
36
|
const extension = type2 === "module" ? "mjs" : "cjs";
|
25
37
|
return (pluginBuild) => {
|
26
38
|
pluginBuild.onResolve({ filter: /.*/u }, async (resolved) => {
|
@@ -45,7 +57,8 @@ async function builder_default({
|
|
45
57
|
inDir: inDir2,
|
46
58
|
outDir: outDir2,
|
47
59
|
outFile: outFile2,
|
48
|
-
external: external2 = []
|
60
|
+
external: external2 = [],
|
61
|
+
minify: minify2 = false
|
49
62
|
}) {
|
50
63
|
const messages2 = [];
|
51
64
|
assert.ok(
|
@@ -107,6 +120,7 @@ async function builder_default({
|
|
107
120
|
const buildResult = await build({
|
108
121
|
entryPoints: productionSourceFiles,
|
109
122
|
bundle: true,
|
123
|
+
minify: minify2,
|
110
124
|
platform: "node",
|
111
125
|
format: type2 === "module" ? "esm" : "cjs",
|
112
126
|
sourcemap: "inline",
|
@@ -116,11 +130,20 @@ async function builder_default({
|
|
116
130
|
outExtension: { ".js": type2 === "module" ? ".mjs" : ".cjs" },
|
117
131
|
plugins: [
|
118
132
|
{
|
119
|
-
name: "resolve-
|
120
|
-
setup:
|
133
|
+
name: "resolve-typescript-paths",
|
134
|
+
setup: resolveTypescriptPaths(type2)
|
135
|
+
}
|
136
|
+
]
|
137
|
+
} : {
|
138
|
+
outfile: path.join(outDir2, outFile2),
|
139
|
+
external: external2,
|
140
|
+
plugins: [
|
141
|
+
{
|
142
|
+
name: "exclude-source-maps",
|
143
|
+
setup: excludeSourceMaps(/node_modules/u)
|
121
144
|
}
|
122
145
|
]
|
123
|
-
}
|
146
|
+
}
|
124
147
|
});
|
125
148
|
messages2.push(...buildResult.errors.map((error) => `esbuild error: ${error.text}`));
|
126
149
|
messages2.push(...buildResult.warnings.map((warning) => `esbuild warning: ${warning.text}`));
|
@@ -132,7 +155,7 @@ async function builder_default({
|
|
132
155
|
|
133
156
|
// src/builder/index.mts
|
134
157
|
var {
|
135
|
-
values: { type, inDir, outDir, entryPoint, outFile, external }
|
158
|
+
values: { type, inDir, outDir, entryPoint, outFile, external, minify }
|
136
159
|
} = parseArgs({
|
137
160
|
options: {
|
138
161
|
type: { type: "string", short: "t", default: "module" },
|
@@ -140,7 +163,8 @@ var {
|
|
140
163
|
outDir: { type: "string", short: "o", default: "build" },
|
141
164
|
entryPoint: { type: "string", short: "e", default: void 0 },
|
142
165
|
outFile: { type: "string", short: "f", default: void 0 },
|
143
|
-
external: { type: "string", short: "x", multiple: true, default: [] }
|
166
|
+
external: { type: "string", short: "x", multiple: true, default: [] },
|
167
|
+
minify: { type: "boolean", short: "m", default: false }
|
144
168
|
}
|
145
169
|
});
|
146
170
|
assert2.ok(type === "module" || type === "commonjs", "type must be module or commonjs");
|
@@ -152,7 +176,8 @@ var messages = await builder_default({
|
|
152
176
|
outDir: path2.join(process.cwd(), outDir),
|
153
177
|
entryPoint,
|
154
178
|
outFile,
|
155
|
-
external
|
179
|
+
external,
|
180
|
+
minify
|
156
181
|
});
|
157
182
|
if (messages.length > 0) {
|
158
183
|
console.warn(JSON.stringify(messages, void 0, 2));
|
package/package.json
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"name":"@checkdigit/typescript-config","version":"3.3.0-PR.30-
|
1
|
+
{"name":"@checkdigit/typescript-config","version":"3.3.0-PR.30-9280","description":"Check Digit standard Typescript configuration","prettier":"@checkdigit/prettier-config","engines":{"node":">=16"},"bin":{"builder":"./bin/builder.mjs"},"peerDependencies":{"@types/node":">=16","esbuild":"0.17.19","typescript":">=5.0.4 <5.1"},"repository":{"type":"git","url":"git+https://github.com/checkdigit/typescript-config.git"},"author":"Check Digit, LLC","license":"MIT","bugs":{"url":"https://github.com/checkdigit/typescript-config/issues"},"homepage":"https://github.com/checkdigit/typescript-config#readme","scripts":{"preversion":"npm test","postversion":"git push && git push --tags","prepare":"npm run build-builder","lint:fix":"eslint -f unix --ext .ts,.mts src --fix","lint":"eslint -f unix --ext .ts,.mts src","prettier":"prettier --ignore-path .gitignore --list-different .","prettier:fix":"prettier --ignore-path .gitignore --write .","test":"npm run ci:compile && npm run ci:test && npm run ci:lint && npm run ci:style","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","build-cjs":"rimraf build-cjs && npx builder --type=commonjs --outDir=build-cjs","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","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","build-esm":"rimraf build-esm && npx builder --type=module --outDir=build-esm","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","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","test-jest-esm":"NODE_OPTIONS=\"--experimental-vm-modules\" jest --coverage=false src/*.mts src/*/*.mts src/*/*/*.mts","test-jest-cjs":"jest --coverage=false src/*.ts src/*/*.ts src/*/*/*.ts","test-cjs":"node --test build-cjs/test/index.test.cjs","test-cjs-bundle":"node --test build-cjs-bundle/test/index.test.cjs","test-cjs-bundle-no-external":"node --test build-cjs-bundle-no-external/test/index.test.cjs","test-esm":"node --test build-esm/test/index.test.mjs","test-esm-bundle":"echo \"node --test build-esm-bundle/test/index.test.mjs\"","test-esm-bundle-no-external":"node --test build-esm-bundle-no-external/test/index.test.mjs","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","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","ci:lint":"npm run lint","ci:style":"npm run prettier"},"devDependencies":{"@checkdigit/prettier-config":"^3.4.0","@types/debug":"^4.1.7","@types/jest":"^29.5.1","@types/uuid":"^9.0.1","@typescript-eslint/eslint-plugin":"^5.59.6","@typescript-eslint/parser":"^5.59.6","debug":"^4.3.4","eslint":"^8.40.0","eslint-config-prettier":"^8.8.0","get-port":"^6.1.2","got":"^11.8.6","jest":"^29.5.0","rimraf":"^5.0.1","ts-jest":"^29.1.0","uuid":"^9.0.0"},"eslintConfig":{"parser":"@typescript-eslint/parser","plugins":["@typescript-eslint"],"parserOptions":{"project":"./tsconfig.json"},"extends":["eslint:all","plugin:@typescript-eslint/recommended","plugin:@typescript-eslint/recommended-requiring-type-checking","plugin:@typescript-eslint/strict","prettier"],"rules":{"@typescript-eslint/non-nullable-type-assertion-style":"error","capitalized-comments":"off","one-var":"off","sort-keys":"off","sort-imports":"off","func-style":["error","declaration",{"allowArrowFunctions":true}],"no-magic-numbers":["error",{"ignore":[0,1,2]}],"no-undefined":"off","no-ternary":"off"},"overrides":[{"files":["*.spec.mts","*.test.mts","*.spec.ts","*.test.ts"],"rules":{"@typescript-eslint/non-nullable-type-assertion-style":"off","@typescript-eslint/ban-types":"off","@typescript-eslint/require-await":"off","@typescript-eslint/consistent-type-definitions":"off","@typescript-eslint/ban-ts-comment":"off","@typescript-eslint/no-unnecessary-condition":"off","@typescript-eslint/consistent-indexed-object-style":"off","@typescript-eslint/no-unused-vars":"off","@typescript-eslint/no-unsafe-member-access":"off","line-comment-position":"off","no-inline-comments":"off","no-param-reassign":"off","id-length":"off","no-magic-numbers":"off","func-names":"off","no-duplicate-imports":"off","symbol-description":"off","no-invalid-this":"off","max-lines-per-function":"off","max-lines":"off","max-statements":"off","no-await-in-loop":"off"}}]},"jest":{"moduleFileExtensions":["js","mjs","cjs","ts","mts","json","node"],"extensionsToTreatAsEsm":[".mts"],"transform":{"^.+\\.mts$":["ts-jest",{"isolatedModules":true,"diagnostics":false,"useESM":true}],"^.+\\.ts$":["ts-jest",{"isolatedModules":true,"diagnostics":false,"useESM":false}]},"collectCoverageFrom":["<rootDir>/src/**","!<rootDir>/src/**/*.spec.mts","!<rootDir>/src/**/*.test.mts","!<rootDir>/src/**/*.spec.ts","!<rootDir>/src/**/*.test.ts"],"testMatch":["<rootDir>/src/**/*.spec.ts","<rootDir>/src/**/*.spec.mts"]},"files":["tsconfig.json","SECURITY.md","/src/"]}
|
package/src/builder/builder.mts
CHANGED
@@ -38,6 +38,11 @@ export interface BuilderOptions {
|
|
38
38
|
* external modules to exclude from the bundle
|
39
39
|
*/
|
40
40
|
external?: string[] | undefined;
|
41
|
+
|
42
|
+
/**
|
43
|
+
* whether to minify output
|
44
|
+
*/
|
45
|
+
minify?: boolean | undefined;
|
41
46
|
}
|
42
47
|
|
43
48
|
/**
|
@@ -56,9 +61,23 @@ async function getFiles(directory: string): Promise<string[]> {
|
|
56
61
|
return files.flat();
|
57
62
|
}
|
58
63
|
|
59
|
-
function
|
64
|
+
function excludeSourceMaps(filter: RegExp) {
|
65
|
+
return (pluginBuild: PluginBuild) => {
|
66
|
+
// ignore source maps for anything that matches filter
|
67
|
+
pluginBuild.onLoad({ filter }, async (args) => ({
|
68
|
+
contents: `${await fs.readFile(
|
69
|
+
args.path,
|
70
|
+
'utf8'
|
71
|
+
)}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIiJdLCJtYXBwaW5ncyI6IkEifQ==`,
|
72
|
+
loader: 'default',
|
73
|
+
}));
|
74
|
+
};
|
75
|
+
}
|
76
|
+
|
77
|
+
function resolveTypescriptPaths(type: 'module' | 'commonjs') {
|
60
78
|
const extension = type === 'module' ? 'mjs' : 'cjs';
|
61
79
|
return (pluginBuild: PluginBuild) => {
|
80
|
+
// rewrite paths based on standard node resolution
|
62
81
|
pluginBuild.onResolve({ filter: /.*/u }, async (resolved) => {
|
63
82
|
if (resolved.kind === 'entry-point' || !resolved.path.startsWith('.') || resolved.path.endsWith('.js')) {
|
64
83
|
return { external: resolved.kind !== 'entry-point' };
|
@@ -85,6 +104,7 @@ export default async function ({
|
|
85
104
|
outDir,
|
86
105
|
outFile,
|
87
106
|
external = [],
|
107
|
+
minify = false,
|
88
108
|
}: BuilderOptions): Promise<string[]> {
|
89
109
|
const messages: string[] = [];
|
90
110
|
|
@@ -158,6 +178,7 @@ export default async function ({
|
|
158
178
|
const buildResult = await build({
|
159
179
|
entryPoints: productionSourceFiles,
|
160
180
|
bundle: true,
|
181
|
+
minify,
|
161
182
|
platform: 'node',
|
162
183
|
format: type === 'module' ? 'esm' : 'cjs',
|
163
184
|
sourcemap: 'inline',
|
@@ -168,12 +189,21 @@ export default async function ({
|
|
168
189
|
outExtension: { '.js': type === 'module' ? '.mjs' : '.cjs' },
|
169
190
|
plugins: [
|
170
191
|
{
|
171
|
-
name: 'resolve-
|
172
|
-
setup:
|
192
|
+
name: 'resolve-typescript-paths',
|
193
|
+
setup: resolveTypescriptPaths(type),
|
173
194
|
},
|
174
195
|
],
|
175
196
|
}
|
176
|
-
: {
|
197
|
+
: {
|
198
|
+
outfile: path.join(outDir, outFile),
|
199
|
+
external,
|
200
|
+
plugins: [
|
201
|
+
{
|
202
|
+
name: 'exclude-source-maps',
|
203
|
+
setup: excludeSourceMaps(/node_modules/u),
|
204
|
+
},
|
205
|
+
],
|
206
|
+
}),
|
177
207
|
});
|
178
208
|
|
179
209
|
messages.push(...buildResult.errors.map((error) => `esbuild error: ${error.text}`));
|
@@ -155,6 +155,22 @@ describe('test builder', () => {
|
|
155
155
|
assert.equal(output.hello, 'world');
|
156
156
|
});
|
157
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
|
+
|
158
174
|
it('should build a single ESM module that exports function as default', async () => {
|
159
175
|
const id = uuid();
|
160
176
|
const inDir = path.join(os.tmpdir(), `in-dir-${id}`, 'src');
|
package/src/builder/index.mts
CHANGED
@@ -9,7 +9,7 @@ import { parseArgs } from 'node:util';
|
|
9
9
|
import builder from './builder.mts';
|
10
10
|
|
11
11
|
const {
|
12
|
-
values: { type, inDir, outDir, entryPoint, outFile, external },
|
12
|
+
values: { type, inDir, outDir, entryPoint, outFile, external, minify },
|
13
13
|
} = parseArgs({
|
14
14
|
options: {
|
15
15
|
type: { type: 'string', short: 't', default: 'module' },
|
@@ -18,6 +18,7 @@ const {
|
|
18
18
|
entryPoint: { type: 'string', short: 'e', default: undefined },
|
19
19
|
outFile: { type: 'string', short: 'f', default: undefined },
|
20
20
|
external: { type: 'string', short: 'x', multiple: true, default: [] },
|
21
|
+
minify: { type: 'boolean', short: 'm', default: false },
|
21
22
|
},
|
22
23
|
});
|
23
24
|
|
@@ -32,6 +33,7 @@ const messages = await builder({
|
|
32
33
|
entryPoint,
|
33
34
|
outFile,
|
34
35
|
external,
|
36
|
+
minify,
|
35
37
|
});
|
36
38
|
if (messages.length > 0) {
|
37
39
|
// eslint-disable-next-line no-console
|