Skip to content

Add support for URI style import #35749

Description

Search Terms

browser es module import url

Suggestion

Related issues: #28985, #19942

In browser and deno, import from a "package" is different from the node style.

// it's valid in browser but not in TypeScript
import lodash from "https://unpkg.com/[email protected]/lodash.js";

// it's valid in deno but not in TypeScript
import { serve } from "https://deno.land/[email protected]/http/server.ts";

Currently there is no way to let TypeScript automatically map the URI to another place like @types/* or $DENO_DIR/deps/https/deno.land/*

The current path can map a simple pattern of import module specifier to another place, but in the URI style import, a more flexible way to map the URI is required.

Proposal

(maybe add a new moduleResolution: browser)
Add a new uriPaths that allows to map from a RegExp to a local path. It will NOT effect the emitted code. Just a way to find the type definition for those URIs.

I'm willing to implement this feature but I'm not sure if TypeScript will accept this.

Use Cases

For TypeScript to find definition file for imports like https://unpkg.com/lodash

Examples

{
  "compilerOptions": {
    "uriPaths": {
      "https://unpkg.com/(.+?)@.+?/.+": "./node_modules/@types/$1",
      "https://deno.land/(.+?)@v.+?/(.+?)/(.+)": "$DENO_DIR/deps/https/deno.land/$1/$2/$3",
      "std:(.+)": "./node_modules/builtin-module-types/$1"
    }
  }
}

This rule map https://unpkg.com/[email protected]/lodash.js to @types/lodash-es

Map https://deno.land/[email protected]/http/server.ts to $DENO_DIR/deps/https/deno.land/std/http/server.ts.

$DENO_DIR is an environment variable.
By default, on Windows, it's ~\AppData\Local\deno\deps\https\deno.land\std\http\server.ts.
By default on Linux, it is ~/.deno/deps/https/deno.land/std/http/server.ts.

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.

Activity

  1. Jack-Works commented on Dec 18, 2019

    @Jack-Works
    ContributorAuthor

    Related: #35589

    If you find yourself trying to write a valid runtime path, and can't get TypeScript to understand how to resolve that path to the target module, tell us about it.
    -- From Ryan Cavanaugh (@RyanCavanaugh)


    Hi xlaywan, Bruce Pascoe (@fatcerberus), Micah Zoltu (@MicahZoltu), Andrew Branch (@andrewbranch)
    Please move from #35163 to here!


    Hi Vladimir Matveev (@vladima) you implemented the current compilerOptions.paths feature in the TypeScript, how do you think about this issue?

  2. NemoStein commented on Aug 17, 2020

    @NemoStein

    Please, don't let this issue die.

    VSCode depends on TS to resolve JS modules definitions.
    The ability to import a package from a remote server and still have access to intellisense is essential to modern day web development.

  3. hybrist commented on Nov 30, 2020

    @hybrist

    This issue seems to focus on loading / using HTTP URLs. I created a more targeted issue to just support import by URL in general, without supporting module locations beyond what TS already supports today (#41730).

  4. ExE-Boss commented on Nov 30, 2020

    @ExE-Boss
    Contributor

    Also, Node v14.13.1+ supports the node: prefix for importing built‑in modules.

  5. newtack commented on Dec 13, 2020

    @newtack

    This is also needed for Deno. Typescript mission is a superset of JavaScript and JavaScript does support loading from url/fully qualified file name (including .ts extension).

    Can you please add this?

  6. MMK21Hub commented on Mar 25, 2021

    @MMK21Hub

    This also applies to importing from https://cdn.skypack.dev using Snowpack. At the moment, I have to add @ts-ignore whenever I want to use a package. Hopefully, 'Next Meeting' is soon.

  7. Jack-Works commented on Mar 25, 2021

    @Jack-Works
    ContributorAuthor

    And another thing to mention, webpack 5 (or rollup?) supports the mix usage of Node style import and URI style import. They can bundle the Node style import and leave the URI import to the runtime so we must not split Node&URI style into two conflict parts.

  8. AngelMunoz commented on Nov 17, 2021

    @AngelMunoz

    This feature would be useful for tooling that doesn't depend on node since VSCode still uses typescript to type check files we can leverage URI style imports specially now that import maps are in the play.

    In my case I'm providing a dev server that uses URL imports for dependencies + import maps this works just fine, but typescript projects get errors on some dependencies but as Mish (@MMK21Hub) mentioned I could make the tooling grab the types from skypack and provide them to typescript in a particular *.d.ts file or in the types property in tsconfig.json

  9. niieani commented on Feb 3, 2022

    @niieani

    Node 18 is coming out with support for https:// imports, making this even more pressing.

  10. tzvc commented on Aug 15, 2022

    @tzvc

    Any updates on this?

  11. iansinnott commented on Jan 31, 2023

    @iansinnott

    Have people tried declaring the ESM URL and manually exporting the types:

    yarn add --dev @types/lodash-es
    
    // src/types.ts
    declare module "https://unpkg.com/[email protected]/lodash.js" {
      export * from "@types/lodash-es";
    }
    
    // src/my_other_file.ts
    import lodash from "https://unpkg.com/[email protected]/lodash.js";
  12. jimmywarting commented on Jan 31, 2023

    @jimmywarting
    Contributor

    Ian Sinnott (@iansinnott) that unminified lodash source includes jsdoc so you shouldn't have to declare the types for it.

    one solution is to use the https://marketplace.visualstudio.com/items?itemName=denoland.vscode-deno extension that can import the types from remote urls

  13. mariusGundersen commented on Jan 16, 2024

    @mariusGundersen

    It's 2024 and it's still not possible to do

    //main.mjs
    import { opneDB } from 'https://unpkg.com/[email protected]/build/index.js';
    
    openDB(
    

    and get intellisense in vscode. It's really unfortunate that TypeScript and VSCode requires installing modules and bundling them in order to get any help. It should be possible to use esmodules without any bundling.

  14. MicahZoltu commented on Jan 16, 2024

    @MicahZoltu

    It should be possible to use esmodules without any bundling.

    For clarity, bundling is not required, but vendoring is. Your dependencies must be available on local disk at compile time. All of my web and Node projects use native ES modules without any bundling, minification, or obfuscation. I do have a build script that copies dependencies into my app though.

  15. mariusGundersen commented on Jan 16, 2024

    @mariusGundersen

    So the problem is that TypeScript, unlike the runtime, is unable to load modules over the network?

  16. MicahZoltu commented on Jan 18, 2024

    @MicahZoltu

    Not all JS runtimes can import from a URI. I don't believe NodeJS can, for example.

  17. mariusGundersen commented on Jan 18, 2024

    @mariusGundersen

    It is supported behind an experimental flag, which means it will be supported. https://nodejs.org/api/esm.html#https-and-http-imports

    The argument "Not all JS runtimes can import from a URI" is not valid, as not all runtimes can import from filesystems. Browsers for example will not do module resolution like node does, so why is TypeScript doing it? A browser will look at the presented path and that path only, it will not try to load with various extensions or in various parent folders.

  18. MicahZoltu commented on Jan 18, 2024

    @MicahZoltu

    Ah, I didn't realize Node was adding URI support.

    I personally think this is a bad idea from a security standpoint, and I always advise everyone to load all scripts from the same server as the main page, but this is a very opinionated position so I can appreciate that not everyone agrees.

  19. louwers commented on Apr 2, 2024

    @louwers

    For people watching this, esm.sh released a VS Code extension that allows this: https://marketplace.visualstudio.com/items?itemName=ije.esm-vscode

    Edit: Also Skypack has a guide here: https://docs.skypack.dev/skypack-cdn/code/javascript#using-skypack-urls-in-typescript

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    In DiscussionNot yet reached consensusSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions