-
SurveyJS
Open-Source JSON Form Builder to Create Dynamic Forms Right in Your App. With SurveyJS form UI libraries, you can build and style forms in a fully-integrated drag & drop form builder, render them in your JS app, and store form submission data in any backend, inc. PHP, ASP.NET Core, and Node.js.
I've started using ESM in a static website builder too [1]. It works, kinda.
Problems that I encountered:
To get `__dirname`, you have to do an awkward workaround using path and url [3].
For npm modules that implement a path e.g. `@lib/method`, the import of this currently isn't allowed in node without a flag.
For ESM incompatible modules, a createRequire [2] function is available to get the old `require` syntax.
For import statements, the cache cannot be deleted yet [4].
Overall, I'm please to see that nodejs will soon be ESM compatible. All changes that have been made look reasonable and useful to me.
1: https://github.com/TimDaub/kloi
2: https://nodejs.org/api/module.html#module_module_createrequi...
3: https://stackoverflow.com/questions/46745014/alternative-for...
4: https://github.com/nodejs/modules/issues/307
I find using ES Modules in Node.js to be full of gotchas and anti-patterns - sticking with CommonJS seems more functional in most cases.
1: With ES Modules, imports are asynchronous.
Synchronous imports are incredibly powerful. You can ensure that your application doesn't block on first requests, but instead on load. Initializing connection pools, setting up caches, etc.
You'll also find quite a few packages in NPM that explicitly depend on require over import just so that they can perform the bindings they have to before things get going (see https://www.npmjs.com/package/honeycomb-beeline as an example).
2: With ES Modules imports are commonly destructured.
I know it makes your code feel lighter to have const { add } = import("whatever"); - but as your files grow larger, and those imports start to become complicated bits for middleware or other features, you're just making it more difficult for future maintainers to figure out what those functions mean. A bit of context never hurt anybody, and for my money I'll be that this:
app.use(check);
is not nearly as useful as
app.use(Validator.check);
The example may be contrived - but 9/10 times I find this makes code better than the alternative.
All of these arguments go out the door for Frontend work - that's a totally different terrain. I think one of the big arguments is that developers want to use the exact same JavaScript on frontend and Node applications - but that's an argument unwilling to admit the fact that they're two very different tasks. :)
Another static site builder author here. I found some of the same awkwardness in recreating __dirname, but after some massaging found it only remains when path.join is also used (which can't work with a file URL and can't be simply replaced with URL construction because the existing path is lost). I went the whole hog and completely replaced all CJS in my own code, and it's working well. Luckily I avoided issues with third party modules breaking.
PR with the changes: https://github.com/qubyte/qubyte-codes/pull/323
This is being looked at https://github.com/microsoft/TypeScript/issues/31658
Related posts
-
Deno developers - if you could improve Deno, what would you change or add?
-
Why did Microsoft decide to call Windows 11's build number, build 10.highernumber still?
-
JSR Is Not Another Package Manager
-
TypeScript Essentials: Distinguishing Types with Branding
-
Smart Contract Programming Languages: sCrypt vs. Solidity