Skip to content

Commit

Permalink
feat(plugin): basic support for buildStart,resolveId,buildEnd,`…
Browse files Browse the repository at this point in the history
…load`,`transform`,`renderChunk` hook (#680)

<!-- Thank you for contributing! -->

### Description

<!-- Please insert your description here and provide especially info about the "what" this PR is solving -->

### Test Plan

<!-- e.g. is there anything you'd like reviewers to focus on? -->

---
  • Loading branch information
hyf0 committed Mar 28, 2024
1 parent 8864a39 commit 3dd1d7c
Show file tree
Hide file tree
Showing 38 changed files with 437 additions and 438 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,6 @@
"search.exclude": {
"rollup": true,
"temp": true
}
},
"editor.wordWrap": "on"
}
19 changes: 9 additions & 10 deletions crates/rolldown/src/module_loader/runtime_normal_module_task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,15 @@ impl RuntimeNormalModuleTask {
builder.pretty_path = Some("<runtime>".to_string());
builder.is_user_defined_entry = Some(false);

self
.tx
.send(Msg::RuntimeNormalModuleDone(RuntimeNormalModuleTaskResult {
warnings: self.warnings,
ast_symbol: symbol,
builder,
runtime,
ast,
}))
.unwrap();
if let Err(_err) = self.tx.send(Msg::RuntimeNormalModuleDone(RuntimeNormalModuleTaskResult {
warnings: self.warnings,
ast_symbol: symbol,
builder,
runtime,
ast,
})) {
// hyf0: If main thread is dead, we should handle errors of main thread. So we just ignore the error here.
};
}

fn make_ast(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::fmt::Debug;

use serde::Deserialize;
use std::fmt::Debug;

use crate::types::{
binding_outputs::BindingOutputs, binding_rendered_chunk::RenderedChunk,
Expand All @@ -24,12 +23,12 @@ pub struct BindingPluginOptions {
pub name: String,

#[serde(skip_deserializing)]
#[napi(ts_type = "(ctx: BindingPluginContext) => MaybePromise<void>")]
#[napi(ts_type = "(ctx: BindingPluginContext) => MaybePromise<VoidNullable>")]
pub build_start: Option<JsAsyncCallback<BindingPluginContext, ()>>,

#[serde(skip_deserializing)]
#[napi(
ts_type = "(specifier: string, importer: string | undefined, options: BindingHookResolveIdExtraOptions) => MaybePromise<undefined | BindingHookResolveIdOutput>"
ts_type = "(specifier: string, importer: Nullable<string>, options: BindingHookResolveIdExtraOptions) => MaybePromise<VoidNullable<BindingHookResolveIdOutput>>"
)]
pub resolve_id: Option<
JsAsyncCallback<
Expand All @@ -39,32 +38,32 @@ pub struct BindingPluginOptions {
>,

#[serde(skip_deserializing)]
#[napi(ts_type = "(id: string) => MaybePromise<undefined | BindingHookLoadOutput>")]
#[napi(ts_type = "(id: string) => MaybePromise<VoidNullable<BindingHookLoadOutput>>")]
pub load: Option<JsAsyncCallback<String, Option<BindingHookLoadOutput>>>,

#[serde(skip_deserializing)]
#[napi(
ts_type = "(id: string, code: string) => MaybePromise<undefined | BindingHookLoadOutput>"
ts_type = "(id: string, code: string) => MaybePromise<VoidNullable<BindingHookLoadOutput>>"
)]
pub transform: Option<JsAsyncCallback<(String, String), Option<BindingHookLoadOutput>>>,

#[serde(skip_deserializing)]
#[napi(ts_type = "(error?: string) => MaybePromise<void>")]
#[napi(ts_type = "(error: Nullable<string>) => MaybePromise<VoidNullable>")]
pub build_end: Option<JsAsyncCallback<Option<String>, ()>>,

#[serde(skip_deserializing)]
#[napi(
ts_type = "(code: string, chunk: RenderedChunk) => MaybePromise<undefined | BindingHookRenderChunkOutput>"
ts_type = "(code: string, chunk: RenderedChunk) => MaybePromise<VoidNullable<BindingHookRenderChunkOutput>>"
)]
pub render_chunk:
Option<JsAsyncCallback<(String, RenderedChunk), Option<BindingHookRenderChunkOutput>>>,

#[serde(skip_deserializing)]
#[napi(ts_type = "(bundle: Outputs, isWrite: boolean) => MaybePromise<void>")]
#[napi(ts_type = "(bundle: Outputs, isWrite: boolean) => MaybePromise<VoidNullable>")]
pub generate_bundle: Option<JsAsyncCallback<(BindingOutputs, bool), ()>>,

#[serde(skip_deserializing)]
#[napi(ts_type = "(bundle: Outputs) => MaybePromise<void>")]
#[napi(ts_type = "(bundle: Outputs) => MaybePromise<VoidNullable>")]
pub write_bundle: Option<JsAsyncCallback<BindingOutputs, ()>>,
}

