Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: worker support #3617

Merged
merged 6 commits into from
Jun 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Cargo.lock

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

3 changes: 3 additions & 0 deletions crates/node_binding/binding.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,9 @@ export interface RawOutputOptions {
hashDigestLength: number
hashSalt?: string
asyncChunks: boolean
workerChunkLoading: string
workerWasmLoading: string
workerPublicPath: string
}

export interface RawParserOptions {
Expand Down
1 change: 1 addition & 0 deletions crates/rspack_binding_options/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ rspack_plugin_schemes = { path = "../rspack_plugin_schemes" }
rspack_plugin_split_chunks = { path = "../rspack_plugin_split_chunks" }
rspack_plugin_split_chunks_new = { path = "../rspack_plugin_split_chunks_new" }
rspack_plugin_wasm = { path = "../rspack_plugin_wasm" }
rspack_plugin_worker = { path = "../rspack_plugin_worker" }
rspack_regex = { path = "../rspack_regex" }

anyhow = { workspace = true, features = ["backtrace"] }
Expand Down
5 changes: 5 additions & 0 deletions crates/rspack_binding_options/src/options/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,11 @@ impl RawOptionsApply for RawOptions {
if experiments.async_web_assembly {
plugins.push(rspack_plugin_wasm::AsyncWasmPlugin::new().boxed());
}
rspack_plugin_worker::worker_plugin(
output.worker_chunk_loading.clone(),
output.worker_wasm_loading.clone(),
plugins,
);
plugins.push(rspack_plugin_javascript::JsPlugin::new().boxed());
plugins.push(rspack_plugin_javascript::InferAsyncModulesPlugin {}.boxed());
plugins.push(
Expand Down
99 changes: 19 additions & 80 deletions crates/rspack_binding_options/src/options/raw_output.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use napi_derive::napi;
use rspack_core::ChunkLoading;
use rspack_core::{
to_identifier, BoxPlugin, CrossOriginLoading, LibraryAuxiliaryComment, LibraryName,
LibraryOptions, OutputOptions, PluginExt, TrustedTypes, WasmLoading,
LibraryOptions, OutputOptions, PluginExt, TrustedTypes,
};
use rspack_error::internal_error;
use serde::Deserialize;
Expand Down Expand Up @@ -150,6 +149,9 @@ pub struct RawOutputOptions {
pub hash_digest_length: u32,
pub hash_salt: Option<String>,
pub async_chunks: bool,
pub worker_chunk_loading: String,
pub worker_wasm_loading: String,
pub worker_public_path: String,
}

impl RawOptionsApply for RawOutputOptions {
Expand All @@ -160,23 +162,27 @@ impl RawOptionsApply for RawOutputOptions {
_: &JsLoaderRunner,
) -> Result<OutputOptions, rspack_error::Error> {
self.apply_chunk_format_plugin(plugins)?;
self.apply_chunk_loading_plugin(plugins)?;
if let Some(chunk_loading_types) = self.enabled_chunk_loading_types.as_ref() {
for chunk_loading_type in chunk_loading_types {
rspack_plugin_runtime::enable_chunk_loading_plugin(
chunk_loading_type.as_str().into(),
plugins,
);
}
}
self.apply_library_plugin(plugins);
for wasm_loading in self.enabled_wasm_loading_types {
for wasm_loading_type in self.enabled_wasm_loading_types {
plugins.push(rspack_plugin_wasm::enable_wasm_loading_plugin(
wasm_loading.as_str().into(),
))
wasm_loading_type.as_str().into(),
));
}

Ok(OutputOptions {
path: self.path.into(),
clean: self.clean,
public_path: self.public_path.into(),
asset_module_filename: self.asset_module_filename.into(),
wasm_loading: match self.wasm_loading.as_str() {
"false" => WasmLoading::Disable,
i => WasmLoading::Enable(i.into()),
},
wasm_loading: self.wasm_loading.as_str().into(),
webassembly_module_filename: self.webassembly_module_filename.into(),
unique_name: self.unique_name,
chunk_loading: self.chunk_loading.as_str().into(),
Expand All @@ -202,6 +208,9 @@ impl RawOptionsApply for RawOutputOptions {
hash_digest_length: self.hash_digest_length as usize,
hash_salt: self.hash_salt.into(),
async_chunks: self.async_chunks,
worker_chunk_loading: self.worker_chunk_loading.as_str().into(),
worker_wasm_loading: self.worker_wasm_loading.as_str().into(),
worker_public_path: self.worker_public_path,
})
}
}
Expand Down Expand Up @@ -230,76 +239,6 @@ impl RawOutputOptions {
Ok(())
}

fn apply_chunk_loading_plugin(
&self,
plugins: &mut Vec<BoxPlugin>,
) -> Result<(), rspack_error::Error> {
if let Some(enabled_chunk_loading_types) = &self.enabled_chunk_loading_types {
for chunk_loading in enabled_chunk_loading_types {
match chunk_loading.as_str() {
"jsonp" => {
plugins.push(rspack_plugin_runtime::JsonpChunkLoadingPlugin {}.boxed());
plugins.push(rspack_plugin_runtime::CssModulesPlugin {}.boxed());
}
"require" => {
plugins.push(
rspack_plugin_runtime::StartupChunkDependenciesPlugin::new(
ChunkLoading::Require,
false,
)
.boxed(),
);
plugins.push(
rspack_plugin_runtime::CommonJsChunkLoadingPlugin {
async_chunk_loading: false,
}
.boxed(),
);
}
"async-node" => {
plugins.push(
rspack_plugin_runtime::StartupChunkDependenciesPlugin::new(
ChunkLoading::AsyncNode,
false,
)
.boxed(),
);
plugins.push(
rspack_plugin_runtime::CommonJsChunkLoadingPlugin {
async_chunk_loading: true,
}
.boxed(),
);
}
"import" => {
plugins.push(rspack_plugin_runtime::ModuleChunkLoadingPlugin {}.boxed());
}
"import-scripts" => {
plugins.push(
rspack_plugin_runtime::StartupChunkDependenciesPlugin::new(
ChunkLoading::ImportScripts,
true,
)
.boxed(),
);
plugins.push(rspack_plugin_runtime::ImportScriptsChunkLoadingPlugin {}.boxed());
}
"universal" => {
return Err(internal_error!(
"Universal Chunk Loading is not implemented yet.",
))
}
_ => {
return Err(internal_error!(
"Unsupported chunk loading type ${chunk_loading}.",
))
}
}
}
}
Ok(())
}

fn apply_library_plugin(&self, plugins: &mut Vec<BoxPlugin>) {
if let Some(enabled_library_types) = &self.enabled_library_types {
for library in enabled_library_types {
Expand Down
10 changes: 8 additions & 2 deletions crates/rspack_core/src/build_chunk_graph/code_splitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ impl<'me> CodeSplitter<'me> {
.chunk_loading
.as_ref()
.unwrap_or(&compilation.options.output.chunk_loading),
ChunkLoading::False
ChunkLoading::Disable
),
async_chunks: options
.async_chunks
Expand Down Expand Up @@ -454,13 +454,19 @@ impl<'me> CodeSplitter<'me> {
RuntimeSpec::from_iter([entry_options.runtime.as_deref().expect("should have runtime for AsyncEntrypoint").into()]),
group_options.to_owned(),
ChunkGroupInfo {
chunk_loading: entry_options.chunk_loading.as_ref().map(|x| !matches!(x, ChunkLoading::False)).unwrap_or(item_chunk_group.info.chunk_loading),
chunk_loading: entry_options.chunk_loading.as_ref().map(|x| !matches!(x, ChunkLoading::Disable)).unwrap_or(item_chunk_group.info.chunk_loading),
async_chunks: entry_options.async_chunks.unwrap_or(item_chunk_group.info.async_chunks),
},
);
entrypoint.set_runtime_chunk(chunk.ukey);
entrypoint.set_entry_point_chunk(chunk.ukey);
self.compilation.async_entrypoints.push(entrypoint.ukey);
self.compilation.chunk_graph.add_module(*module_identifier);
self.compilation.chunk_graph.connect_chunk_and_entry_module(
chunk.ukey,
*module_identifier,
entrypoint.ukey,
);
entrypoint
} else {
chunk
Expand Down
1 change: 1 addition & 0 deletions crates/rspack_core/src/chunk_group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ impl ChunkGroupKind {
}
}

// TODO: split ChunkGroupOptions and EntryOptions, put options on kind
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct ChunkGroupOptions {
pub name: Option<String>,
Expand Down
8 changes: 8 additions & 0 deletions crates/rspack_core/src/dependency/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ pub enum DependencyType {
CjsRequire,
// new URL("./foo", import.meta.url)
NewUrl,
// new Worker()
NewWorker,
// import.meta.webpackHot.accept
ImportMetaHotAccept,
// import.meta.webpackHot.decline
Expand Down Expand Up @@ -87,6 +89,7 @@ impl Display for DependencyType {
DependencyType::DynamicImport => write!(f, "dynamic import"),
DependencyType::CjsRequire => write!(f, "cjs require"),
DependencyType::NewUrl => write!(f, "new URL()"),
DependencyType::NewWorker => write!(f, "new Worker()"),
DependencyType::ImportMetaHotAccept => write!(f, "import.meta.webpackHot.accept"),
DependencyType::ImportMetaHotDecline => write!(f, "import.meta.webpackHot.decline"),
DependencyType::ModuleHotAccept => write!(f, "module.hot.accept"),
Expand Down Expand Up @@ -117,6 +120,7 @@ pub enum DependencyCategory {
CssImport,
CssCompose,
Wasm,
Worker,
}

impl From<&str> for DependencyCategory {
Expand All @@ -143,6 +147,7 @@ impl Display for DependencyCategory {
DependencyCategory::CssImport => write!(f, "css-import"),
DependencyCategory::CssCompose => write!(f, "css-compose"),
DependencyCategory::Wasm => write!(f, "wasm"),
DependencyCategory::Worker => write!(f, "worker"),
}
}
}
Expand Down Expand Up @@ -338,6 +343,9 @@ pub fn is_async_dependency(dep: &BoxModuleDependency) -> bool {
if matches!(dep.dependency_type(), DependencyType::DynamicImport) {
return true;
}
if matches!(dep.dependency_type(), DependencyType::NewWorker) {
return true;
}
if matches!(dep.dependency_type(), DependencyType::ContextElement) {
if let Some(options) = dep.options() {
return matches!(options.mode, ContextMode::Lazy | ContextMode::LazyOnce);
Expand Down
35 changes: 30 additions & 5 deletions crates/rspack_core/src/options/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ pub struct OutputOptions {
pub hash_digest_length: usize,
pub hash_salt: HashSalt,
pub async_chunks: bool,
pub worker_chunk_loading: ChunkLoading,
pub worker_wasm_loading: WasmLoading,
pub worker_public_path: String,
}

impl From<&OutputOptions> for RspackHash {
Expand All @@ -63,7 +66,21 @@ pub struct TrustedTypes {

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ChunkLoading {
False,
Enable(ChunkLoadingType),
Disable,
}

impl From<&str> for ChunkLoading {
fn from(value: &str) -> Self {
match value {
"false" => ChunkLoading::Disable,
v => ChunkLoading::Enable(v.into()),
}
}
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ChunkLoadingType {
Jsonp,
ImportScripts,
Require,
Expand All @@ -72,27 +89,35 @@ pub enum ChunkLoading {
// TODO: Custom
}

impl From<&str> for ChunkLoading {
impl From<&str> for ChunkLoadingType {
fn from(value: &str) -> Self {
match value {
"jsonp" => Self::Jsonp,
"import-scripts" => Self::ImportScripts,
"require" => Self::Require,
"async-node" => Self::AsyncNode,
"import" => Self::Import,
"false" => Self::False,
_ => unimplemented!("custom chunkLoading in not supported yet"),
}
}
}

#[derive(Debug)]
#[derive(Debug, Clone)]
pub enum WasmLoading {
Enable(WasmLoadingType),
Disable,
}

#[derive(Debug)]
impl From<&str> for WasmLoading {
fn from(value: &str) -> Self {
match value {
"false" => Self::Disable,
v => Self::Enable(v.into()),
}
}
}

#[derive(Debug, Clone)]
pub enum WasmLoadingType {
Fetch,
AsyncNode,
Expand Down
7 changes: 6 additions & 1 deletion crates/rspack_loader_sass/tests/fixtures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ async fn loader_test(actual: impl AsRef<Path>, expected: impl AsRef<Path>) {
chunk_filename: rspack_core::Filename::from_str("").expect("TODO:"),
cross_origin_loading: rspack_core::CrossOriginLoading::Disable,
unique_name: Default::default(),
chunk_loading: rspack_core::ChunkLoading::Jsonp,
chunk_loading: rspack_core::ChunkLoading::Enable(rspack_core::ChunkLoadingType::Jsonp),
chunk_loading_global: "webpackChunkwebpack".to_string(),
css_chunk_filename: rspack_core::Filename::from_str("").expect("TODO:"),
css_filename: rspack_core::Filename::from_str("").expect("TODO:"),
Expand All @@ -67,6 +67,11 @@ async fn loader_test(actual: impl AsRef<Path>, expected: impl AsRef<Path>) {
hash_digest_length: 16,
hash_salt: rspack_core::HashSalt::None,
async_chunks: true,
worker_chunk_loading: rspack_core::ChunkLoading::Enable(
rspack_core::ChunkLoadingType::ImportScripts,
),
worker_wasm_loading: rspack_core::WasmLoading::Disable,
worker_public_path: String::new(),
},
target: rspack_core::Target::new(&vec![String::from("web")]).expect("TODO:"),
resolve: rspack_core::Resolve::default(),
Expand Down
7 changes: 6 additions & 1 deletion crates/rspack_loader_swc/tests/fixtures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ async fn loader_test(actual: impl AsRef<Path>, expected: impl AsRef<Path>) {
chunk_filename: rspack_core::Filename::from_str("").expect("TODO:"),
cross_origin_loading: rspack_core::CrossOriginLoading::Disable,
unique_name: Default::default(),
chunk_loading: rspack_core::ChunkLoading::Jsonp,
chunk_loading: rspack_core::ChunkLoading::Enable(rspack_core::ChunkLoadingType::Jsonp),
chunk_loading_global: "webpackChunkwebpack".to_string(),
css_chunk_filename: rspack_core::Filename::from_str("").expect("TODO:"),
css_filename: rspack_core::Filename::from_str("").expect("TODO:"),
Expand All @@ -67,6 +67,11 @@ async fn loader_test(actual: impl AsRef<Path>, expected: impl AsRef<Path>) {
hash_digest_length: 16,
hash_salt: rspack_core::HashSalt::None,
async_chunks: true,
worker_chunk_loading: rspack_core::ChunkLoading::Enable(
rspack_core::ChunkLoadingType::ImportScripts,
),
worker_wasm_loading: rspack_core::WasmLoading::Disable,
worker_public_path: String::new(),
},
target: rspack_core::Target::new(&vec![String::from("web")]).expect("TODO:"),
resolve: rspack_core::Resolve::default(),
Expand Down
Loading