deepkit / deepkit-framework

A new full-featured and high-performance TypeScript framework
https://deepkit.io/
MIT License
3.24k stars 124 forks source link

Compiler produces mixed ESM and CJS import syntax (Electron Forge x Vite x DeepKit) #615

Closed augustsaintfreytag closed 1 month ago

augustsaintfreytag commented 1 month ago

Example project: https://github.com/augustsaintfreytag/electron-vite-typescript

Setting up a very basic project with Electron Forge, TypeScript, and the default bundler Vite (included with Forge) together with DeepKit seems to produce output script files with mixed ESM and CJS syntax.

import { serialize, integer, UUID } from "@deepkit/type"
import { v4 as randomUUID } from "uuid"

— becomes —

const {__ΩUUID} = require("@deepkit/type");
import {serialize} from "/node_modules/.vite/deps/@deepkit_type.js?v=6b441ca2";
import {v4 as randomUUID} from "/node_modules/.vite/deps/uuid.js?v=24137d49”;

Now I’m really wandering in the dark here. As far as I know, Electron generally only works with CJS syntax (e.g. setting tsconfig.json module to ES6 gives me a number of build time errors while CommonJS is the default in every example and template). Electron Forge uses Vite (ESBuild, Rollup) to bundle everything. Somehow, once it gets to the renderer process (a.k.a. the browser window), it has become ESM syntax again.

I’m assuming DeepKit reads the tsconfig.json, sees CommonJS there and that’s what it outputs. I can’t seem to override this to have the injected DeepKit compiler output ESM or have Vite transform the rest.

Even using "@rollup/plugin-commonjs" to maybe transform mixed syntax does not change the final output. Ultimately, my project crashes with a runtime error.


Electron Forge 7.5.0 Vite 5.0.12 TypeScript 5.6.2 DeepKit 1.0.1-alpha.154

marcj commented 1 month ago

just as a note, this is the code we use for determining cjs/esm: https://github.com/deepkit/deepkit-framework/blob/ab96f2f3c0f7f795692d49e6a37ee5194647a9c1/packages/type-compiler/src/compiler.ts#L1048-L1056

so it comes from the typescript compiler/tsconfig itself

marcj commented 1 month ago

you can enable DEBUG=deepkit your-build-command to get more information about what tsconfig is loaded and which module system is picked

augustsaintfreytag commented 1 month ago

Did some testing and yeah, Forge’s strange mixed module setting is the heart of the issue. A reasonable solution was for me to define three files, tsconfig.common.json with common settings (for me, everything but target, module, and moduleResolution), and then dedicated config entry points, one for Electron Forge (a default tsconfig.json extending the common one), and a new one for DeepKit (a tsconfig.deepkit.json, also extending the common one).

Then I’ve configured the Vite config with an explicit path:

plugins: [
  deepkitType({
      tsConfig: joinPath(projectRoot, "tsconfig.deepkit.json")
  })
]

I’d say this issue is predominantly one of Forge not properly supporting ESM, something they’re apparently working on right now anyway. Thanks for your input on this, @marcj!