-
Notifications
You must be signed in to change notification settings - Fork 190
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
cbbd02f
commit f47988d
Showing
2 changed files
with
101 additions
and
141 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,70 +4,65 @@ oldUrl: /runtime/manual/basics/modules/import_maps/ | |
--- | ||
|
||
In order for Deno to resolve a _bare specifier_ like `"react"` or `"lodash"`, it | ||
needs to be told where to look for it. Does `"lodash"` refer to an npm module or | ||
does it map to an https URL? | ||
needs to be told where to look for it. Does `"lodash"` refer to an module in our | ||
project or does it refer to a third party dependency? Deno needs to know where | ||
to resolve the import specifier `lodash` to. | ||
|
||
```ts | ||
import lodash from "lodash"; | ||
``` | ||
|
||
Node and npm use `package.json` and the `node_modules` folder to do this | ||
resolution. Deno, on the other hand, uses the | ||
[import map](https://github.com/WICG/import-maps) standard. | ||
|
||
To make the above `import lodash from "lodash"` work, add the following to the | ||
[`deno.json` configuration file](../getting_started/configuration_file.md). | ||
We can point Deno to the `lodash` package on npm, for example, by adding it to | ||
the `"imports"` section in `deno.json`. | ||
|
||
```json | ||
{ | ||
"imports": { | ||
"lodash": "https://esm.sh/[email protected].21" | ||
"lodash": "npm:lodash@^4.17" | ||
} | ||
} | ||
``` | ||
|
||
The `"imports"` section in `deno.json` is often referred to as an `import map` | ||
that is based on the | ||
[Import Maps Standard](https://github.com/WICG/import-maps). | ||
|
||
You may have seen Node and npm use `package.json` and the `node_modules` folder | ||
to do similar package resolution. | ||
|
||
The `deno.json` file is auto-discovered and acts (among other things) as an | ||
import map. | ||
[Read more about `deno.json` here](../getting_started/configuration_file.md). | ||
|
||
This also works with npm specifiers. Instead of the above, we could have also | ||
written something similar in our `deno.json` configuration file: | ||
|
||
```json | ||
{ | ||
"imports": { | ||
"lodash": "npm:lodash@^4.17" | ||
} | ||
} | ||
``` | ||
|
||
## Example - Using the Deno Standard Library | ||
|
||
Running the following: | ||
Using third party modules is explained further in | ||
[ECMAScript Modules](./modules/). | ||
|
||
```bash | ||
deno add @std/foo | ||
``` | ||
## Custom path mappings | ||
|
||
Produces the following: | ||
The import map in `deno.json` can be used for more general path mapping of | ||
specifiers. You can map an exact specifiers to a third party module or a file | ||
directly, or you can map a part of an import specifier to a directory. | ||
|
||
```json title="deno.json" | ||
```jsonc title="deno.jsonc" | ||
{ | ||
"imports": { | ||
"@std/foo": "jsr:@std/foo@^1.2.3" | ||
// Map to an exact file | ||
"foo": "./some/long/path/foo.ts", | ||
// Map to a directory, usage: "bar/file.ts" | ||
"bar/": "./some/folder/bar/" | ||
} | ||
} | ||
``` | ||
|
||
The import can then be used in your script: | ||
Usage: | ||
|
||
```ts title="bar.ts" | ||
import { bar } from "@std/foo"; | ||
|
||
bar(1, 2); | ||
```ts | ||
import * as foo from "foo"; | ||
import * as bar from "bar/file.ts"; | ||
``` | ||
|
||
## Example - Using project root for absolute imports | ||
Path mapping of import specifies is commonly used in larger code bases for | ||
brevity. | ||
|
||
To use your project root for absolute imports: | ||
|
||
|
@@ -86,37 +81,3 @@ import { MyUtil } from "/util.ts"; | |
|
||
This causes import specifiers starting with `/` to be resolved relative to the | ||
import map's URL or file path. | ||
|
||
## Overriding imports | ||
|
||
The other situation where import maps can be very useful is to override imports | ||
in specific modules. | ||
|
||
Let's say you want to override a Deno Standard Library package import from | ||
^1.2.3 to the latest in all of your imported modules, but for the | ||
`https://deno.land/x/example/` module you want to use files in a local `patched` | ||
directory. You can do this by using a scope in the import map that looks | ||
something like this: | ||
|
||
```json | ||
{ | ||
"imports": { | ||
"@std/foo": "jsr:@std/foo@^1.2.3" | ||
}, | ||
"scopes": { | ||
"https://deno.land/x/example/": { | ||
"@std/foo": "./patched/mod.ts" | ||
} | ||
} | ||
} | ||
``` | ||
|
||
## Import Maps are for Applications | ||
|
||
It is important to note that import map configuration files are | ||
[only applied for Deno applications][scope], not in the various libraries that | ||
your application code may import. This lets you, the application author, have | ||
final say about what versions of libraries get included in your project. | ||
|
||
[scope]: https://github.com/WICG/import-maps#scope | ||
[Environment Variables]: /runtime/manual/basics/env_variables/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,114 +2,86 @@ | |
title: "ECMAScript Modules in Deno" | ||
--- | ||
|
||
## Concepts | ||
|
||
- [import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) | ||
allows you to include and use modules held elsewhere, on your local file | ||
system or remotely. | ||
- [export](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export) | ||
allows you to specify which parts of your module are accessible to users who | ||
import your module. | ||
|
||
## Overview | ||
|
||
Deno by default standardizes the way modules are imported in both JavaScript and | ||
TypeScript using the ECMAScript 6 `import/export` standard. | ||
|
||
It adopts browser-like module resolution, meaning that file names must be | ||
specified in full. You may not omit the file extension and there is no special | ||
handling of `index.js`. | ||
|
||
```js | ||
import { add, multiply } from "./arithmetic.ts"; | ||
``` | ||
|
||
Dependencies are also imported directly, there is no package management | ||
overhead. Local modules are imported in exactly the same way as remote modules. | ||
As the examples show below, the same functionality can be produced in the same | ||
way with local or remote modules. | ||
|
||
## Local Import | ||
|
||
In this example the `add` and `multiply` functions are imported from a local | ||
`arithmetic.ts` module. | ||
|
||
**Command:** `deno run local.ts` | ||
TypeScript using the | ||
[ECMAScript module standard](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules). | ||
In line with this standard, **file names must be specified in full**. You should | ||
not omit the file extension and there is no special handling of `index.js`. | ||
|
||
```ts | ||
import { add, multiply } from "./arithmetic.ts"; | ||
|
||
function totalCost(outbound: number, inbound: number, tax: number): number { | ||
return multiply(add(outbound, inbound), tax); | ||
} | ||
|
||
console.log(totalCost(19, 31, 1.2)); // 60 | ||
console.log(totalCost(45, 27, 1.15)); // 82.8 | ||
// Always include the file extension | ||
import { add } from "./calc.ts"; | ||
``` | ||
|
||
## Export | ||
## Importing modules | ||
|
||
In the local import example above the `add` and `multiply` functions are | ||
imported from a locally stored arithmetic module. To make this possible the | ||
functions stored in the arithmetic module must be exported. | ||
In this example the `add` function is imported from a local `calc.ts` module. | ||
|
||
To do this just add the keyword `export` to the beginning of the function | ||
signature as is shown below. | ||
|
||
```ts | ||
```ts title="calc.ts" | ||
export function add(a: number, b: number): number { | ||
return a + b; | ||
} | ||
``` | ||
|
||
export function multiply(a: number, b: number): number { | ||
return a * b; | ||
} | ||
```ts title="main.ts" | ||
import { add } from "./calc.ts"; | ||
|
||
console.log(add(1, 2)); // 3 | ||
``` | ||
|
||
All functions, classes, constants and variables which need to be accessible | ||
inside external modules must be exported. Either by prepending them with the | ||
`export` keyword or including them in an export statement at the bottom of the | ||
file. | ||
You can run this example by calling `deno run main.ts` in the directory that | ||
contains `main.ts` and `calc.ts`. | ||
|
||
## Using third party modules and libraries with Deno | ||
## Adding third party modules and libraries to deno.json | ||
|
||
Using remote modules (downloaded from a registry) in Deno uses the same `import` | ||
syntax as your local code. | ||
|
||
The modules that you add to your project are tracked as `imports` in | ||
`deno.json` - we call this the import map. | ||
|
||
```json | ||
```json title="deno.json" | ||
{ | ||
"tasks": { | ||
"dev": "deno run --watch main.ts" | ||
}, | ||
"imports": { | ||
"@scopename/mypackage": "jsr:@scopename/mypackage@^16.1.0" | ||
} | ||
} | ||
``` | ||
|
||
You can add modules using the `Deno CLI` subcommand `deno add` | ||
You can add modules using the `deno add` subcommand: | ||
|
||
```bash | ||
$ deno add @scopename/mypackage | ||
Add @scopename/mypackage - jsr:@scopename/mypackage@^16.1.0 | ||
```sh | ||
# Add the latest version of the module to deno.json | ||
$ deno add @luca/cases | ||
Add @luca/cases - jsr:@luca/cases@^1.0.0 | ||
``` | ||
|
||
Deno add will automatically add the latest version of the module you requested | ||
to your project imports. If you're coming from the `node` ecosystem, this is | ||
equivalent to `npm install PACKAGE --save`. | ||
```json title="deno.json" | ||
{ | ||
"imports": { | ||
"@luca/cases": "jsr:@luca/cases@^1.0.0" | ||
} | ||
} | ||
``` | ||
|
||
## Using Imported Packages | ||
The `deno add` command will automatically add the latest version of the module | ||
you requested to your project imports, unless you specify an exact version: | ||
|
||
```sh | ||
# Passing an exact version | ||
$ deno add @luca/[email protected] | ||
Add @luca/cases - jsr:@luca/cases@^1.0.0 | ||
``` | ||
|
||
## Using installed modules | ||
|
||
Once a package is added to the import map in `deno.json`, you can import the | ||
module by its name, and Deno will automatically resolve the module. | ||
module by its name, and Deno will automatically resolve the module. For example: | ||
|
||
```ts title="mod.ts" | ||
import { someFunction } from "@scopename/mypackage"; | ||
```ts title="main.ts" | ||
import { camelCase } from "@luca/cases"; | ||
|
||
someFunction(); | ||
camelCase("hello world"); // "helloWorld" | ||
``` | ||
|
||
## Package Registries | ||
|
@@ -227,6 +199,33 @@ not generally recommend this approach for third-party components. | |
URL imports remain supported, **but we recommend using a package registry for | ||
the best experience.** | ||
|
||
### Overriding URL imports | ||
|
||
The other situation where import maps can be very useful is to override URL | ||
imports in specific modules. | ||
|
||
Let's say you want to override a `https://deno.land/x/[email protected]/mod.ts` | ||
specifier that is used inside files coming from `https://deno.land/x/example/` | ||
to a local patched version. You can do this by using a scope in the import map | ||
that looks something like this: | ||
|
||
```json | ||
{ | ||
"imports": { | ||
"example/": "https://deno.land/x/example/" | ||
}, | ||
"scopes": { | ||
"https://deno.land/x/example/": { | ||
"https://deno.land/x/[email protected]/mod.ts": "./patched/mod.ts" | ||
} | ||
} | ||
} | ||
``` | ||
|
||
_It is important to note that URL imports have no notion of packages. Only the | ||
import map at the root of your project is used. Import maps used inside URL | ||
dependencies are ignored._ | ||
|
||
## Proxies | ||
|
||
Deno supports proxies for module downloads and the Web standard `fetch` API. | ||
|