You can see my sample project here: https://github.com/DanKaplanSES/typescript-stub-examples/tree/JavaScript-import-invalid
I have created this file called main.ts:
import uuid from "uuid";
console.log(uuid.v4());
Although typescript is fine with this import, when I try to node main.js, it gives this error:
console.log(uuid_1["default"].v4());
^
TypeError: Cannot read property 'v4' of undefined
at Object.<anonymous> (C:\root\lib\main.js:5:31)
←[90m at Module._compile (internal/modules/cjs/loader.js:1063:30)←[39m
←[90m at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)←[39m
←[90m at Module.load (internal/modules/cjs/loader.js:928:32)←[39m
←[90m at Function.Module._load (internal/modules/cjs/loader.js:769:14)←[39m
←[90m at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)←[39m
←[90m at internal/main/run_main_module.js:17:47←[39m
If I change the file to this, it executes fine:
import * as uuid from "uuid";
console.log(uuid.v4());
If the first version is invalid, why doesn't typescript inform me?
I have a multi file tsconfig setup. Check the github project for more details, but here are the shared compiler options which may be relevant:
{
"compilerOptions": {
"rootDir": ".",
"esModuleInterop": true,
"module": "CommonJS",
"moduleResolution": "node",
"composite": true,
"importHelpers": true,
},
}
Here is how the main.js looks:
"use strict";
exports.__esModule = true;
var tslib_1 = require("tslib");
var uuid_1 = tslib_1.__importDefault(require("uuid"));
console.log(uuid_1["default"].v4());
"use strict";
exports.__esModule = true;
var tslib_1 = require("tslib");
var uuid = tslib_1.__importStar(require("uuid"));
console.log(uuid.v4());
First of all, I'm working under the ESM module environment.
I have been struggling with the uuid package import issue multiple times, in the past years.
Today I ran into it again, and found something new to me and like to share it under your great analytics answer.
TL;DR: the behavior of the import UUID from 'uuid' is different when the uuid package is dependent directly, or indirectly.
I think this is related to the ESM behavior.
package.json dependency with uuid |
import * as UUID from 'uuid' |
import UUID from 'uuid' |
|---|---|---|
| directly (tsc) | OK | OK |
| directly (runtime) | OK | SyntaxError: The requested module 'uuid' does not provide an export named 'default' |
| in-directly (tsc) | OK | Module "node_modules/@types/uuid/index" has no default export.ts(1192) |
| in-directly (runtime) | TypeError: UUID.v4 is not a function |
OK |
uuid" means we have a uuid in the dependencies of package.jsonuuid" means we have no uuid in the dependencies of package.json (but other dependency module has included it)It seems that there is only one situation in which the typing system and the runtime both work as expected with ESM: use a direct dependency to the uuid package.
Always npm install --save uuid. (see my issue here with commits)