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 [ERR_INVALID_PROTOCOL]: Protocol 'node:' not supported. Expected 'file:' #904

Open
msipinski opened this issue Sep 16, 2021 · 3 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);

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

No branches or pull requests

4 participants