为什么 TS "unable to find module"使用基本导入?



我正在尝试使用TS而不是常规ES/JS开始一个基本的阿波罗GraphQL项目。

我已经得到了一些非常基本的代码编写,但在目前的时刻,我不断得到这个错误时,试图处理什么似乎是…在我的代码中一个基本的相对导入:

Cannot find module '/Users/czbaker/Projects/express-apollo-ts/dist/gql/resolvers' imported from /Users/czbaker/Projects/express-apollo-ts/dist/main.js

我完全不明白为什么会发生这种情况。下面是我要做的:

src/main.ts

import express, { Express, Request, Response } from 'express';
import { ApolloServer } from '@apollo/server';
import { expressMiddleware } from '@apollo/server/express4';
import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';
import http, { Server } from 'http';
import path from 'path';
import dotenv from 'dotenv';
// GQL
import { resolvers } from './gql/resolvers';
import { typeDefs } from './gql/typeDefs';

// Load config
const envpath: string = path.resolve(process.cwd(), '.env');
dotenv.config({
path: envpath,
debug: true
});
// Create Apollo Server
const server = new ApolloServer({ 
resolvers, 
typeDefs,
plugins: [ApolloServerPluginDrainHttpServer({ httpServer })]
});
await server.start();
// Use Middleware
app.use(expressMiddleware(server));
// Launch Server
await new Promise<void>((resolve) => httpServer.listen({ port: process.env.SERVER_PORT }, resolve));
console.log(`Server available at http://localhost:${process.env.SERVER_PORT}/`);

src/gql resolvers.ts

export const resolvers: any = {
Query: {
hello: () => "World!"
}
}

src/gql typeDefs.ts

export const typeDefs = `#graphql
type Query {
hello: String;
}
`

tsconfig.json

{
"compilerOptions": {
"rootDirs": ["src"],
"outDir": "dist",
"lib": ["es2020"],
"target": "es2020",
"module": "ES6",
"moduleResolution": "node",
"esModuleInterop": true,
"types": ["node"],
},
"include": [
"src/**/*"
],
"exclude": [
"node_modules"
]
}

package.json

{
"name": "express-apollo-ts",
"version": "1.0.0",
"description": "Apollo GraphQL server via Express/TypeScript/Mongoose w/ Subscription support",
"main": "main.ts",
"repository": "https://github.com/czbak3r/express-apollo-ts",
"author": "Charles Baker",
"license": "MIT",
"type": "module",
"devDependencies": {
"@types/express": "^4.17.14",
"@types/node": "^18.11.9",
"nodemon": "^2.0.20",
"typescript": "^4.9.3"
},
"dependencies": {
"@apollo/server": "^4.2.1",
"dotenv": "^16.0.3",
"express": "^4.18.2",
"graphql": "^16.6.0",
"mongoose": "^6.7.3"
},
"scripts": {
"dev": "concurrently "tsc --watch" "nodemon -q dist/main.js"",
"build": "tsc",
"start": "nodemon ./dist/main.js"
}
}
到目前为止,最终的结果是TSC在编译代码时没有问题,但是当它执行时,我得到了前面提到的错误。

我清楚地定义了resolvers.ts,并在编译时或在VSCode中导入没有错误,那么是什么导致了这个问题?

我已经尝试过使用tsc(在观察模式下)使用ts-node,但最终结果是相同的。从我所能做的研究和搜索来看,这可能是因为ESM?我刚从编程中断中回来,以前从未听说过ESM,所以……这对我来说是全新的体验。

编辑:在查看输出文件时,我在/dist中有以下结构:

main.js
- /gql
- resolvers.js
- typeDefs.js

我在一些地方读到,导入语句必须有文件扩展名取决于不同的设置…这会在这里引起问题吗?

看起来所有的文件都在编译时正确输出,编译代码的import语句是完整的,所以…我仍然无法理解为什么它显然没有看到./gql/的东西在运行时

事实证明,当您在项目中使用文件导入时,您需要使用.js扩展名:

import { resolvers } from './gql/resolvers.js';
import { typeDefs } from './gql/typeDefs.js';

根据进一步的研究,这不是一个bug,而是TypeScript的一个特性。

不知道为什么这是默认行为,但只要它的工作方式应该和VSCode不生气,那么我就用它。

希望这也能帮助到别人!:)

最新更新