Expand Down
2 changes: 1 addition & 1 deletion crates/rolldown_binding/src/types/js_async_callback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use napi::{

/// This represents a JavaScript function, whose return value is `Promise<T> | T`
///
/// For example, the equivalent type of `(a: string, b: number) => Promise<number | undefined> | number | undefined` in Rust is
/// For example, the equivalent type of `(a: string, b: number) => Promise<number | null | undefined> | number | null | undefined` in Rust is
/// `JsAsyncCallback<(String, i32), Option<i32>>`
pub type JsAsyncCallback<Args, Ret> = ThreadsafeFunction<Args, JsAsyncCallbackReturn<Ret>, false>;

Expand Down
5 changes: 3 additions & 2 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,18 @@
"arraify",
"astro",
"bindgen",
"bindingify",
"binstall",
"Brooooooklyn",
"cdylib",
"citty",
"clippy",
"codegen",
"codemirror",
"codspeed",
"compat",
"concat",
"consola",
"corepack",
"dashmap",
"deconflict",
Expand Down Expand Up @@ -99,8 +102,6 @@
"tinybench",
"transpiling",
"treeshake",
"consola",
"citty",
"underfin",
"UNKEYED",
"vite",
Expand Down
6 changes: 3 additions & 3 deletions packages/rolldown/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@
"# Scrips for binding #": "_",
"artifacts": "napi artifacts -o=./artifacts --npm-dir ./npm",
"format-generated-binding-files": "prettier --write src/binding.js src/binding.d.ts",
"build-binding": "napi build -o=./src --manifest-path ../../crates/rolldown_binding/Cargo.toml --platform -p rolldown_binding --js binding.js --dts binding.d.ts --dts-header \"type MaybePromise<T> = T | Promise<T>\"",
"build-binding:release": "napi build -o=./src --release --manifest-path ../../crates/rolldown_binding/Cargo.toml --platform -p rolldown_binding --js binding.js --dts binding.d.ts --dts-header \"type MaybePromise<T> = T | Promise<T>\"",
"build-binding": "napi build -o=./src --manifest-path ../../crates/rolldown_binding/Cargo.toml --platform -p rolldown_binding --js binding.js --dts binding.d.ts --dts-header \"type MaybePromise<T> = T | Promise<T>\ntype Nullable<T> = T | null | undefined\ntype VoidNullable<T = void> = T | null | undefined | void\"",
"build-binding:release": "napi build -o=./src --release --manifest-path ../../crates/rolldown_binding/Cargo.toml --platform -p rolldown_binding --js binding.js --dts binding.d.ts --dts-header \"type MaybePromise<T> = T | Promise<T>\ntype Nullable<T> = T | null | undefined\ntype VoidNullable<T = void> = T | null | undefined | void\"",
"# Scrips for node #": "_",
"build-node": "unbuild",
"build": "pnpm build-binding && pnpm build-node && pnpm format-generated-binding-files",
"build:release": "pnpm build-binding:release && pnpm build-node && pnpm format-generated-binding-files",
"# Scrips for checking #": "_",
"test": "vitest run --reporter verbose",
"test": "vitest run --reporter verbose --hideSkippedTests",
"test:update": "vitest run -u",
"type-check": "tsc"
},
Expand Down
23 changes: 14 additions & 9 deletions packages/rolldown/src/binding.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
type MaybePromise<T> = T | Promise<T>
type Nullable<T> = T | null | undefined
type VoidNullable<T = void> = T | null | undefined | void
export class BindingPluginContext {
resolve(
specifier: string,
Expand Down Expand Up @@ -94,24 +96,27 @@ export interface BindingPluginContextResolveOptions {

export interface BindingPluginOptions {
name: string
buildStart?: (ctx: BindingPluginContext) => MaybePromise<void>
buildStart?: (ctx: BindingPluginContext) => MaybePromise<VoidNullable>
resolveId?: (
specifier: string,
importer: string | undefined,
importer: Nullable<string>,
options: BindingHookResolveIdExtraOptions,
) => MaybePromise<undefined | BindingHookResolveIdOutput>
load?: (id: string) => MaybePromise<undefined | BindingHookLoadOutput>
) => MaybePromise<VoidNullable<BindingHookResolveIdOutput>>
load?: (id: string) => MaybePromise<VoidNullable<BindingHookLoadOutput>>
transform?: (
id: string,
code: string,
) => MaybePromise<undefined | BindingHookLoadOutput>
buildEnd?: (error?: string) => MaybePromise<void>
) => MaybePromise<VoidNullable<BindingHookLoadOutput>>
buildEnd?: (error: Nullable<string>) => MaybePromise<VoidNullable>
renderChunk?: (
code: string,
chunk: RenderedChunk,
) => MaybePromise<undefined | BindingHookRenderChunkOutput>
generateBundle?: (bundle: Outputs, isWrite: boolean) => MaybePromise<void>
writeBundle?: (bundle: Outputs) => MaybePromise<void>
) => MaybePromise<VoidNullable<BindingHookRenderChunkOutput>>
generateBundle?: (
bundle: Outputs,
isWrite: boolean,
) => MaybePromise<VoidNullable>
writeBundle?: (bundle: Outputs) => MaybePromise<VoidNullable>
}

export interface BindingRenderedModule {
Expand Down
7 changes: 4 additions & 3 deletions packages/rolldown/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { RolldownOutput } from './objects/rolldown-output'
import type { InputOptions, RolldownPlugin } from './options/input-options'
import { RolldownOutput } from './types/rolldown-output'
import type { InputOptions } from './options/input-options'
import type { OutputOptions } from './options/output-options'
import type { RolldownOptions } from './types/rolldown-options'
import type { Plugin } from './plugin'
import { defineConfig } from './utils/define-config'
import { rolldown, experimental_scan } from './rolldown'

Expand All @@ -12,7 +13,7 @@ export type {
RolldownOutput,
InputOptions,
OutputOptions,
RolldownPlugin as Plugin,
Plugin,
}

// Exports for compatibility
Expand Down

0 comments on commit 3dd1d7c

Please sign in to comment.