node.js - Migrering af et NX-arbejdsområde til at bruge ESM
Jeg har et stort NX-baseret monorepo, et halvt dusin apps, frontend, backend, snesevis af biblioteker. Det er alt sammen stadig sat op til at arbejde med commonjs-modultyper, hvilket er det, som NX-generatorerne altid har produceret, og stadig gør.
Men flere og flere biblioteker udgiver "kun ESM"-versioner, som slet ikke fungerer for dette monorepo.
Jeg har lige fuldført nx migrate latest, er på NX 17, Typescript 5.2, Angular 17, men commonjs ser bare ud til at blive, hvor det er.
Forsøg på at opgradere manuelt har alle fejlet, hver gang jeg retter en fejl, kommer den næste, ofte krævende omfattende ændringer over 1.000+ imports eller hundredevis af filer med usikre resultater.
Er der nogen dokumentation, jeg mangler et sted for, hvordan man migrerer?
Svar #1
Aafik er den bedste måde at understøtte ESM og CommonJS-moduler samtidig ved at bruge TypeScript, som tillader begge dele og vil samle CommonJS- og ESM-afhængighederne med allowSyntheticDefaultImports og esModuleInterop.
https://www.typescriptlang.org/docs/handbook/modules/appendices/esm-cjs-interop.html
Det betyder dog ikke, at det virker overalt. For eksempel bundler NodeJS-projekter normalt ikke afhængigheder, men vælger i stedet at bundle app-koden og derefter installere afhængighederne hver gang, specifikt fordi nogle afhængigheder er afhængige af hardware-/OS-niveau checks under installationstid for at kompilere kode af præstationsmæssige årsager, eller for at bruge specifikke hardwarefunktioner som GPU.
Artiklen i TS-dokumentationen nævner også Interop i NodeJS, og essensen af det er, at du ikke kan require en ægte ESM, hvilket ikke betyder noget for os, da vi ønsker vores src i ægte ESM.
https://www.typescriptlang.org/docs/handbook/modules/appendices/esm-cjs-interop.html#interop-in-nodejs
Hvis jeg forstår dette korrekt, for NodeJS > 16, hvis du definerer i package.json "type": "module", vil NodeJS antage, at din kodebase er ESM, og med esModuleInterop vil det importere CommonJS-moduler uden problemer. Problemet opstår, når din kode ikke er ægte ESM og forsøger at importere ægte ESM.