34

I try to initialize database base via typescript.

my ts is like:

import { User, UserRole } from '../entity/User';
import crypto from 'crypto';
import {dbManager, pwhash } from '..';

async function inituser() 
{
    const user = new User();
    user.email = 'sheng.lu@mq.edu.au';
    user.own_organization = []
    user.salt = crypto.randomBytes(16).toString('hex');
    user.password = pwhash("password", user.salt);
    user.role = UserRole.admin;
    await dbManager.save(user);
    const duser = await dbManager.findOne(User);
    return duser;
}
const duser = inituser();

console.log("Loaded users: ", duser);

when I try to run the script by ts-node like:

npx ts-node db/initializers/inituser.ts

there is error for:

SyntaxError: Cannot use import statement outside a module
    at wrapSafe (internal/modules/cjs/loader.js:1167:16)
    at Module._compile (internal/modules/cjs/loader.js:1215:27)
    at Module.m._compile (/usr/lib/node_modules/ts-node/src/index.ts:858:23)
    at Module._extensions..js (internal/modules/cjs/loader.js:1272:10)
    at Object.require.extensions.<computed> [as .ts] (/usr/lib/node_modules/ts-node/src/index.ts:861:12)
    at Module.load (internal/modules/cjs/loader.js:1100:32)
    at Function.Module._load (internal/modules/cjs/loader.js:962:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
    at main (/usr/lib/node_modules/ts-node/src/bin.ts:227:14)
    at Object.<anonymous> (/usr/lib/node_modules/ts-node/src/bin.ts:513:3)
root@MEDAIHILW237:/mnt/c/workgit/projeny# ts-node db/initializers/inituser.ts
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for /mnt/c/workgit/projeny/db/initializers/inituser.ts
    at Loader.defaultGetFormat [as _getFormat] (internal/modules/esm/get_format.js:65:15)
    at Loader.getFormat (internal/modules/esm/loader.js:101:42)
    at Loader.getModuleJob (internal/modules/esm/loader.js:230:31)
    at Loader.import (internal/modules/esm/loader.js:164:17)
    at Object.loadESM (internal/process/esm_loader.js:68:5)
root@MEDAIHILW237:/mnt/c/workgit/projeny# ts-node db/initializers/inituser
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for /mnt/c/workgit/projeny/db/initializers/inituser.ts
    at Loader.defaultGetFormat [as _getFormat] (internal/modules/esm/get_format.js:65:15)
    at Loader.getFormat (internal/modules/esm/loader.js:101:42)
    at Loader.getModuleJob (internal/modules/esm/loader.js:230:31)
    at Loader.import (internal/modules/esm/loader.js:164:17)
    at Object.loadESM (internal/process/esm_loader.js:68:5)

I add "type": "module" in package.json file.

{
  "name": "typescript-test",
  "version": "1.0.0",
  "type": "module",
...
}

for overcome the error of

(node:3854) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
user504909
  • 9,119
  • 12
  • 60
  • 109

4 Answers4

40

The Error Warning: To load an ES module, set "type": "module" in the package.json or is caused by the following Bug in ts-node: https://github.com/TypeStrong/ts-node/issues/935

The Bug is closed, and there is a proposal to solve it, but it is still open: https://github.com/TypeStrong/ts-node/issues/1007

I don't need "type": "module" in package.json.

In tsconfig.json, I'm using using "module": "commonjs" instead of "module": "es6",.

I noted this as technical debt pending that ts-node issue #1007 is resolved.

Gulam Hussain
  • 1,591
  • 10
  • 19
Rafael Emshoff
  • 2,541
  • 1
  • 35
  • 47
12

When ts-node is run inside a project, it uses the local tsconfig.json, which is usually not set up to build for execution.

But you can add a section specifically for ts-node, overriding those settings. Telling it to build for esm works for me:

{
  "compilerOptions": {
    ...
  },
  "ts-node": {
    "esm": true,
    "compilerOptions": {
      "module": "nodenext",
    }
  }
}
Moritz Ringler
  • 9,772
  • 9
  • 21
  • 34
3

Maybe this helps:

node --no-warnings --loader ts-node/esm file.ts
Moritz
  • 1,590
  • 13
  • 8
0

Just add -O '{\"module\": \"commonjs\"}':

npx ts-node -O '{\"module\": \"commonjs\"}' db/initializers/inituser.ts

And there is no need to set "type": "module" in package.json.

Ivan Komar
  • 53
  • 2
  • 1
    As explained in the question, the `import * from *`-statement only works with `type: module`. There are some packages (e.g., node-fetch, chalk) which cannot be used without ESM in their latest version; and so this suggestion won't work for all people suffering from this issue. – STh Apr 09 '22 at 13:40