esbuild-dev icon indicating copy to clipboard operation
esbuild-dev copied to clipboard

support tsconfig path aliases

Open IlyaSemenov opened this issue 4 years ago • 3 comments

It seems that esbuild-dev doesn't recognize path aliases.

For example, consider tsconfig.json

{
	"compilerOptions": {
		"target": "esnext",
		"module": "esnext",
		"moduleResolution": "node",
		"strict": true,
		"esModuleInterop": true,
		"lib": ["esnext"],
		"baseUrl": "src",
		"paths": {
			"@/*": ["./*"]
		}
	}
}

and two files:

  • src/main.ts doing import "@/foo"
  • src/foo.ts doing console.log("I am foo")

The app will crash:

❯ yarn esbuild-dev src/main.ts
yarn run v1.22.17
$ /Users/semenov/work/xxx/node_modules/.bin/esbuild-dev src/main.ts
Error: Cannot find module '@/foo'
Require stack:
- /Users/semenov/work/xxx/src/main.ts
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.Module._resolveFilename.sharedData.moduleResolveFilenameHook.installedValue [as _resolveFilename] (/Users/semenov/work/xxx/node_modules/@cspotcode/source-map-support/source-map-support.js:679:30)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.<anonymous> (/Users/semenov/work/xxx/src/main.ts:19:29)
    at Module._compile (node:internal/modules/cjs/loader:1101:14)
    at Object.require.extensions.<computed> [as .ts] (/Users/semenov/work/xxx/node_modules/esbuild-dev/src/child-process-registration.ts:68:14)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [ '/Users/semenov/work/xxx/src/main.ts' ]
}
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

For comparison, esbuild-runner will work just fine:

❯ yarn esr src/main.ts
yarn run v1.22.17
$ /Users/semenov/work/xxx/node_modules/.bin/esr src/main.ts
I am foo

IlyaSemenov avatar Dec 17 '21 11:12 IlyaSemenov

I thought the esbuild-dev you installed is not mine. Mine is @hyrious/esbuild-dev. You can post the issue there.

hyrious avatar Dec 17 '21 12:12 hyrious

About the tsconfig support, It will be really a lot of code to implement it in plain js because it could contains extends and comments and trailing comma. People have written tsconfck for vite, you can just check out to see how many codes it is (22kb not minified).

None of us esbuild wrappers (@hyrious/esbuild-dev, esbuild-dev, esbuild-register, esno (esbuild-node-loader)) would support it in transform only mode. For example, using require.extensions or --experimental-loaders.

So the support for tsconfig paths are just from using the esbuild bundle mode. This is what esbuild-runner does when not using --cache according to its source code. This is also what @hyrious/esbuild-dev current does since I didn't use the transform mode.

One possible implementation for tsconfig in --experimental-loaders, is using esbuild to really bundle once to resolve the correct path, which is implemented in esno.

hyrious avatar Dec 17 '21 12:12 hyrious

My apologies for confusing a different esbuild-dev with yours! 🙈

I didn't pay attention to the different modes (transform vs. build) indeed, that explains it now. Here's the related issue in esbuild for reference: https://github.com/evanw/esbuild/issues/394

What I've noticed however, is that esbuild-runner --cache (transform mode) works with tsconfig-paths/register, but esbuild-dev still doesn't:

❯ yarn esr --cache src/main.ts
yarn run v1.22.17
$ /Users/semenov/work/testing/node_modules/.bin/esr --cache src/main.ts
Error: Cannot find module '@/foo'
Require stack:
- /Users/semenov/work/testing/src/main.ts
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.<anonymous> (/Users/semenov/work/testing/src/main.ts:1:8)
    at Module._compile (node:internal/modules/cjs/loader:1101:14)
    at Module._compile (/Users/semenov/work/testing/node_modules/source-map-support/source-map-support.js:547:25)
    at Module.mod._compile (/Users/semenov/work/testing/node_modules/esbuild-runner/src/hook.ts:53:22)
    at Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
    at Object.Module._extensions.<computed> [as .ts] (/Users/semenov/work/testing/node_modules/esbuild-runner/src/hook.ts:56:7)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
❯ NODE_OPTIONS="-r tsconfig-paths/register" yarn esr --cache src/main.ts
yarn run v1.22.17
$ /Users/semenov/work/testing/node_modules/.bin/esr --cache src/main.ts
I am foo
❯ NODE_OPTIONS="-r tsconfig-paths/register" yarn esbuild-dev src/main.ts
yarn run v1.22.17
$ /Users/semenov/work/testing/node_modules/.bin/esbuild-dev src/main.ts
Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@/foo' imported from /Users/semenov/work/testing/node_modules/.esbuild-dev/src/main.ts.js
    at __node_internal_captureLargerStackTrace (node:internal/errors:464:5)
    at new NodeError (node:internal/errors:371:5)
    at packageResolve (node:internal/modules/esm/resolve:884:9)
    at moduleResolve (node:internal/modules/esm/resolve:929:18)
    at defaultResolve (node:internal/modules/esm/resolve:1044:11)
    at ESMLoader.resolve (node:internal/modules/esm/loader:422:30)
    at ESMLoader.getModuleJob (node:internal/modules/esm/loader:222:40)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:76:40)
    at link (node:internal/modules/esm/module_job:75:36) {
  code: 'ERR_MODULE_NOT_FOUND'
}

I'm not asking anything here — just sharing my experience.

IlyaSemenov avatar Dec 18 '21 05:12 IlyaSemenov