Skip to content

Commit

Permalink
adding new files for modules in deno
Browse files Browse the repository at this point in the history
  • Loading branch information
thisisjofrank committed Jul 11, 2024
1 parent 7fda994 commit 4ccc6d5
Show file tree
Hide file tree
Showing 3 changed files with 334 additions and 0 deletions.
80 changes: 80 additions & 0 deletions runtime/manual/basics/modules/module_metadata.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
title: "Module Metadata"
oldUrl:
- /runtime/manual/examples/module_metadata/
---

## Concepts

- [import.meta](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import.meta)
can provide information on the context of the module.
- The boolean [import.meta.main](https://deno.land/api?s=ImportMeta#prop_main)
will let you know if the current module is the program entry point.
- The string [import.meta.url](https://deno.land/api?s=ImportMeta#prop_url) will
give you the URL of the current module.
- The string
[import.meta.filename](https://deno.land/api?s=ImportMeta#prop_filename) will
give you the fully resolved path to the current module. _For local modules
only_.
- The string
[import.meta.dirname](https://deno.land/api?s=ImportMeta#prop_dirname) will
give you the fully resolved path to the directory containing the current
module. _For local modules only_.
- The [import.meta.resolve](https://deno.land/api?s=ImportMeta#prop_resolve)
allows you to resolve specifier relative to the current module. This function
takes into account an import map (if one was provided on startup).
- The string [Deno.mainModule](https://deno.land/api?s=Deno.mainModule) will
give you the URL of the main module entry point, i.e. the module invoked by
the deno runtime.

## Example

The example below uses two modules to show the difference between
`import.meta.url`, `import.meta.main` and `Deno.mainModule`. In this example,
`module_a.ts` is the main module entry point:

```ts title="module_b.ts"
export function outputB() {
console.log("Module B's import.meta.url", import.meta.url);
console.log("Module B's mainModule url", Deno.mainModule);
console.log(
"Is module B the main module via import.meta.main?",
import.meta.main,
);
}
```

```ts title="module_a.ts"
import { outputB } from "./module_b.ts";

function outputA() {
console.log("Module A's import.meta.url", import.meta.url);
console.log("Module A's mainModule url", Deno.mainModule);
console.log(
"Is module A the main module via import.meta.main?",
import.meta.main,
);
console.log(
"Resolved specifier for ./module_b.ts",
import.meta.resolve("./module_b.ts"),
);
}

outputA();
console.log("");
outputB();
```

If `module_a.ts` is located in `/home/alice/deno` then the output of
`deno run --allow-read module_a.ts` is:

```console
Module A's import.meta.url file:///home/alice/deno/module_a.ts
Module A's mainModule url file:///home/alice/deno/module_a.ts
Is module A the main module via import.meta.main? true
Resolved specifier for ./module_b.ts file:///home/alice/deno/module_b.ts

Module B's import.meta.url file:///home/alice/deno/module_b.ts
Module B's mainModule url file:///home/alice/deno/module_a.ts
Is module B the main module via import.meta.main? false
```
89 changes: 89 additions & 0 deletions runtime/manual/basics/modules/publishing_modules.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
---
Title: Publishing Modules
---

Any Deno program that defines an export can be published as a module. This
allows other developers to import and use your code in their own projects.
Modules can be published to [JSR](https://jsr.io).

## Configuring your module

To configure your module for publishing, you need to ensure you have the
following properties defined in a `deno.json` file at the root of your project:

```json title="deno.json"
{
"name": "@my-scope/my-module",
"version": "1.0.0",
"exports": "./mod.ts"
}
```

In order to publish, you need a
[JSR scope and a new package](https://jsr.io/docs/publishing-packages#creating-a-scope-and-package)
to identify your module. You can create your scope and package at
[jsr.io/new](https://jsr.io/new).

The `name` property in your `deno.json` file is a concatenation of your scope
and package name, separated by a `/`. The `exports` property should point to the
main entry point of your module.

## Publishing your module

Packages can be published to JSR in the CLI with the
[`deno publish` command](https://jsr.io/docs/publishing-packages#publishing-from-your-local-machine).

To publish your module, run the following command in the root of your project:

```bash
deno publish
```

Before publishing, you can use the `--dry-run` flag locally to test the
publishing process, without actually publishing your module. This will print out
a list of all of the files that will be published and can be used to verify that
your module is set up correctly:

```bash
deno publish --dry-run
```

By default, interactive authentication is used to publish - this means that a
browser window will open to authenticate you with JSR. If you want to publish
without the interactive browser window, you can use the `--token` flag to
provide a JSR auth token:

```bash
deno publish --token <your-auth-token>
```

You can create a new auth token at
[jsr.io/account/tokens](https://jsr.io/account/tokens).

If you're configuring a CI pipeline to publish your module, you can use the
`--token` flag to authenticate with JSR but it's important to ensure that your
token is kept secure.

If you're publishing a package from GitHub Actions it is recommended to link
your repository by following the instructions at
[jsr.io/docs/publishing-packages#publishing-from-github-actions](https://jsr.io/docs/publishing-packages#publishing-from-github-actions).
This will allow you to publish packages without needing to provide an auth token
and instead uses OIDC authentication from GitHub itself.

## Other publishing methods

You can publish your modules from the browser at
[jsr.io/new](https://jsr.io/new).

## Publishing for Node

Library authors may want to make their Deno modules available to Node.js users.
This is possible by using the [dnt](https://github.com/denoland/dnt) build tool.

dnt allows you to develop your Deno module mostly as-is and use a single Deno
script to build, type check, and test an npm package in an output directory.
Once built, you only need to `npm publish` the output directory to distribute it
to Node.js users.

For more details, see
[https://github.com/denoland/dnt](https://github.com/denoland/dnt).
165 changes: 165 additions & 0 deletions runtime/manual/basics/modules/remote_modules.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
# Using Remote Modules with Deno

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
{
"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`

```bash
$ deno add @scopename/mypackage
Add @scopename/mypackage - jsr:@scopename/mypackage@^16.1.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`.

## Using Imported Packages

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.

```ts title="mod.ts"
import { someFunction } from "@scopename/mypackage";

someFunction();
```

## Package Registries

Deno recommends that you use [JSR](https://jsr.io/), the JavaScript registry, to
publish and manage your modules for the best publishing experience. JSR offers
automatic documentation generation, semver resolution and improved performance
for TypeScript code. Deno also supports
[other platforms](https://jsr.io/docs/other-registries) for publishing modules,
such as npm, and JavaScript CDNs like deno.land/x, esm.h and unpkg.com

By default when you use the CLI, the package will be resolved from JSR.

```bash
deno add @scopename/mypackage
```

The resulting import map contains the `jsr:` import specifier in the resulting
`deno.json` file.

```json
{
"imports": {
"@scopename/mypackage": "jsr:@scopename/mypackage@^16.1.0"
}
}
```

## Importing from other package registries

Using existing packages from registries like `npm` is equivalent to the
experience in `node`. To add a package from `npm` you need to prefix the package
name with the `npm:` specifier:

```bash
$ deno add npm:uuid
Add uuid - npm:uuid@^10.0.0
```

The resulting `deno.json` will look like this:

```json
{
"imports": {
"uuid": "npm:uuid@^10.0.0"
}
}
```

You will then be able to use the `npm` module by importing it with the name from
the import map.

```ts title="mod.ts"
import * as uuid from "uuid";

console.log(uuid.v4());
```

### Supported package registries and specifiers

We support the following registries:

| Registry | Specifier |
| -------- | --------- |
| JSR | jsr: |
| npm | npm: |

## Understanding Package Versions

When using Deno add, you can specify a version range for the package you are
adding. This is done using the `@` symbol followed by a version range specifier,
and follows the [semver](https://semver.org/) versioning scheme.

```bash
deno add @scopename/mypackage # latest version
deno add @scopename/[email protected] # exact version
deno add @scopename/mypackage@^16.1.0 # latest patch version 16.x
deno add @scopename/mypackage@~16.1.0 # latest version that doesn't increment the first non-zero portion
```

## Importing by URL

Deno also supports import statements that reference URLs, either directly:

```js
import { Application } from "https://deno.land/x/oak/mod.ts";
```

or part of your `deno.json` import map:

```json
{
"imports": {
"oak": "https://deno.land/x/oak/mod.ts"
}
}
```

Supporting URL imports enables us to support the following JavaScript CDNs, as
they provide URL access to JavaScript modules:

- [deno.land/x](https://deno.land/x)
- [esm.h](https://esm.sh)
- [unpkg.com](https://unpkg.com)

URL imports are useful if you have a small, often single file, Deno project that
doesn't require any other configuration because you can avoid having a
`Deno.json` file at all. It's not advised to use this style of import in larger
applications as you may end up with version conflicts (where different files use
different version specifiers).

From a security perspective, the contents of files at URLs can change, so we do
not generally recommend this approach for third-party components.

URL imports remain supported, **but we recommend using a package registry for
the best experience.**

## Proxies

Deno supports proxies for module downloads and the Web standard `fetch` API.

Proxy configuration is read from environmental variables: `HTTP_PROXY`,
`HTTPS_PROXY` and `NO_PROXY`.

In case of Windows, if environment variables are not found Deno falls back to
reading proxies from registry.

0 comments on commit 4ccc6d5

Please sign in to comment.