Skip to content
This repository has been archived by the owner on Nov 4, 2024. It is now read-only.

Error [ERR_INVALID_PROTOCOL]: Protocol 'node:' not supported. Expected 'file:' #904

Open
msipinski opened this issue Sep 16, 2021 · 5 comments

Comments

@msipinski
Copy link

Problem:

Using esm to import module that imports builtin Node modules using 'node:*' URL results with an error:

file:///C:/NodeJsProjects/esm-error-test/some-external-module.mjs:1
Error [ERR_INVALID_PROTOCOL]: Protocol 'node:' not supported. Expected 'file:'
    at file:///C:/NodeJsProjects/esm-error-test/some-external-module.mjs:1
    at Generator.next (<anonymous>)

Import with 'node:*' type URL lies inside external package so I can't replace it. Switching my project from CJS to ESM is probably not possible (I'm creating Electron.js app).

Reproducing:

some-external-module.mjs:

import process from 'node:process'

export default process.platform

package.json:

{
  "dependencies": {
    "esm": "^3.2.25"
  }
}

index.mjs:

import platform from './some-external-module.mjs'

console.log('mjs: ' + platform)

index.cjs:

require = require('esm')(module)
const platform = require('./some-external-module.mjs')

console.log('cjs: ' + platform)

Running node index.mjs gives expected output ("mjs: win32"), but running node index.cjs results in error

  • esm version: 3.2.25
  • node version: v14.15.3
@ioquatix
Copy link

ioquatix commented Apr 9, 2022

I'm running into the same issue :(

@KittyGiraudel
Copy link

Can confirm this happens as well.

@ItaloCobains
Copy link

I am also having the same problem.

Using esm to import module that imports builtin Node modules using 'node:*' URL results with an error:

Error [ERR_INVALID_PROTOCOL]: Protocol 'node:' not supported. Expected 'file:'
    at Object.<anonymous> (C:\msys64\home\italo\typi\src\main.js:1)
    at Generator.next (<anonymous>)

Reproducing:

src/main.js:

import ncp from "ncp";
import fs from "node:fs";
import { promisify } from "node:util";

const access = promisify(fs.access);
const copy = promisify(ncp);

async function copyTemplateFiles(options) {
    return copy(options.templateDirectory, options.targetDirectory, {
        clobber: false,
    });
}

export async function createProject(options) {
    options = {
        ...options,
        targetDirectory: options.targetDirectory || process.cwd(),
    };

    const currentFileUrl = import.meta.url;
    const templateDir = path.resolve(
        new URL(currentFileUrl).pathname,
        "../../templates",
        options.template.toLowerCase()
    );
    options.templateDirectory = templateDir;

    try {
        await access(templateDir, fs.constants.R_OK);
    } catch (err) {
        console.log("%s Invalid template name", chalk.red.bold("ERROR"));
        process.exit(1);
    }

    console.log("Copy project files");
    await copyTemplateFiles(options);
    console.log("%s Project ready", chalk.green.bold("DONE"));
    return true;
}

src/cli.js:

import arg from "arg";
import inquirer from "inquirer";
import { createProject } from "./main";

function parseArgumentsIntoOptions(rawArgs) {
    const args = arg(
        {
            "--git": Boolean,
            "--test": Boolean,
            "--lint": Boolean,
            "--yes": Boolean,
            "--install": Boolean,
            "-g": "--git",
            "-t": "--test",
            "-l": "--lint",
            "-y": "--yes",
            "-i": "--install",
        },
        {
            argv: rawArgs.slice(2),
        }
    );

    return {
        skipPrompts: args["--yes"] || false,
        git: args["--git"] || false,
        template: args._[0],
        runInstall: args["--install"] || false,
    };
}

async function promptForMissingOptions(options) {
    const defaultTemplate = "TypeScript";
    if (options.skipPrompts) {
        return {
            ...options,
            template: options.template || defaultTemplate,
        };
    }

    const questions = [];
    if (!options.template) {
        questions.push({
            type: "list",
            name: "template",
            message: "Please choose which project template to use",
            choices: ["JavaScript", "TypeScript"],
            default: defaultTemplate,
        });
    }

    if (!options.git) {
        questions.push({
            type: "confirm",
            name: "git",
            message: "Initialize a git repository?",
            default: false,
        });
    }

    const answars = await inquirer.prompt(questions);
    return {
        ...options,
        template: options.template || answars.template,
        git: options.git || answars.git,
    };
}

export async function cli(args) {
    let options = parseArgumentsIntoOptions(args);
    options = await promptForMissingOptions(options);
    await createProject(options);
}

package.json:

{
    
    "dependencies": {
        "arg": "^5.0.2",
        "chalk": "^4.1.2",
        "esm": "^3.2.25",
        "inquirer": "^8.0.0",
        "ncp": "^2.0.0"
    }
}

bin/typi:

#!/usr/bin/env node

require = require("esm")(module /*, options*/);
require("../src/cli").cli(process.argv);

@sandz9b
Copy link

sandz9b commented May 9, 2024

Is there any update related to this issues?
I also got this error (while using an import).

And when I use a require, I got this error while using a "sharp" libraries:
Cannot find module 'node:util'

@xeoshow
Copy link

xeoshow commented Jul 26, 2024

Any latest update for this?
I also met the same problem, hope esm could support it.

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

No branches or pull requests

6 participants