最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Relative Imports in Typescript and Node - Stack Overflow

programmeradmin2浏览0评论

I am trying to build a node app using typescript. The plan is to deploy the build folder independently (i.e. it has it's own node_modules). Here is an MWE of my folder structure:

root
|-node_modules
|-src
|  |-index.ts
|  |-other.ts
|-build
|  |-node_modules
|  |-index.js
|  |-other.js
|  |-package.json
|  |-package-lock.json
|-package.json
|-package-lock.json
|-tsconfig.json

The index.ts and other.ts files contains the following:

//index.ts                               ||   //other.ts
import { HelloWorld } from "./other";    ||   export function HelloWorld() {
                                         ||     console.log("Hello World!");
HelloWorld();                            ||   }

The package.json file looks like (the real one contains devDependencies and dependencies as well):

{
  "name":"MyApp",
  "version":"0.1.0",
  "type":"module"
}

The tsconfig.json file looks like:

{
  "pilerOptions": {
    "outDir": "./build",
    "strict": true,
    "baseUrl":"src",
    "rootDir":"./src",
    "esModuleInterop": true
    },
  "include": [
    "src"
  ]
}

I am building my build folder by first copying the package.json file into build, running npm install --prefix ./build --omit=dev to get a production ready node_modules folder, then running npx tsc to build the .js files.

When I try and run node build/index.js, I get the following error:

ERR_MODULE_NOT_FOUND:
Cannot find module 'C:Users\MichaelBarrowman\TestRepo\build\other' imported from 'C:Users\MichaelBarrowman\TestRepo\build\index.js'

I tried to change the moduleResolution to node16 in the tsconfig.json file, and I get:

Relative import paths need explicit file extensions in EcmaScript imports when '--moduleResolution' is 'node16' or 'nodenext'.

I was under the impression that using the Node16 resolution algorithm, the "./other" in the import statement in index.ts/index.js would be resolved to "./other.js" automatically.

I am running locally on Node v18.12.1 (but these errors persist on a server using Node20) with typescript version 8.19.2

I am trying to build a node app using typescript. The plan is to deploy the build folder independently (i.e. it has it's own node_modules). Here is an MWE of my folder structure:

root
|-node_modules
|-src
|  |-index.ts
|  |-other.ts
|-build
|  |-node_modules
|  |-index.js
|  |-other.js
|  |-package.json
|  |-package-lock.json
|-package.json
|-package-lock.json
|-tsconfig.json

The index.ts and other.ts files contains the following:

//index.ts                               ||   //other.ts
import { HelloWorld } from "./other";    ||   export function HelloWorld() {
                                         ||     console.log("Hello World!");
HelloWorld();                            ||   }

The package.json file looks like (the real one contains devDependencies and dependencies as well):

{
  "name":"MyApp",
  "version":"0.1.0",
  "type":"module"
}

The tsconfig.json file looks like:

{
  "pilerOptions": {
    "outDir": "./build",
    "strict": true,
    "baseUrl":"src",
    "rootDir":"./src",
    "esModuleInterop": true
    },
  "include": [
    "src"
  ]
}

I am building my build folder by first copying the package.json file into build, running npm install --prefix ./build --omit=dev to get a production ready node_modules folder, then running npx tsc to build the .js files.

When I try and run node build/index.js, I get the following error:

ERR_MODULE_NOT_FOUND:
Cannot find module 'C:Users\MichaelBarrowman\TestRepo\build\other' imported from 'C:Users\MichaelBarrowman\TestRepo\build\index.js'

I tried to change the moduleResolution to node16 in the tsconfig.json file, and I get:

Relative import paths need explicit file extensions in EcmaScript imports when '--moduleResolution' is 'node16' or 'nodenext'.

I was under the impression that using the Node16 resolution algorithm, the "./other" in the import statement in index.ts/index.js would be resolved to "./other.js" automatically.

I am running locally on Node v18.12.1 (but these errors persist on a server using Node20) with typescript version 8.19.2

Share Improve this question asked Oct 10, 2023 at 18:04 Michael BarrowmanMichael Barrowman 1,2112 gold badges11 silver badges21 bronze badges 5
  • 1 "I am building my build folder by first copying the package.json file into build [...]" why? tsc already copies the piled source to the dir you tell it to, and the top level node_modules will resolve just fine from any subdirectory; you don't need to copy your package.json and then run npm install inside build. Where is the npm script that runs the typescript pile pass? – Mike 'Pomax' Kamermans Commented Oct 10, 2023 at 19:04
  • I am creating a separate node_modules directory in the build folder because this folder is going to be deployed on it's own. The workflow is going to be under CI/CD pipeline and the build folder will be a separate branch. – Michael Barrowman Commented Oct 11, 2023 at 8:11
  • Can't say that makes a lot of sense, you may want to read up on how TS-based projects are typically deployed a bit (you're basically doing something very unusual probably for reasons that don't actually require you to do this at all) – Mike 'Pomax' Kamermans Commented Oct 11, 2023 at 15:28
  • I appreciate the concern for my workflow, but your response doesn't really address the question I was asking. – Michael Barrowman Commented Oct 20, 2023 at 9:33
  • 1 That's why it was a ment, not an answer post. Not all problems are best solved by posting an answer, some require reexamining the setup that allows the problem to even exists. (And when you do something very unusual, you typically want to explain why in your post, so that folks who are familiar with the thing you're asking about and the methodologies around that can understand why you're doing something so different from convention, because otherwise the first step is to stop doing things differently and follow the normal approach and see if that fixes things) – Mike 'Pomax' Kamermans Commented Oct 20, 2023 at 16:54
Add a ment  | 

1 Answer 1

Reset to default 8

When you specify your package / project with "type": "module" in package.json, your relative file imports MUST contain the file extension.

relative import paths need full extensions (e.g we have to write import "./foo.js" instead of import "./foo")

Furthermore, even if you initially write your file in TypeScript (with .ts file extension), you should directly use the final file extension (so .js); tsc knows how to handle it.

it will have to be rewritten to use the extension of the output of foo.ts - so bar.ts will instead have to import from ./foo.js.

So simply make sure to add file extensions to your imports:

import { HelloWorld } from "./other.js"; // Notice the file extension
发布评论

评论列表(0)

  1. 暂无评论