Deno import, environment variables and code debugging

?Table of Contents

1. Import mapping

Example – Using deno_std’s fmt module via

?edit

Example – absolute import using project root

Override import

Import mapping is available for apps

2. Environment variables

Built-in Deno.env

.env file

std/flags

Special environment variables

3. Debugging code

Chrome Devtools

VSCode


1. Import mapping

In order for Deno to parse a specifier like "react" or "lodash", it needs to be told where to look for "lodash" to refer to npm Module or whether it is mapped to https URL.

import lodash from "lodash";

Node and npm use the pack.json and node_modules folders to perform this parsing. Deno, on the other hand, uses the import mapping standard.

To make the above import lodash from “lodash” work properly, add the following content to the deno.json configuration file.

{
  "imports": {
    "lodash": "https://esm.sh/[email protected]"
  }
}

deno.json files are automatically discovered and act as import maps.

This also works with npm specifiers. In addition to the above, we can also write similar content in the deno.json configuration file:

{
  "imports": {
    "lodash": "npm:lodash@^4.17"
  }
}

Example – using deno_std’s fmt module in the following way

deno.json

{
  "imports": {
    "fmt/": "https://deno.land/[email protected]/fmt/"
  }
}

color.ts

import { red } from "fmt/colors.ts";

console.log(red("hello world"));

Example-using project root for absolute imports

To use the project root for absolute imports:

deno.json

{
  "imports": {
    "/": "./",
    "./": "./"
  }
}

main.ts

import { MyUtil } from "/util.ts";

This will cause import specifiers starting at / to be relative to the import map URL or file path.

overwrite import

Another situation where import mapping is useful is overriding imports in a specific module.

Let’s say you want to override the deno_std import in all modules from 0.177.0 to the latest import, but for the https://deno.land/x/example/ module you want to use the file in the local patched directory. You can do this by using a scope in the import map, like this:

{
  "imports": {
    "https://deno.land/[email protected]/": "https://deno.land/[email protected]/"
  },
  "scopes": {
    "https://deno.land/x/example/": {
      "https://deno.land/[email protected]/": "./patched/"
    }
  }
}

Import mapping applies to applications

It is important to note that importing map configuration files only applies to Deno applications, not the various libraries that application code may import. This gives the application author the final say on which versions of the library are included in the project.

If you are developing a library, you should prefer using the deps.ts pattern discussed in Managing Dependencies.

2. Environment variables

There are several ways to use environment variables in Deno:

Built-in Deno.env

The Deno runtime has built-in support for environment variables.

Deno.env has getter and setter methods. Here is example usage:

Deno.env.set("FIREBASE_API_KEY", "examplekey123");
Deno.env.set("FIREBASE_AUTH_DOMAIN", "firebasedomain.com");

console.log(Deno.env.get("FIREBASE_API_KEY")); // examplekey123
console.log(Deno.env.get("FIREBASE_AUTH_DOMAIN")); // firebasedomain.com
console.log(Deno.env.has("FIREBASE_AUTH_DOMAIN")); // true

.env file

You can also put environment variables in .env files and retrieve them using dotenv in the standard library.

Let’s say you have a .env file that looks like this:

PASSWORD=123456

To access environment variables in a .env file, import the load function from the standard library

import { load } from "https://deno.land/[email protected]/dotenv/mod.ts";

const env = await load();
const password = env["PASSWORD"];

console.log(password);
// "123456"

std/flags

The Deno standard library has a std/tag module for parsing command line arguments.

Special environment variable

The Deno runtime has these special environment variables.

name description
DENO_AUTH_TOKENS Semicolon separated list of bearer tokens and hostnames to use when fetching remote modules from private repositories
(e.g. [email protected];[email protected])
DENO_TLS_CA_STORE Comma separated order of related certificates Storage list.
Possible values: system, mozilla. Defaults to mozilla.
DENO_CERT Load certificate authority from PEM encoded file
DENO_DIR Set cache directory
DENO_INSTALL_ROOT Set the output directory of deno install (defaults to $HOME/.deno/bin)
DENO_REPL_HISTORY Disable the history file when setting the REPL history file path value to empty
(defaults to $DENO_DIR/deno_history.txt)
DENO_NO_PACKAGE_JSON Disable automatic parsing of package.json
DENO_NO_PROMPT Set to disable access prompts
(alternative to passing --no-prompt on invocation)
DENO_NO_UPDATE_CHECK Set to disable checking for updated Deno Versions available
DENO_V8_FLAGS Set V8 command line options
DENO_JOBS The number of parallel jobs with the test subcommand is marked by --parallel
The default is the number of available CPUs
HTTP_PROXY The proxy address of HTTP requests (module downloads, fetch)
HTTPS_PROXY Proxy address for HTTPS requests (module downloads, fetch)
NPM_CONFIG_REGISTRY URL for npm registry .
NO_COLOR Set to disabled color
NO_PROXY Not used Comma separated list of hosts for proxies (module downloads, fetch)

You can also use deno –help to view the same content.

3. Debugging code

Deno supports the V8 inspector protocol used by Chrome, Edge, and Node.js. This makes it possible to debug Deno programs using ChromeDevTools or other clients that support the protocol (such as VSCode).

To activate debugging, run Deno with the –ynch-wait or –execy-brk flag.

The –inspect flag allows the debugger to be attached at any point in time. The –inspect-wait flag will wait for the debugger to attach and start executing code. The --inspect-brk flag will wait for the debugger to attach and start executing code. Pause execution of the first line of code.

If you use the –inspect flag, the code will start executing immediately. If your program is short, you may not have enough time to connect the debugger before the program completes execution. In this case, try running –inspect-wait Or –inspect-brk flag, or add a delay at the end of the code.

Chrome Devtools

Let’s try debugging the program using ChromeDevtools. For this we will use file_server.ts from std, a static file server.

Use –inspect-brk to break execution on the first line:

$ deno run --inspect-brk --allow-read --allow-net https://deno.land/[email protected]/http/file_server.ts

In a Chromium-derived browser, such as Google Chrome or Microsoft Edge, open chrome://inspect, as shown below:

Click Inspect next to the target. After DevTools appears, it will automatically jump to the breakpoint location:

You may notice that DevTools pauses execution on the first line of assert_path.ts instead of file_server.ts. This is expected behavior caused by the way ES modules are evaluated in JavaScript (assert_path.ts, leftmost and bottom, depends on file_server.ts, so it is evaluated first).

Next, add a breakpoint in the dirViewerTemplate method:

Once we add a breakpoint, DevTools automatically opens the source code map file, which allows us to step through the actual source code containing the type.

Now that we have set a breakpoint, we can resume execution of the script so that we can inspect incoming requests. Click the “Resume Script Execution” button to do this. You may even need to click twice!

After running our script, try sending the request and checking it in Devtools:

$ curl http://0.0.0.0:4507/

Or while browsing, open:

VSCode

This extension provides access to the built-in VSCode debugger. You can generate the configuration by going to the Run and Debug panel, click on Create launch.json file and select the Deno option from the available debugger options.

By default, the configuration will use the –inspect-wait flag. If the configured Deno version is greater than 1.29, versions earlier than 1.29 use the –inspect-brk flag. This ensures that the debugger has a chance to connect to your program and register the code. All breakpoints specified in .

?