Skip to content

Commit

Permalink
feat(turbopack-ecmascript): cache external modules with wrapper (#7988)
Browse files Browse the repository at this point in the history
  • Loading branch information
ForsakenHarmony authored Jun 10, 2024
1 parent 4061e06 commit efcea76
Show file tree
Hide file tree
Showing 25 changed files with 435 additions and 119 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 2 additions & 4 deletions crates/turbopack-core/src/resolve/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use anyhow::{bail, Result};
use indexmap::{indexmap, IndexMap, IndexSet};
use serde::{Deserialize, Serialize};
use tracing::{Instrument, Level};
use turbo_tasks::{trace::TraceRawVcs, RcStr, TryJoinIterExt, Value, ValueToString, Vc};
use turbo_tasks::{trace::TraceRawVcs, RcStr, TaskInput, TryJoinIterExt, Value, ValueToString, Vc};
use turbo_tasks_fs::{
util::{normalize_path, normalize_request},
FileSystemEntryType, FileSystemPath, RealPathResult,
Expand Down Expand Up @@ -392,9 +392,8 @@ impl ModuleResolveResultOption {
}
}

#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize, Deserialize, TraceRawVcs)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize, Deserialize, TraceRawVcs, TaskInput)]
pub enum ExternalType {
OriginalReference,
Url,
CommonJs,
EcmaScriptModule,
Expand All @@ -403,7 +402,6 @@ pub enum ExternalType {
impl Display for ExternalType {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
ExternalType::OriginalReference => write!(f, "original reference"),
ExternalType::CommonJs => write!(f, "commonjs"),
ExternalType::EcmaScriptModule => write!(f, "esm"),
ExternalType::Url => write!(f, "url"),
Expand Down
22 changes: 16 additions & 6 deletions crates/turbopack-ecmascript-runtime/js/src/shared/runtime-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -406,21 +406,31 @@ function asyncModule(

const depQueues: Set<AsyncQueue> = new Set();

ensureDynamicExports(module, module.exports);
const exports = module.exports;

const { resolve, reject, promise: rawPromise } = createPromise<Exports>();

const promise: AsyncModulePromise = Object.assign(rawPromise, {
[turbopackExports]: exports,
[turbopackExports]: module.exports,
[turbopackQueues]: (fn) => {
queue && fn(queue);
depQueues.forEach(fn);
promise["catch"](() => {});
},
} satisfies AsyncModuleExt);

module.exports = module.namespaceObject = promise;
const attributes: PropertyDescriptor = {
get(): any {
return promise;
},
set(v: any) {
// Calling `esmExport` leads to this.
if (v !== promise) {
promise[turbopackExports] = v;
}
},
};

Object.defineProperty(module, "exports", attributes);
Object.defineProperty(module, "namespaceObject", attributes);

function handleAsyncDependencies(deps: Dep[]) {
const currentDeps = wrapDeps(deps);
Expand Down Expand Up @@ -456,7 +466,7 @@ function asyncModule(
if (err) {
reject((promise[turbopackError] = err));
} else {
resolve(exports);
resolve(promise[turbopackExports]);
}

resolveQueue(queue);
Expand Down
2 changes: 1 addition & 1 deletion crates/turbopack-ecmascript/src/chunk/chunk_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use turbopack_core::{

use super::{EcmascriptChunk, EcmascriptChunkContent, EcmascriptChunkItem};

#[derive(Default)]
#[turbo_tasks::value]
#[derive(Default)]
pub struct EcmascriptChunkType {}

#[turbo_tasks::value_impl]
Expand Down
16 changes: 3 additions & 13 deletions crates/turbopack-ecmascript/src/references/async_module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@ use turbopack_core::{
};

use super::esm::base::ReferencedAsset;
use crate::{
chunk::EcmascriptChunkPlaceable, code_gen::CodeGeneration, create_visitor,
references::esm::base::insert_hoisted_stmt,
};
use crate::{code_gen::CodeGeneration, create_visitor, references::esm::base::insert_hoisted_stmt};

/// Information needed for generating the async module wrapper for
/// [EcmascriptChunkItem](crate::chunk::EcmascriptChunkItem)s.
Expand Down Expand Up @@ -47,7 +44,6 @@ impl OptionAsyncModuleOptions {
/// level await statement or is referencing an external ESM module.
#[turbo_tasks::value(shared)]
pub struct AsyncModule {
pub placeable: Vc<Box<dyn EcmascriptChunkPlaceable>>,
pub has_top_level_await: bool,
pub import_externals: bool,
}
Expand Down Expand Up @@ -116,10 +112,7 @@ impl AsyncModule {
return Ok(None);
};
Ok(match &*referenced_asset {
ReferencedAsset::External(
_,
ExternalType::OriginalReference | ExternalType::EcmaScriptModule,
) => {
ReferencedAsset::External(_, ExternalType::EcmaScriptModule) => {
if self.import_externals {
referenced_asset.get_ident().await?
} else {
Expand Down Expand Up @@ -168,10 +161,7 @@ impl AsyncModule {
};
Ok(matches!(
&*referenced_asset,
ReferencedAsset::External(
_,
ExternalType::OriginalReference | ExternalType::EcmaScriptModule
)
ReferencedAsset::External(_, ExternalType::EcmaScriptModule)
))
})
.try_join()
Expand Down
5 changes: 1 addition & 4 deletions crates/turbopack-ecmascript/src/references/esm/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,10 +264,7 @@ impl CodeGenerateable for EsmAssetReference {
insert_hoisted_stmt(program, stmt);
}));
}
ReferencedAsset::External(
request,
ExternalType::OriginalReference | ExternalType::EcmaScriptModule,
) => {
ReferencedAsset::External(request, ExternalType::EcmaScriptModule) => {
if !*chunking_context
.environment()
.supports_esm_externals()
Expand Down
10 changes: 2 additions & 8 deletions crates/turbopack-ecmascript/src/references/esm/url.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,10 +182,7 @@ impl CodeGenerateable for UrlAssetReference {
}
}));
}
ReferencedAsset::External(
request,
ExternalType::OriginalReference | ExternalType::Url,
) => {
ReferencedAsset::External(request, ExternalType::Url) => {
let request = request.to_string();
visitors.push(create_visitor!(ast_path, visit_mut_expr(new_expr: &mut Expr) {
let should_rewrite_to_relative = if let Expr::New(NewExpr { args: Some(args), .. }) = new_expr {
Expand Down Expand Up @@ -274,10 +271,7 @@ impl CodeGenerateable for UrlAssetReference {
}
}));
}
ReferencedAsset::External(
request,
ExternalType::OriginalReference | ExternalType::Url,
) => {
ReferencedAsset::External(request, ExternalType::Url) => {
let request = request.to_string();
visitors.push(create_visitor!(ast_path, visit_mut_expr(new_expr: &mut Expr) {
if let Expr::New(NewExpr { args: Some(args), .. }) = new_expr {
Expand Down
Loading

0 comments on commit efcea76

Please sign in to comment.