parcel: Simple tilde resolution not working for me

πŸ› bug report

Simple tilde paths as described under getting started don’t seem to be resolving.

πŸ€” Expected Behavior

A repo of the error. My folder structure:

node_modules
  xhook
    dist
      xhook.js
folder1
  index.html
index.html
package.json

And both index.html files have:

<html>
  <body>
    <script src="~/node_modules/xhook/dist/xhook.js"></script>
  </body>
</html>

When I run parcel folder1/index.html it should build.

😯 Current Behavior

parcel index.html works fine but parcel folder1/index.html returns:

D:\dev\parcel-test\folder1\node_modules\xhook\dist\xhook.js: ENOENT: no such file or directory, open 'D:\dev\parcel-test\folder1\node_modules\xhook\dist\xhook.js'

It seems to be treating the tilde as a relative path rather than looking for the folder containing node_modules.

πŸ’» Code Sample

Repository of the bug.

🌍 Your Environment

Software Version(s)
Parcel 1.12.2
Node 11.12.0
npm/Yarn npm 6.7.0
Operating System Windows 10

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 6
  • Comments: 34 (11 by maintainers)

Most upvoted comments

The code does appear like it’s set up how it’s supposed to be, but ~ is also not working for me as described in the above issue report.

~ should resolve to the package root (closest node_modules), but it is resolving to the entry point, not the package location. As soon as I changed my entry point from ./index.html to ./src/index.html, my ~ references broke, and I had to change them to relative folders with ...

Needing to add ./src was pretty much the nature of the bug/missing feature.

It should take the root from the TypeScript config paths field. Not sure if they finally fixed this; due to this and a few other problems I had with Parcel I gave up and switched to vite: https://vitejs.dev/

With Vite it all works if you import the vite-tsconfig-paths plugin. Vite is also crazy faster than Parcel because it uses esbuild. But some TypeScript features aren’t supported. YMMV.

Parcel 2 is broken with respect to TypeScript tilde paths.

In the Parcel docs it tells us to use ~ to refer to files relative to the src folder. See this tsconfig.json from the example:

{
  "compilerOptions": {
    "baseUrl": "./src",
    "paths": {
      "~/*": ["./*"]
    },
    "typeRoots": ["node_modules/@types"]
  },
  "include": ["src/**/*"]
}

And this from the gist:

import { Reset } from '~/ui/shared/Reset'

No src path in the example – and in Parcel 1 it worked.

Apparently Parcel 2 is using ~ as a relative path to the package.json folder? That profoundly breaks all TypeScript code which depends on the original example. The original approach is frankly a more sane assumption, too; otherwise you’re adding src redundantly to all imports.

Understood. But the sane approach includes let us define what the root folder should be. Don’t just pick one arbitrarily; let us have a say in it.

And let us pick src in the second example, even though index.html is outside of src. In fact, the best case would be to let us pick an array of root folders, and just search for every ~ file sequentially in each root.

Don’t break hundreds of lines of existing code because of some arbitrary new rule you’d like to add. Make the feature actually useful.

Even better: Respect the paths entry from the TypeScript file instead of relying on a hack.

Still not working for me in latest version (alpha 2.3). TS compiles fine, Visual Studio autocompletes fine, parcel says path doesn’t exist.

tsconfig:

{
    "compilerOptions": {
        "baseUrl": ".",
        "paths": {
            "~/*": [
                "./src/*"
            ]
        },
        ....
    },
    "include": [
        "./src/**/*"
    ]
}

Folder structure:

root
 - package.json
 --src
 ---index.html

Command: parcel src/index.html or parcel ./src/index.html.

Error: @parcel/resolver-default: Cannot find module '~/config/Config' from 'C:\project-root\src\components\sidebar'.

I also get Build failed. Error: Got unexpected undefined. sometimes when building, after I clear the cache this undefined error goes away.

I also have to note that in Parcel v1 this worked as expected.

An alternative to that symlink is using alias.

Like the local-module entry here: https://v2.parceljs.org/features/module-resolution#aliases

In your case, "alias": {"static": "./static"} should work (in a package.json next to src)

Merging this into https://github.com/parcel-bundler/parcel/issues/202.


The original issue post and the most +1’ed comment say

~ should resolve to the package root (closest node_modules),

which is already the case in Parcel 2.

All of that is typescript specific. Parcel has supported tilde resolution for literally years, and it applies the same way across all file types. TS doesn’t get to dictate how all of Parcel works.

As @mischnic said, Parcel 2 supports custom resolver plugins, and these can be chained. So we could easily support a @parcel/resolver-typescript package for better TS support, which could override the default resolver for TypeScript files.

The original approach is frankly a more sane assumption, too; otherwise you’re adding src redundantly to all imports.

The problem with Parcel 1’s ~ is that was never really was src but rather the nearest parent folder of all entries:

β”œβ”€β”€ package.json
└── src
	β”œβ”€β”€ index.html (entry)  with `<script src=./index.ts`
	└── index.ts

-> ~ = root/src
β”œβ”€β”€ package.json
β”œβ”€β”€ index.html (entry)  with `<script src=./src/index.ts`
└── src
	└── index.ts

-> ~ = root

@DeMoorJasper I am on the absolute latest version, but I can see when I get home and give you more information.

@YassienW this is broken in Parcel 2