Building NPM module fails to find local module
Version: Deno 2.1.9
When building a NPM module with deno, it will error out and fail to find the local module.
deno run -A build_npm.ts 0.0.1"
Error
[dnt] Building project...
[dnt] Type checking ESM...
src/main.ts:6:17 - error TS2339: Property 'main' does not exist on type 'ImportMeta'.
6 if (import.meta.main) {
~~~~
src/main_test.ts:2:30 - error TS2307: Cannot find module '@std/assert' or its corresponding type declarations.
2 import { assertEquals } from "@std/assert";
~~~~~~~~~~~~~
error: Uncaught (in promise) Error: Had 2 diagnostics.
throw new Error(`Had ${diagnostics.length} diagnostics.`);
^
at getProgramAndMaybeTypeCheck (https://deno.land/x/[email protected]/mod.ts:450:17)
at build (https://deno.land/x/[email protected]/mod.ts:343:17)
at eventLoopTick (ext:core/01_core.js:177:7)
at async file:///tmp/npm/myadd/build_npm.ts:5:1
deno.json
{
"tasks": {
"dev": "deno run --watch main.ts",
"npm": "deno run -A build_npm.ts 0.0.1"
},
"imports": {
"@std/assert": "jsr:@std/assert@1"
}
}
main_test.ts
import { assertEquals } from "@std/assert";
import { myAdd } from "./main.ts";
Deno.test(function addTest() {
assertEquals(myAdd(2, 3), 5);
});
main.ts
export function myAdd(a: number, b: number): number {
return a + b;
}
// Learn more at https://docs.deno.com/runtime/manual/examples/module_metadata#concepts
if (import.meta.main) {
console.log("Add 2 + 3 =", myAdd(2, 3));
}
build_npm.ts
import { build, emptyDir } from "https://deno.land/x/[email protected]/mod.ts";
await emptyDir("./npm");
await build({
entryPoints: ["./main.ts"],
outDir: "./npm",
shims: {
deno: true,
},
package: {
name: "myapp",
version: Deno.args[0],
description:
"Boolean function that returns whether or not parameter is the number 42",
license: "MIT",
repository: {
type: "git",
url: "git+https://github.com/lambtron/is-42.git",
},
bugs: {
url: "https://github.com/lambtron/is-42/issues",
},
},
postBuild() {
Deno.copyFileSync("README.md", "npm/README.md");
},
});
I seem to be having the same issue, execution and tests work fine in deno, but when I try to bundle for npm i get a series of errors relating to the included packages:
build script
$ cat scripts/build_npm.ts
import { build, emptyDir } from "@deno/dnt";
import deno from "../deno.json" with { type: "json" };
await emptyDir("./npm");
await build({
typeCheck: "both",
entryPoints: ["./index.ts"],
outDir: "./npm",
shims: {
deno: "dev",
timers: true
},
package: {
// package.json properties
name: deno.name,
version: deno.version,
description: deno.description,
license: deno.license,
repository: {
type: "git",
url: "git+https://github.com/silverbucket/ajv-formats-draft2019.git",
},
bugs: {
url: "https://github.com/silverbucket/ajv-formats-draft2019/issues",
},
},
postBuild() {
// steps to run after building and before running the tests
Deno.copyFileSync("LICENSE", "npm/LICENSE");
Deno.copyFileSync("README.md", "npm/README.md");
},
});
deno.json
{
"name": "@silverbucket/ajv-formats-draft2019",
"version": "1.6.5",
"description": "Plugin for AJV that adds support for some of string formats adding in the draft2019 JSON Schema.",
"exports": "./index.ts",
"tasks": {
"coverage": "deno coverage | deno run jsr:@silverbucket/threshold 77 93",
"test": "deno test --fail-fast --coverage --clean --allow-env --allow-read *.test.ts",
"build:npm": "deno run -A scripts/build_npm.ts",
"publish:npm": "cd npm && npm publish && cd .."
},
"license": "MIT",
"imports": {
"@deno/dnt": "jsr:@deno/dnt@^0.41.3",
"@silverbucket/iana-schemes": "jsr:@silverbucket/iana-schemes@^1.4.2",
"punycode-esm": "npm:punycode-esm@^1.0.14",
"smtp-address-parser": "npm:smtp-address-parser@^1.1.0",
"uri-js-replace": "npm:uri-js-replace@^1.0.1",
"ajv": "npm:ajv@^8.17.1"
}
}
build output
$ deno clean && deno i && deno task build:npm
Removed /Users/njenning/Library/Caches/deno (1606 files, 28.81MB)
Task build:npm deno run -A scripts/build_npm.ts
[dnt] Transforming...
Download https://jsr.io/@std/assert/meta.json
...
Download https://jsr.io/@std/internal/1.0.5/types.ts
[dnt] Running npm install...
added 13 packages, and audited 14 packages in 3s
2 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
[dnt] Building project...
[dnt] Type checking ESM...
src/deps/jsr.io/@std/assert/1.0.11/assertion_error.ts:27:42 - error TS2304: Cannot find name 'ErrorOptions'.
27 constructor(message: string, options?: ErrorOptions) {
~~~~~~~~~~~~
src/deps/jsr.io/@std/assert/1.0.11/assertion_error.ts:28:20 - error TS2554: Expected 0-1 arguments, but got 2.
28 super(message, options);
~~~~~~~
src/deps/jsr.io/@std/assert/1.0.11/equal.ts:148:22 - error TS2339: Property 'symmetricDifference' does not exist on type 'Set<unknown>'.
148 return a.symmetricDifference(b).size === 0;
~~~~~~~~~~~~~~~~~~~
src/deps/jsr.io/@std/assert/1.0.11/equal.ts:194:31 - error TS2339: Property 'union' does not exist on type 'Set<string | symbol>'.
194 keys = getKeysDeep(a).union(getKeysDeep(b));
~~~~~
src/deps/jsr.io/@std/assert/1.0.11/object_match.ts:136:47 - error TS2339: Property 'intersection' does not exist on type 'Set<any>'.
136 defineProperty(filtered, key, value.intersection(subset));
~~~~~~~~~~~~
src/deps/jsr.io/@std/assert/1.0.11/object_match.ts:201:31 - error TS2339: Property 'intersection' does not exist on type 'Set<any>'.
201 filtered.push(value.intersection(subset));
~~~~~~~~~~~~
src/deps/jsr.io/@std/expect/1.0.13/_equal.ts:169:22 - error TS2339: Property 'symmetricDifference' does not exist on type 'Set<unknown>'.
169 return a.symmetricDifference(b).size === 0;
~~~~~~~~~~~~~~~~~~~
src/formats/idn-email.ts:1:23 - error TS2307: Cannot find module 'smtp-address-parser' or its corresponding type declarations.
1 import { parse } from "smtp-address-parser";
~~~~~~~~~~~~~~~~~~~~~
src/formats/idn-hostname.ts:1:25 - error TS2307: Cannot find module 'punycode-esm' or its corresponding type declarations.
1 import { toASCII } from "punycode-esm";
~~~~~~~~~~~~~~
src/formats/iri-reference.ts:1:43 - error TS2307: Cannot find module 'uri-js-replace' or its corresponding type declarations.
1 import { parse, type URIComponents } from "uri-js-replace";
~~~~~~~~~~~~~~~~
src/formats/iri-reference.ts:2:40 - error TS2307: Cannot find module 'smtp-address-parser' or its corresponding type declarations.
2 import { parse as addressParser } from "smtp-address-parser";
~~~~~~~~~~~~~~~~~~~~~
src/formats/iri-reference.ts:3:21 - error TS2307: Cannot find module '@silverbucket/iana-schemes' or its corresponding type declarations.
3 import schemes from "@silverbucket/iana-schemes";
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/formats/iri.ts:1:41 - error TS2307: Cannot find module 'uri-js-replace' or its corresponding type declarations.
1 import uri, { type URIComponents } from "uri-js-replace";
~~~~~~~~~~~~~~~~
src/formats/iri.ts:2:25 - error TS2307: Cannot find module 'smtp-address-parser' or its corresponding type declarations.
2 import smtpAddress from "smtp-address-parser";
~~~~~~~~~~~~~~~~~~~~~
src/formats/iri.ts:3:21 - error TS2307: Cannot find module '@silverbucket/iana-schemes' or its corresponding type declarations.
3 import schemes from "@silverbucket/iana-schemes";
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: Uncaught (in promise) Error: Had 15 diagnostics.
throw new Error(`Had ${diagnostics.length} diagnostics.`);
^
at getProgramAndMaybeTypeCheck (https://jsr.io/@deno/dnt/0.41.3/mod.ts:468:17)
at build (https://jsr.io/@deno/dnt/0.41.3/mod.ts:354:17)
at eventLoopTick (ext:core/01_core.js:177:7)
at async file:///Users/njenning/code/projects/ajv-formats-draft2019/scripts/build_npm.ts:6:1
Repository: https://github.com/silverbucket/ajv-formats-draft2019
I can get around the type checking failures by adding typeCheck: false, to my dnt build script:
await build({
typeCheck: false,
entryPoints: ["./index.ts"],
...
However this leads to another issue where the npm packages are not being added to the generated package.json:
$ deno clean && deno i && deno task build:npm
Removed /Users/njenning/Library/Caches/deno (1601 files, 32.56MB)
Task build:npm deno run -A scripts/build_npm.ts
[dnt] Transforming...
Download https://deno.land/x/punycode/punycode.js
Download https://jsr.io/@std/assert/meta.json
...
Download https://jsr.io/@std/internal/1.0.5/types.ts
[dnt] Running npm install...
added 12 packages, and audited 13 packages in 4s
2 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
[dnt] Building project...
[dnt] Emitting ESM package...
[dnt] Emitting script package...
[dnt] Running post build action...
[dnt] Running tests...
> @silverbucket/[email protected] test
> node test_runner.js
Running tests in ./script/index.test.js...
Error: Cannot find module 'uri-js-replace'
Require stack:
- /Users/njenning/code/projects/ajv-formats-draft2019/npm/script/formats/iri.js
- /Users/njenning/code/projects/ajv-formats-draft2019/npm/script/formats/index.js
- /Users/njenning/code/projects/ajv-formats-draft2019/npm/script/index.test.js
- /Users/njenning/code/projects/ajv-formats-draft2019/npm/test_runner.js
at Function._resolveFilename (node:internal/modules/cjs/loader:1249:15)
at Function._load (node:internal/modules/cjs/loader:1075:27)
at TracingChannel.traceSync (node:diagnostics_channel:322:14)
at wrapModuleLoad (node:internal/modules/cjs/loader:219:24)
at Module.require (node:internal/modules/cjs/loader:1340:12)
at require (node:internal/modules/helpers:138:16)
at Object.<anonymous> (/Users/njenning/code/projects/ajv-formats-draft2019/npm/script/formats/iri.js:6:42)
at Module._compile (node:internal/modules/cjs/loader:1565:14)
at Object..js (node:internal/modules/cjs/loader:1708:10)
at Module.load (node:internal/modules/cjs/loader:1318:32) {
code: 'MODULE_NOT_FOUND',
requireStack: [
'/Users/njenning/code/projects/ajv-formats-draft2019/npm/script/formats/iri.js',
'/Users/njenning/code/projects/ajv-formats-draft2019/npm/script/formats/index.js',
'/Users/njenning/code/projects/ajv-formats-draft2019/npm/script/index.test.js',
'/Users/njenning/code/projects/ajv-formats-draft2019/npm/test_runner.js'
]
}
error: Uncaught (in promise) Error: npm run test failed with exit code 1
throw new Error(
^
at runCommand (https://jsr.io/@deno/dnt/0.41.3/lib/utils.ts:56:13)
at eventLoopTick (ext:core/01_core.js:177:7)
at async build (https://jsr.io/@deno/dnt/0.41.3/mod.ts:419:5)
at async file:///Users/njenning/code/projects/ajv-formats-draft2019/scripts/build_npm.ts:6:1
The needed packages do not exist:
$ cat npm/package.json
{
"name": "@silverbucket/ajv-formats-draft2019",
"version": "1.6.5",
"description": "Plugin for AJV that adds support for some of string formats adding in the draft2019 JSON Schema.",
"repository": {
"type": "git",
"url": "git+https://github.com/silverbucket/ajv-formats-draft2019.git"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/silverbucket/ajv-formats-draft2019/issues"
},
"main": "./script/index.js",
"module": "./esm/index.js",
"exports": {
".": {
"import": "./esm/index.js",
"require": "./script/index.js"
}
},
"scripts": {
"test": "node test_runner.js"
},
"devDependencies": {
"@types/node": "^20.9.0",
"picocolors": "^1.0.0",
"ajv": "*",
"@deno/shim-deno": "~0.18.0"
},
"_generatedBy": "dnt@dev"
}%
$ cat deno.json
{
"name": "@silverbucket/ajv-formats-draft2019",
"version": "1.6.5",
"description": "Plugin for AJV that adds support for some of string formats adding in the draft2019 JSON Schema.",
"exports": "./index.ts",
"tasks": {
"coverage": "deno coverage | deno run jsr:@silverbucket/threshold 77 93",
"test": "deno test --fail-fast --coverage --clean --allow-env --allow-read *.test.ts",
"build:npm": "deno run -A scripts/build_npm.ts",
"publish:npm": "cd npm && npm publish && cd .."
},
"license": "MIT",
"imports": {
"@deno/dnt": "jsr:@deno/dnt@^0.41.3",
"@silverbucket/iana-schemes": "jsr:@silverbucket/iana-schemes@^1.4.4",
"smtp-address-parser": "npm:smtp-address-parser@^1.1.0",
"uri-js-replace": "npm:uri-js-replace@^1.0.1",
"ajv": "npm:ajv@^8.17.1"
}
}
I'm a little surprised at how complicated this is, these are already node packages, and I'm trying to build a package to publish to npm. All that needs to happen are the packages included in the package.json. Or is there something else I'm missing?
@silverbucket you might also want to add to the npm build script the following to skip test, which is where I was seeing the build error with dnt.
test:false,
With this setting, I was able to build and publish my npm library.