parcel-bundler / parcel

The zero configuration build tool for the web. 📦🚀
https://parceljs.org
MIT License
43.47k stars 2.27k forks source link

Parcel resolver cryptic errors with the new Riot.js Transformer #7115

Closed GianlucaGuarini closed 3 years ago

GianlucaGuarini commented 3 years ago

🐛 bug report

Hi there, I am the Riot.js maintainer and I am trying to update the riot transformer to support Parcel v2. https://github.com/riot/parcel-transformer-riot

I am getting cryptic errors from the @parcel/resolver-default and your help is highly appreciated.

I have setup a repo to reproduce the issue https://github.com/riot/parcel-template/tree/feature/parcel-v2: just run npm start to see the error.

{
  "extends": "@parcel/config-default",
  "resolvers": [
    "@parcel/resolver-glob",
    "..."
  ],
  "transformers": {
    "*.riot": ["@riotjs/parcel-transformer-riot"]
  }
}

🤔 Expected Behavior

The transformer loads and generates the proper javascript output

😯 Current Behavior

I get a generic error @parcel/core: Failed to resolve...

💁 Possible Solution

🔦 Context

💻 Code Sample

https://github.com/riot/parcel-template/tree/feature/parcel-v2

🌍 Your Environment

Software Version(s)
Parcel 2
Node v14.16.1
npm/Yarn 8.1.0
Operating System MacOS Big Sur
mischnic commented 3 years ago

You need to do this in your transformer:

asset.setCode(`${code}${config?.hot ? hotReload(path.basename(asset.filePath)) : ''}`)

instead of https://github.com/riot/parcel-transformer-riot/blob/d73842fa0d9eb36ded5e1bd29b026487b6d90774/index.js#L45.

After that, HMR works 👍


Currently, your transformer insert this code

require('./src/components/global/my-component/my-component.riot')

for the asset to import itself (instead of ./my-component.riot);

GianlucaGuarini commented 3 years ago

@mischnic thank you I will try it asap and give you my feedback

GianlucaGuarini commented 3 years ago

@mischnic thank you for your help, your suggestion helped me finding the issue, however it would be nice if the resolver errors were a bit more explicit.

mischnic commented 3 years ago

So the error is @parcel/core: Failed to resolve './src/components/global/my-component/my-component.riot' from './src/components/global/my-component/my-component.riot' and the issue was indeed that require('./src/components/global/my-component/my-component.riot') was inserted in the file './src/components/global/my-component/my-component.riot'`. What would you want the error to say instead to be more explicit?

GianlucaGuarini commented 3 years ago

@mischnic probably the behaviour should be consistent with the node resolver.

in main.js

const { join } = require('path')

require(join(__dirname, 'main.js'))

This code compiles in node without errors

mischnic commented 3 years ago

This is how it behaves currently.

And this also why

let __dirname = '/home/user/projects/src/components/global/my-component/';
let specifier = './src/components/global/my-component/my-component.riot'

require(join(__dirname, specifier))

doesn't work: /home/user/projects/src/components/global/my-component/src/components/global/my-component/my-component.riot is not a valid path.

GianlucaGuarini commented 3 years ago

But in that case I get: Cannot find module '/home/user/projects/src/components/global/my-component/src/components/global/my-component/my-component.js'

that it's not the same as Failed to resolve. Failed to resolve might mean also that the transformer wasn't able to parse the file.

Since you have built your own resolver (and you have the resolve cache under control) you might also add hints for example:

Did you mean `./my-componnent.js`?
mischnic commented 3 years ago

The total error I get is

@parcel/core: Failed to resolve './src/components/global/my-component/my-component.riot' from
'./src/components/global/my-component/my-component.riot'

  /home/projects/src/components/global/my-component/my-component.riot:41:33

@parcel/resolver-default: Cannot load file './src/components/global/my-component/my-component.riot' in
'./src/components/global/my-component'.

If you concatenate the paths in the last line, you get the equivalent of the Cannot find module path.

Failed to resolve might mean also that the transformer wasn't able to parse the file.

That might be true for Node, not for Parcel. Resolving and transforming (e.g. parsing) happen separately.

GianlucaGuarini commented 3 years ago

Cannot load file !== Cannot find module but probably it's only me not being native english speaker.