@checkdigit/typescript-config 3.3.0-PR.30-c398 → 3.3.0-PR.30-f96e

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 CHANGED
@@ -6,7 +6,9 @@ Copyright (c) 2022-2023 [Check Digit, LLC](https://checkdigit.com)
6
6
 
7
7
  ### Introduction
8
8
 
9
- This module contains the standard Check Digit Typescript configuration.
9
+ This module contains the standard Check Digit Typescript configuration, along with our standard build tool `builder`.
10
+
11
+ ### Typescript Configuration
10
12
 
11
13
  - currently requires Node 16 or above.
12
14
  - emits `esnext`, with the default libraries, to avoid down-leveling. It is intended that application spec tests pick
@@ -15,17 +17,50 @@ This module contains the standard Check Digit Typescript configuration.
15
17
  - uses the `module` type of `commonjs`.
16
18
  - all compiler options set for maximum strictness.
17
19
 
20
+ ### Builder
21
+
22
+ `builder` is a command line tool that generates either commonjs or esm modules, from Typescript source. It is intended
23
+ to be used when publishing a package to NPM, or to bundle a package for deployment. It uses `tsc` for generating
24
+ types, and `esbuild` for generating code.
25
+
26
+ #### Options
27
+
28
+ - `--type` the type of module to generate. Defaults to `module` (ESM). Valid values are `commonjs` and `module`.
29
+ - `--entryPoint` the entry point for the bundle, relative to the inDir. if not provided, the files in the inDir will
30
+ be processed as individual unbundled files.
31
+ - `--inDir` the input source code directory.
32
+ - `--outDir` the output directory.
33
+ - `--outFile` the output file, relative to `--outDir`. This is provided for single-file bundles, along with `--entryPoint`.
34
+ - `--external` external modules to exclude from the bundle. Built-in `node` modules are automatically excluded.
35
+ A wildcard `*` can be used to exclude multiple external modules.
36
+ - `--minify` whether to minify the output.
37
+
38
+ #### Examples
39
+
40
+ ```
41
+ # build commonjs .cjs files from Typescript source
42
+ npx builder --type=commonjs --outDir=build-cjs
43
+
44
+ # build single-file commonjs .cjs bundle from Typescript source
45
+ npx builder --type=commonjs --entryPoint=index.ts --outDir=build-cjs-bundle --outFile=index.cjs
46
+
47
+ # build ESM .mjs files from Typescript source
48
+ npx builder --type=module --outDir=build-esm
49
+
50
+ # build single-file ESM .mjs bundle from Typescript source
51
+ npx builder --type=module --outDir=build-esm-bundle --entryPoint=index.ts --outFile=index.mjs
52
+ ```
53
+
18
54
  ### Tests
19
55
 
20
56
  This module includes a number of integration-style tests, to ensure that a specific version of Typescript will interoperate
21
- with various bundlers, libraries and frameworks used by Check Digit:
57
+ with `builder`, in addition to libraries and frameworks used by Check Digit:
22
58
 
23
59
  - Jest and `ts-jest`
24
60
  - ESLint and `@typescript-eslint/eslint-plugin`
25
61
  - Built-in `node:test` runner
26
62
  - prettier
27
63
  - tsc
28
- - swc
29
64
  - esbuild
30
65
 
31
66
  We do this to ensure that Typescript upgrades do not break these dependencies. New major versions of Typescript are not immediately
package/bin/builder.mjs CHANGED
@@ -45,7 +45,8 @@ async function builder_default({
45
45
  inDir: inDir2,
46
46
  outDir: outDir2,
47
47
  outFile: outFile2,
48
- external: external2 = []
48
+ external: external2 = [],
49
+ minify: minify2 = false
49
50
  }) {
50
51
  const messages2 = [];
51
52
  assert.ok(
@@ -107,6 +108,7 @@ async function builder_default({
107
108
  const buildResult = await build({
108
109
  entryPoints: productionSourceFiles,
109
110
  bundle: true,
111
+ minify: minify2,
110
112
  platform: "node",
111
113
  format: type2 === "module" ? "esm" : "cjs",
112
114
  sourcemap: "inline",
@@ -132,7 +134,7 @@ async function builder_default({
132
134
 
133
135
  // src/builder/index.mts
134
136
  var {
135
- values: { type, inDir, outDir, entryPoint, outFile, external }
137
+ values: { type, inDir, outDir, entryPoint, outFile, external, minify }
136
138
  } = parseArgs({
137
139
  options: {
138
140
  type: { type: "string", short: "t", default: "module" },
@@ -140,7 +142,8 @@ var {
140
142
  outDir: { type: "string", short: "o", default: "build" },
141
143
  entryPoint: { type: "string", short: "e", default: void 0 },
142
144
  outFile: { type: "string", short: "f", default: void 0 },
143
- external: { type: "string", short: "x", multiple: true, default: [] }
145
+ external: { type: "string", short: "x", multiple: true, default: [] },
146
+ minify: { type: "boolean", short: "m", default: false }
144
147
  }
145
148
  });
146
149
  assert2.ok(type === "module" || type === "commonjs", "type must be module or commonjs");
@@ -152,7 +155,8 @@ var messages = await builder_default({
152
155
  outDir: path2.join(process.cwd(), outDir),
153
156
  entryPoint,
154
157
  outFile,
155
- external
158
+ external,
159
+ minify
156
160
  });
157
161
  if (messages.length > 0) {
158
162
  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-c398","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.18","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 --outDir=build-cjs --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","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","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.0","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/"]}
1
+ {"name":"@checkdigit/typescript-config","version":"3.3.0-PR.30-f96e","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","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/"]}
@@ -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
  /**
@@ -85,6 +90,7 @@ export default async function ({
85
90
  outDir,
86
91
  outFile,
87
92
  external = [],
93
+ minify = false,
88
94
  }: BuilderOptions): Promise<string[]> {
89
95
  const messages: string[] = [];
90
96
 
@@ -158,6 +164,7 @@ export default async function ({
158
164
  const buildResult = await build({
159
165
  entryPoints: productionSourceFiles,
160
166
  bundle: true,
167
+ minify,
161
168
  platform: 'node',
162
169
  format: type === 'module' ? 'esm' : 'cjs',
163
170
  sourcemap: 'inline',
@@ -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');
@@ -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