Closed AgainPsychoX closed 2 years ago
I removed the experimental-specifier-resolution=node
in place for adding .js
to imports in source files (.js
in Typescript, sic!) in last commit ( https://github.com/taoqf/node-html-parser/pull/150/commits/18ca5848c25f051a12acab4a69b6b3aca63c1a0c ).
It causes multiple warnings about not linter not being able to resolve the imports, like
warning Unable to resolve path to module './html.js' import/no-unresolved
but it also compiles and works well.
I added it as alternative to using the flag, IMO should be reverted (the last commit), but wanted to provide possible outcome.
I don't think there is any good way of making it work without any of those solutions. I was reading online whole morning about using ES modules, and it seems TS devs/JS community still don't know (or still argue) which approach would be the best.
Some of the stuff I found interesting:
Have to say, it's weird stuff Typescript is doing around ES modules. It feels like Typescript is stuck few years ago because holding to compatibly, or some part of community/devs are stubborn.
Interesting stuff! Just a thought, you can use typescript-transform-paths with the @transform-path
tag to transform the imports to .js
in the output.
Steps:
tsconfig.esm.json
@transform-path
comments to the source, specifying the path with a .js
extensionI think that would do what you want. I'm still not as knowledgeable about esm, but I'm getting there in having to deal with various support tickets for it in the repos I maintain. If this is a solution, maybe it would make sense to add a config option to typescript-transform-paths
to set a common output extension for imports.
I knew I could use transformers for that, problem is using ts-patch
is like another layer of configuration. Also, using the plugin you suggest require to use @transform-path
comments everywhere in source, which isn't much better than adding .js
extensions to imports in the source anyway (maybe the warning would be gone, but if it all it does it's just easier to disable the warning then).
I think I will try to explore other options, like maybe custom transformer just to add the .js
in the output (i found this https://github.com/Zoltu/typescript-transformer-append-js-extension , but requires updates and testing). All
There is also another issue apart from the .js
extension in imports, I forgot to mention. If you import CJS modules from ESM you can't just write:
import { decode, encode } from 'he';
because some exports can't be deduced (there are tools for it, but not perfect; even in this project there is he
used with does not work). That's why i modified sources around other modules imports (like in src/nodes/node.ts
)
Anyway, ESM with Typescript is messy, no official solutions provided as the standards aren't yet fully created. Yet, having .js
in compiled files (targeting ESM) seems to be best strategy for now.
It's probably best to leave the syntax unchanged and use a transformer to convert it on output. Although verbose, even the comment method is less likely to produce any side-effects later. As you mentioned, ESM in TS is very messy. That said, a transformer which added the .js
would definitely be nicer!
The logic in the transformer you posted looks sound, however it does seem to be a bit outdated. Does not incorporate factory changes in the compiler API, so the methods it's using are deprecated. It will likely need an update in a few TS versions.
The problem discussed a few years ago, until now has not been resolved, really fuck
Thanks for all your work, It is a big change. I didn't know much about this. But I think we should take of this carefully. I used some module and did have a good experiences. expacillay add .js to import. I could not navigate to right d.ts file but js file. So I think I will wait and here more voice about this. There is a way to avoid the error using default exports. see https://github.com/taoqf/node-html-parser/issues/149
This should be addressed in the following PR:
Would appreciate feedback to ensure it's working for your use cases @AgainPsychoX @apprat
Corrected in v5
Fixes #149.
Tests included are passed okay (after fixing paths and adding
experimental-specifier-resolution=node
). I noticed the benchmarks on the README are "a bit" outdated, but it isn't my concern today.Why currently included tests were passing despite they were using ES modules?
There seems to be files in
test
folder using ES modules, among themcompare-node-html-parser.mjs
.Despite first impression, it wasn't using ES modules version from
./dist/esm/*
, but it was using./dist/index.js
; that's why the benchmark was running fine before.Additional testing
I tested proper the ESM support myself using simple project like:
package.json
(changing type to
commonjs
(when not added at all, it's alsocommonjs
))main.js
(I had the
node-html-parser
linked bynpm link
for the test)Results:
import
approach, it works only usingrequire
(commonjs).Notes
experimental-specifier-resolution=node
is used because generated files inesm
version don't have.js
/.mjs
extensions. It could be done by adding.js
extension in Typescript sources (yes, in.ts
adding.js
when importing), but it was more work and I wasn't sure should I really edit sources for it. The choice itself don't have to be final, and even node devs still don't know what they want to finally do with the directory name resolution in ES modules.