Skip to content

Commit

Permalink
fix: don't depend on npm:esbuild (#120)
Browse files Browse the repository at this point in the history
`npm:esbuild-wasm` does not actually use WASM when not loaded in a browser. As such, we need to use https://deno.land/x/[email protected]/wasm.js when targeting wasm.

This commit decouples esbuild_deno_loader from any specific esbuild version, by bundling the required types for the esbuild plugin API itself.
  • Loading branch information
lucacasonato authored Mar 15, 2024
1 parent 1903397 commit 54a50d6
Show file tree
Hide file tree
Showing 11 changed files with 151 additions and 19 deletions.
4 changes: 0 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ jobs:
if: runner.os == 'Linux'
run: deno lint

- name: Doc lint
if: runner.os == 'Linux'
run: deno doc --lint mod.ts

- name: Run tests
run: deno test -A

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ This example bundles an entrypoint into a single ESM output.
import * as esbuild from "npm:[email protected]";
// Import the WASM build on platforms where running subprocesses is not
// permitted, such as Deno Deploy, or when running without `--allow-run`.
// import * as esbuild from "npm:esbuild-wasm@0.20";
// import * as esbuild from "https://deno.land/x/[email protected].2/wasm.js";

import { denoPlugins } from "jsr:@luca/esbuild-deno-loader@^0.10.2";

Expand Down
7 changes: 4 additions & 3 deletions deno.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
{
"name": "@luca/esbuild-deno-loader",
"version": "0.10.2",
"exports": "./mod.ts",
"exports": {
".": "./mod.ts",
"./esbuild_types": "./src/esbuild_types.ts"
},
"imports": {
"@std/assert": "jsr:@std/[email protected]",
"@std/encoding/base32": "jsr:@std/[email protected]/base32",
"@std/encoding": "jsr:@std/[email protected]",
"@std/fs": "jsr:@std/[email protected]",
"@std/jsonc": "jsr:@std/[email protected]",
"@std/path": "jsr:@std/[email protected]",
"esbuild-wasm": "npm:[email protected]",
"esbuild": "npm:[email protected]",
"x/importmap": "./vendor/x/importmap/mod.ts",
"x/importmap/_util.ts": "./vendor/x/importmap/_util.ts"
},
Expand Down
2 changes: 1 addition & 1 deletion mod.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type esbuild from "esbuild";
import type * as esbuild from "./src/esbuild_types.ts";

import {
denoResolverPlugin,
Expand Down
7 changes: 3 additions & 4 deletions mod_test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type esbuild from "esbuild";
import esbuildNative from "esbuild";
import esbuildWasm from "esbuild-wasm";
import * as esbuildNative from "https://deno.land/x/[email protected]/mod.js";
import * as esbuildWasm from "https://deno.land/x/[email protected]/wasm.js";
import { join } from "@std/path";
import { assert, assertEquals, assertStringIncludes } from "@std/assert";
import {
Expand Down Expand Up @@ -767,7 +766,7 @@ Deno.test("bundle config inline import map with expansion", async (t) => {
});
});

const COMPUTED_PLUGIN: esbuild.Plugin = {
const COMPUTED_PLUGIN: esbuildNative.Plugin = {
name: "computed",
setup(build) {
build.onResolve({ filter: /.*/, namespace: "computed" }, (args) => {
Expand Down
136 changes: 136 additions & 0 deletions src/esbuild_types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/**
* This is a copy of the esbuild types that `deno_esbuild_loader` uses. This is
* necessary because the `esbuild` package is not available on JSR yet.
*
* @module
*/

/** the type of import */
export type ImportKind =
| "entry-point"
// JS
| "import-statement"
| "require-call"
| "dynamic-import"
| "require-resolve"
// CSS
| "import-rule"
| "composes-from"
| "url-token";

/** Documentation: https://esbuild.github.io/api/#loader */
export type Loader =
| "base64"
| "binary"
| "copy"
| "css"
| "dataurl"
| "default"
| "empty"
| "file"
| "js"
| "json"
| "jsx"
| "local-css"
| "text"
| "ts"
| "tsx";

/** Documentation: https://esbuild.github.io/plugins */
export interface Plugin {
name: string;
setup: (build: PluginBuild) => void | Promise<void>;
}

/** Documentation: https://esbuild.github.io/plugins */
export interface PluginBuild {
/** Documentation: https://esbuild.github.io/plugins/#build-options */
initialOptions: BuildOptions;

/** Documentation: https://esbuild.github.io/plugins/#resolve */
resolve(path: string, options?: ResolveOptions): Promise<ResolveResult>;

/** Documentation: https://esbuild.github.io/plugins/#on-start */
onStart(callback: () => Promise<void>): void;

/** Documentation: https://esbuild.github.io/plugins/#on-resolve */
onResolve(
options: OnResolveOptions,
callback: (args: OnResolveArgs) => Promise<OnResolveResult | undefined>,
): void;

/** Documentation: https://esbuild.github.io/plugins/#on-load */
onLoad(
options: OnLoadOptions,
callback: (args: OnLoadArgs) => Promise<OnLoadResult | null> | undefined,
): void;
}

/** Documentation: https://esbuild.github.io/api */
export interface BuildOptions {
/** Documentation: https://esbuild.github.io/api/#external */
external?: string[];
/** Documentation: https://esbuild.github.io/api/#working-directory */
absWorkingDir?: string;
}

/** Documentation: https://esbuild.github.io/plugins/#resolve-options */
export interface ResolveOptions {
importer?: string;
resolveDir?: string;
namespace?: string;
kind?: ImportKind;
}

/** Documentation: https://esbuild.github.io/plugins/#resolve-results */
export interface ResolveResult {
path: string;
namespace: string;
}

/** Documentation: https://esbuild.github.io/plugins/#on-resolve-options */
export interface OnResolveOptions {
filter: RegExp;
namespace?: string;
}

/** Documentation: https://esbuild.github.io/plugins/#on-resolve-arguments */
export interface OnResolveArgs {
path: string;
importer: string;
namespace: string;
resolveDir: string;
kind: ImportKind;
}

export interface OnResolveResult {
path?: string;
external?: boolean;
namespace?: string;
}

/** Documentation: https://esbuild.github.io/plugins/#on-load-options */
export interface OnLoadOptions {
filter: RegExp;
namespace?: string;
}

/** Documentation: https://esbuild.github.io/plugins/#on-load-arguments */
export interface OnLoadArgs {
path: string;
namespace: string;
}

/** Documentation: https://esbuild.github.io/plugins/#on-load-results */
export interface OnLoadResult {
contents?: string | Uint8Array;
resolveDir?: string;
loader?: Loader;

watchFiles?: string[];
}

/** Documentation: https://esbuild.github.io/plugins/#on-start-results */
// deno-lint-ignore no-empty-interface
export interface OnStartResult {
}
2 changes: 1 addition & 1 deletion src/loader_native.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import esbuild from "esbuild";
import type * as esbuild from "./esbuild_types.ts";
import { dirname, fromFileUrl, join } from "@std/path";
import { encodeBase32 } from "@std/encoding/base32";
import * as deno from "./deno.ts";
Expand Down
2 changes: 1 addition & 1 deletion src/loader_portable.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import esbuild from "esbuild";
import type * as esbuild from "./esbuild_types.ts";
import { fromFileUrl } from "@std/path";
import * as deno from "./deno.ts";
import {
Expand Down
4 changes: 2 additions & 2 deletions src/plugin_deno_loader.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import esbuild from "esbuild";
import type * as esbuild from "./esbuild_types.ts";
import { dirname, join } from "@std/path";
import { NativeLoader } from "./loader_native.ts";
import { PortableLoader } from "./loader_portable.ts";
Expand Down Expand Up @@ -231,7 +231,7 @@ export function denoLoaderPlugin(

async function onResolve(
args: esbuild.OnResolveArgs,
): Promise<esbuild.OnResolveResult | null | undefined> {
): Promise<esbuild.OnResolveResult | undefined> {
if (isNodeModulesResolution(args)) {
if (
BUILTIN_NODE_MODULES.has(args.path) ||
Expand Down
2 changes: 1 addition & 1 deletion src/plugin_deno_resolver.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import esbuild from "esbuild";
import type * as esbuild from "./esbuild_types.ts";
import { toFileUrl } from "@std/path";
import {
ImportMap,
Expand Down
2 changes: 1 addition & 1 deletion src/shared.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import esbuild from "esbuild";
import { extname, fromFileUrl, SEPARATOR, toFileUrl } from "@std/path";
import * as JSONC from "@std/jsonc";
import { ImportMap } from "x/importmap";
import { MediaType } from "./deno.ts";
import type * as esbuild from "./esbuild_types.ts";

export interface Loader {
resolve(specifier: URL): Promise<LoaderResolution>;
Expand Down

0 comments on commit 54a50d6

Please sign in to comment.