-
Notifications
You must be signed in to change notification settings - Fork 12
.js extension is not appended when using typescript v4.9.3 #21
Comments
This makes me very sad, but I'm not surprised. There are two possible causes:
Unfortunately, I suspect this may be the final straw for me that causes me to mark this repository as deprecated. 😢 I have been lobbying for Microsoft to build this into the compiler for a long time, and my hope was that this could serve as a stop-gap until they were finally convinced to make the change. Unfortunately, they just keep doubling down on their refusal to support it and I think at this point it may be a lost cause. If someone wants to dig into this bug and figure out what the cause is and propose a fix I'm open to reviewing and potentially merging it (depending on how complicated the fix is), but I think this project is nearing the end of its lifespan. 😢 |
I've never written a TypeScript plugin but this is working for me: import path from "node:path";
import typescript from "typescript";
// eslint-disable-next-line import/no-default-export
export default function transformer(_: typescript.Program) {
return (transformationContext: typescript.TransformationContext) =>
(sourceFile: typescript.SourceFile) => {
function shouldMutateModuleSpecifier(node: typescript.Node): node is (
| typescript.ImportDeclaration
| typescript.ExportDeclaration
) & {
moduleSpecifier: typescript.StringLiteral;
} {
if (!typescript.isImportDeclaration(node) && !typescript.isExportDeclaration(node)) {
return false;
}
if (node.moduleSpecifier === undefined) {
return false;
}
// Only when module specifier is valid
if (!typescript.isStringLiteral(node.moduleSpecifier)) {
return false;
}
// Only when path is relative
if (
!node.moduleSpecifier.text.startsWith("./") &&
!node.moduleSpecifier.text.startsWith("../")
) {
return false;
}
// Only when module specifier hasn't specific extensions or has no extension
if (
[
".js",
".jsx",
".ts",
".tsx",
".mts",
".cts",
".json",
".css",
".less",
".htm",
".html",
".scss",
".sass",
].includes(path.extname(node.moduleSpecifier.text)) === true ||
(path.extname(node.moduleSpecifier.text) !== "" &&
path.extname(node.moduleSpecifier.text).length <= 4)
) {
return false;
}
return true;
}
function visitNode(node: typescript.Node): typescript.VisitResult<typescript.Node> {
if (shouldMutateModuleSpecifier(node)) {
if (typescript.isImportDeclaration(node)) {
const newModuleSpecifier = typescript.factory.createStringLiteral(
`${node.moduleSpecifier.text}.js`,
);
return typescript.factory.updateImportDeclaration(
node,
node.modifiers,
node.importClause,
newModuleSpecifier,
undefined,
);
}
if (typescript.isExportDeclaration(node)) {
const newModuleSpecifier = typescript.factory.createStringLiteral(
`${node.moduleSpecifier.text}.js`,
);
return typescript.factory.updateExportDeclaration(
node,
node.modifiers,
false,
node.exportClause,
newModuleSpecifier,
undefined,
);
}
}
return typescript.visitEachChild(node, visitNode, transformationContext);
}
return typescript.visitNode(sourceFile, visitNode);
};
} |
The code is based on https://github.com/nvandamme/typescript-transformer-append-js-extension and I've updated all the deprecated functions. I'm using TypeScript 4.9.3 and the output files are correctly appended with the .js file extension. PS: I'm using ts-patch instead of |
Moreover, I'm using import { AuthMiddleware } from "@/helpers/auth-middleware"; Compiled: import { AuthMiddleware } from "../helpers/auth-middleware.js"; |
Am I missing something or do you want me to create a PR? |
If this works then it probably is a reasonable solution. This was my first (and only) TSC plugin and the change is sufficiently large compared to my previous code that I cannot provide very useful feedback on it unfortunately. Since this issue was filed, I have stopped using this plugin myself and capitulated with TypeScript's recommendation of "appending My recommendation is to fork this repository, make the change you propose, and publish a new package to NPM (a fairly easy process). |
I recently updated typescript to v4.9.3 and generated files no longer have
.js
extension in relative imports.When reverting typescript to v4.8.4
.js
extension is appended as expected.The text was updated successfully, but these errors were encountered: