D
Deno

help

Using esbuild with import maps

Kkeb9/16/2023
Hello 👋 I'm attempting to migrate one of my front-end projects to using Deno for tooling instead of Node. The setup is very simple; my frontend code lives in src/ and should be bundled by esbuild and output to dist/. I'd like to use import maps to keep my front-end code easy to read, so for example, in my frontend code I have an import that looks like import { m } from 'umai'; and then in my deno.json file I have:
"imports": {
"std/": "https://deno.land/std@0.201.0/",
"umai": "https://deno.land/x/umai@0.2.4/index.js",
"esbuild": "https://deno.land/x/esbuild@v0.19.3/mod.js"
}
"imports": {
"std/": "https://deno.land/std@0.201.0/",
"umai": "https://deno.land/x/umai@0.2.4/index.js",
"esbuild": "https://deno.land/x/esbuild@v0.19.3/mod.js"
}
However, when I try running my esbuild build script, I get this error:
✘ [ERROR] Could not resolve "umai"

src/Apps.js:1:26:
1 │ import { m } from 'umai';
╵ ~~~~~~
✘ [ERROR] Could not resolve "umai"

src/Apps.js:1:26:
1 │ import { m } from 'umai';
╵ ~~~~~~
Which seems to imply that while Deno can resolve import maps, esbuild cannot. Has anyone figure out a way around this? My best guess is that I'll need to implement an esbuild plugin that will resolve the paths at build time to their ESM url counterparts So like rewrite umai -> https://deno.land/x/umai@0.2.4/index.js at build time. Although I'm not sure if that would even work 🤔 I wish Deno just took care of this somehow gonna give it a shot and report back OK yeah esbuild doesn't like that. I guess because it doesn't want HTTP urls as paths
Plugin "import-map" returned a non-absolute path: https://deno.land/x/umai@0.2.4/index.js (set a namespace if this is not a file path)

src/components.js:1:18:
1 │ import { m } from 'umai';
╵ ~~~~~~
Plugin "import-map" returned a non-absolute path: https://deno.land/x/umai@0.2.4/index.js (set a namespace if this is not a file path)

src/components.js:1:18:
1 │ import { m } from 'umai';
╵ ~~~~~~
DAHDeno AI Helper9/16/2023
Based on the documentation, Deno does support import maps which allow you to use bare specifiers like "umai" in your code. However, it seems like esbuild, the tool you're using to bundle your code, is not able to resolve these bare specifiers using Deno's import map. The documentation does not provide a direct solution for this issue. It's important to note that the output of deno bundle is intended for consumption in Deno and not for use in a web browser or other runtimes. If you wish to bundle for the web, the documentation recommends other solutions such as esbuild, but it does not provide specific guidance on how to use esbuild with Deno's import maps. As a general advice (which is not in the documentation), you might need to configure esbuild to understand Deno's import maps, or use a plugin if one exists. If esbuild does not support Deno's import maps, you might need to use the full URLs in your import statements when you're bundling your code with esbuild. Remember to always refer to the official esbuild and Deno documentation or their respective communities for the most accurate and up-to-date information. 🦕
IioB9/16/2023
please send code I’m assuming you’re using esbuild_deno_loader? If so there’s a config option that you can set to handle this for you
Kkeb9/16/2023
I was using only esbuild. I'm not near my PC right now, but will send when I have the chance. Is there a way to use esbuild with deno without esbuild_deno_loader while still using third party packages in your source?
IioB9/16/2023
unless you’re willing to recreate the plugin, unfortunately not the default loader doesn’t work with http imports, and it definitely doesn’t work with import maps
Kkeb9/17/2023
that's a bummer I'll take a look at the loader. Thanks for clarifying.
IioB9/17/2023
definitely a bummer hopefully the esbuild folks take deno support more seriously in the future
ABAltair 680b9/17/2023
This has always worked for me. Even when a deps.ts includes external http imports.
export * as esbuild from "https://deno.land/x/esbuild@v0.17.11/mod.js";
export { denoPlugin } from "https://deno.land/x/esbuild_deno_loader@0.6.0/mod.ts";

const buildConfig = {
Out: "dist",
FileName: "bundle.js",
Entry: ["./src/main.ts"],
Minify: false
}

/**
* builds and bundles an entrypoint into a single ESM output.
* @param {Config} cfg - the configuration to build from, object that contains:
* - Out: string - the folder to place the bundle in (defaults to 'dist')
* - Entry: string[] - the entry points to build from (defaults to ["./src/main.ts"])
* - Minify: boolean - whether or not to minify the bundle
*/
export async function buildIt( buildConfig = {
Out: "dist",
FileName: "bundle.js",
Entry: ["./src/main.ts"],
Minify: false
} ) {
console.log(`Bundling ${cfg.Entry} to ${cfg.Out} - minified = ${cfg.Minify}`)
await esbuild.build({
// @ts-ignore: outdated types
plugins: [denoPlugin({})],
entryPoints: cfg.Entry,
outfile: cfg.Out,
bundle: true,
minify: cfg.Minify,
keepNames: true,
banner: { js: '// deno-lint-ignore-file' },
format: "esm"
}).catch((e) => console.info(e));
esbuild.stop();
}
export * as esbuild from "https://deno.land/x/esbuild@v0.17.11/mod.js";
export { denoPlugin } from "https://deno.land/x/esbuild_deno_loader@0.6.0/mod.ts";

const buildConfig = {
Out: "dist",
FileName: "bundle.js",
Entry: ["./src/main.ts"],
Minify: false
}

/**
* builds and bundles an entrypoint into a single ESM output.
* @param {Config} cfg - the configuration to build from, object that contains:
* - Out: string - the folder to place the bundle in (defaults to 'dist')
* - Entry: string[] - the entry points to build from (defaults to ["./src/main.ts"])
* - Minify: boolean - whether or not to minify the bundle
*/
export async function buildIt( buildConfig = {
Out: "dist",
FileName: "bundle.js",
Entry: ["./src/main.ts"],
Minify: false
} ) {
console.log(`Bundling ${cfg.Entry} to ${cfg.Out} - minified = ${cfg.Minify}`)
await esbuild.build({
// @ts-ignore: outdated types
plugins: [denoPlugin({})],
entryPoints: cfg.Entry,
outfile: cfg.Out,
bundle: true,
minify: cfg.Minify,
keepNames: true,
banner: { js: '// deno-lint-ignore-file' },
format: "esm"
}).catch((e) => console.info(e));
esbuild.stop();
}
You can see the application of it in my dev-server Hot! https://github.com/nhrones/Hot
Kkeb9/17/2023
it looks like main.ts doesn't include any external dependencies in your example
ABAltair 680b9/17/2023
The following was used as a test. Note that the external https dependency was bundled properly!
// src/main.ts

import { VERSION }from "https://deno.land/std@0.201.0/version.ts";
console.log('ver. ', VERSION)
// src/main.ts

import { VERSION }from "https://deno.land/std@0.201.0/version.ts";
console.log('ver. ', VERSION)
bundles to --
// /dist/bundle.js

// deno-lint-ignore-file

// https://deno.land/std@0.201.0/version.ts
var VERSION = "0.201.0";

// src/main.ts
console.log("ver. ", VERSION);
// /dist/bundle.js

// deno-lint-ignore-file

// https://deno.land/std@0.201.0/version.ts
var VERSION = "0.201.0";

// src/main.ts
console.log("ver. ", VERSION);
Kkeb9/17/2023
interestingggg I'll give that a shot
ABAltair 680b9/17/2023
All of my personal projects use either Hot, or another utility I use called BuildIt. Most of them have many external dependencies. I've never had an issue. These tools are Deno-installed locally. I only need to call them on the command line when needed. If I need to bundle a lib, I just type build on the terminal in the root. If I'm working on a web-app, I just type Hot in the root. I've even bundled Deno-Desktop apps that include native code with this utility. My DWM-ReactiveUI framework creates nice little desktop apps using only Deno-TS code.

Looking for more? Join the community!

Recommended Posts
proxy-agent not working on Deno DeployI'm trying to use a proxy for the node-fetch requests in a deno app. I chose proxy-agent npm packagExtremely high CPU usage in Windows running on Intel Pentium processorI have a simple app (about 300 lines of code, few deps). I compile it into a Windows executable. WheImpossible to use `"jsx": "preserve"` in deno.json...Well it seems that I can't use jsx preserve in deno.json, when I try to run any tasks in deno.json, integrating deno_webOk I seem to have poobrain today. Can't seem to get the deno_web extension working. The core versioCan I use Workers in an executable ?Everything is in the questions, on the doc site, it is mention that we can't use Workers when creatiWalkSync dosnt get filesIm trying to read all files of a folder with WalkSync from the deno STD libary but it dosnt see thedeno behaving differently in local dev env and production docker buildsI'm currently trying to switch from using node+yarn 2 for my blogs static files to deno. however theFront end dev needed for 6 months.Hello. I am in need of a frontend developer. dm me pls.Include platform and version in compiled binary filenameRight now when i run `deno compile --output bin/myprogram`, it works as expected. Is is possible to How to handle a user abort by Deno.serveHello, I have a question and discovered this Discord channel now. The Deno website has an example atAPI hooks during restart for deno run --watchHello! I thought it would be super fun to further minimize repetitive tasks while manually testing adeno compile -A npm:cowsay not workingHello, I am trying `deno compile -A npm:cowsay` and then following that with `./cowsay Hello World!`compiling issue with import { WebSocketServer } from "npm:ws@^8.14.1"Using this impot in a "deno run --unstable [etc...]" env works flawless / as intended but trying to Is there any way to get Deno to not statically analyze import()?I understand that statically analyzing and fetching dynamic import() calls is a good thing for perfoUsing Deno in Frontend.Hey, I was wandering if it is possible to use Deno for Vanilla Frontend development. I dont want to Excluding certain directories when using "walk"Hello, I'm writing a script that should crawl through a directory and search for a given text insideSyntax Error: Unexpected token 'export'Hello, We are using Supabase Deno Edge Functions and are getting this error while trying to import aDeno Deploy QuestionsHey there. We are using Supabase to run edge functions, which in turn built their feature on top of Bunle OAK static assets to the compiled binaryHi, I am currently switching from NodeJS to Deno, and so far so good! One of the reasons for this sThe requested module does not provide an export named 'default'I'm trying to export the following interface: ```import User from '../models/User.ts'; export defa