unjs / jiti

Runtime Typescript and ESM support for Node.js
MIT License
1.49k stars 52 forks source link

Custom transforms in v2 #270

Open webpro opened 2 days ago

webpro commented 2 days ago

Describe the feature

Perhaps this should be a discussion, but that led me to a more generic forum. Feel free to close or move it.

Great work on v2, glad this seems to be progressing wonderfully!

Using jiti v1, Knip can do this:

import transform from 'jiti/dist/babel.js';
import type { TransformOptions } from 'jiti/dist/types.js';

The goal is to use a custom transform and remove a specific line from the imported file:

https://github.com/webpro-nl/knip/blob/main/packages/knip/src/util/require.ts#L55-L65

(this is some necessary evil because knip is loading the eslint config file from a different cwd)

Can I do something similar in v2, or maybe there's an alternative/better way to go about this?

Currently playing a bit with v2 and 2.0.0-beta.3 TS doesn't allow importing transform and neither does Node.js:

Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './dist/babel.cjs' is not defined by "exports" in [..]/node_modules/jiti/package.json imported from [..]/knip/dist/util/require.js

Additional information

pi0 commented 2 days ago

Thanks for kind words. It is a tricky situation honestly. I also used jiti in places like unbuild/untyed as custom loader with custom transform and i know there are other libs that hook into jiti to add their transformer replacing babel.

But this also pushed back jiti from natively supporting more features and also when using jiti in envs like bun (and in the future vitest, web, deno) we want to bypass jiti as the core functionality (TS support) is natively available in those platforms.

Thanks for sharing usecase. I think if jiti exposes an agnostic transform hook it would fix your issue? (also have you tried using alias option to patch that specific package?)

webpro commented 2 days ago

Hah, alias solves my issue completely, eg:

const empty = join(fileURLToPath(import.meta.url), '../empty.js');

const options = {
  interopDefault: true,
  extensions: DEFAULT_EXTENSIONS,
  esmResolve: false,
  alias: {
    '@rushstack/eslint-config/patch/modern-module-resolution': empty,
    '@rushstack/eslint-patch/modern-module-resolution': empty,
  },
};

const createLoader = (options: JitiOptions) => createJiti(process.cwd(), options);

In https://github.com/webpro-nl/knip/commit/b9f1715e565096e5a37f850d6dda103000aa708e

Tried in both v1 and v2. Thanks, this is a great cleanup - why didn't I try this before :)

(v2 migration in https://github.com/webpro-nl/knip/commit/c37369061d35d255092d096c87f6ee870ce2870e which works great too!)