avajs / typescript

Test TypeScript projects using AVA.
MIT License
73 stars 16 forks source link

Support ESM test files #5

Closed novemberborn closed 3 years ago

novemberborn commented 4 years ago

Once https://github.com/avajs/ava/issues/2345 has shipped it should be possible to configure AVA to load ts files as ES modules.

This means we need to import them, instead of using require.

We should also explore if there may be a way to configure this within the typescript configuration.

cinderblock commented 4 years ago

Is this why I'm getting this error?

  C:\Users\Cameron\git\http-terminator\test\http-terminator\http.ts:3
  import createTests from '../helpers/createTests';
  ^^^^^^

  SyntaxError: Cannot use import statement outside a module

  × test\http-terminator\http.ts exited with a non-zero exit code: 1

  Uncaught exception in test\http-terminator\https.ts
novemberborn commented 4 years ago

Yes, right now the files are loaded using require().

rien commented 4 years ago

I am using TypeScript with ES Modules using ts-node. However, when I want to precompile typescript in order speed up the tests, the tests fail with syntax errors:

  Rejected promise returned by test. Reason:

  SyntaxError {
    message: 'Invalid or unexpected token',
  }

  › SyntaxError: Invalid or unexpected token
  › module.exports (node_modules/default-require-extensions/js.js:7:9)

Is there something else I have to do to get this working? I have "module": "commonjs" in my tsconfig.json and I don't have "type": "module" in my package.json.

novemberborn commented 4 years ago

@rien there's not enough context in order for me to help. What is your AVA configuration? TypeScript configuration? This will be better as a new issue.

rien commented 4 years ago

My apologies for hijacking the issue, I thought this could be a straightforward bug. I've tried to make a minimal reproduction, but even with exactly the same stack everything was working fine.

I've been debugging that issue for too long so I've had to switch to jest unfortunately :(

sindresorhus commented 3 years ago

@novemberborn Just so we're on the same page, this issue is about supporting projects that use AVA with @ava/typescript where package.json has "type": "module" and the tsconfig has "module": "es2020", meaning the TS output is native ESM. Correct?

novemberborn commented 3 years ago

@sindresorhus Yes.

novemberborn commented 3 years ago

Having looked at the logic here and in AVA itself, I think the way to do this is first to remove this check:

https://github.com/avajs/typescript/blob/27650db45b4807f14056bc142d6e46a8558fd372/index.js#L162-L166

Then instead of immediately using the requireFn here: https://github.com/avajs/typescript/blob/27650db45b4807f14056bc142d6e46a8558fd372/index.js#L171

We currently always rewrite to js file, so if js is in extensionsToLoadAsModules then just use import().

We then need to document that, since TypeScript compiles to JS files, you need to configure either your package.json#type or AVA itself to load JS files as modules. Configuring the ts extension will cause AVA to disregard @ava/typescript, as per these lines: https://github.com/avajs/ava/blob/a87460acf570a1d6080f35f0ecf2ccb1cac476b9/lib/worker/base.js#L161-L169

novemberborn commented 3 years ago

I think the way to do this is first to remove this check:

https://github.com/avajs/typescript/blob/27650db45b4807f14056bc142d6e46a8558fd372/index.js#L162-L166

https://github.com/avajs/ava/pull/2882 reorders it so that the provider has first dibs.