-
-
Notifications
You must be signed in to change notification settings - Fork 62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for non-relative import paths (explicit file extensions). #377
Comments
Right, I am semi-aware of this issue. I remember seeing discussions in the TS repo about whether or not you should be able to specify |
Hey, thanks for showing interest in this issue. Please be warned that I don't consider myself an expert in this, but my basic understanding is that with CommonJS you can be less strict and leave out the extension when importing. That is when you set
https://nodejs.org/api/esm.html#import-specifiers
I am just leaving these out for your convenience if you want to check the docs because as I said I'm not an expert, but I do think you need to specify an extension in all cases. Unfortunately, I can't categorically answer your question about So should type imports also have |
Right. I think it will need to support I know that Sindre Sorhus is telling me and everyone else to switch to ESM so I do need to look into this, but there are quite a few things about it that still confuse me.. |
Well, your library (Kanel) only ever outputs type definitions, so personally I can't envision a scenario where it would be necessary to import those as My original idea when submitting this issue was to perhaps have a
Yep, I only use module these days, and a As for the rest of what you said, I can only vouch for ESM. I have some experience with it working with monorepos which are a similar concept to a library, and when I switched to ESM it made a certain things way easier. The two articles I linked above pretty much explain how to use them and most of the details, but perhaps if you have some particular question I might be able to help. Your library doesn't have a lot of dependencies, so I don't think you will have much difficulties if you decided to transition one day. |
It can output enums which do create code. I am not sure if it's a problem though. The solution should be pretty easy, the importGenerator simply needs to support extensions, I just want to make sure we cover the necessary cases. |
So I think you are right about ESM. I don't have any particular questions at the moment because I just have a bit of research to do. I will start looking into it, thank you for nudging me :-) |
You're right, I totally forgot about enums because I never use them, apologies for that.
Hey, no problem. I actually decided to experiment with it a little bit and managed to get a working fork demo, you can find it here: https://github.com/virtuallyunknown/kanel You can see all the changes I made here and I made a quick INSTALL.md to test it. This is by no means ready for production or anything like that, and I haven't researched into CJS backwards compatibility support (if this is something you care about), but other than that I think it works as expected and honestly it only took a couple of hours. Maybe you find this useful, maybe not. Cheers. |
Nice work! Just to manage expectations, I will need a bit of time to get comfortable with this and as I am just starting up a new consulting client at the moment, I don't have the excess time and energy right now. I promise I will look into this as soon as I have a bit of time, I do consider it important. |
Take as much time as you want, I am not in a rush about this whatsoever and of course real life takes priority. It was actually you who initially brought up the idea of converting to ESM, I merely suggested that it's great :) Will be keeping an eye on the repo, cheers! |
I'm facing this issue right now, all my projects use |
I was able to get around this issue using the programmatic API, I wonder if it shouldn't be documented as the default way, since ESM users will just grow more and more: import kk from "kanel-kysely";
const { makeKyselyHook } = kk;
import { recase } from "@kristiandupont/recase";
import kanel from "kanel";
const outputPath = "./models";
const toPascalCase = recase("snake", "pascal");
await kanel.processDatabase({
connection: {
host: "localhost",
user: "postgres",
password: "postgres",
database: "postgres",
port: 5432,
},
outputPath,
schemas: ["public"],
resolveViews: true,
preDeleteOutputFolder: true,
enumStyle: "type",
preRenderHooks: [makeKyselyHook({ databaseFilename: "Database" })],
generateIdentifierType: (c, d, config) => {
const tableName = toPascalCase(d.name);
const name = toPascalCase(c.name);
const fullName = tableName + name;
const innerType = kanel.resolveType(c, d, {
...config,
// @ts-ignore
generateIdentifierType: undefined,
});
return {
declarationType: "typeDeclaration",
name: fullName,
exportAs: "named",
typeDefinition: [`${innerType}`],
comment: [],
};
},
customTypeMap: {
"pg_catalog.tsvector": "Set<string>",
"pg_catalog.int4": "number",
"pg_catalog.json": "string",
"pg_catalog.jsonb": "string",
"pg_catalog.bpchar": "string",
"public.citext": "string",
},
}); |
@thelinuxlich how exactly does this solve your problem? Because as far as I'm aware, relative import paths need explicit file extension at their end, otherwise it's not valid ESM, and the code you showed above doesn't address that issue (?). Maybe your tsconfig is different, but I have this: {
"compilerOptions": {
"module": "esnext",
"moduleResolution": "NodeNext",
"target": "esnext"
} and it's not working.
When I looked into this issue some months ago, the only workaround I found was through export function convertESMPaths(path, lines, instantiatedConfig) {
return lines.map(line => line.replace(/^import\stype\s.*'(.*)';$/, (match, p1) => {
return /\sfrom\s'kysely';$/.test(match)
? match
: match.replace(p1, `${p1}.js`)
}))
}
import kanel from 'kanel';
import kanelKysely from 'kanel-kysely';
export async function processDatabase() {
await kanel.processDatabase({
connection: {
// credentials
},
preRenderHooks: [kanelKysely.makeKyselyHook()],
postRenderHooks: [convertESMPaths],
});
}
await processDatabase(); Needless to say, this is far from an ideal solution. |
Hey @virtuallyunknown , I forgot to say I run this script with tsx, which automaticallly solves lots of ESM problems |
Also sharing my base tsconfig.json for science: {
"compilerOptions": {
"target": "esnext",
"incremental": true,
"composite": true,
"module": "esnext",
"moduleResolution": "node",
"inlineSourceMap": true,
"noEmit": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"exactOptionalPropertyTypes": false,
"allowUnreachableCode": false,
"noUncheckedIndexedAccess": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"preserveSymlinks": false,
"verbatimModuleSyntax": true
},
"include": ["src/**/*.ts"],
"exclude": ["**/node_modules"]
} |
Yep, that explains it, and also you have |
Yeah I gave up on moduleResolution: "nodenext" because it doesn't seem to respect allowSyntheticDefaultImports: true |
I would appreciate if someone could help me configure this with the tsconfig.json given below. Sadly none of solutions proposed previously works in my case and I am kinda stuck. Thanks in advance!
|
Greetings!
So I was wondering if support for non-relative import paths in the generated files could be added. To illustrate the problem and exactly what I mean, consider the following
tsconfig.json
:When
moduleResolution
is set tonode16
ornodenext
, you need to explicitly specify file extensions in your import paths.I found a workaround for this problem, but it's a bit hacky.
Essentially what this does is check each line for an import statement, and if it finds one it appends
.js
to the import path.I don't think this is a terrible solution overall, but I think it would be easier and more intuitive to have that built-in to the main
Config
object so it can be set there instead of using a hook.That's all, cheers!
The text was updated successfully, but these errors were encountered: