node.js - TypeScript 4.5: Módulo não encontrado ao importar arquivo local
Eu tenho uma aplicação baseada em Node Express com o seguinte tsconfig:
{
"compilerOptions": {
"lib": [ "es6", "es2021", "esnext" ],
"target": "esnext",
"module": "es2022",
"composite": true,
"declaration": true,
"declarationMap": true,
"forceConsistentCasingInFileNames": true,
"importHelpers": true,
"newLine": "LF",
"noFallthroughCasesInSwitch": true,
"noImplicitReturns": true,
"noUncheckedIndexedAccess": true,
"noUnusedLocals": false,
"noUnusedParameters": false,
"preserveConstEnums": true,
"removeComments": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"noImplicitAny": true,
"moduleResolution": "Node",
"sourceMap": false,
"rootDir": "./src",
"outDir": "./dist",
"baseUrl": "./src",
"paths": {
"*": [
"node_modules/*"
]
}
}, }
Nota: mudar meu módulo para commonjs NÃO é uma solução, quero que ele seja construído como um módulo.
Eu recebo um erro na primeira importação de arquivo local no meu arquivo index, mas o arquivo que ele diz que não pode encontrar (módulo não encontrado) existe, ele tem uma exportação padrão e a saída da build também tem um arquivo .d.ts ao lado dele com uma exportação de tipo para ele.
Não consigo entender por que simplesmente não está funcionando.
Erro :
Cannot find module 'workspace\dist\config\csrf' imported from workspace\dist\index.js
Nota: Eu substituí o caminho absoluto por um espaço reservado de workspace. Neste caso, eu tenho um arquivo: src/config/csrf.ts que está sendo construído/transpilado para dist/config/csrf.js, e tudo parece estar em ordem, e ainda assim ele não importa.
Dado que este é o primeiro import de arquivo local no arquivo de entrada, eu presumiria que todos os outros terão o mesmo problema.
O que está acontecendo, como exatamente eu deveria estar resolvendo meus arquivos locais ao construir um módulo?
Minhas exportações são assim:
const csrf = () => {
// Code ommitted
}
export default csrf;
Usando Node ^16.13.2 e TypeScript 4.5.6
Editar: Eu tenho os seguintes scripts configurados
"scripts": {
"clean": "rm -rf dist/",
"lint": "tslint -c tslint.json -p tsconfig.json --fix",
"tsc": "tsc",
"build": "npm run clean && npm run lint && npm run tsc",
"build:light": "npm run tsc",
"migrate:dev": "npx prisma migrate dev",
"migrate:prod": "npm run migrate:prod && npm run prisma:generate",
"dev:start": "npm run build && npm run start",
"dev:light": "npm run build:light && npm run start",
"dev": "nodemon --watch src -e ts,ejs --exec npm run dev:start",
"light": "nodemon --watch src -e ts,ejs --exec npm run dev:light",
"start": "node -r dotenv/config .",
"test": "echo \"Error: no test specified\" && exit 1"
},
E o erro ocorre ao usar npm run dev ou npm run light.
Então, observe, o TypeScript compila normalmente, esse erro está ocorrendo quando o JavaScript realmente construído é executado via node.
Editar: Descobri que, se eu atualizar manualmente a importação do JavaScript compilado, funciona
Ex.:
import csrf from "./config/csrf";
atualizações para:
import csrf from "./config/csrf.js"
de repente funciona,
Que diabos? Eu não deveria ter que atualizar manualmente todos os meus arquivos transpilados, certo? Qual é a abordagem correta para que seus imports do TypeScript sejam transpilados para imports de JavaScript compatíveis?
Isso parece extremamente complicado e desnecessário. O que estou perdendo? Não faz sentido algum ter ".js" nos imports no TypeScript apenas para que o resultado compilado realmente funcione
Resposta #1
O pacote got no GitHub tem um guia bastante prático/interessante sobre como converter de commonjs para ESM, tanto para js quanto para TypeScript:
De acordo com isso, você realmente precisa adicionar a extensão .js aos imports nos arquivos TypeScript, então eu fiz isso. Está funcionando e eu encontrei um problema diferente, que vai gerar uma nova pergunta.