diff --git a/.github/actions/docker-build/action.yml b/.github/actions/docker-build/action.yml index 3980b892665e..1ebe76eb0c9f 100644 --- a/.github/actions/docker-build/action.yml +++ b/.github/actions/docker-build/action.yml @@ -26,6 +26,10 @@ inputs: required: false default: "" type: string + plugin: + required: false + default: true + type: boolean runs: using: composite @@ -46,7 +50,7 @@ runs: echo "Corepack version: $(corepack --version)" corepack enable - RUST_TARGET=${{ inputs.target }} pnpm build:binding:${{ inputs.profile }} + RUST_TARGET=${{ inputs.target }} ${{ inputs.plugin == 'false' && 'DISABLE_PLUGIN=1' || '' }} pnpm build:binding:${{ inputs.profile }} ${{ inputs.post }} ' if [[ ! -n "$CARGO_HOME" ]]; then diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1948fc725ef1..892e56657da2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -93,6 +93,18 @@ jobs: skipable: ${{ needs.check-changed.outputs.changed != 'true' }} full-install: false + test-wasm: + name: Test WASM + needs: [get-runner-labels, check-changed] + uses: ./.github/workflows/reusable-build.yml + with: + target: wasm32-wasip1-threads + profile: "ci" + runner: ${{ needs.get-runner-labels.outputs.LINUX_RUNNER_LABELS }} + skipable: ${{ needs.check-changed.outputs.changed != 'true' }} + full-install: false + test: false + cargo-deny: name: Check license of dependencies runs-on: ubuntu-latest @@ -147,7 +159,7 @@ jobs: - name: Lint js if: steps.changes.outputs.src == 'true' run: pnpm run lint-ci:js - + - name: Prettier if: steps.changes.outputs.src == 'true' run: pnpm run format-ci:js @@ -165,7 +177,7 @@ jobs: echo "====================================" pnpm build:js pnpm api-extractor:ci - + - name: Documentation coverage check if: steps.changes.outputs.src == 'true' run: pnpm doc-coverage diff --git a/.github/workflows/reusable-build.yml b/.github/workflows/reusable-build.yml index 49b20e831cf2..4adb0c92a1cf 100644 --- a/.github/workflows/reusable-build.yml +++ b/.github/workflows/reusable-build.yml @@ -201,10 +201,33 @@ jobs: - name: Upload artifact id: upload-artifact uses: ./.github/actions/artifact/upload - if: ${{ steps.check_cache.outputs.exists != 'true' && !inputs.skipable }} + if: ${{ inputs.target != 'wasm32-wasip1-threads' && steps.check_cache.outputs.exists != 'true' && !inputs.skipable }} with: name: bindings-${{ inputs.target }} path: crates/node_binding/*.node + try-local-cache: ${{ inputs.profile == 'ci' }} + mv-when-local: true + + # WASM + - name: Build wasm32-wasip1-threads with linux in Docker + if: ${{ inputs.target == 'wasm32-wasip1-threads' && steps.check_cache.outputs.exists != 'true' && !inputs.skipable }} + uses: ./.github/actions/docker-build + with: + image: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian + target: ${{ inputs.target }} + profile: ${{ inputs.profile }} + plugin: false + pre: unset CC_x86_64_unknown_linux_gnu && unset CC # for jemallocator to compile + + - name: Upload wasm artifact + id: upload-wasm-artifact + uses: ./.github/actions/artifact/upload + if: ${{ inputs.target == 'wasm32-wasip1-threads' && steps.check_cache.outputs.exists != 'true' && !inputs.skipable }} + with: + name: bindings-wasm32-wasi + path: crates/node_binding/rspack.wasm32-wasi.wasm + try-local-cache: ${{ inputs.profile == 'ci' }} + mv-when-local: true e2e: name: E2E Testing @@ -359,8 +382,6 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} sha: ${{ github.sha }} - - bench: name: Bench if: ${{ inputs.bench && !inputs.skipable }} diff --git a/.gitignore b/.gitignore index 653d737006cc..410f3f82a889 100644 --- a/.gitignore +++ b/.gitignore @@ -200,6 +200,7 @@ npm/**/*.node !npm/darwin-arm64/ !npm/darwin-x64/ !npm/linux-x64-gnu/ +!npm/wasm32-wasi !npm/win32-x64-msvc/ # Precompiled config schema diff --git a/Cargo.lock b/Cargo.lock index 26096122a4d1..c1ab8432f3a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -479,24 +479,6 @@ version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50fd5174866dc2fa2ddc96e8fb800852d37f064f32a45c7b7c2f8fa2c64c77fa" -[[package]] -name = "browserslist-rs" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdf0ca73de70c3da94e4194e4a01fe732378f55d47cf4c0588caab22a0dbfa14" -dependencies = [ - "ahash 0.8.11", - "chrono", - "either", - "indexmap 2.7.1", - "itertools 0.13.0", - "nom", - "once_cell", - "serde", - "serde_json", - "thiserror 1.0.69", -] - [[package]] name = "browserslist-rs" version = "0.17.0" @@ -2705,13 +2687,13 @@ dependencies = [ [[package]] name = "lightningcss" -version = "1.0.0-alpha.63" +version = "1.0.0-alpha.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a75fcbcdbcc84fc1ae7c60c31f99337560b620757a9bfc1c9f84df3cff8ac24" +checksum = "a296273515b1036d06fce6c1d6bfc11347083458e1765ae4a70d6288cdb15521" dependencies = [ "ahash 0.8.11", "bitflags 2.6.0", - "browserslist-rs 0.16.0", + "browserslist-rs", "const-str", "cssparser", "cssparser-color", @@ -3680,7 +3662,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07852df2dda2f0ab8c3407a6fd19e9389563af11c20f6c299bd07ff9fc96d6ae" dependencies = [ "anyhow", - "browserslist-rs 0.17.0", + "browserslist-rs", "dashmap 5.5.3", "from_variant", "once_cell", @@ -4413,6 +4395,7 @@ name = "rspack_futures" version = "0.2.0" dependencies = [ "async-scoped", + "futures", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 47cc4cf3bcc0..da14f6dbcf3b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,7 +51,7 @@ indoc = { version = "2.0.5" } insta = { version = "1.42.0" } itertools = { version = "0.14.0" } json = { version = "0.12.4" } -lightningcss = { version = "1.0.0-alpha.63" } +lightningcss = { version = "1.0.0-alpha.64" } linked_hash_set = { version = "0.1.5" } mimalloc = { version = "0.2.3", package = "mimalloc-rspack" } mime_guess = { version = "2.0.5" } diff --git a/crates/node_binding/.gitignore b/crates/node_binding/.gitignore index 692a2e69264b..031bd83c1dd5 100644 --- a/crates/node_binding/.gitignore +++ b/crates/node_binding/.gitignore @@ -1 +1,2 @@ -/*.node \ No newline at end of file +/*.node +/*.wasm \ No newline at end of file diff --git a/crates/node_binding/Cargo.toml b/crates/node_binding/Cargo.toml index 84c8c1bd8330..a2ba0ae0313a 100644 --- a/crates/node_binding/Cargo.toml +++ b/crates/node_binding/Cargo.toml @@ -57,7 +57,7 @@ rustc-hash = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } swc_core = { workspace = true, default-features = false, features = ["ecma_transforms_react"] } -tokio = { workspace = true, features = ["rt", "rt-multi-thread", "macros", "test-util", "parking_lot"] } +tokio = { workspace = true, features = ["rt", "macros", "test-util", "parking_lot"] } rspack_loader_lightningcss = { workspace = true } @@ -103,6 +103,11 @@ rspack_plugin_wasm = { workspace = true } rspack_plugin_web_worker_template = { workspace = true } rspack_plugin_worker = { workspace = true } +[target.'cfg(not(target_family = "wasm"))'.dependencies] +tokio = { workspace = true, features = ["rt-multi-thread"] } + +rspack_tracing = { workspace = true, features = ["otel"] } + [build-dependencies] napi-build = { workspace = true } diff --git a/crates/node_binding/binding.js b/crates/node_binding/binding.js index e33dada8ac22..ca8168c53430 100644 --- a/crates/node_binding/binding.js +++ b/crates/node_binding/binding.js @@ -212,6 +212,25 @@ switch (platform) { throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`) } +if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) { + try { + nativeBinding = require('./rspack.wasi.cjs') + } catch (e) { + if (process.env.NAPI_RS_FORCE_WASI) { + loadError = e + } + } + if (!nativeBinding) { + try { + nativeBinding = require('@rspack/binding-wasm32-wasi') + } catch (e) { + if (process.env.NAPI_RS_FORCE_WASI) { + loadError = e + } + } + } +} + if (!nativeBinding) { if (loadError) { throw loadError diff --git a/crates/node_binding/browser.js b/crates/node_binding/browser.js new file mode 100644 index 000000000000..868cebd46c1e --- /dev/null +++ b/crates/node_binding/browser.js @@ -0,0 +1 @@ +export * from '@rspack/binding-wasm32-wasi' diff --git a/crates/node_binding/package.json b/crates/node_binding/package.json index 24760af610e9..85d9f3d38dc4 100644 --- a/crates/node_binding/package.json +++ b/crates/node_binding/package.json @@ -26,15 +26,39 @@ "repository": "web-infra-dev/rspack", "devDependencies": { "@napi-rs/cli": "3.0.0-alpha.73", + "@napi-rs/wasm-runtime": "^0.2.7", + "emnapi": "^1.3.1", "typescript": "^5.7.3" }, "napi": { - "binaryName": "rspack" + "binaryName": "rspack", + "packageName": "@rspack/binding", + "targets": [ + "x86_64-apple-darwin", + "x86_64-pc-windows-msvc", + "x86_64-unknown-linux-gnu", + "x86_64-unknown-linux-musl", + "x86_64-unknown-freebsd", + "i686-pc-windows-msvc", + "armv7-unknown-linux-gnueabihf", + "aarch64-unknown-linux-gnu", + "aarch64-apple-darwin", + "aarch64-unknown-linux-musl", + "aarch64-pc-windows-msvc", + "wasm32-wasip1-threads" + ], + "wasm": { + "initialMemory": 16384, + "browser": { + "fs": true + } + } }, "optionalDependencies": { "@rspack/binding-darwin-arm64": "workspace:*", "@rspack/binding-darwin-x64": "workspace:*", "@rspack/binding-linux-x64-gnu": "workspace:*", + "@rspack/binding-wasm32-wasi": "workspace:*", "@rspack/binding-win32-x64-msvc": "workspace:*" } } \ No newline at end of file diff --git a/crates/node_binding/rspack.wasi-browser.js b/crates/node_binding/rspack.wasi-browser.js new file mode 100644 index 000000000000..6689e3192c52 --- /dev/null +++ b/crates/node_binding/rspack.wasi-browser.js @@ -0,0 +1,94 @@ +import { + instantiateNapiModuleSync as __emnapiInstantiateNapiModuleSync, + getDefaultContext as __emnapiGetDefaultContext, + WASI as __WASI, + createOnMessage as __wasmCreateOnMessageForFsProxy, +} from '@napi-rs/wasm-runtime' +import { memfs } from '@napi-rs/wasm-runtime/fs' +import __wasmUrl from './rspack.wasm32-wasi.wasm?url' + +export const { fs: __fs, vol: __volume } = memfs() + +const __wasi = new __WASI({ + version: 'preview1', + fs: __fs, + preopens: { + '/': '/', + }, +}) + +const __emnapiContext = __emnapiGetDefaultContext() + +const __sharedMemory = new WebAssembly.Memory({ + initial: 16384, + maximum: 65536, + shared: true, +}) + +const __wasmFile = await fetch(__wasmUrl).then((res) => res.arrayBuffer()) + +const { + instance: __napiInstance, + module: __wasiModule, + napiModule: __napiModule, +} = __emnapiInstantiateNapiModuleSync(__wasmFile, { + context: __emnapiContext, + asyncWorkPoolSize: 4, + wasi: __wasi, + onCreateWorker() { + const worker = new Worker(new URL('./wasi-worker-browser.mjs', import.meta.url), { + type: 'module', + }) + worker.addEventListener('message', __wasmCreateOnMessageForFsProxy(__fs)) + + return worker + }, + overwriteImports(importObject) { + importObject.env = { + ...importObject.env, + ...importObject.napi, + ...importObject.emnapi, + memory: __sharedMemory, + } + return importObject + }, + beforeInit({ instance }) { + for (const name of Object.keys(instance.exports)) { + if (name.startsWith('__napi_register__')) { + instance.exports[name]() + } + } + }, +}) +export const Dependency = __napiModule.exports.Dependency +export const EntryDataDto = __napiModule.exports.EntryDataDto +export const EntryDataDTO = __napiModule.exports.EntryDataDTO +export const EntryDependency = __napiModule.exports.EntryDependency +export const EntryOptionsDto = __napiModule.exports.EntryOptionsDto +export const EntryOptionsDTO = __napiModule.exports.EntryOptionsDTO +export const JsChunk = __napiModule.exports.JsChunk +export const JsChunkGraph = __napiModule.exports.JsChunkGraph +export const JsChunkGroup = __napiModule.exports.JsChunkGroup +export const JsCompilation = __napiModule.exports.JsCompilation +export const JsCompiler = __napiModule.exports.JsCompiler +export const JsContextModuleFactoryAfterResolveData = __napiModule.exports.JsContextModuleFactoryAfterResolveData +export const JsContextModuleFactoryBeforeResolveData = __napiModule.exports.JsContextModuleFactoryBeforeResolveData +export const JsDependencies = __napiModule.exports.JsDependencies +export const JsDependenciesBlock = __napiModule.exports.JsDependenciesBlock +export const JsEntries = __napiModule.exports.JsEntries +export const JsExportsInfo = __napiModule.exports.JsExportsInfo +export const JsModule = __napiModule.exports.JsModule +export const JsModuleGraph = __napiModule.exports.JsModuleGraph +export const JsModuleGraphConnection = __napiModule.exports.JsModuleGraphConnection +export const JsResolver = __napiModule.exports.JsResolver +export const JsResolverFactory = __napiModule.exports.JsResolverFactory +export const JsStats = __napiModule.exports.JsStats +export const RawExternalItemFnCtx = __napiModule.exports.RawExternalItemFnCtx +export const BuiltinPluginName = __napiModule.exports.BuiltinPluginName +export const cleanupGlobalTrace = __napiModule.exports.cleanupGlobalTrace +export const formatDiagnostic = __napiModule.exports.formatDiagnostic +export const JsLoaderState = __napiModule.exports.JsLoaderState +export const JsRspackSeverity = __napiModule.exports.JsRspackSeverity +export const RawRuleSetConditionType = __napiModule.exports.RawRuleSetConditionType +export const registerGlobalTrace = __napiModule.exports.registerGlobalTrace +export const RegisterJsTapKind = __napiModule.exports.RegisterJsTapKind diff --git a/crates/node_binding/rspack.wasi.cjs b/crates/node_binding/rspack.wasi.cjs new file mode 100644 index 000000000000..057dbecf3273 --- /dev/null +++ b/crates/node_binding/rspack.wasi.cjs @@ -0,0 +1,119 @@ +/* eslint-disable */ +/* prettier-ignore */ + +/* auto-generated by NAPI-RS */ + +const __nodeFs = require('node:fs') +const __nodePath = require('node:path') +const { WASI: __nodeWASI } = require('node:wasi') +const { Worker } = require('node:worker_threads') + +const { + instantiateNapiModuleSync: __emnapiInstantiateNapiModuleSync, + getDefaultContext: __emnapiGetDefaultContext, + createOnMessage: __wasmCreateOnMessageForFsProxy, +} = require('@napi-rs/wasm-runtime') + +const __rootDir = __nodePath.parse(process.cwd()).root + +const __wasi = new __nodeWASI({ + version: 'preview1', + env: process.env, + preopens: { + [__rootDir]: __rootDir, + } +}) + +const __emnapiContext = __emnapiGetDefaultContext() + +const __sharedMemory = new WebAssembly.Memory({ + initial: 16384, + maximum: 65536, + shared: true, +}) + +let __wasmFilePath = __nodePath.join(__dirname, 'rspack.wasm32-wasi.wasm') +const __wasmDebugFilePath = __nodePath.join(__dirname, 'rspack.wasm32-wasi.debug.wasm') + +if (__nodeFs.existsSync(__wasmDebugFilePath)) { + __wasmFilePath = __wasmDebugFilePath +} else if (!__nodeFs.existsSync(__wasmFilePath)) { + try { + __wasmFilePath = __nodePath.resolve('@rspack/binding-wasm32-wasi') + } catch { + throw new Error('Cannot find rspack.wasm32-wasi.wasm file, and @rspack/binding-wasm32-wasi package is not installed.') + } +} + +const { instance: __napiInstance, module: __wasiModule, napiModule: __napiModule } = __emnapiInstantiateNapiModuleSync(__nodeFs.readFileSync(__wasmFilePath), { + context: __emnapiContext, + asyncWorkPoolSize: (function() { + const threadsSizeFromEnv = Number(process.env.NAPI_RS_ASYNC_WORK_POOL_SIZE ?? process.env.UV_THREADPOOL_SIZE) + // NaN > 0 is false + if (threadsSizeFromEnv > 0) { + return threadsSizeFromEnv + } else { + return 4 + } + })(), + reuseWorker: true, + wasi: __wasi, + onCreateWorker() { + const worker = new Worker(__nodePath.join(__dirname, 'wasi-worker.mjs'), { + env: process.env, + }) + worker.onmessage = ({ data }) => { + __wasmCreateOnMessageForFsProxy(__nodeFs)(data) + } + return worker + }, + overwriteImports(importObject) { + importObject.env = { + ...importObject.env, + ...importObject.napi, + ...importObject.emnapi, + memory: __sharedMemory, + } + return importObject + }, + beforeInit({ instance }) { + for (const name of Object.keys(instance.exports)) { + if (name.startsWith('__napi_register__')) { + instance.exports[name]() + } + } + }, +}) + +module.exports.Dependency = __napiModule.exports.Dependency +module.exports.EntryDataDto = __napiModule.exports.EntryDataDto +module.exports.EntryDataDTO = __napiModule.exports.EntryDataDTO +module.exports.EntryDependency = __napiModule.exports.EntryDependency +module.exports.EntryOptionsDto = __napiModule.exports.EntryOptionsDto +module.exports.EntryOptionsDTO = __napiModule.exports.EntryOptionsDTO +module.exports.JsChunk = __napiModule.exports.JsChunk +module.exports.JsChunkGraph = __napiModule.exports.JsChunkGraph +module.exports.JsChunkGroup = __napiModule.exports.JsChunkGroup +module.exports.JsCompilation = __napiModule.exports.JsCompilation +module.exports.JsCompiler = __napiModule.exports.JsCompiler +module.exports.JsContextModuleFactoryAfterResolveData = __napiModule.exports.JsContextModuleFactoryAfterResolveData +module.exports.JsContextModuleFactoryBeforeResolveData = __napiModule.exports.JsContextModuleFactoryBeforeResolveData +module.exports.JsDependencies = __napiModule.exports.JsDependencies +module.exports.JsDependenciesBlock = __napiModule.exports.JsDependenciesBlock +module.exports.JsEntries = __napiModule.exports.JsEntries +module.exports.JsExportsInfo = __napiModule.exports.JsExportsInfo +module.exports.JsModule = __napiModule.exports.JsModule +module.exports.JsModuleGraph = __napiModule.exports.JsModuleGraph +module.exports.JsModuleGraphConnection = __napiModule.exports.JsModuleGraphConnection +module.exports.JsResolver = __napiModule.exports.JsResolver +module.exports.JsResolverFactory = __napiModule.exports.JsResolverFactory +module.exports.JsStats = __napiModule.exports.JsStats +module.exports.RawExternalItemFnCtx = __napiModule.exports.RawExternalItemFnCtx +module.exports.BuiltinPluginName = __napiModule.exports.BuiltinPluginName +module.exports.cleanupGlobalTrace = __napiModule.exports.cleanupGlobalTrace +module.exports.formatDiagnostic = __napiModule.exports.formatDiagnostic +module.exports.JsLoaderState = __napiModule.exports.JsLoaderState +module.exports.JsRspackSeverity = __napiModule.exports.JsRspackSeverity +module.exports.RawRuleSetConditionType = __napiModule.exports.RawRuleSetConditionType +module.exports.registerGlobalTrace = __napiModule.exports.registerGlobalTrace +module.exports.RegisterJsTapKind = __napiModule.exports.RegisterJsTapKind diff --git a/crates/node_binding/src/lib.rs b/crates/node_binding/src/lib.rs index 609f5b3ba5c2..5f381a168896 100644 --- a/crates/node_binding/src/lib.rs +++ b/crates/node_binding/src/lib.rs @@ -19,7 +19,6 @@ use rspack_core::{ use rspack_error::Diagnostic; use rspack_fs::IntermediateFileSystem; use rspack_fs_node::{NodeFileSystem, ThreadsafeNodeFS}; -use rspack_napi::napi::bindgen_prelude::within_runtime_if_available; mod asset; mod asset_condition; @@ -88,7 +87,7 @@ pub use resolver::*; use resolver_factory::*; pub use resource_data::*; pub use rsdoctor::*; -use rspack_tracing::{ChromeTracer, OtelTracer, StdoutTracer, Tracer}; +use rspack_tracing::{ChromeTracer, StdoutTracer, Tracer}; pub use runtime::*; use rustc_hash::FxHashMap; pub use source::*; @@ -337,6 +336,7 @@ enum TraceState { Off, } +#[cfg(not(target_family = "wasm"))] #[ctor] fn init() { panic::install_panic_handler(); @@ -389,7 +389,12 @@ pub fn register_global_trace( if let TraceState::Off = *state { let mut tracer: Box = match layer.as_str() { "chrome" => Box::new(ChromeTracer::default()), - "otel" => Box::new(within_runtime_if_available(OtelTracer::default)), + #[cfg(not(target_family = "wasm"))] + "otel" => { + use rspack_tracing::OtelTracer; + use rspack_napi::napi::bindgen_prelude::within_runtime_if_available; + Box::new(within_runtime_if_available(OtelTracer::default)) + }, "logger" => Box::new(StdoutTracer), _ => anyhow::bail!( "Unexpected layer: {}, supported layers: 'chrome', 'logger', 'console' and 'otel' ", diff --git a/crates/node_binding/src/plugins/js_loader/context.rs b/crates/node_binding/src/plugins/js_loader/context.rs index e7cc932e6855..5cb4d9818f37 100644 --- a/crates/node_binding/src/plugins/js_loader/context.rs +++ b/crates/node_binding/src/plugins/js_loader/context.rs @@ -6,8 +6,6 @@ use rspack_core::{LoaderContext, Module, RunnerContext}; use rspack_error::error; use rspack_loader_runner::{LoaderItem, State as LoaderState}; use rspack_napi::threadsafe_js_value_ref::ThreadsafeJsValueRef; -use rspack_tracing::otel::{opentelemetry::global, tracing::OpenTelemetrySpanExt as _}; -use tracing::Span; use crate::{JsModuleWrapper, JsResourceData, JsRspackError}; @@ -99,11 +97,20 @@ impl TryFrom<&mut LoaderContext> for JsLoaderContext { ) -> std::result::Result { let module = unsafe { cx.context.module.as_ref() }; + #[allow(unused_mut)] let mut carrier = HashMap::new(); - global::get_text_map_propagator(|propagator| { - let cx = Span::current().context(); - propagator.inject_context(&cx, &mut carrier); - }); + + #[cfg(not(target_family = "wasm"))] + { + use rspack_tracing::otel::{opentelemetry::global, tracing::OpenTelemetrySpanExt as _}; + use tracing::Span; + + global::get_text_map_propagator(|propagator| { + let cx = Span::current().context(); + propagator.inject_context(&cx, &mut carrier); + }); + }; + #[allow(clippy::unwrap_used)] Ok(JsLoaderContext { resource_data: cx.resource_data.as_ref().into(), diff --git a/crates/node_binding/wasi-worker-browser.mjs b/crates/node_binding/wasi-worker-browser.mjs new file mode 100644 index 000000000000..cc4469bb1e98 --- /dev/null +++ b/crates/node_binding/wasi-worker-browser.mjs @@ -0,0 +1,39 @@ +import { instantiateNapiModuleSync, MessageHandler, WASI, createFsProxy } from '@napi-rs/wasm-runtime' +import { memfsExported as __memfsExported } from '@napi-rs/wasm-runtime/fs' + +const fs = createFsProxy(__memfsExported) + +const handler = new MessageHandler({ + onLoad({ wasmModule, wasmMemory }) { + const wasi = new WASI({ + fs, + preopens: { + '/': '/', + }, + print: function () { + // eslint-disable-next-line no-console + console.log.apply(console, arguments) + }, + printErr: function() { + // eslint-disable-next-line no-console + console.error.apply(console, arguments) + }, + }) + return instantiateNapiModuleSync(wasmModule, { + childThread: true, + wasi, + overwriteImports(importObject) { + importObject.env = { + ...importObject.env, + ...importObject.napi, + ...importObject.emnapi, + memory: wasmMemory, + } + }, + }) + }, +}) + +globalThis.onmessage = function (e) { + handler.handle(e) +} diff --git a/crates/node_binding/wasi-worker.mjs b/crates/node_binding/wasi-worker.mjs new file mode 100644 index 000000000000..84b448fcc52a --- /dev/null +++ b/crates/node_binding/wasi-worker.mjs @@ -0,0 +1,63 @@ +import fs from "node:fs"; +import { createRequire } from "node:module"; +import { parse } from "node:path"; +import { WASI } from "node:wasi"; +import { parentPort, Worker } from "node:worker_threads"; + +const require = createRequire(import.meta.url); + +const { instantiateNapiModuleSync, MessageHandler, getDefaultContext } = require("@napi-rs/wasm-runtime"); + +if (parentPort) { + parentPort.on("message", (data) => { + globalThis.onmessage({ data }); + }); +} + +Object.assign(globalThis, { + self: globalThis, + require, + Worker, + importScripts: function (f) { + ;(0, eval)(fs.readFileSync(f, "utf8") + "//# sourceURL=" + f); + }, + postMessage: function (msg) { + if (parentPort) { + parentPort.postMessage(msg); + } + }, +}); + +const emnapiContext = getDefaultContext(); + +const __rootDir = parse(process.cwd()).root; + +const handler = new MessageHandler({ + onLoad({ wasmModule, wasmMemory }) { + const wasi = new WASI({ + version: 'preview1', + env: process.env, + preopens: { + [__rootDir]: __rootDir, + }, + }); + + return instantiateNapiModuleSync(wasmModule, { + childThread: true, + wasi, + context: emnapiContext, + overwriteImports(importObject) { + importObject.env = { + ...importObject.env, + ...importObject.napi, + ...importObject.emnapi, + memory: wasmMemory + }; + }, + }); + }, +}); + +globalThis.onmessage = function (e) { + handler.handle(e); +}; diff --git a/crates/rspack_allocator/Cargo.toml b/crates/rspack_allocator/Cargo.toml index 8b1929669612..887250b81be7 100644 --- a/crates/rspack_allocator/Cargo.toml +++ b/crates/rspack_allocator/Cargo.toml @@ -14,5 +14,5 @@ mimalloc = { workspace = true, features = ["local_dynamic_tls"] } [target.'cfg(target_os = "macos")'.dependencies] mimalloc = { workspace = true, features = ["v3"] } -[target.'cfg(all(not(target_os = "linux"), not(target_os = "macos")))'.dependencies] +[target.'cfg(all(not(target_os = "linux"), not(target_os = "macos"), not(target_family = "wasm")))'.dependencies] mimalloc = { workspace = true } diff --git a/crates/rspack_allocator/src/lib.rs b/crates/rspack_allocator/src/lib.rs index 5d4205881355..8e6d227a4fc6 100644 --- a/crates/rspack_allocator/src/lib.rs +++ b/crates/rspack_allocator/src/lib.rs @@ -1,3 +1,3 @@ #[global_allocator] -#[cfg(not(miri))] +#[cfg(not(any(miri, target_family = "wasm")))] static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; diff --git a/crates/rspack_core/Cargo.toml b/crates/rspack_core/Cargo.toml index 02f41d0f2e93..79a304d7b359 100644 --- a/crates/rspack_core/Cargo.toml +++ b/crates/rspack_core/Cargo.toml @@ -67,7 +67,7 @@ swc_core = { workspace = true, features = [ "swc_ecma_visit", ] } swc_node_comments = { workspace = true } -tokio = { workspace = true, features = ["rt", "rt-multi-thread", "macros", "test-util", "parking_lot"] } +tokio = { workspace = true, features = ["rt", "macros"] } tracing = { workspace = true } ustr = { workspace = true } diff --git a/crates/rspack_fs/Cargo.toml b/crates/rspack_fs/Cargo.toml index e62f79d3cf92..10665b9d601d 100644 --- a/crates/rspack_fs/Cargo.toml +++ b/crates/rspack_fs/Cargo.toml @@ -12,4 +12,10 @@ dunce = { version = "1.0.5" } pnp = { version = "0.9.0" } rspack_error = { path = "../rspack_error", version = "0.2.0" } rspack_paths = { path = "../rspack_paths", version = "0.2.0" } -tokio = { workspace = true, features = ["fs", "test-util", "macros"] } +tokio = { workspace = true, features = ["rt", "macros", "sync"] } + +[target.'cfg(not(target_family = "wasm"))'.dependencies] +tokio = { workspace = true, features = ["rt", "macros", "sync", "fs"] } + +[dev-dependencies] +tokio = { workspace = true, features = ["time"] } diff --git a/crates/rspack_fs/src/native_fs.rs b/crates/rspack_fs/src/native_fs.rs index 7fcc41535071..2e3d7ed207e1 100644 --- a/crates/rspack_fs/src/native_fs.rs +++ b/crates/rspack_fs/src/native_fs.rs @@ -28,6 +28,8 @@ impl NativeFileSystem { } } } + +#[cfg(not(target_family = "wasm"))] #[async_trait::async_trait] impl WritableFileSystem for NativeFileSystem { async fn create_dir(&self, dir: &Utf8Path) -> Result<()> { @@ -70,6 +72,52 @@ impl WritableFileSystem for NativeFileSystem { FileMetadata::try_from(metadata) } } + +#[cfg(target_family = "wasm")] +#[async_trait::async_trait] +impl WritableFileSystem for NativeFileSystem { + async fn create_dir(&self, dir: &Utf8Path) -> Result<()> { + fs::create_dir(dir).map_err(Error::from) + } + + async fn create_dir_all(&self, dir: &Utf8Path) -> Result<()> { + fs::create_dir_all(dir).map_err(Error::from) + } + + async fn write(&self, file: &Utf8Path, data: &[u8]) -> Result<()> { + fs::write(file, data).map_err(Error::from) + } + + async fn remove_file(&self, file: &Utf8Path) -> Result<()> { + fs::remove_file(file).map_err(Error::from) + } + + async fn remove_dir_all(&self, dir: &Utf8Path) -> Result<()> { + let dir = dir.to_path_buf(); + fs::remove_dir_all(dir).map_err(Error::from) + } + + async fn read_dir(&self, dir: &Utf8Path) -> Result> { + let dir = dir.to_path_buf(); + let mut res = vec![]; + let reader = fs::read_dir(dir).map_err(Error::from)?; + for entry in reader { + let entry = entry.map_err(Error::from)?; + res.push(entry.file_name().to_string_lossy().to_string()); + } + Ok(res) + } + + async fn read_file(&self, file: &Utf8Path) -> Result> { + fs::read(file).map_err(Error::from) + } + + async fn stat(&self, file: &Utf8Path) -> Result { + let metadata = fs::metadata(file).map_err(Error::from)?; + FileMetadata::try_from(metadata) + } +} + impl From for FileMetadata { fn from(value: FileType) -> Self { FileMetadata { @@ -85,6 +133,7 @@ impl From for FileMetadata { } } +#[cfg(not(target_family = "wasm"))] #[async_trait::async_trait] impl ReadableFileSystem for NativeFileSystem { fn read(&self, path: &Utf8Path) -> Result> { @@ -148,6 +197,33 @@ impl ReadableFileSystem for NativeFileSystem { } } +#[cfg(target_family = "wasm")] +#[async_trait::async_trait] +impl ReadableFileSystem for NativeFileSystem { + fn read(&self, path: &Utf8Path) -> Result> { + fs::read(path).map_err(Error::from) + } + + fn metadata(&self, path: &Utf8Path) -> Result { + let meta = fs::metadata(path)?; + meta.try_into() + } + + fn symlink_metadata(&self, path: &Utf8Path) -> Result { + let meta = fs::symlink_metadata(path)?; + meta.try_into() + } + + fn canonicalize(&self, path: &Utf8Path) -> Result { + let path = dunce::canonicalize(path)?; + Ok(path.assert_utf8()) + } + + async fn async_read(&self, file: &Utf8Path) -> Result> { + fs::read(file).map_err(Error::from) + } +} + #[async_trait::async_trait] impl IntermediateFileSystemExtras for NativeFileSystem { async fn rename(&self, from: &Utf8Path, to: &Utf8Path) -> Result<()> { diff --git a/crates/rspack_futures/Cargo.toml b/crates/rspack_futures/Cargo.toml index 880093a64331..dca7e6e82e95 100644 --- a/crates/rspack_futures/Cargo.toml +++ b/crates/rspack_futures/Cargo.toml @@ -6,5 +6,8 @@ name = "rspack_futures" repository = "https://github.com/web-infra-dev/rspack" version = "0.2.0" -[dependencies] +[target.'cfg(target_family = "wasm")'.dependencies] +futures = { workspace = true } + +[target.'cfg(not(target_family = "wasm"))'.dependencies] async-scoped = { workspace = true, features = ["use-tokio"] } diff --git a/crates/rspack_futures/src/lib.rs b/crates/rspack_futures/src/lib.rs index 963b6d5e9adc..46a2b5891626 100644 --- a/crates/rspack_futures/src/lib.rs +++ b/crates/rspack_futures/src/lib.rs @@ -3,8 +3,6 @@ use std::{ ops::{Deref, DerefMut}, }; -use async_scoped::{Scope, TokioScope}; - /// Run futures in parallel. /// /// @@ -38,6 +36,7 @@ impl FuturesResults { } } +#[cfg(not(target_family = "wasm"))] impl FromIterator for FuturesResults where Fut: Future + Send, @@ -47,6 +46,8 @@ where where I: IntoIterator, { + use async_scoped::{Scope, TokioScope}; + let (_, inner) = Scope::scope_and_block(|s: &mut TokioScope<'_, _>| { iter.into_iter().for_each(|fut| { s.spawn(fut); @@ -71,6 +72,24 @@ where } } +#[cfg(target_family = "wasm")] +impl FromIterator for FuturesResults +where + Fut: Future + Send, + Fut::Output: Send + 'static, +{ + fn from_iter(iter: I) -> Self + where + I: IntoIterator, + { + use futures::future::join_all; + + Self { + inner: futures::executor::block_on(join_all(iter)), + } + } +} + impl Deref for FuturesResults { type Target = Vec; diff --git a/crates/rspack_loader_runner/Cargo.toml b/crates/rspack_loader_runner/Cargo.toml index acc321774842..41fc04b69db9 100644 --- a/crates/rspack_loader_runner/Cargo.toml +++ b/crates/rspack_loader_runner/Cargo.toml @@ -10,7 +10,7 @@ anymap = { workspace = true } async-trait = { workspace = true } derive_more = { workspace = true, features = ["debug"] } rustc-hash = { workspace = true } -tokio = { workspace = true, features = ["rt", "rt-multi-thread", "macros", "test-util", "parking_lot", "fs"] } +tokio = { workspace = true, features = ["test-util"] } once_cell = { workspace = true } regex = { workspace = true } diff --git a/crates/rspack_loader_swc/Cargo.toml b/crates/rspack_loader_swc/Cargo.toml index be5a4c4b9c18..a0407ce09635 100644 --- a/crates/rspack_loader_swc/Cargo.toml +++ b/crates/rspack_loader_swc/Cargo.toml @@ -35,7 +35,6 @@ rspack_util = { workspace = true } rustc-hash = { workspace = true } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } -stacker = { workspace = true } swc = { workspace = true, features = ["manual-tokio-runtime"] } swc_config = { workspace = true } swc_core = { workspace = true, features = ["base", "ecma_ast", "common"] } @@ -43,5 +42,8 @@ tokio = { workspace = true } tracing = { workspace = true } url = "2.5.0" +[target.'cfg(not(target_family = "wasm"))'.dependencies] +stacker = { workspace = true } + [build-dependencies] cargo_toml = { version = "0.21.0" } diff --git a/crates/rspack_loader_swc/src/lib.rs b/crates/rspack_loader_swc/src/lib.rs index a89a978b317c..3079a5326c1e 100644 --- a/crates/rspack_loader_swc/src/lib.rs +++ b/crates/rspack_loader_swc/src/lib.rs @@ -147,7 +147,7 @@ impl Loader for SwcLoader { async fn run(&self, loader_context: &mut LoaderContext) -> Result<()> { #[allow(unused_mut)] let mut inner = || self.loader_impl(loader_context); - #[cfg(debug_assertions)] + #[cfg(all(debug_assertions, not(target_family = "wasm")))] { // Adjust stack to avoid stack overflow. stacker::maybe_grow( @@ -156,7 +156,7 @@ impl Loader for SwcLoader { inner, ) } - #[cfg(not(debug_assertions))] + #[cfg(any(not(debug_assertions), target_family = "wasm"))] inner() } } diff --git a/crates/rspack_napi/Cargo.toml b/crates/rspack_napi/Cargo.toml index 2bf42b466af7..93fecab4c6cb 100644 --- a/crates/rspack_napi/Cargo.toml +++ b/crates/rspack_napi/Cargo.toml @@ -11,4 +11,4 @@ version = "0.2.0" napi = { workspace = true, features = ["async", "tokio_rt", "serde-json", "napi4", "anyhow"] } oneshot = "0.1.8" rspack_error = { workspace = true } -tokio = { workspace = true, features = ["rt", "rt-multi-thread", "macros", "test-util", "parking_lot"] } +tokio = { workspace = true, features = ["sync"] } diff --git a/crates/rspack_plugin_copy/Cargo.toml b/crates/rspack_plugin_copy/Cargo.toml index fd40fe2cd7cd..5495a39a92ba 100644 --- a/crates/rspack_plugin_copy/Cargo.toml +++ b/crates/rspack_plugin_copy/Cargo.toml @@ -21,8 +21,10 @@ rspack_paths = { workspace = true } rspack_util = { workspace = true } rustc-hash = { workspace = true } sugar_path = { workspace = true } -tokio = { workspace = true, features = ["fs"] } tracing = { workspace = true } +[target.'cfg(not(target_family = "wasm"))'.dependencies] +tokio = { workspace = true, features = ["fs"] } + [package.metadata.cargo-shear] ignored = ["tracing"] diff --git a/crates/rspack_plugin_copy/src/lib.rs b/crates/rspack_plugin_copy/src/lib.rs index 033dee224379..72072a1ff00e 100644 --- a/crates/rspack_plugin_copy/src/lib.rs +++ b/crates/rspack_plugin_copy/src/lib.rs @@ -264,7 +264,12 @@ impl CopyRspackPlugin { logger.debug(format!("reading '{}'...", absolute_filename)); // TODO inputFileSystem - let source_vec = match tokio::fs::read(absolute_filename.clone()).await { + #[cfg(not(target_family = "wasm"))] + let data = tokio::fs::read(absolute_filename.clone()).await; + #[cfg(target_family = "wasm")] + let data = std::fs::read(absolute_filename.clone()); + + let source_vec = match data { Ok(data) => { logger.debug(format!("read '{}'...", absolute_filename)); diff --git a/crates/rspack_plugin_javascript/Cargo.toml b/crates/rspack_plugin_javascript/Cargo.toml index b0b44f642da9..2552b5301596 100644 --- a/crates/rspack_plugin_javascript/Cargo.toml +++ b/crates/rspack_plugin_javascript/Cargo.toml @@ -35,7 +35,6 @@ rspack_regex = { workspace = true } rspack_util = { workspace = true } rustc-hash = { workspace = true } serde_json = { workspace = true } -stacker = { workspace = true } sugar_path = { workspace = true } swc_core = { workspace = true, features = [ "__parser", @@ -53,5 +52,8 @@ swc_node_comments = { workspace = true } tracing = { workspace = true } url = { workspace = true } +[target.'cfg(not(target_family = "wasm"))'.dependencies] +stacker = { workspace = true } + [package.metadata.cargo-shear] ignored = ["tracing"] diff --git a/crates/rspack_plugin_javascript/src/ast/parse.rs b/crates/rspack_plugin_javascript/src/ast/parse.rs index ca517d00d354..678e9302fefc 100644 --- a/crates/rspack_plugin_javascript/src/ast/parse.rs +++ b/crates/rspack_plugin_javascript/src/ast/parse.rs @@ -68,7 +68,7 @@ fn parse_with_lexer( } }; - #[cfg(debug_assertions)] + #[cfg(all(debug_assertions, not(target_family = "wasm")))] { // Adjust stack to avoid stack overflow. stacker::maybe_grow( @@ -77,7 +77,7 @@ fn parse_with_lexer( inner, ) } - #[cfg(not(debug_assertions))] + #[cfg(any(not(debug_assertions), target_family = "wasm"))] inner() } diff --git a/crates/rspack_plugin_mf/src/sharing/consume_shared_plugin.rs b/crates/rspack_plugin_mf/src/sharing/consume_shared_plugin.rs index acb4ab626f70..d8c1e8f21141 100644 --- a/crates/rspack_plugin_mf/src/sharing/consume_shared_plugin.rs +++ b/crates/rspack_plugin_mf/src/sharing/consume_shared_plugin.rs @@ -110,7 +110,13 @@ async fn get_description_file( loop { let description_file = dir.join(description_filename); - if let Ok(data) = tokio::fs::read(&description_file).await + + #[cfg(not(target_family = "wasm"))] + let data = tokio::fs::read(&description_file).await; + #[cfg(target_family = "wasm")] + let data = std::fs::read(&description_file); + + if let Ok(data) = data && let Ok(data) = serde_json::from_slice::(&data) { if satisfies_description_file_data diff --git a/crates/rspack_storage/Cargo.toml b/crates/rspack_storage/Cargo.toml index 7a0593cb80e7..a026cc3d7f1a 100644 --- a/crates/rspack_storage/Cargo.toml +++ b/crates/rspack_storage/Cargo.toml @@ -19,7 +19,7 @@ rspack_error = { workspace = true } rspack_fs = { workspace = true } rspack_paths = { workspace = true } rustc-hash = { workspace = true } -tokio = { workspace = true, features = ["rt", "rt-multi-thread", "macros", "test-util", "parking_lot", "fs"] } +tokio = { workspace = true } tracing = { workspace = true } [dev-dependencies] diff --git a/crates/rspack_tracing/Cargo.toml b/crates/rspack_tracing/Cargo.toml index 07265b473aa6..3300c42b2086 100644 --- a/crates/rspack_tracing/Cargo.toml +++ b/crates/rspack_tracing/Cargo.toml @@ -7,12 +7,14 @@ repository = "https://github.com/web-infra-dev/rspack" version = "0.2.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[features] +otel = ["opentelemetry", "opentelemetry-otlp", "opentelemetry_sdk", "tracing-opentelemetry"] [dependencies] -opentelemetry = "0.26.0" -opentelemetry-otlp = "0.26.0" -opentelemetry_sdk = { version = "0.26.0", features = ["rt-tokio"] } +opentelemetry = { version = "0.26.0", optional = true } +opentelemetry-otlp = { version = "0.26.0", optional = true } +opentelemetry_sdk = { version = "0.26.0", features = ["rt-tokio"], optional = true } tracing = { workspace = true } tracing-chrome = "0.7.2" -tracing-opentelemetry = "0.27.0" +tracing-opentelemetry = { version = "0.27.0", optional = true } tracing-subscriber = { workspace = true, features = ["env-filter"] } diff --git a/crates/rspack_tracing/src/lib.rs b/crates/rspack_tracing/src/lib.rs index b82d572a1798..05afb42f04cd 100644 --- a/crates/rspack_tracing/src/lib.rs +++ b/crates/rspack_tracing/src/lib.rs @@ -1,21 +1,18 @@ mod chrome; -mod opentelemetry; mod stdout; mod tracer; use std::{fs, io, path::Path}; pub use chrome::ChromeTracer; -pub use opentelemetry::OtelTracer; pub use stdout::StdoutTracer; pub use tracer::Tracer; use tracing_subscriber::fmt::writer::BoxMakeWriter; -pub mod otel { - pub use opentelemetry; - pub use opentelemetry_sdk as sdk; - pub use tracing_opentelemetry as tracing; -} +#[cfg(feature = "otel")] +mod opentelemetry; +#[cfg(feature = "otel")] +pub use opentelemetry::*; pub(crate) enum TraceWriter<'a> { Stdout, diff --git a/crates/rspack_tracing/src/opentelemetry.rs b/crates/rspack_tracing/src/opentelemetry.rs index f9839686679c..23f5eb89a2ff 100644 --- a/crates/rspack_tracing/src/opentelemetry.rs +++ b/crates/rspack_tracing/src/opentelemetry.rs @@ -45,3 +45,9 @@ impl Tracer for OtelTracer { opentelemetry::global::shutdown_tracer_provider(); } } + +pub mod otel { + pub use opentelemetry; + pub use opentelemetry_sdk as sdk; + pub use tracing_opentelemetry as tracing; +} diff --git a/npm/wasm32-wasi/package.json b/npm/wasm32-wasi/package.json new file mode 100644 index 000000000000..35f9bf19d89d --- /dev/null +++ b/npm/wasm32-wasi/package.json @@ -0,0 +1,28 @@ +{ + "name": "@rspack/binding-wasm32-wasi", + "version": "1.2.7", + "license": "MIT", + "description": "Node binding for rspack", + "main": "rspack.wasi.cjs", + "browser": "rspack.wasi-browser.js", + "homepage": "https://rspack.dev", + "bugs": "https://github.com/web-infra-dev/rspack/issues", + "repository": { + "type": "git", + "url": "https://github.com/web-infra-dev/rspack" + }, + "publishConfig": { + "access": "public", + "provenance": true + }, + "files": [ + "rspack.wasm32-wasi.wasm", + "rspack.wasi.cjs", + "rspack.wasi-browser.js", + "wasi-worker.mjs", + "wasi-worker-browser.mjs" + ], + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.7" + } +} diff --git a/packages/rspack-test-tools/tests/__snapshots__/StatsAPI.test.js.snap b/packages/rspack-test-tools/tests/__snapshots__/StatsAPI.test.js.snap index 3f44f2b465e2..d5a3ce18f2ab 100644 --- a/packages/rspack-test-tools/tests/__snapshots__/StatsAPI.test.js.snap +++ b/packages/rspack-test-tools/tests/__snapshots__/StatsAPI.test.js.snap @@ -49,7 +49,7 @@ Object { main.js, ], filteredModules: undefined, - hash: 50f4182a210ae3fc, + hash: 9cd19fc0a208da71, id: 909, idHints: Array [], initial: true, @@ -179,7 +179,7 @@ Object { errorsCount: 0, filteredAssets: undefined, filteredModules: undefined, - hash: 59afbeeb2d3dd524, + hash: 23417a360dbe1de8, modules: Array [ Object { assets: Array [], @@ -330,7 +330,7 @@ Object { main.js, ], filteredModules: undefined, - hash: 6b90d3665b9a32f0, + hash: 526d08f00e1e8f2f, id: 909, idHints: Array [], initial: true, @@ -718,7 +718,7 @@ Object { errorsCount: 0, filteredAssets: undefined, filteredModules: undefined, - hash: 78322e9a4de35476, + hash: 1bb5e91c0d72ce7a, modules: Array [ Object { assets: Array [], @@ -1521,7 +1521,7 @@ Object { files: Array [ main.js, ], - hash: 50f4182a210ae3fc, + hash: 9cd19fc0a208da71, id: 909, idHints: Array [], initial: true, @@ -1661,7 +1661,7 @@ Object { main.js, ], filteredModules: undefined, - hash: e813d411c0f3d316, + hash: 9cf6270d68f3f78e, id: 909, idHints: Array [], initial: true, @@ -2030,7 +2030,7 @@ exports.c = require("./c?c=3");, errorsCount: 0, filteredAssets: undefined, filteredModules: undefined, - hash: 27d6c5d54c85318d, + hash: 2026699fe6b29204, modules: Array [ Object { assets: Array [], diff --git a/packages/rspack-test-tools/tests/statsAPICases/basic.js b/packages/rspack-test-tools/tests/statsAPICases/basic.js index f03b449cd8e2..a3c2c7fae904 100644 --- a/packages/rspack-test-tools/tests/statsAPICases/basic.js +++ b/packages/rspack-test-tools/tests/statsAPICases/basic.js @@ -37,7 +37,7 @@ module.exports = { entry ./fixtures/a cjs self exports reference self [585] ./fixtures/a.js - Rspack compiled successfully (59afbeeb2d3dd524) + Rspack compiled successfully (23417a360dbe1de8) `); } }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ca144e427729..0fadba79d3fc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -106,13 +106,22 @@ importers: '@rspack/binding-linux-x64-gnu': specifier: workspace:* version: link:../../npm/linux-x64-gnu + '@rspack/binding-wasm32-wasi': + specifier: workspace:* + version: link:../../npm/wasm32-wasi '@rspack/binding-win32-x64-msvc': specifier: workspace:* version: link:../../npm/win32-x64-msvc devDependencies: '@napi-rs/cli': specifier: 3.0.0-alpha.73 - version: 3.0.0-alpha.73(@emnapi/runtime@1.3.1)(@types/node@20.17.23) + version: 3.0.0-alpha.73(@emnapi/runtime@1.3.1)(@types/node@20.17.23)(emnapi@1.3.1) + '@napi-rs/wasm-runtime': + specifier: ^0.2.7 + version: 0.2.7 + emnapi: + specifier: ^1.3.1 + version: 1.3.1 typescript: specifier: ^5.7.3 version: 5.7.3 @@ -132,6 +141,12 @@ importers: npm/linux-x64-gnu: {} + npm/wasm32-wasi: + dependencies: + '@napi-rs/wasm-runtime': + specifier: ^0.2.7 + version: 0.2.7 + npm/win32-x64-msvc: {} packages/create-rspack: @@ -2312,8 +2327,8 @@ packages: resolution: {integrity: sha512-hDsvmMZY8tl2CcLfjnTeE1o5W1eGTSL+ZIX8YEybtcJwA+Cc8SNHb7l6JqMnGcjOrWBZbHt8tzTN+W7qHS5Wmg==} engines: {node: '>= 10'} - '@napi-rs/wasm-runtime@0.2.5': - resolution: {integrity: sha512-kwUxR7J9WLutBbulqg1dfOrMTwhMdXLdcGUhcbCcGwnPLt3gz19uHVdwH1syKVDbE022ZS2vZxOWflFLS0YTjw==} + '@napi-rs/wasm-runtime@0.2.7': + resolution: {integrity: sha512-5yximcFK5FNompXfJFoWanu5l8v1hNGqNHh9du1xETp9HWk/B/PzvchX55WYOPaIeNglG8++68AAiauBAtbnzw==} '@napi-rs/wasm-tools-android-arm-eabi@0.0.2': resolution: {integrity: sha512-/b+UU3suXjW4P0DzHRNdrnebQtFKcQf/YMeZJH+xUlKgvwli5kbmWjx8Wqqz0VETVkUTuPqJMBDIVLyc+14FGw==} @@ -4713,6 +4728,14 @@ packages: resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} engines: {node: '>=12'} + emnapi@1.3.1: + resolution: {integrity: sha512-8rnw2VLJmHAXBSyhtrL9O5aW1VdbXA1ovRslp0IyTwnM62Fz83jQIo+VaIObgzdo6r1A98J9AHEq4KTqIR67Aw==} + peerDependencies: + node-addon-api: '>= 6.1.0' + peerDependenciesMeta: + node-addon-api: + optional: true + emoji-regex@10.4.0: resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==} @@ -8929,17 +8952,14 @@ snapshots: dependencies: '@emnapi/wasi-threads': 1.0.1 tslib: 2.8.1 - optional: true '@emnapi/runtime@1.3.1': dependencies: tslib: 2.8.1 - optional: true '@emnapi/wasi-threads@1.0.1': dependencies: tslib: 2.8.1 - optional: true '@esbuild/aix-ppc64@0.21.5': optional: true @@ -9557,7 +9577,7 @@ snapshots: '@napi-rs/cli@2.18.4': {} - '@napi-rs/cli@3.0.0-alpha.73(@emnapi/runtime@1.3.1)(@types/node@20.17.23)': + '@napi-rs/cli@3.0.0-alpha.73(@emnapi/runtime@1.3.1)(@types/node@20.17.23)(emnapi@1.3.1)': dependencies: '@inquirer/prompts': 7.0.1(@types/node@20.17.23) '@napi-rs/cross-toolchain': 0.0.19 @@ -9574,6 +9594,7 @@ snapshots: wasm-sjlj: 1.0.5 optionalDependencies: '@emnapi/runtime': 1.3.1 + emnapi: 1.3.1 transitivePeerDependencies: - '@napi-rs/cross-toolchain-arm64-target-aarch64' - '@napi-rs/cross-toolchain-arm64-target-armv7' @@ -9633,7 +9654,7 @@ snapshots: '@napi-rs/lzma-wasm32-wasi@1.4.1': dependencies: - '@napi-rs/wasm-runtime': 0.2.5 + '@napi-rs/wasm-runtime': 0.2.7 optional: true '@napi-rs/lzma-win32-arm64-msvc@1.4.1': @@ -9703,7 +9724,7 @@ snapshots: '@napi-rs/tar-wasm32-wasi@0.1.4': dependencies: - '@napi-rs/wasm-runtime': 0.2.5 + '@napi-rs/wasm-runtime': 0.2.7 optional: true '@napi-rs/tar-win32-arm64-msvc@0.1.4': @@ -9734,12 +9755,11 @@ snapshots: '@napi-rs/tar-win32-ia32-msvc': 0.1.4 '@napi-rs/tar-win32-x64-msvc': 0.1.4 - '@napi-rs/wasm-runtime@0.2.5': + '@napi-rs/wasm-runtime@0.2.7': dependencies: '@emnapi/core': 1.3.1 '@emnapi/runtime': 1.3.1 '@tybys/wasm-util': 0.9.0 - optional: true '@napi-rs/wasm-tools-android-arm-eabi@0.0.2': optional: true @@ -9770,7 +9790,7 @@ snapshots: '@napi-rs/wasm-tools-wasm32-wasi@0.0.2': dependencies: - '@napi-rs/wasm-runtime': 0.2.5 + '@napi-rs/wasm-runtime': 0.2.7 optional: true '@napi-rs/wasm-tools-win32-arm64-msvc@0.0.2': @@ -10681,7 +10701,6 @@ snapshots: '@tybys/wasm-util@0.9.0': dependencies: tslib: 2.8.1 - optional: true '@types/acorn@4.0.6': dependencies: @@ -12352,6 +12371,8 @@ snapshots: emittery@0.13.1: {} + emnapi@1.3.1: {} + emoji-regex@10.4.0: {} emoji-regex@8.0.0: {} diff --git a/scripts/build-npm.cjs b/scripts/build-npm.cjs index 50aa8722b8b5..5720c52fe53c 100644 --- a/scripts/build-npm.cjs +++ b/scripts/build-npm.cjs @@ -89,7 +89,8 @@ const bindings = fs .readdirSync(ARTIFACTS, { withFileTypes: true }) - .filter(item => item.isDirectory()) + // We are not going to release wasm yet + .filter(item => item.isDirectory() && !item.name.includes("wasm")) .map(item => path.join(ARTIFACTS, item.name)); const optionalDependencies = {};