wallabyjs / quokka

Repository for Quokka.js questions and issues
https://quokkajs.com
1.18k stars 31 forks source link

Add support for custom transformers (similar to `ts-node`) #856

Open patroza opened 1 year ago

patroza commented 1 year ago

Issue description or question

Why does Quokka not respect the custom typescript compiler, which is used fine by ts-node --esm from the console? So far it seems errors occur even before ts-node/typescript parser/compiler is leveraged. How do I fix this behaviour?

Is this issue related to Quokka not outputting the expected results of your code?: Yes

https://github.com/effect-ts-app/playground/blob/main/starter-traced/src/main.ts

import "@effect-app/prelude/_global"

export interface Name {
  getName: Effect<never, never, string>;
}

export const Name: Tag<Name> = Tag<Name>();

export const program: Effect<Name, never, void> = Effect.gen(function* ($) {
  const { getName } = yield* $(Effect.service(Name));

  yield* $(Effect.log(`Hello ${yield* $(getName)}`));
  yield* $(Effect.die("Error"));
});

export const NameLive: Layer<never, never, Name> = Layer.effect(Name)(
  Effect.sync(() => ({
    getName: Effect.succeed("Mike"),
  }))
);

  program
  .provideLayer(NameLive)
  .tapErrorCause(_ => Effect.logErrorCauseMessage("Error", _))
  .unsafeFork

Several globals and extension methods are at play here, which are auto provided through the extended compiler. It is important that ts-node's transpileOnly is false.

Compiled output (for reference)

import * as tracer_1 from "@effect/io/Debug";
const fileName_1 = "~/Projects/effect-ts-app/playground/starter-traced/src/main.ts";
import * as tsplus_module_1 from "@fp-ts/data/Context";
import * as tsplus_module_2 from "@effect/io/Effect";
import * as tsplus_module_3 from "@effect-app/core/Effect";
import "@effect-app/prelude/_global";
export const Name = tsplus_module_1.Tag();
export const program = tracer_1.withCallTrace(fileName_1 + ":9:58")(tsplus_module_2.gen(function* ($) {
    const { getName } = yield* $(tracer_1.withCallTrace(fileName_1 + ":10:39")(tsplus_module_2.service(Name)));
    yield* $(tracer_1.withCallTrace(fileName_1 + ":12:19")(tsplus_module_2.log(`Hello ${yield* $(getName)}`)));
    yield* $(tracer_1.withCallTrace(fileName_1 + ":13:19")(tsplus_module_2.die("Error")));
}));
export const NameLive = tsplus_module_3.LayerFromEffect(Name)(tracer_1.withCallTrace(fileName_1 + ":17:10")(tsplus_module_2.sync(() => ({
    getName: tracer_1.withCallTrace(fileName_1 + ":18:21")(tsplus_module_2.succeed("Mike")),
}))));
tsplus_module_2.unsafeFork(tracer_1.withCallTrace(fileName_1 + ":24:4")(tsplus_module_2.tapErrorCause(_ => tracer_1.withCallTrace(fileName_1 + ":24:30")(tsplus_module_2.logErrorCauseMessage("Error", _))))(tracer_1.withCallTrace(fileName_1 + ":23:4")(tsplus_module_2.provideLayer(NameLive))(program)));

Sample repository link

\"Error\"

Stack:

~/Projects/effect-ts-app/playground/starter-traced/src/main.ts:9:58 ~/Projects/effect-ts-app/playground/starter-traced/src/main.ts:24:4

Execution:

~/Projects/effect-ts-app/playground/starter-traced/src/main.ts:13:19 ~/Projects/effect-ts-app/playground/starter-traced/src/main.ts:9:58 ~/Projects/effect-ts-app/playground/starter-traced/src/main.ts:12:19 ~/Projects/effect-ts-app/playground/starter-traced/src/main.ts:9:58 ~/Projects/effect-ts-app/playground/starter-traced/src/main.ts:18:21

"


- open vscode **from within the `starter-traced` folder**
- **Set VS Code Typescript compiler to the node_modules one**
- Open main.ts
- Quokka: Start on Current File

### Quokka console output

​​​​​Quokka PRO 'main.ts' (node: v18.12.1, TypeScript: v5.0.0-tsplus.20230113)​​​​   Tag is not defined  ​​​​​at ​​​​​​starter-traced/src/main.ts:7​



### Code editor version

Visual Studio Code v1.74.1

### OS name and version

OSX Ventura 13.1
patroza commented 1 year ago

In contrast, when using Vite, it works as expected; https://github.com/effect-ts-app/playground/tree/main/starter-traced-vite

Setup

Launch

To inspect the compiled output, look at .cache/*

Quokka

Though atm we have some other limitations here when we make code edits; We must save, and we must make another change after that for the previous change to activate. But that's a known limitations because of our vite tsc compiler plugin architecture, and the reason we would like to use the ts-node implementation.

smcenlly commented 1 year ago

Thanks for the sample repo. We had never seen tsplus before.

Why does Quokka not respect the custom typescript compiler, which is used fine by ts-node --esm from the console? So far it seems errors occur even before ts-node/typescript parser/compiler is leveraged.

Wallaby uses TypeScript to compile the file that you start Quokka with, while ts-node is used for any project-level imports. ts-node is not being used for the main file that you start Quokka on.

Internally we are using the TypeScript compiler API and the ts.transpileModule function (which does not know about custom transforms).

How do I fix this behaviour?

We would need to add support for custom TypeScript compilers to add support for custom transformers.


I will update the title to reflect this as a feature request. Unfortunately we can't commit to a timeline for the request at this point in time; it may be faster to resolve your vite solution.

patroza commented 1 year ago

@smcenlly thanks for the response! There are others out there like the compiler of deepkit, and ttypescript and ts-patch. So general support for custom compilers as long as they support sourcemaps etc, could be neat.

Will look into the vite plugin, but with running from buffer vs file it's not so easy.

smcenlly commented 1 year ago

Will look into the vite plugin, but with running from buffer vs file it's not so easy.

We need to do a similar thing for both Wallaby and Quokka vitest and vite-node support. You should be able to implement without too much trouble with a resolveId and load plugin. Having said that, if you're using Quokka, it should already be automatically reset unless you have some internal caching in your transformer?