Skip to content

Commit

Permalink
feat(node): add scan api (#340)
Browse files Browse the repository at this point in the history
  • Loading branch information
underfin committed Nov 20, 2023
1 parent 43c9211 commit ba5257a
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 14 deletions.
48 changes: 39 additions & 9 deletions crates/rolldown/src/bundler/bundler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ use super::{
bundle::output::Output,
options::input_options::SharedInputOptions,
plugin_driver::{PluginDriver, SharedPluginDriver},
stages::link_stage::{LinkStage, LinkStageOutput},
stages::{
link_stage::{LinkStage, LinkStageOutput},
scan_stage::ScanStageOutput,
},
};
use crate::{
bundler::stages::{bundle_stage::BundleStage, scan_stage::ScanStage},
error::BatchedResult,
error::{BatchedErrors, BatchedResult},
plugin::plugin::BoxPlugin,
HookBuildEndArgs, InputOptions, OutputOptions, SharedResolver,
};
Expand Down Expand Up @@ -94,12 +97,35 @@ impl<T: FileSystem + Default + 'static> Bundler<T> {
Ok(())
}

pub async fn scan(&mut self) -> BatchedResult<()> {
self.plugin_driver.build_start().await?;

let ret = self.scan_inner().await;

self.call_build_end_hook(ret.err()).await?;

Ok(())
}

async fn build_inner(&mut self) -> BatchedResult<()> {
self.plugin_driver.build_start().await?;

let build_ret = self.try_build().await;
let ret = self.try_build().await;

let (err, value) = match ret {
Err(e) => (Some(e), None),
Ok(value) => (None, Some(value)),
};

self.call_build_end_hook(err).await?;

self.build_result = value;

if let Err(e) = build_ret {
Ok(())
}

async fn call_build_end_hook(&mut self, ret: Option<BatchedErrors>) -> BatchedResult<()> {
if let Some(e) = ret {
let error = e.get().expect("should have a error");
self
.plugin_driver
Expand All @@ -112,20 +138,24 @@ impl<T: FileSystem + Default + 'static> Bundler<T> {
}

self.plugin_driver.build_end(None).await?;
self.build_result = build_ret.ok();

Ok(())
}

#[tracing::instrument(skip_all)]
async fn try_build(&mut self) -> BatchedResult<LinkStageOutput> {
let build_info = ScanStage::new(
async fn scan_inner(&mut self) -> BatchedResult<ScanStageOutput> {
ScanStage::new(
Arc::clone(&self.input_options),
Arc::clone(&self.plugin_driver),
self.fs.share(),
Arc::clone(&self.resolver),
)
.scan()
.await?;
.await
}

#[tracing::instrument(skip_all)]
async fn try_build(&mut self) -> BatchedResult<LinkStageOutput> {
let build_info = self.scan_inner().await?;

let link_stage = LinkStage::new(build_info);

Expand Down
1 change: 1 addition & 0 deletions crates/rolldown_binding/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,5 @@ export class Bundler {
write(opts: OutputOptions): Promise<Outputs>
generate(opts: OutputOptions): Promise<Outputs>
build(): Promise<void>
scan(): Promise<void>
}
23 changes: 23 additions & 0 deletions crates/rolldown_binding/src/bundler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ impl Bundler {
pub async fn build(&self) -> napi::Result<()> {
self.build_impl().await
}

#[napi]
pub async fn scan(&self) -> napi::Result<()> {
self.scan_impl().await
}
}

impl Bundler {
Expand All @@ -47,6 +52,24 @@ impl Bundler {
})
}

#[instrument(skip_all)]
#[allow(clippy::significant_drop_tightening)]
pub async fn scan_impl(&self) -> napi::Result<()> {
let mut bundler_core = self.inner.try_lock().map_err(|_| {
napi::Error::from_reason("Failed to lock the bundler. Is another operation in progress?")
})?;

let result = bundler_core.scan().await;

if let Err(err) = result {
// TODO: better handing errors
eprintln!("{err:?}");
return Err(napi::Error::from_reason("Build failed"));
}

Ok(())
}

#[instrument(skip_all)]
#[allow(clippy::significant_drop_tightening)]
pub async fn build_impl(&self) -> napi::Result<()> {
Expand Down
2 changes: 1 addition & 1 deletion packages/node/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { InputOptions, RolldownPlugin } from './options/input-options'
import type { OutputOptions } from './options/output-options'
import { RolldownOutput } from './utils'

export { rolldown } from './rolldown'
export { rolldown, scan } from './rolldown'

interface RollupOptions extends InputOptions {
// This is included for compatibility with config files but ignored by rollup.rollup
Expand Down
19 changes: 15 additions & 4 deletions packages/node/src/rolldown-build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,28 @@ export class RolldownBuild implements RollupBuild {
this.#bundler = bundler
}

static async fromInputOptions(
inputOptions: InputOptions,
): Promise<RolldownBuild> {
static async createBundler(inputOptions: InputOptions): Promise<Bundler> {
// Convert `InputOptions` to `NormalizedInputOptions`.
const normalizedInputOptions = await normalizeInputOptions(inputOptions)
// Convert `NormalizedInputOptions` to `BindingInputOptions`
const bindingInputOptions = createInputOptionsAdapter(
normalizedInputOptions,
inputOptions,
)
const bundler = new Bundler(bindingInputOptions)
return new Bundler(bindingInputOptions)
}

static async fromInputOptionsForScanStage(
inputOptions: InputOptions,
): Promise<void> {
const bundler = await RolldownBuild.createBundler(inputOptions)
await bundler.scan()
}

static async fromInputOptions(
inputOptions: InputOptions,
): Promise<RolldownBuild> {
const bundler = await RolldownBuild.createBundler(inputOptions)
await bundler.build()
return new RolldownBuild(bundler)
}
Expand Down
6 changes: 6 additions & 0 deletions packages/node/src/rolldown.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { InputOptions } from './options/input-options'
import { RolldownBuild } from './rolldown-build'

// Compat to `rollup.rollup`, it is include scan module graph and linker.
export const rolldown = (input: InputOptions): Promise<RolldownBuild> => {
return RolldownBuild.fromInputOptions(input)
}

// It is only for scan module graph.
export const scan = (input: InputOptions): Promise<void> => {
return RolldownBuild.fromInputOptionsForScanStage(input)
}

0 comments on commit ba5257a

Please sign in to comment.