Skip to content

Commit

Permalink
feat(compiler): use rust to write resources in parallel
Browse files Browse the repository at this point in the history
  • Loading branch information
fu050409 committed Jan 9, 2025
1 parent a30ba66 commit 0315881
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 12 deletions.
18 changes: 17 additions & 1 deletion crates/node/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub mod plugin_toolkit;
#[cfg(feature = "profile")]
pub mod profile_gui;

use farmfe_core::rayon::iter::{IntoParallelRefIterator, ParallelIterator};
use farmfe_core::{
config::{Config, Mode},
module::ModuleId,
Expand Down Expand Up @@ -211,7 +212,7 @@ impl JsCompiler {
}

/// async compile, return promise
#[napi]
#[napi(ts_return_type = "Promise<JsUpdateResult>")]
pub fn compile(&self, e: Env) -> napi::Result<JsObject> {
let (promise, result) =
e.create_deferred::<JsUndefined, Box<dyn FnOnce(Env) -> napi::Result<JsUndefined>>>()?;
Expand Down Expand Up @@ -438,6 +439,21 @@ impl JsCompiler {
resources_map
}

#[napi]
pub fn write_resources_to_disk(&self, output_path: String) -> () {
let context = self.compiler.context();
let resources = context.resources_map.lock();

resources.par_iter().for_each(|(name, resource)| {
let path = Path::new(&output_path).join(name.split(|c| c == '?' || c == '#').next().unwrap());
let dir = path.parent().unwrap();
if !dir.exists() {
std::fs::create_dir_all(dir).unwrap();
};
std::fs::write(path, resource.bytes.clone()).unwrap();
});
}

#[napi]
pub fn watch_modules(&self) -> Vec<String> {
let context = self.compiler.context();
Expand Down
3 changes: 2 additions & 1 deletion packages/core/binding/binding.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export declare class Compiler {
traceDependencies(): object
traceModuleGraph(): object
/** async compile, return promise */
compile(): object
compile(): Promise<JsUpdateResult>
/** sync compile */
compileSync(): void
/** TODO: usage example */
Expand All @@ -74,6 +74,7 @@ export declare class Compiler {
getParentFiles(resolvedPath: string): Array<string>
resources(): Record<string, Buffer>
resourcesMap(): Record<string, unknown>
writeResourcesToDisk(outputPath: string): void
watchModules(): Array<string>
relativeModulePaths(): Array<string>
resource(name: string): Buffer | null
Expand Down
17 changes: 7 additions & 10 deletions packages/core/src/compiler/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { existsSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
import { existsSync, rmSync } from 'node:fs';
import path from 'node:path';

import { Compiler as BindingCompiler } from '../../binding/index.js';
Expand Down Expand Up @@ -46,7 +46,6 @@ export class Compiler {

constructor(public config: ResolvedUserConfig) {
this._bindingCompiler = new BindingCompiler({
// @ts-ignore
config: config.compilation,
jsPlugins: config.jsPlugins,
rustPlugins: config.rustPlugins
Expand Down Expand Up @@ -169,16 +168,14 @@ export class Compiler {
return this._bindingCompiler.resourcesMap() as Record<string, Resource>;
}

/**
* Writes the compiled resources to disk and calls the write resources hook.
*/
writeResourcesToDisk(): void {
const resources = this.resources();
const outputPath = this.getOutputPath();

Object.entries(resources).forEach(([name, resource]) => {
const filePath = path.join(outputPath, name.split(/[?#]/)[0]);
mkdirSync(path.dirname(filePath), { recursive: true });
writeFileSync(filePath, new Uint8Array(resource));
});

// Write the resources to disk using the binding compiler
this._bindingCompiler.writeResourcesToDisk(outputPath);
// Call the write resources hook to allow plugins to perform additional actions
this.callWriteResourcesHook();
}

Expand Down

0 comments on commit 0315881

Please sign in to comment.