I'm building a discord.js
Discord bot. Now for some reason, discord.js
doesn't work with ESM
modules (a totally separate issue), so my bot app uses CommonJS
modules. Now I have another project on my system called Lib
, which has a lot of utility functions that I plan to use in several different projects so I don't have to rewrite them. This Lib
project uses ESM
modules. Since I have to import Lib
from DiscordBot
, I use the dynamic import syntax in typescript. Now, whenever I transpile my DiscordBot
project, the dynamic imports get converted into some ugly javascript module code, and that ugly module code ultimately ends up using require(). Since require() can't import ESM modules, my bot ends up crashing.
I tried however to stop my ts compiler, copy the code from my ts file that imports Lib
then pasting that code into the corresponding JS file manually (and removing TS-exclusive features like type annotations and interfaces). Then I ran my bot app, and it worked perfectly fine. But I don't want to have to do this every time. So it's tsc
's compiling that's the problem. How do I fix this?
This is currently not possible. There is a very new issue at GitHub (https://github.com/microsoft/TypeScript/issues/43329), but that is not implemented yet. So everything you can do now is to switch from ESM to CommonJS with your Lib
project.
The issue has been closed and there is now a new option for "module"
called node12
. That should fix the problem
So I understand the purpose is:
If "module"
in tsconfig.json
is set to "commonjs"
, currently there's no way to prevent TypeScript from transpiling dynamic import()
into require()
- except that you hide the code in a string and use eval
to execute it. Like this:
async function body (pMap:any){
// do something with module pMap here
}
eval ("import('p-map').then(body)");
No way TypeScript transpiles a string!
Set "module"
in tsconfig.json
to "es2020"
. By doing this, dynamic import would not be transpiled into require()
, and you can use dynamic import to import a CommonJS or ES Module. Or, you can use the const someModule = require("someModule")
syntax to import a CommonJS module (would not be transpiled to ES6 import syntax). You cannot use the ES6 import syntax such as import * as someModule from "someModule"
or import someModule from "someModule"
. These syntaxes will emit ES Module syntax imports ("module" is set to "es2020") and cannot be run in CommonJS package.
Below is a bit information:
If "module"
is set to "es2020"
: dynamic import import()
is not transpiled.
If "module"
is set to `"es2015": there's an error:
TS1323: Dynamic imports are only supported when the '--module' flag is set to 'es2020', 'esnext', 'commonjs', 'amd', 'system', or 'umd'.
If "module"
is set to "commonjs"
: dynamic imports are transpiled.
Quote tsconfig.json
reference for "module"
field:
If you are wondering about the difference between ES2015 and ES2020, ES2020 adds support for dynamic imports, and import.meta.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With