rustyscript icon indicating copy to clipboard operation
rustyscript copied to clipboard

Importing npm modules without `npm:` prefix

Open LukasBombach opened this issue 8 months ago • 1 comments

Is your feature request related to a problem? Please describe. Deno, and by extension rustyscript requires to prefix imports of npm packages with npm:, so for instance

import * as emoji from "npm:node-emoji";

code taken from their npm example

The Code-Editor Support for this is... subpar, enabling this in VS Code with the Deno Plugins lets lose all kinds of developer hell.

Also, not everyone might agree that a required npm: prefix is the right way to go. I myself get the why of it, still, I am used to node's resolve mechanism and I use it day to day in job and hobby projects. While I get why they want to enforce this, I don't necessearily want to do this. Or, for that matter enforce this on my users.

For some projects, this might even come as an impediment.

Describe the solution you'd like

I'd love to have a crate flag to opt-out of the required prefix so that I can "just import the normal way"

import * as emoji from "node-emoji";

Describe alternatives you've considered

The alternatives would be to give no option at all or disable the prefix altogether. I'd vote for a default prefix-enabled (the deno way) because, to my understanding, it is safer and pays respect to deno and an option to opt-out. People who opt-out are at least required to give it some thought if and why they want to do this but are still welcome to give it a go

Additional context

If you are interested I am happy to try and help with this with a PR

LukasBombach avatar Apr 29 '25 14:04 LukasBombach

I tried implementing this with a custom import resolver, but it cannot be done.

The import_provider will be invoked after deno_core::resolve_import

        // Resolve the module specifier to an absolute URL
        let url = deno_core::resolve_import(specifier, referrer)?;

        // Check if the module is in the cache
        if self
            .cache_provider
            .as_ref()
            .is_some_and(|c| c.get(&url).is_some())
        {
            return Ok(url);
        }

        // Check if the import provider allows the import
        if let Some(import_provider) = &mut self.import_provider {
            let resolve_result = import_provider.resolve(&url, referrer, kind);
            if let Some(result) = resolve_result {
                return result;
            }
        }

See inner_loader.rs lines 195-213

So an import like this

import React from "react";

will be handled by deno_core::resolve_import before it reaches my own import_provider and I will get the error

Relative import path "react" not prefixed with / or ./ or ../ from "file:///foo/bartsx"

LukasBombach avatar May 02 '25 16:05 LukasBombach

Unfortunately this is just not how Deno was designed - I must follow their engine's rules for now!

rscarson avatar Aug 16 '25 03:08 rscarson