Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

error with esm on windows #98

Closed
amis-shokoohi opened this issue Aug 12, 2020 · 25 comments
Closed

error with esm on windows #98

amis-shokoohi opened this issue Aug 12, 2020 · 25 comments

Comments

@amis-shokoohi
Copy link
Contributor

I was following @mcollina tutorial for Fastify, and I faced with an error related to fastify-autoload plugin:

Error [ERR_UNSUPPORTED_ESM_URL_SCHEME]: Only file and data URLs are supported by the default ESM loader
    at Loader.defaultResolve [as _resolve] (internal/modules/esm/resolve.js:781:11)
    at Loader.resolve (internal/modules/esm/loader.js:85:40)
    at Loader.getModuleJob (internal/modules/esm/loader.js:229:28)
    at Loader.import (internal/modules/esm/loader.js:164:28)
    at importModuleDynamically (internal/modules/cjs/loader.js:1199:27)
    at exports.importModuleDynamicallyCallback (internal/process/esm_loader.js:30:14)
    at loadPlugin (C:\Users\amis\Desktop\fastify3-test\node_modules\fastify-autoload\index.js:117:5)
    at C:\Users\amis\Desktop\fastify3-test\node_modules\fastify-autoload\index.js:27:12
    at Array.map (<anonymous>)
    at fastifyAutoload (C:\Users\amis\Desktop\fastify3-test\node_modules\fastify-autoload\index.js:26:29) {
  code: 'ERR_UNSUPPORTED_ESM_URL_SCHEME'
}

I'm running Node v14.7.0 on Windows 10.
This is how the app looks like:

app.js
import fastify from 'fastify'
import autoload from 'fastify-autoload'
import { join } from 'desm'

export default function (opts) {
    const app = fastify(opts)

    app.register(autoload, {
        dir: join(import.meta.url, 'routes')
    })

    return app
}
/routes/hello.js
export default async function (app) {
    app.get('/', async function (req, rep) {
        return { hello: 'world' }
    })
}
@mcollina
Copy link
Member

I have to admit I have not tested that setup on Windows.
Can you please console.log(join(import.meta.url, 'routes'))?

@amis-shokoohi
Copy link
Contributor Author

amis-shokoohi commented Aug 12, 2020

C:\Users\amis\Desktop\fastify3-test\routes

@mcollina
Copy link
Member

Unfortunately I do not know how to fix this. I'm moving this to fastify-autoload as a bug.

I might need some help from a Windows users here.. maybe @StarpTech or @Ethan-Arrowood?

@mcollina mcollina transferred this issue from fastify/help Aug 12, 2020
@mcollina mcollina changed the title fastify-autoload error error with esm on windows Aug 12, 2020
@Eomm
Copy link
Member

Eomm commented Aug 12, 2020

The join from desm is doing this work?

import { dirname } from 'path';
import { fileURLToPath } from 'url';

const __dirname = dirname(fileURLToPath(import.meta.url)); ... path.join(__dirname, 'public'))) ...

@mcollina
Copy link
Member

yes, that's the idea

@amis-shokoohi
Copy link
Contributor Author

I've actually tried that but still getting the same error.
I also went through fastify-autoload/index.js in debug mode, it seemed to work properly.
The problem is with esm. I rewrote it with cjs, it worked. I was just too excited to use esm.

@fox1t
Copy link
Member

fox1t commented Aug 13, 2020

This seems the same as this one nodejs/node#31710
Isn't this by design?
From what I am understanding we need to do the opposite of fileURLToPath (since in ESM context the absolute paths need to start with file://), so we need to use pathToFileURL.

@StarpTech
Copy link
Member

How can I help? Will pathToFileURL solve the issue?

@fox1t
Copy link
Member

fox1t commented Aug 13, 2020

@StarpTech my bad, I am making some test now and import.meta.url indeed has already file://.

@fox1t
Copy link
Member

fox1t commented Aug 13, 2020

@StarpTech if you are a windows user just try to reproduce the issue using the provided apps.mjs and /routes/hello.js
It would be nice to know that is the file value at 117 line on windows.

@StarpTech
Copy link
Member

StarpTech commented Aug 13, 2020

console.log(join(import.meta.url, 'routes')); = "D:\repositories\fastify-autoload\route"

It would be nice to know that is the file value at 117 line on windows.v

D:\repositories\fastify-autoload\routes\hello.mjs

I could fix it with

fastify-autoloader/index.js

  if (type === 'module') {
    content = await import(url.pathToFileURL(file).href)
  } else {
    content = require(file)
  }

app.js

export function dirname(importMeta) {
    return path.dirname(filename(importMeta));
}

export function filename(importMeta) {
    return url.fileURLToPath(importMeta.url);
}

export default function (opts) {
    const app = fastify(opts)

    app.register(autoload, {
        dir: path.join(dirname(import.meta), 'routes')
    })


    return app
}

@fox1t
Copy link
Member

fox1t commented Aug 13, 2020

Nice, as supposed it worked! Now it would be nice to know why it was missing in the first place. Any clouds @mcollina ?

@fox1t
Copy link
Member

fox1t commented Aug 13, 2020

I think that since fastify-plugin handles ESM natively the users doesn't have to use desm package. 🤔

@amis-shokoohi
Copy link
Contributor Author

Oh thanks
So passing C:\...\hello.js to import() rather than file://C:/.../hello.js was the problem?

@mcollina
Copy link
Member

Nice, as supposed it worked! Now it would be nice to know why it was missing in the first place. Any clouds @mcollina ?

No idea. The above code is exactly doing what desm is doing. See

https://github.com/mcollina/desm/blob/master/index.js

@amis-shokoohi
Copy link
Contributor Author

Can I steal @StarpTech code and send a PR? 😄

@mcollina
Copy link
Member

sure. I don't 100% understand the problem, but +1

@StarpTech
Copy link
Member

@amis-shokoohi feel free 😄

amis-shokoohi pushed a commit to amis-shokoohi/fastify-autoload that referenced this issue Aug 13, 2020
@StarpTech
Copy link
Member

StarpTech commented Aug 13, 2020

@mcollina the issue sits not there. We need to pass file URL to await import(), C:\ isn't one.

amis-shokoohi pushed a commit to amis-shokoohi/fastify-autoload that referenced this issue Aug 13, 2020
@mcollina
Copy link
Member

why the heck this works on Mac and Linux then? :)

@StarpTech
Copy link
Member

StarpTech commented Aug 13, 2020

Because in Linux a path is a valid file URL? 🤔

@mcollina
Copy link
Member

Released as v3.0.8!

@StarpTech
Copy link
Member

Indeed, I tried it with WSL2 on Windows and /mnt/d/repositories/fastify-autoload/routes/hello.mjs is a valid file URL 😄 feels like a bug to me in Node.js. It's odd that the API doesn't abstract that behavior.

@fox1t
Copy link
Member

fox1t commented Aug 13, 2020

The Node.js parser takes c: part of the Windows paths as protocol. :/

@mcollina
Copy link
Member

@StarpTech can you open an issue on node core on this and tag me on it? Thanks. This is very confusing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants