What is the recommended way to use this tool with ESM projects?
Hi, thanks for building/maintaining this project! I had a small question: currently, the code generated from this project generates import statements of the form:
import { Table as Table4 } from "ts-sql-query/Table";
import { extractColumnsFrom as extractColumnsFrom4 } from "ts-sql-query/extras/utils";
This causes an issue, as relative imports in ESM require extensions, like so:
import { Table as Table4 } from "ts-sql-query/Table.js";
import { extractColumnsFrom as extractColumnsFrom4 } from "ts-sql-query/extras/utils.js";
Is there a work around for this, apart from using a custom NodeJS import loader/bundler (or --experimental-specifier-resolution for older node versions)?
Hello, thanks for your interest.
So even if the generator here is updated to add extension, the underlying library (ts-sql-query) will need to be updated as well because that is also not esm friendly out of the box. There was some discussion around this in https://github.com/juanluispaz/ts-sql-query/issues/66 - perhaps we can continue the discussion with @juanluispaz there.
Once ts-sql-query supports ESM, I'll update this to add the .js extensions too.
Until then using a bundler or --experimental-specifier-resolution=node is your best bet.
I am working right now on ts-sql-query 2.0, in which I want to address several things, including ESM
Thanks @lorefnon @juanluispaz for the clarifications! Just leaving some additional comments, although i'll stick to using a custom node loader for now to get around this:
So even if the generator here is updated to add extension, the underlying library (ts-sql-query) will need to be updated as well because that is also not esm friendly out of the box
I don't believe the underlying library will need to be updated, due to how NodeJS ESM <> CJS interoperability works (https://nodejs.org/api/esm.html#import-statements). Have also verified this on Node LTS (v20), I was able to use an ESM import like the following to import from ts-sql-query (even though it is a CJS library):
import { extractColumnsFrom } from "ts-sql-query/extras/utils.js"
However, when I do it without the .js extension I get:
> node ./dist/index.js
node:internal/process/esm_loader:34
internalBinding('errors').triggerUncaughtException(
^
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/redacted/node_modules/ts-sql-query/extras/utils' imported from /redacted/dist/index.js
Did you mean to import ts-sql-query/extras/utils.js?
Until then using a bundler or --experimental-specifier-resolution=node is your best bet.
Although yes, this works for Node below v19 (https://github.com/nodejs/node/issues/45108). In v19, and the latest LTS (v20), this option does not exist anymore....., instead its recommended to use a custom loader (like https://www.npmjs.com/package/extensionless).
I am working right now on ts-sql-query 2.0, in which I want to address several things, including ESM
That's amazing! I was trying to avoid using a bundler/custom loader, although I do understand spending too much time on fixing this is probably not necessary right now if 2.0 is coming soon.
I don't believe the underlying library will need to be updated, due to how NodeJS ESM <> CJS interoperability works (https://nodejs.org/api/esm.html#import-statements).
Yes, you are correct. Just verified.
In 3.20.0 I have added an option output.import.extension which can be set to .js to ensure that all imports have a .js extension.
I'll enable it by default in a future major version, but for now you can add this to your configuration:
output: {
import: {
extension: ".js"
}
}
Hi @lorefnon , thanks for rolling this out! I verified this new option works for some of the imports, but not the ones inside {{each}} blocks due to hbs scoping rules inside those. I have opened a PR and verified this fixes it (https://github.com/lorefnon/ts-sql-codegen/pull/16)
Thank you.