diff --git a/.github/actions/clone-crates/action.yml b/.github/actions/clone-crates/action.yml index a3b67be..033f050 100644 --- a/.github/actions/clone-crates/action.yml +++ b/.github/actions/clone-crates/action.yml @@ -12,7 +12,7 @@ inputs: required: false type: string ref: - default: 'v0.5.7' + default: 'v1.0.3' required: false type: string temp: diff --git a/Cargo.lock b/Cargo.lock index fc75791..5cb52f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,9 +29,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ "getrandom", "once_cell", @@ -40,9 +40,9 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.6" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "getrandom", @@ -54,9 +54,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -82,12 +82,6 @@ dependencies = [ "libc", ] -[[package]] -name = "anes" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" - [[package]] name = "ansi_term" version = "0.12.1" @@ -97,12 +91,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "anstyle" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" - [[package]] name = "any_ascii" version = "0.1.7" @@ -111,9 +99,9 @@ checksum = "70033777eb8b5124a81a1889416543dddef2de240019b674c81285a2635a7e1e" [[package]] name = "anyhow" -version = "1.0.80" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" +checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" dependencies = [ "backtrace", ] @@ -125,34 +113,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f1f8f5a6f3d50d89e3797d7593a50f96bb2aaa20ca0cc7be1fb673232c91d72" [[package]] -name = "argh" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7af5ba06967ff7214ce4c7419c7d185be7ecd6cc4965a8f6e1d8ce0398aad219" -dependencies = [ - "argh_derive", - "argh_shared", -] - -[[package]] -name = "argh_derive" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56df0aeedf6b7a2fc67d06db35b09684c3e8da0c95f8f27685cb17e08413d87a" -dependencies = [ - "argh_shared", - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "argh_shared" -version = "0.1.12" +name = "arca" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5693f39141bda5760ecc4111ab08da40565d1771038c4a0250f03457ec707531" +checksum = "5f915ddd863ef73f11c10c75170e86db1d4f539689bc6bfb9ce25d6528d6fe83" dependencies = [ - "serde", + "clean-path", + "path-slash", + "radix_trie", ] [[package]] @@ -169,25 +137,25 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "ast_node" -version = "0.9.6" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3e3e06ec6ac7d893a0db7127d91063ad7d9da8988f8a1a256f03729e6eec026" +checksum = "2ab31376d309dd3bfc9cfb3c11c93ce0e0741bbe0354b20e7f8c60b044730b79" dependencies = [ "proc-macro2", "quote", "swc_macros_common", - "syn 2.0.52", + "syn 2.0.63", ] [[package]] name = "async-recursion" -version = "1.0.5" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.63", ] [[package]] @@ -203,13 +171,13 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.77" +version = "0.1.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.63", ] [[package]] @@ -234,14 +202,13 @@ dependencies = [ [[package]] name = "auto_impl" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fee3da8ef1276b0bee5dd1c7258010d8fffd31801447323115a25560e1327b89" +checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ - "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.63", ] [[package]] @@ -275,22 +242,25 @@ dependencies = [ ] [[package]] -name = "base-x" -version = "0.2.11" +name = "base64" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64" -version = "0.13.1" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] -name = "base64" -version = "0.21.7" +name = "base64-simd" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +checksum = "781dd20c3aff0bd194fe7d2a977dd92f21c173891f3a03b677359e5fa457e5d5" +dependencies = [ + "simd-abstraction", +] [[package]] name = "base64-simd" @@ -298,7 +268,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195" dependencies = [ - "outref", + "outref 0.5.1", "vsimd", ] @@ -325,65 +295,87 @@ name = "binding_options" version = "0.1.0" dependencies = [ "async-trait", - "better_scoped_tls", "derivative", "glob", "loader_barrel", "loader_compilation", - "napi", "napi-derive", - "plugin_manifest", - "rspack_binding_macros", - "rspack_binding_options", + "napi-h", "rspack_binding_values", + "rspack_collections", "rspack_core", "rspack_error", "rspack_hash", - "rspack_identifier", + "rspack_hook", "rspack_ids", + "rspack_loader_lightningcss", + "rspack_loader_preact_refresh", "rspack_loader_react_refresh", "rspack_loader_runner", "rspack_loader_swc", - "rspack_napi_shared", + "rspack_loader_testing", + "rspack_napi", + "rspack_napi_macros", + "rspack_paths", "rspack_plugin_asset", "rspack_plugin_banner", "rspack_plugin_copy", "rspack_plugin_css", "rspack_plugin_devtool", + "rspack_plugin_dynamic_entry", "rspack_plugin_ensure_chunk_conditions", "rspack_plugin_entry", "rspack_plugin_externals", + "rspack_plugin_extract_css", "rspack_plugin_hmr", "rspack_plugin_html", + "rspack_plugin_ignore", "rspack_plugin_javascript", "rspack_plugin_json", + "rspack_plugin_lazy_compilation", "rspack_plugin_library", + "rspack_plugin_lightning_css_minimizer", "rspack_plugin_limit_chunk_count", "rspack_plugin_merge_duplicate_chunks", "rspack_plugin_mf", + "rspack_plugin_no_emit_on_errors", "rspack_plugin_progress", "rspack_plugin_real_content_hash", "rspack_plugin_remove_empty_chunks", "rspack_plugin_runtime", + "rspack_plugin_runtime_chunk", "rspack_plugin_schemes", + "rspack_plugin_size_limits", "rspack_plugin_split_chunks", - "rspack_plugin_swc_css_minimizer", "rspack_plugin_swc_js_minimizer", "rspack_plugin_warn_sensitive_module", "rspack_plugin_wasm", "rspack_plugin_web_worker_template", "rspack_plugin_worker", "rspack_regex", - "rspack_swc_visitors", - "rustc-hash", + "rustc-hash 1.1.0", "serde", "serde_json", - "swc_config", "swc_core", "tokio", "tracing", ] +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + [[package]] name = "bitflags" version = "1.3.2" @@ -392,9 +384,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "bitvec" @@ -432,42 +424,40 @@ dependencies = [ [[package]] name = "browserslist-rs" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "405bbd46590a441abe5db3e5c8af005aa42e640803fecb51912703e93e4ce8d3" +checksum = "fdf0ca73de70c3da94e4194e4a01fe732378f55d47cf4c0588caab22a0dbfa14" dependencies = [ - "ahash 0.8.6", - "anyhow", + "ahash 0.8.11", "chrono", "either", - "indexmap 2.2.5", - "itertools 0.12.1", + "indexmap 2.2.6", + "itertools 0.13.0", "nom", "once_cell", - "quote", "serde", "serde_json", - "string_cache", - "string_cache_codegen", "thiserror", ] [[package]] name = "bstr" -version = "0.2.17" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" +checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" dependencies = [ - "lazy_static", "memchr", - "regex-automata 0.1.10", + "serde", ] [[package]] name = "bumpalo" -version = "3.13.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +dependencies = [ + "allocator-api2", +] [[package]] name = "bytecheck" @@ -507,35 +497,30 @@ dependencies = [ ] [[package]] -name = "camino" -version = "1.1.6" +name = "bytesize" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +checksum = "a3e368af43e418a04d52505cf3dbc23dda4e3407ae2fa99fd0e4f308ce546acc" dependencies = [ "serde", ] [[package]] -name = "cargo-platform" -version = "0.1.7" +name = "camino" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "694c8807f2ae16faecc43dc17d74b3eb042482789fd0eb64b39a2e04e087053f" +checksum = "3054fea8a20d8ff3968d5b22cc27501d2b08dc4decdb31b184323f00c5ef23bb" dependencies = [ "serde", ] [[package]] -name = "cargo-rst" -version = "0.1.0" +name = "cargo-platform" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" dependencies = [ - "colored", - "console", - "derive_builder 0.20.0", - "glob", "serde", - "serde_json", - "similar", - "testing_macros", ] [[package]] @@ -553,10 +538,18 @@ dependencies = [ ] [[package]] -name = "cast" -version = "0.3.0" +name = "cargo_metadata" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +dependencies = [ + "camino", + "cargo-platform", + "semver 1.0.20", + "serde", + "serde_json", + "thiserror", +] [[package]] name = "cc" @@ -579,60 +572,15 @@ dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", - "windows-targets 0.52.0", -] - -[[package]] -name = "ciborium" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" -dependencies = [ - "ciborium-io", - "ciborium-ll", "serde", + "windows-targets 0.52.0", ] [[package]] -name = "ciborium-io" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" - -[[package]] -name = "ciborium-ll" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" -dependencies = [ - "ciborium-io", - "half 2.3.1", -] - -[[package]] -name = "clap" -version = "4.4.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" -dependencies = [ - "clap_builder", -] - -[[package]] -name = "clap_builder" -version = "4.4.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" -dependencies = [ - "anstyle", - "clap_lex", -] - -[[package]] -name = "clap_lex" -version = "0.6.0" +name = "clean-path" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "aaa6b4b263a5d737e9bf6b7c09b72c41a5480aec4d7219af827f6564e950b6a5" [[package]] name = "color-backtrace" @@ -644,22 +592,21 @@ dependencies = [ "termcolor", ] -[[package]] -name = "colored" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" -dependencies = [ - "lazy_static", - "windows-sys 0.48.0", -] - [[package]] name = "concat-string" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7439becb5fafc780b6f4de382b1a7a3e70234afe783854a4702ee8adbb838609" +[[package]] +name = "concurrent_lru" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7feb5cb312f774e8a24540e27206db4e890f7d488563671d24a16389cf4c2e4e" +dependencies = [ + "once_cell", +] + [[package]] name = "console" version = "0.15.8" @@ -674,10 +621,24 @@ dependencies = [ ] [[package]] -name = "const_fn" -version = "0.4.9" +name = "const-str" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21077772762a1002bb421c3af42ac1725fa56066bfc53d9a55bb79905df2aaf3" +dependencies = [ + "const-str-proc-macro", +] + +[[package]] +name = "const-str-proc-macro" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbdcdcb6d86f71c5e97409ad45898af11cbc995b4ee8112d59095a28d376c935" +checksum = "5e1e0fdd2e5d3041e530e1b21158aeeef8b5d0e306bc5c1e3d6cf0930d10e25a" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] [[package]] name = "constant_time_eq" @@ -821,49 +782,20 @@ dependencies = [ ] [[package]] -name = "criterion" -version = "0.5.1" +name = "critical-section" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" -dependencies = [ - "anes", - "cast", - "ciborium", - "clap", - "criterion-plot", - "futures", - "is-terminal", - "itertools 0.10.5", - "num-traits", - "once_cell", - "oorandom", - "plotters", - "rayon", - "regex", - "serde", - "serde_derive", - "serde_json", - "tinytemplate", - "tokio", - "walkdir", -] +checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" [[package]] -name = "criterion-plot" -version = "0.5.0" +name = "crossbeam-channel" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" +checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" dependencies = [ - "cast", - "itertools 0.10.5", + "crossbeam-utils", ] -[[package]] -name = "critical-section" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" - [[package]] name = "crossbeam-deque" version = "0.8.3" @@ -884,21 +816,24 @@ dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "memoffset 0.9.0", + "memoffset", "scopeguard", ] [[package]] -name = "crossbeam-utils" -version = "0.8.19" +name = "crossbeam-queue" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +dependencies = [ + "crossbeam-utils", +] [[package]] -name = "crunchy" -version = "0.2.2" +name = "crossbeam-utils" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" [[package]] name = "crypto-common" @@ -911,20 +846,55 @@ dependencies = [ ] [[package]] -name = "ctor" -version = "0.2.3" +name = "css-module-lexer" +version = "0.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed5fff0d93c7559121e9c72bf9c242295869396255071ff2cb1617147b608c5" +checksum = "7c3cb070d213f1295804b62e861ba5d05435497591212a55826af6d54b2447c8" +dependencies = [ + "smallvec", +] + +[[package]] +name = "cssparser" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9be934d936a0fbed5bcdc01042b770de1398bf79d0e192f49fa7faea0e99281e" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa", + "phf 0.11.2", + "smallvec", +] + +[[package]] +name = "cssparser-color" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556c099a61d85989d7af52b692e35a8d68a57e7df8c6d07563dc0778b3960c9f" +dependencies = [ + "cssparser", +] + +[[package]] +name = "cssparser-macros" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote", - "syn 2.0.52", + "syn 2.0.63", ] [[package]] -name = "cty" -version = "0.2.2" +name = "ctor" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" +checksum = "eed5fff0d93c7559121e9c72bf9c242295869396255071ff2cb1617147b608c5" +dependencies = [ + "quote", + "syn 2.0.63", +] [[package]] name = "darling" @@ -971,7 +941,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.52", + "syn 2.0.63", ] [[package]] @@ -993,7 +963,7 @@ checksum = "c5a91391accf613803c2a9bf9abccdbaa07c54b4244a5b64883f9c3c137c86be" dependencies = [ "darling_core 0.20.6", "quote", - "syn 2.0.52", + "syn 2.0.63", ] [[package]] @@ -1003,7 +973,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "hashbrown 0.14.3", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", + "rayon", +] + +[[package]] +name = "dashmap" +version = "6.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "804c8821570c3f8b70230c2ba75ffa5c0f9a4189b9a432b6656c536712acae28" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", "lock_api", "once_cell", "parking_lot_core", @@ -1011,9 +996,18 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.5.0" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" + +[[package]] +name = "data-url" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" +checksum = "3a30bfce702bcfa94e906ef82421f2c0e61c076ad76030c16ee5d2e9a32fe193" +dependencies = [ + "matches", +] [[package]] name = "debugid" @@ -1025,6 +1019,16 @@ dependencies = [ "uuid", ] +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", + "serde", +] + [[package]] name = "derivative" version = "2.2.0" @@ -1042,16 +1046,7 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8" dependencies = [ - "derive_builder_macro 0.12.0", -] - -[[package]] -name = "derive_builder" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0350b5cb0331628a5916d6c5c0b72e97393b8b6b03b47a9284f4e7f5a405ffd7" -dependencies = [ - "derive_builder_macro 0.20.0", + "derive_builder_macro", ] [[package]] @@ -1066,38 +1061,16 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "derive_builder_core" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d48cda787f839151732d396ac69e3473923d54312c070ee21e9effcaa8ca0b1d" -dependencies = [ - "darling 0.20.6", - "proc-macro2", - "quote", - "syn 2.0.52", -] - [[package]] name = "derive_builder_macro" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e" dependencies = [ - "derive_builder_core 0.12.0", + "derive_builder_core", "syn 1.0.109", ] -[[package]] -name = "derive_builder_macro" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "206868b8242f27cecce124c19fd88157fbd0dd334df2587f36417bafbc85097b" -dependencies = [ - "derive_builder_core 0.20.0", - "syn 2.0.52", -] - [[package]] name = "diff" version = "0.1.13" @@ -1121,39 +1094,33 @@ dependencies = [ ] [[package]] -name = "dirs" -version = "4.0.0" +name = "dissimilar" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" -dependencies = [ - "dirs-sys", -] +checksum = "86e3bdc80eee6e16b2b6b0f87fbc98c04bee3455e35174c0de1a125d0688c632" [[package]] -name = "dirs-sys" -version = "0.3.7" +name = "document-features" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +checksum = "cb6969eaabd2421f8a2775cfd2471a2b634372b4a25d41e3bd647b79912850a0" dependencies = [ - "libc", - "redox_users", - "winapi", + "litrs", ] [[package]] -name = "discard" -version = "1.0.4" +name = "dtoa" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" +checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" [[package]] -name = "dojang" -version = "0.1.6" +name = "dtoa-short" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f07994caf710e9d5fc534432b40c4a9c16ed320aa673bb768eec6c7d5cbfbc32" +checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87" dependencies = [ - "html-escape", - "serde_json", + "dtoa", ] [[package]] @@ -1170,9 +1137,9 @@ checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" [[package]] name = "either" -version = "1.9.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "encode_unicode" @@ -1180,6 +1147,12 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + [[package]] name = "enum-iterator" version = "0.7.0" @@ -1218,7 +1191,7 @@ dependencies = [ "darling 0.20.6", "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.63", ] [[package]] @@ -1254,6 +1227,32 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" +[[package]] +name = "fancy-regex" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "531e46835a22af56d1e3b66f04844bed63158bc094a628bec1d321d9b4c44bf2" +dependencies = [ + "bit-set", + "regex-automata 0.4.4", + "regex-syntax 0.8.3", +] + +[[package]] +name = "fast-glob" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb10ed0f8a3dca52477be37ac0fb8f9d1fd4cd8d311b4484bdd45c1c56e0c9ec" + +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + [[package]] name = "fastrand" version = "2.0.1" @@ -1288,6 +1287,15 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" +dependencies = [ + "num-traits", +] + [[package]] name = "fnv" version = "1.0.7" @@ -1305,13 +1313,13 @@ dependencies = [ [[package]] name = "from_variant" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a0b11eeb173ce52f84ebd943d42e58813a2ebb78a6a3ff0a243b71c5199cd7b" +checksum = "fdc9cc75639b041067353b9bce2450d6847e547276c6fbe4487d7407980e07db" dependencies = [ "proc-macro2", "swc_macros_common", - "syn 2.0.52", + "syn 2.0.63", ] [[package]] @@ -1353,12 +1361,13 @@ dependencies = [ [[package]] name = "futures-concurrency" -version = "7.4.3" +version = "7.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef6712e11cdeed5c8cf21ea0b90fec40fbe64afc9bbf2339356197eeca829fc3" +checksum = "51ee14e256b9143bfafbf2fddeede6f396650bacf95d06fc1b3f2b503df129a0" dependencies = [ "bitvec", "futures-core", + "futures-lite", "pin-project", "slab", "smallvec", @@ -1387,6 +1396,21 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand 1.9.0", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + [[package]] name = "futures-macro" version = "0.3.30" @@ -1395,7 +1419,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.63", ] [[package]] @@ -1437,6 +1461,19 @@ dependencies = [ "byteorder", ] +[[package]] +name = "generator" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e" +dependencies = [ + "cc", + "libc", + "log", + "rustversion", + "windows", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -1449,9 +1486,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "js-sys", @@ -1484,10 +1521,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] -name = "glob-match" -version = "0.2.1" +name = "globset" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985c9503b412198aa4197559e9a318524ebc4519c229bfa05a535828c950b9d" +checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata 0.4.4", + "regex-syntax 0.8.3", +] [[package]] name = "half" @@ -1496,20 +1540,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" [[package]] -name = "half" -version = "2.3.1" +name = "halfbrown" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc52e53916c08643f1b56ec082790d1e86a32e58dc5268f897f313fbae7b4872" +checksum = "8588661a8607108a5ca69cab034063441a0413a0b041c13618a7dd348021ef6f" dependencies = [ - "cfg-if", - "crunchy", + "hashbrown 0.14.5", + "serde", ] [[package]] name = "handlebars" -version = "5.1.0" +version = "5.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab283476b99e66691dee3f1640fea91487a8d81f50fb5ecc75538f8f8879a1e4" +checksum = "d08485b96a0e6393e9e4d1b8d48cf74ad6c063cd905eb33f42c1ce3f0377539b" dependencies = [ "log", "pest", @@ -1534,7 +1578,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash 0.7.6", + "ahash 0.7.8", ] [[package]] @@ -1543,26 +1587,26 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.11", ] [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.11", "allocator-api2", ] [[package]] name = "hashlink" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692eaaf7f7607518dd3cef090f1474b61edc5301d8012f09579920df68b725ee" +checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" dependencies = [ - "hashbrown 0.14.3", + "hashbrown 0.14.5", ] [[package]] @@ -1589,9 +1633,9 @@ dependencies = [ [[package]] name = "heck" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" @@ -1614,23 +1658,18 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -[[package]] -name = "hrx-parser" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb741d1d6fce95c065abb032a5f302299520a23928a95e96ab64799b5fd97f3a" - [[package]] name = "hstr" -version = "0.2.6" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de90d3db62411eb62eddabe402d706ac4970f7ac8d088c05f11069cad9be9857" +checksum = "96274be293b8877e61974a607105d09c84caebe9620b47774aa8a6b942042dd4" dependencies = [ + "hashbrown 0.14.5", "new_debug_unreachable", "once_cell", - "phf", - "rustc-hash", - "smallvec", + "phf 0.11.2", + "rustc-hash 1.1.0", + "triomphe", ] [[package]] @@ -1644,9 +1683,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.12" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -1704,6 +1743,22 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" +[[package]] +name = "ignore" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1" +dependencies = [ + "crossbeam-deque", + "globset", + "log", + "memchr", + "regex-automata 0.4.4", + "same-file", + "walkdir", + "winapi-util", +] + [[package]] name = "indexmap" version = "1.9.3" @@ -1717,12 +1772,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.5" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "rayon", "serde", ] @@ -1741,18 +1796,10 @@ dependencies = [ ] [[package]] -name = "insta" -version = "1.36.1" +name = "indoc" +version = "2.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a7c22c4d34ef4788c351e971c52bfdfe7ea2766f8c5466bc175dd46e52ac22e" -dependencies = [ - "console", - "lazy_static", - "linked-hash-map", - "serde", - "similar", - "yaml-rust", -] +checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" [[package]] name = "instant" @@ -1765,15 +1812,14 @@ dependencies = [ [[package]] name = "is-macro" -version = "0.3.0" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4467ed1321b310c2625c5aa6c1b1ffc5de4d9e42668cf697a08fb033ee8265e" +checksum = "59a85abdc13717906baccb5a1e435556ce0df215f242892f721dff62bf25288f" dependencies = [ "Inflector", - "pmutil", "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.63", ] [[package]] @@ -1804,18 +1850,18 @@ dependencies = [ [[package]] name = "itertools" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" dependencies = [ "either", ] [[package]] name = "itoa" -version = "1.0.8" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" @@ -1868,49 +1914,6 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" -[[package]] -name = "lexical" -version = "6.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7aefb36fd43fef7003334742cbf77b243fcd36418a1d1bdd480d613a67968f6" -dependencies = [ - "lexical-core", -] - -[[package]] -name = "lexical-core" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cde5de06e8d4c2faabc400238f9ae1c74d5412d03a7bd067645ccbc47070e46" -dependencies = [ - "lexical-parse-float", - "lexical-parse-integer", - "lexical-util", - "lexical-write-float", - "lexical-write-integer", -] - -[[package]] -name = "lexical-parse-float" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683b3a5ebd0130b8fb52ba0bdc718cc56815b6a097e28ae5a6997d0ad17dc05f" -dependencies = [ - "lexical-parse-integer", - "lexical-util", - "static_assertions", -] - -[[package]] -name = "lexical-parse-integer" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d0994485ed0c312f6d965766754ea177d07f9c00c9b82a5ee62ed5b47945ee9" -dependencies = [ - "lexical-util", - "static_assertions", -] - [[package]] name = "lexical-sort" version = "0.3.1" @@ -1921,60 +1924,69 @@ dependencies = [ ] [[package]] -name = "lexical-util" -version = "0.8.5" +name = "libc" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5255b9ff16ff898710eb9eb63cb39248ea8a5bb036bea8085b1a767ff6c4e3fc" -dependencies = [ - "static_assertions", -] +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] -name = "lexical-write-float" -version = "0.8.5" +name = "libloading" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accabaa1c4581f05a3923d1b4cfd124c329352288b7b9da09e766b0668116862" +checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" dependencies = [ - "lexical-util", - "lexical-write-integer", - "static_assertions", + "cfg-if", + "windows-sys 0.48.0", ] [[package]] -name = "lexical-write-integer" -version = "0.8.5" +name = "libmimalloc-sys" +version = "0.1.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1b6f3d1f4422866b68192d62f77bc5c700bee84f3069f2469d7bc8c77852446" +checksum = "23aa6811d3bd4deb8a84dde645f943476d13b248d818edcf8ce0b2f37f036b44" dependencies = [ - "lexical-util", - "static_assertions", + "cc", + "libc", ] [[package]] -name = "libc" -version = "0.2.147" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" - -[[package]] -name = "libloading" -version = "0.8.1" +name = "lightningcss" +version = "1.0.0-alpha.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" +checksum = "ec380ca49dc7f6a1cafbdd2de5e587958eac0f67ab26b1e56727fcc60a0c3d4d" dependencies = [ - "cfg-if", - "windows-sys 0.48.0", + "ahash 0.8.11", + "bitflags 2.5.0", + "browserslist-rs", + "const-str", + "cssparser", + "cssparser-color", + "dashmap 5.5.3", + "data-encoding", + "getrandom", + "itertools 0.10.5", + "lazy_static", + "lightningcss-derive", + "parcel_selectors", + "parcel_sourcemap", + "paste", + "pathdiff", + "rayon", + "serde", + "smallvec", + "static-self", ] [[package]] -name = "libredox" -version = "0.0.1" +name = "lightningcss-derive" +version = "1.0.0-alpha.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +checksum = "84c12744d1279367caed41739ef094c325d53fb0ffcd4f9b84a368796f870252" dependencies = [ - "bitflags 2.4.2", - "libc", - "redox_syscall 0.4.1", + "convert_case", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -1998,6 +2010,12 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" +[[package]] +name = "litrs" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" + [[package]] name = "loader_barrel" version = "0.1.0" @@ -2016,6 +2034,7 @@ dependencies = [ "rspack_util", "serde", "serde_json", + "stacker", "swc_compiler", "swc_core", "swc_optimize_barrel", @@ -2029,8 +2048,7 @@ dependencies = [ "anyhow", "async-trait", "either", - "indexmap 2.2.5", - "lazy_static", + "indexmap 2.2.6", "once_cell", "regex", "rspack_ast", @@ -2039,15 +2057,14 @@ dependencies = [ "rspack_loader_runner", "rspack_plugin_javascript", "rspack_regex", - "rspack_testing", "rspack_util", "serde", "serde_json", + "stacker", "swc_change_package_import", "swc_compiler", "swc_config", "swc_core", - "swc_emotion", "swc_env_replacement", "swc_keep_export", "swc_named_import_transform", @@ -2068,9 +2085,23 @@ dependencies = [ [[package]] name = "log" -version = "0.4.19" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "loom" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" +dependencies = [ + "cfg-if", + "generator", + "pin-utils", + "scoped-tls", + "tracing", + "tracing-subscriber", +] [[package]] name = "lru" @@ -2082,14 +2113,29 @@ dependencies = [ ] [[package]] -name = "mach" -version = "0.3.2" +name = "lz4_flex" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "912b45c753ff5f7f5208307e8ace7d2a2e30d024e26d3509f3dce546c044ce15" +dependencies = [ + "twox-hash", +] + +[[package]] +name = "mach2" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" +checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" dependencies = [ "libc", ] +[[package]] +name = "managed" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d" + [[package]] name = "matchers" version = "0.1.0" @@ -2099,6 +2145,12 @@ dependencies = [ "regex-automata 0.1.10", ] +[[package]] +name = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + [[package]] name = "md4" version = "0.10.2" @@ -2132,15 +2184,6 @@ dependencies = [ "libc", ] -[[package]] -name = "memoffset" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" -dependencies = [ - "autocfg", -] - [[package]] name = "memoffset" version = "0.9.0" @@ -2160,12 +2203,12 @@ dependencies = [ "backtrace", "miette-derive 4.7.1", "once_cell", - "owo-colors", + "owo-colors 3.5.0", "supports-color 1.3.1", "supports-hyperlinks 1.2.0", "supports-unicode 1.0.2", - "terminal_size", - "textwrap", + "terminal_size 0.1.17", + "textwrap 0.15.2", "thiserror", "unicode-width", ] @@ -2181,12 +2224,26 @@ dependencies = [ "is-terminal", "miette-derive 5.10.0", "once_cell", - "owo-colors", + "owo-colors 3.5.0", "supports-color 2.1.0", "supports-hyperlinks 2.1.0", "supports-unicode 2.0.0", - "terminal_size", - "textwrap", + "terminal_size 0.1.17", + "textwrap 0.15.2", + "thiserror", + "unicode-width", +] + +[[package]] +name = "miette" +version = "7.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4edc8853320c2a0dab800fbda86253c8938f6ea88510dc92c5f1ed20e794afc1" +dependencies = [ + "cfg-if", + "miette-derive 7.2.0", + "owo-colors 4.0.0", + "textwrap 0.16.1", "thiserror", "unicode-width", ] @@ -2210,27 +2267,27 @@ checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.63", ] [[package]] -name = "mimalloc-rust" -version = "0.2.1" +name = "miette-derive" +version = "7.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eb726c8298efb4010b2c46d8050e4be36cf807b9d9e98cb112f830914fc9bbe" +checksum = "dcf09caffaac8068c346b6df2a7fc27a177fd20b39421a39ce0a211bde679a6c" dependencies = [ - "cty", - "mimalloc-rust-sys", + "proc-macro2", + "quote", + "syn 2.0.63", ] [[package]] -name = "mimalloc-rust-sys" -version = "1.7.9-source" +name = "mimalloc" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6413e13241a9809f291568133eca6694572cf528c1a6175502d090adce5dd5db" +checksum = "68914350ae34959d83f732418d51e2427a794055d0b9529f48259ac07af65633" dependencies = [ - "cc", - "cty", + "libmimalloc-sys", ] [[package]] @@ -2264,29 +2321,24 @@ dependencies = [ "adler", ] +[[package]] +name = "mio" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.48.0", +] + [[package]] name = "more-asserts" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" -[[package]] -name = "napi" -version = "2.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a63d0570e4c3e0daf7a8d380563610e159f538e20448d6c911337246f40e84" -dependencies = [ - "anyhow", - "bitflags 2.4.2", - "ctor", - "napi-derive", - "napi-sys", - "once_cell", - "serde", - "serde_json", - "tokio", -] - [[package]] name = "napi-build" version = "2.1.2" @@ -2304,7 +2356,7 @@ dependencies = [ "napi-derive-backend", "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.63", ] [[package]] @@ -2319,23 +2371,49 @@ dependencies = [ "quote", "regex", "semver 1.0.20", - "syn 2.0.52", + "syn 2.0.63", +] + +[[package]] +name = "napi-h" +version = "2.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8122073a4a01e851f0a9bbc4322b8f8cdf6f9faafc260f005cfd782098aff4fb" +dependencies = [ + "anyhow", + "bitflags 2.5.0", + "ctor", + "napi-derive", + "napi-sys", + "once_cell", + "serde", + "serde_json", + "tokio", ] [[package]] name = "napi-sys" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2503fa6af34dc83fb74888df8b22afe933b58d37daf7d80424b1c60c68196b8b" +checksum = "427802e8ec3a734331fec1035594a210ce1ff4dc5bc1950530920ab717964ea3" dependencies = [ "libloading", ] [[package]] name = "new_debug_unreachable" -version = "1.0.4" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "nibble_vec" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec", +] [[package]] name = "node_binding" @@ -2344,22 +2422,25 @@ dependencies = [ "async-trait", "binding_options", "color-backtrace", - "mimalloc-rust", - "napi", "napi-build", "napi-derive", + "napi-h", "once_cell", - "rspack_binding_macros", - "rspack_binding_options", + "plugin_manifest", + "rspack_allocator", "rspack_binding_values", + "rspack_collections", "rspack_core", "rspack_error", "rspack_fs_node", + "rspack_hash", "rspack_hook", - "rspack_napi_shared", + "rspack_napi", + "rspack_paths", + "rspack_plugin_html", + "rspack_plugin_javascript", "rspack_tracing", - "testing_macros", - "tikv-jemallocator", + "tokio", "tracing", ] @@ -2394,31 +2475,35 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" dependencies = [ - "autocfg", "num-integer", "num-traits", "serde", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] @@ -2476,10 +2561,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] -name = "oorandom" -version = "11.1.3" +name = "oneshot" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f6640c6bda7731b1fdbab747981a0f896dd1fedaf9f4a53fa237a04a84431f4" +dependencies = [ + "loom", +] + +[[package]] +name = "outref" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" +checksum = "7f222829ae9293e33a9f5e9f440c6760a3d450a64affe1846486b140db81c1f4" [[package]] name = "outref" @@ -2500,23 +2594,48 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" [[package]] -name = "oxc_resolver" -version = "1.5.4" +name = "owo-colors" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caff54706df99d2a78a5a4e3455ff45448d81ef1bb63c22cd14052ca0e993a3f" + +[[package]] +name = "parcel_selectors" +version = "0.26.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2033cc3b0e72446d3321866db0954804b9ca559ad692480205053f6aea4bfc15" +checksum = "512215cb1d3814e276ace4ec2dbc2cac16726ea3fcac20c22ae1197e16fdd72d" dependencies = [ - "dashmap", - "dunce", - "indexmap 2.2.5", - "json-strip-comments", - "once_cell", - "rustc-hash", + "bitflags 2.5.0", + "cssparser", + "fxhash", + "log", + "phf 0.10.1", + "phf_codegen", + "precomputed-hash", + "smallvec", + "static-self", +] + +[[package]] +name = "parcel_sourcemap" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "485b74d7218068b2b7c0e3ff12fbc61ae11d57cb5d8224f525bd304c6be05bbb" +dependencies = [ + "base64-simd 0.7.0", + "data-url", + "rkyv", "serde", "serde_json", - "thiserror", - "tracing", + "vlq", ] +[[package]] +name = "parking" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" + [[package]] name = "parking_lot" version = "0.12.1" @@ -2542,9 +2661,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.13" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4b27ab7be369122c218afc2079489cdcb4b517c0a3fc386ff11e1fedfcc2b35" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "path-clean" @@ -2558,11 +2677,20 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17359afc20d7ab31fdb42bb844c8b3bb1dabd7dcf7e68428492da7f16966fcef" +[[package]] +name = "path-slash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e91099d4268b0e11973f036e885d652fb0b21fedcf69738c627f94db6a44f42" + [[package]] name = "pathdiff" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" +dependencies = [ + "camino", +] [[package]] name = "percent-encoding" @@ -2600,7 +2728,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.63", ] [[package]] @@ -2616,14 +2744,21 @@ dependencies = [ [[package]] name = "petgraph" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.2.5", - "serde", - "serde_derive", + "indexmap 2.2.6", +] + +[[package]] +name = "phf" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +dependencies = [ + "phf_shared 0.10.0", ] [[package]] @@ -2636,6 +2771,16 @@ dependencies = [ "phf_shared 0.11.2", ] +[[package]] +name = "phf_codegen" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", +] + [[package]] name = "phf_generator" version = "0.10.0" @@ -2666,7 +2811,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.63", ] [[package]] @@ -2704,7 +2849,7 @@ checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.63", ] [[package]] @@ -2719,34 +2864,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "plotters" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" -dependencies = [ - "num-traits", - "plotters-backend", - "plotters-svg", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "plotters-backend" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" - -[[package]] -name = "plotters-svg" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" -dependencies = [ - "plotters-backend", -] - [[package]] name = "plugin_manifest" version = "0.1.0" @@ -2756,7 +2873,6 @@ dependencies = [ "rspack_core", "rspack_error", "rspack_hook", - "rspack_testing", "serde", "serde_json", "tracing", @@ -2769,7 +2885,6 @@ dependencies = [ "async-trait", "rspack_core", "rspack_error", - "rspack_testing", "tracing", ] @@ -2781,7 +2896,27 @@ checksum = "52a40bc70c2c58040d2d8b167ba9a5ff59fc9dab7ad44771cfde3dcfde7a09c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.63", +] + +[[package]] +name = "pnp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46770cee76a618023fea15411d0449dd066dc232cc17e4562f154da215f27af7" +dependencies = [ + "arca", + "byteorder", + "concurrent_lru", + "fancy-regex", + "lazy_static", + "miniz_oxide", + "pathdiff", + "regex", + "serde", + "serde_json", + "serde_with", + "thiserror", ] [[package]] @@ -2790,6 +2925,12 @@ version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "767eb9f07d4a5ebcb39bbf2d452058a93c011373abf6832e24194a1c3f004794" +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -2804,14 +2945,14 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "preset_env_base" -version = "0.4.11" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d99dc6ba4753f07bfbc4dbf3137618d31af2611fcaced7237647075ca687eaa" +checksum = "1b30eab18be480c194938e433e269d5298a279f6410f02fbc73f3576a325c110" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.11", "anyhow", "browserslist-rs", - "dashmap", + "dashmap 5.5.3", "from_variant", "once_cell", "semver 1.0.20", @@ -2864,17 +3005,11 @@ dependencies = [ "version_check", ] -[[package]] -name = "proc-macro-hack" -version = "0.5.20+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" - [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] @@ -2921,9 +3056,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -2940,6 +3075,16 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce082a9940a7ace2ad4a8b7d0b1eac6aa378895f18be598230c5f2284ac05426" +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + [[package]] name = "rand" version = "0.8.5" @@ -2972,9 +3117,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -3009,14 +3154,23 @@ dependencies = [ ] [[package]] -name = "redox_users" -version = "0.4.4" +name = "ref-cast" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +checksum = "ccf0a6f84d5f1d581da8b41b47ec8600871962f2a528115b542b362d4b744931" dependencies = [ - "getrandom", - "libredox", - "thiserror", + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.63", ] [[package]] @@ -3033,14 +3187,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.3" +version = "1.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ "aho-corasick", "memchr", "regex-automata 0.4.4", - "regex-syntax 0.8.2", + "regex-syntax 0.8.3", ] [[package]] @@ -3060,7 +3214,7 @@ checksum = "3b7fa1134405e2ec9353fd416b17f8dacd46c473d7d3fd1cf202706a14eb792a" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax 0.8.3", ] [[package]] @@ -3071,37 +3225,37 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "region" -version = "3.0.0" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76e189c2369884dce920945e2ddf79b3dff49e071a167dd1817fa9c4c00d512e" +checksum = "e6b6ebd13bc009aef9cd476c1310d49ac354d36e240cf1bd753290f3dc7199a7" dependencies = [ "bitflags 1.3.2", "libc", - "mach", - "winapi", + "mach2", + "windows-sys 0.52.0", ] [[package]] name = "regress" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d06f9a1f7cd8473611ba1a480cf35f9c5cffc2954336ba90a982fdb7e7d7f51e" +checksum = "16fe0a24af5daaae947294213d2fd2646fbf5e1fbacc1d4ba3e84b2393854842" dependencies = [ - "hashbrown 0.14.3", + "hashbrown 0.14.5", "memchr", ] [[package]] name = "relative-path" -version = "1.8.0" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bf2521270932c3c7bed1a59151222bd7643c79310f2916f01925e1e16255698" +checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" [[package]] name = "rend" @@ -3120,12 +3274,13 @@ checksum = "e3a8614ee435691de62bcffcf4a66d91b3594bf1428a5722e79103249a095690" [[package]] name = "rkyv" -version = "0.7.42" +version = "0.7.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58" +checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" dependencies = [ "bitvec", "bytecheck", + "bytes", "hashbrown 0.12.3", "indexmap 1.9.3", "ptr_meta", @@ -3158,26 +3313,10 @@ dependencies = [ ] [[package]] -name = "rspack" +name = "rspack_allocator" version = "0.1.0" dependencies = [ - "cargo-rst", - "criterion", - "insta", - "mimalloc-rust", - "rspack_binding_options", - "rspack_core", - "rspack_fs", - "rspack_plugin_javascript", - "rspack_testing", - "rspack_tracing", - "serde", - "serde_json", - "testing_macros", - "tikv-jemallocator", - "tokio", - "ustr-fxhash", - "xshell", + "mimalloc", ] [[package]] @@ -3186,88 +3325,81 @@ version = "0.1.0" dependencies = [ "anyhow", "swc_core", - "swc_error_reporters", + "swc_error_reporters 0.21.0", "swc_node_comments", ] -[[package]] -name = "rspack_ast_viewer" -version = "0.1.0" -dependencies = [ - "anyhow", - "argh", - "regex", - "swc_core", - "swc_error_reporters", -] - [[package]] name = "rspack_base64" version = "0.1.0" dependencies = [ - "base64-simd", - "once_cell", + "base64-simd 0.8.0", "regex", ] -[[package]] -name = "rspack_binding_macros" -version = "0.1.0" - [[package]] name = "rspack_binding_options" version = "0.1.0" dependencies = [ "async-trait", - "better_scoped_tls", "derivative", "glob", - "napi", "napi-derive", - "rspack_binding_macros", + "napi-h", "rspack_binding_values", + "rspack_collections", "rspack_core", "rspack_error", - "rspack_identifier", + "rspack_hook", "rspack_ids", + "rspack_loader_lightningcss", + "rspack_loader_preact_refresh", "rspack_loader_react_refresh", "rspack_loader_runner", "rspack_loader_swc", - "rspack_napi_shared", + "rspack_loader_testing", + "rspack_napi", + "rspack_napi_macros", + "rspack_paths", "rspack_plugin_asset", "rspack_plugin_banner", "rspack_plugin_copy", "rspack_plugin_css", "rspack_plugin_devtool", + "rspack_plugin_dynamic_entry", "rspack_plugin_ensure_chunk_conditions", "rspack_plugin_entry", "rspack_plugin_externals", + "rspack_plugin_extract_css", "rspack_plugin_hmr", "rspack_plugin_html", + "rspack_plugin_ignore", "rspack_plugin_javascript", "rspack_plugin_json", + "rspack_plugin_lazy_compilation", "rspack_plugin_library", + "rspack_plugin_lightning_css_minimizer", "rspack_plugin_limit_chunk_count", "rspack_plugin_merge_duplicate_chunks", "rspack_plugin_mf", + "rspack_plugin_no_emit_on_errors", "rspack_plugin_progress", "rspack_plugin_real_content_hash", "rspack_plugin_remove_empty_chunks", "rspack_plugin_runtime", + "rspack_plugin_runtime_chunk", "rspack_plugin_schemes", + "rspack_plugin_size_limits", "rspack_plugin_split_chunks", - "rspack_plugin_swc_css_minimizer", "rspack_plugin_swc_js_minimizer", "rspack_plugin_warn_sensitive_module", "rspack_plugin_wasm", "rspack_plugin_web_worker_template", "rspack_plugin_worker", "rspack_regex", - "rspack_swc_visitors", - "rustc-hash", + "rustc-hash 1.1.0", "serde", "serde_json", - "swc_config", "swc_core", "tokio", "tracing", @@ -3277,17 +3409,32 @@ dependencies = [ name = "rspack_binding_values" version = "0.1.0" dependencies = [ - "dashmap", "futures", - "napi", + "heck 0.5.0", "napi-derive", - "napi-sys", - "rspack_binding_macros", + "napi-h", + "rspack_collections", "rspack_core", "rspack_error", - "rspack_identifier", - "rspack_napi_shared", - "rustc-hash", + "rspack_napi", + "rspack_plugin_html", + "rspack_regex", + "rspack_util", + "rustc-hash 1.1.0", + "serde", + "serde_json", +] + +[[package]] +name = "rspack_collections" +version = "0.1.0" +dependencies = [ + "dashmap 5.5.3", + "hashlink", + "indexmap 2.2.6", + "rayon", + "serde", + "ustr-fxhash", ] [[package]] @@ -3297,43 +3444,40 @@ dependencies = [ "anymap", "async-recursion", "async-trait", - "bitflags 2.4.2", - "dashmap", + "bitflags 2.5.0", + "dashmap 5.5.3", "derivative", "dyn-clone", "either", "futures", - "glob-match", "hashlink", "hex", - "indexmap 2.2.5", - "itertools 0.12.1", + "indexmap 2.2.6", + "indoc", + "itertools 0.13.0", "json", "mime_guess", "num-bigint", "once_cell", - "oxc_resolver", "paste", - "petgraph", "pretty_assertions", "rayon", "regex", - "rkyv", "rspack_ast", - "rspack_core_macros", - "rspack_database", + "rspack_collections", "rspack_error", "rspack_fs", "rspack_futures", "rspack_hash", "rspack_hook", - "rspack_identifier", "rspack_loader_runner", + "rspack_macros", + "rspack_paths", "rspack_regex", + "rspack_resolver", "rspack_sources", - "rspack_swc_visitors", "rspack_util", - "rustc-hash", + "rustc-hash 1.1.0", "serde", "serde_json", "sugar_path", @@ -3346,21 +3490,13 @@ dependencies = [ ] [[package]] -name = "rspack_core_macros" -version = "0.1.0" -dependencies = [ - "quote", - "syn 2.0.52", -] - -[[package]] -name = "rspack_database" -version = "0.1.0" +name = "rspack_dojang" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45c6a270521e3fb5e430a3c43282cff5da7c3717e0081f6b10999968c1bf5d01" dependencies = [ - "dashmap", - "once_cell", - "rayon", - "rustc-hash", + "html-escape", + "serde_json", ] [[package]] @@ -3368,14 +3504,16 @@ name = "rspack_error" version = "0.1.0" dependencies = [ "anyhow", + "derivative", "futures", "miette 5.10.0", "once_cell", - "owo-colors", - "rspack_identifier", + "owo-colors 3.5.0", + "rspack_collections", + "rspack_paths", "swc_core", "termcolor", - "textwrap", + "textwrap 0.15.2", "thiserror", "unicode-width", ] @@ -3386,6 +3524,7 @@ version = "0.1.0" dependencies = [ "futures", "rspack_error", + "rspack_paths", "tokio", ] @@ -3394,11 +3533,12 @@ name = "rspack_fs_node" version = "0.1.0" dependencies = [ "futures", - "napi", "napi-build", "napi-derive", + "napi-h", "rspack_fs", - "rspack_napi_shared", + "rspack_napi", + "rspack_paths", ] [[package]] @@ -3425,60 +3565,75 @@ dependencies = [ "async-trait", "futures-concurrency", "rspack_error", - "rustc-hash", -] - -[[package]] -name = "rspack_identifier" -version = "0.1.0" -dependencies = [ - "hashlink", - "serde", - "ustr-fxhash", + "rspack_macros", + "rustc-hash 1.1.0", ] [[package]] name = "rspack_ids" version = "0.1.0" dependencies = [ - "dashmap", - "itertools 0.12.1", - "once_cell", + "itertools 0.13.0", "rayon", "regex", "rspack_core", "rspack_error", + "rspack_hook", "rspack_util", - "rustc-hash", + "tracing", ] [[package]] -name = "rspack_loader_react_refresh" +name = "rspack_loader_lightningcss" version = "0.1.0" dependencies = [ "async-trait", + "derivative", + "lightningcss", + "parcel_sourcemap", "rspack_core", "rspack_error", "rspack_loader_runner", + "serde", + "tokio", ] [[package]] -name = "rspack_loader_runner" +name = "rspack_loader_preact_refresh" version = "0.1.0" dependencies = [ - "anymap", - "async-recursion", "async-trait", - "bitflags 2.4.2", - "derivative", - "once_cell", - "regex", + "rspack_core", "rspack_error", - "rspack_identifier", - "rspack_sources", - "rustc-hash", - "serde_json", - "similar-asserts", + "rspack_loader_runner", +] + +[[package]] +name = "rspack_loader_react_refresh" +version = "0.1.0" +dependencies = [ + "async-trait", + "rspack_core", + "rspack_error", + "rspack_loader_runner", +] + +[[package]] +name = "rspack_loader_runner" +version = "0.1.0" +dependencies = [ + "anymap", + "async-trait", + "derivative", + "once_cell", + "regex", + "rspack_collections", + "rspack_error", + "rspack_paths", + "rspack_sources", + "rspack_util", + "rustc-hash 1.1.0", + "serde_json", "tokio", ] @@ -3488,62 +3643,116 @@ version = "0.1.0" dependencies = [ "anyhow", "async-trait", - "dashmap", + "base64 0.22.1", + "dashmap 5.5.3", "either", - "indexmap 2.2.5", "jsonc-parser 0.23.0", - "once_cell", "rspack_ast", "rspack_core", "rspack_error", "rspack_loader_runner", "rspack_plugin_javascript", - "rspack_swc_visitors", - "rspack_testing", "rspack_util", "serde", "serde_json", + "stacker", "swc_config", "swc_core", + "swc_plugin_import", "tokio", - "xxhash-rust", + "url", +] + +[[package]] +name = "rspack_loader_testing" +version = "0.1.0" +dependencies = [ + "async-trait", + "rspack_core", + "rspack_error", + "rspack_loader_runner", + "serde_json", ] [[package]] -name = "rspack_napi_shared" +name = "rspack_macros" version = "0.1.0" dependencies = [ - "napi", + "proc-macro2", + "quote", + "syn 2.0.63", +] + +[[package]] +name = "rspack_macros_test" +version = "0.1.0" +dependencies = [ + "rspack_collections", + "rspack_core", + "rspack_error", + "rspack_hook", + "rspack_macros", + "rspack_util", + "tokio", + "tracing", + "trybuild", +] + +[[package]] +name = "rspack_napi" +version = "0.1.0" +dependencies = [ + "napi-h", + "oneshot", "rspack_error", "rspack_regex", "tokio", ] +[[package]] +name = "rspack_napi_macros" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.63", +] + [[package]] name = "rspack_node" version = "0.1.0" dependencies = [ "async-trait", "color-backtrace", - "mimalloc-rust", - "napi", "napi-build", "napi-derive", + "napi-h", "once_cell", - "rspack_binding_macros", + "rspack_allocator", "rspack_binding_options", "rspack_binding_values", + "rspack_collections", "rspack_core", "rspack_error", "rspack_fs_node", + "rspack_hash", "rspack_hook", - "rspack_napi_shared", + "rspack_napi", + "rspack_paths", + "rspack_plugin_html", + "rspack_plugin_javascript", "rspack_tracing", - "testing_macros", - "tikv-jemallocator", + "tokio", "tracing", ] +[[package]] +name = "rspack_paths" +version = "0.1.0" +dependencies = [ + "camino", +] + [[package]] name = "rspack_plugin_asset" version = "0.1.0" @@ -3551,14 +3760,14 @@ dependencies = [ "async-trait", "mime_guess", "rayon", - "rkyv", "rspack_base64", "rspack_core", "rspack_error", "rspack_hash", - "rspack_testing", + "rspack_hook", "rspack_util", "serde_json", + "tracing", "urlencoding", ] @@ -3567,23 +3776,23 @@ name = "rspack_plugin_banner" version = "0.1.0" dependencies = [ "async-recursion", - "async-trait", "futures", - "once_cell", "regex", "rspack_core", "rspack_error", "rspack_hook", "rspack_regex", "rspack_util", + "tracing", ] [[package]] name = "rspack_plugin_copy" version = "0.1.0" dependencies = [ - "async-trait", - "dashmap", + "dashmap 5.5.3", + "derivative", + "futures", "glob", "lazy_static", "pathdiff", @@ -3593,11 +3802,12 @@ dependencies = [ "rspack_futures", "rspack_hash", "rspack_hook", - "rspack_testing", - "rustc-hash", + "rspack_paths", + "rspack_util", + "rustc-hash 1.1.0", "sugar_path", - "testing_macros", "tokio", + "tracing", ] [[package]] @@ -3605,27 +3815,21 @@ name = "rspack_plugin_css" version = "0.1.0" dependencies = [ "async-trait", - "bitflags 2.4.2", - "heck 0.4.1", - "hrx-parser", + "css-module-lexer", + "heck 0.5.0", "indexmap 1.9.3", - "insta", "once_cell", "rayon", "regex", - "rkyv", + "rspack_collections", "rspack_core", "rspack_error", "rspack_hash", "rspack_hook", - "rspack_identifier", "rspack_plugin_runtime", - "rspack_testing", "rspack_util", - "rustc-hash", + "rustc-hash 1.1.0", "serde_json", - "sugar_path", - "swc_core", "tracing", "urlencoding", ] @@ -3635,30 +3839,48 @@ name = "rspack_plugin_devtool" version = "0.1.0" dependencies = [ "async-trait", - "dashmap", + "dashmap 5.5.3", "derivative", "futures", - "once_cell", + "itertools 0.13.0", "pathdiff", "rayon", "regex", "rspack_base64", + "rspack_collections", "rspack_core", "rspack_error", "rspack_hash", "rspack_hook", + "rspack_plugin_javascript", "rspack_util", - "rustc-hash", - "serde_json", + "rustc-hash 1.1.0", + "simd-json", + "tracing", ] [[package]] -name = "rspack_plugin_ensure_chunk_conditions" +name = "rspack_plugin_dynamic_entry" version = "0.1.0" dependencies = [ "async-trait", + "derivative", + "futures", + "rspack_core", + "rspack_error", + "rspack_hook", + "tracing", +] + +[[package]] +name = "rspack_plugin_ensure_chunk_conditions" +version = "0.1.0" +dependencies = [ "rspack_core", "rspack_error", + "rspack_hook", + "rustc-hash 1.1.0", + "tracing", ] [[package]] @@ -3669,32 +3891,57 @@ dependencies = [ "rspack_core", "rspack_error", "rspack_hook", + "tracing", ] [[package]] name = "rspack_plugin_externals" version = "0.1.0" dependencies = [ - "async-trait", - "once_cell", "regex", "rspack_core", + "rspack_error", + "rspack_hook", + "rspack_plugin_javascript", "rspack_regex", + "tracing", ] [[package]] -name = "rspack_plugin_hmr" +name = "rspack_plugin_extract_css" version = "0.1.0" dependencies = [ "async-trait", + "regex", + "rspack_collections", "rspack_core", "rspack_error", "rspack_hash", "rspack_hook", - "rspack_identifier", + "rspack_plugin_css", + "rspack_plugin_javascript", + "rspack_plugin_runtime", + "rspack_util", + "rustc-hash 1.1.0", + "serde", + "serde_json", + "tracing", + "ustr-fxhash", +] + +[[package]] +name = "rspack_plugin_hmr" +version = "0.1.0" +dependencies = [ + "async-trait", + "rspack_collections", + "rspack_core", + "rspack_error", + "rspack_hook", "rspack_util", - "rustc-hash", + "rustc-hash 1.1.0", "serde_json", + "tracing", ] [[package]] @@ -3702,18 +3949,19 @@ name = "rspack_plugin_html" version = "0.1.0" dependencies = [ "anyhow", - "async-trait", - "dojang", - "itertools 0.12.1", + "dashmap 5.5.3", + "futures", + "itertools 0.13.0", "path-clean 1.0.1", "rayon", "regex", "rspack_base64", "rspack_core", + "rspack_dojang", "rspack_error", "rspack_hook", - "rspack_testing", - "schemars", + "rspack_paths", + "rspack_util", "serde", "serde_json", "sha2", @@ -3721,17 +3969,35 @@ dependencies = [ "swc_core", "swc_html", "swc_html_minifier", + "tracing", + "urlencoding", +] + +[[package]] +name = "rspack_plugin_ignore" +version = "0.1.0" +dependencies = [ + "derivative", + "futures", + "rspack_core", + "rspack_error", + "rspack_hook", + "rspack_regex", + "tracing", ] [[package]] name = "rspack_plugin_javascript" version = "0.1.0" dependencies = [ + "anymap", "async-trait", - "bitflags 2.4.2", - "dashmap", - "indexmap 2.2.5", - "itertools 0.12.1", + "bitflags 2.5.0", + "dashmap 5.5.3", + "fast-glob", + "indexmap 2.2.6", + "indoc", + "itertools 0.13.0", "linked_hash_set", "num-bigint", "once_cell", @@ -3739,22 +4005,22 @@ dependencies = [ "regex", "ropey", "rspack_ast", + "rspack_collections", "rspack_core", "rspack_error", "rspack_hash", "rspack_hook", - "rspack_identifier", "rspack_ids", + "rspack_paths", "rspack_regex", - "rspack_swc_visitors", - "rspack_testing", "rspack_util", - "rustc-hash", - "serde", + "rustc-hash 1.1.0", "serde_json", + "stacker", "sugar_path", "swc_core", "swc_node_comments", + "tracing", "url", ] @@ -3766,7 +4032,24 @@ dependencies = [ "ropey", "rspack_core", "rspack_error", - "rspack_testing", + "rspack_util", +] + +[[package]] +name = "rspack_plugin_lazy_compilation" +version = "0.1.0" +dependencies = [ + "async-trait", + "rspack_collections", + "rspack_core", + "rspack_error", + "rspack_hook", + "rspack_plugin_javascript", + "rspack_regex", + "rspack_util", + "rustc-hash 1.1.0", + "tokio", + "tracing", ] [[package]] @@ -3774,30 +4057,56 @@ name = "rspack_plugin_library" version = "0.1.0" dependencies = [ "async-trait", - "once_cell", "regex", + "rspack_collections", "rspack_core", "rspack_error", - "rspack_identifier", + "rspack_hash", + "rspack_hook", + "rspack_plugin_javascript", + "rspack_util", + "rustc-hash 1.1.0", "serde_json", + "tracing", +] + +[[package]] +name = "rspack_plugin_lightning_css_minimizer" +version = "0.1.0" +dependencies = [ + "lightningcss", + "parcel_sourcemap", + "rayon", + "regex", + "rspack_core", + "rspack_error", + "rspack_hash", + "rspack_hook", + "rspack_util", + "tracing", ] [[package]] name = "rspack_plugin_limit_chunk_count" version = "0.1.0" dependencies = [ - "async-trait", + "rspack_collections", "rspack_core", - "rspack_database", + "rspack_error", + "rspack_hook", + "tracing", ] [[package]] name = "rspack_plugin_merge_duplicate_chunks" version = "0.1.0" dependencies = [ - "async-trait", + "rspack_collections", "rspack_core", - "rustc-hash", + "rspack_error", + "rspack_hook", + "rustc-hash 1.1.0", + "tracing", ] [[package]] @@ -3806,20 +4115,30 @@ version = "0.1.0" dependencies = [ "async-trait", "hashlink", - "itertools 0.12.1", - "once_cell", + "itertools 0.13.0", "regex", + "rspack_collections", "rspack_core", "rspack_error", - "rspack_hash", "rspack_hook", - "rspack_identifier", "rspack_loader_runner", + "rspack_plugin_runtime", "rspack_util", - "rustc-hash", + "rustc-hash 1.1.0", "serde", "serde_json", "tokio", + "tracing", +] + +[[package]] +name = "rspack_plugin_no_emit_on_errors" +version = "0.1.0" +dependencies = [ + "rspack_core", + "rspack_error", + "rspack_hook", + "tracing", ] [[package]] @@ -3828,19 +4147,19 @@ version = "0.1.0" dependencies = [ "async-trait", "indicatif", - "linked-hash-map", + "rspack_collections", "rspack_core", "rspack_error", "rspack_hook", + "tracing", ] [[package]] name = "rspack_plugin_real_content_hash" version = "0.1.0" dependencies = [ - "async-trait", "derivative", - "indexmap 2.2.5", + "indexmap 2.2.6", "once_cell", "rayon", "regex", @@ -3848,15 +4167,18 @@ dependencies = [ "rspack_error", "rspack_hash", "rspack_hook", - "rustc-hash", + "rustc-hash 1.1.0", + "tracing", ] [[package]] name = "rspack_plugin_remove_empty_chunks" version = "0.1.0" dependencies = [ - "async-trait", "rspack_core", + "rspack_error", + "rspack_hook", + "tracing", ] [[package]] @@ -3864,17 +4186,29 @@ name = "rspack_plugin_runtime" version = "0.1.0" dependencies = [ "async-trait", - "indexmap 2.2.5", - "itertools 0.12.1", - "once_cell", + "indexmap 2.2.6", + "itertools 0.13.0", + "rspack_collections", "rspack_core", "rspack_error", "rspack_hash", - "rspack_identifier", + "rspack_hook", "rspack_plugin_javascript", "rspack_util", - "rustc-hash", + "rustc-hash 1.1.0", "serde_json", + "tracing", +] + +[[package]] +name = "rspack_plugin_runtime_chunk" +version = "0.1.0" +dependencies = [ + "futures", + "rspack_core", + "rspack_error", + "rspack_hook", + "tracing", ] [[package]] @@ -3882,73 +4216,79 @@ name = "rspack_plugin_schemes" version = "0.1.0" dependencies = [ "async-trait", - "once_cell", "regex", "rspack_base64", "rspack_core", "rspack_error", + "rspack_hook", + "rspack_paths", + "tracing", "url", "urlencoding", ] [[package]] -name = "rspack_plugin_split_chunks" +name = "rspack_plugin_size_limits" version = "0.1.0" dependencies = [ - "async-trait", - "dashmap", "derivative", - "num-bigint", - "once_cell", - "rayon", - "regex", + "futures", "rspack_core", - "rspack_hash", - "rspack_identifier", - "rspack_regex", + "rspack_error", + "rspack_hook", "rspack_util", - "rustc-hash", "tracing", ] [[package]] -name = "rspack_plugin_swc_css_minimizer" +name = "rspack_plugin_split_chunks" version = "0.1.0" dependencies = [ - "async-trait", + "dashmap 5.5.3", + "derivative", "rayon", + "regex", + "rspack_collections", "rspack_core", "rspack_error", + "rspack_hash", "rspack_hook", - "rspack_plugin_css", + "rspack_regex", + "rspack_util", + "rustc-hash 1.1.0", + "tracing", ] [[package]] name = "rspack_plugin_swc_js_minimizer" version = "0.1.0" dependencies = [ - "async-trait", "once_cell", "rayon", "regex", "rspack_core", "rspack_error", + "rspack_hash", "rspack_hook", "rspack_plugin_javascript", - "rspack_regex", "rspack_util", "serde_json", "swc_config", "swc_core", "swc_ecma_minifier", + "tracing", ] [[package]] name = "rspack_plugin_warn_sensitive_module" version = "0.1.0" dependencies = [ + "rspack_collections", "rspack_core", "rspack_error", + "rspack_hook", + "rustc-hash 1.1.0", + "tracing", ] [[package]] @@ -3956,18 +4296,18 @@ name = "rspack_plugin_wasm" version = "0.1.0" dependencies = [ "async-trait", - "dashmap", - "indexmap 2.2.5", + "dashmap 5.5.3", + "indexmap 2.2.6", "rayon", + "rspack_collections", "rspack_core", "rspack_error", "rspack_hook", - "rspack_identifier", - "rspack_testing", "rspack_util", "serde_json", "swc_core", - "wasmparser 0.201.0", + "tracing", + "wasmparser 0.207.0", ] [[package]] @@ -3982,88 +4322,55 @@ dependencies = [ name = "rspack_plugin_worker" version = "0.1.0" dependencies = [ - "async-trait", "rspack_core", "rspack_error", "rspack_hook", + "tracing", ] [[package]] name = "rspack_regex" version = "0.1.0" dependencies = [ - "regex-syntax 0.8.2", + "regex-syntax 0.8.3", "regress", "rspack_error", "swc_core", ] [[package]] -name = "rspack_sources" -version = "0.2.12" +name = "rspack_resolver" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81f2ba1487539680b821bc58b7ef432441ae09dfa4d9e6478720efd1a46180ab" -dependencies = [ - "dashmap", - "dyn-clone", - "memchr", - "rustc-hash", - "serde", - "serde_json", - "smallvec", - "str_indices", - "substring", -] - -[[package]] -name = "rspack_swc_visitors" -version = "0.1.0" +checksum = "f26478f9e708a84a3122e7d1fffea1271ac4bd61cbb5722ee41d32e29ac714f7" dependencies = [ + "cfg-if", + "dashmap 6.0.1", + "dunce", + "indexmap 2.2.6", + "json-strip-comments", "once_cell", - "regex", + "pnp", + "rustc-hash 2.0.0", "serde", - "styled_components", - "swc_core", - "swc_emotion", - "swc_plugin_import", + "serde_json", + "thiserror", + "tracing", ] [[package]] -name = "rspack_testing" -version = "0.1.0" +name = "rspack_sources" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e058ff4b4bc95115441a567a9caa2a14cfeb8c39a0cf431c694bd9ea5869c3b" dependencies = [ - "async-trait", - "cargo-rst", - "insta", - "itertools 0.12.1", - "rspack_binding_options", - "rspack_core", - "rspack_error", - "rspack_fs", - "rspack_ids", - "rspack_loader_swc", - "rspack_plugin_asset", - "rspack_plugin_css", - "rspack_plugin_devtool", - "rspack_plugin_entry", - "rspack_plugin_externals", - "rspack_plugin_hmr", - "rspack_plugin_html", - "rspack_plugin_javascript", - "rspack_plugin_json", - "rspack_plugin_merge_duplicate_chunks", - "rspack_plugin_remove_empty_chunks", - "rspack_plugin_runtime", - "rspack_plugin_warn_sensitive_module", - "rspack_plugin_wasm", - "rspack_regex", - "rspack_tracing", - "schemars", + "dashmap 5.5.3", + "dyn-clone", + "memchr", + "rustc-hash 1.1.0", "serde", "serde_json", - "swc_core", - "testing_macros", - "tokio", + "simd-json", ] [[package]] @@ -4079,13 +4386,19 @@ dependencies = [ name = "rspack_util" version = "0.1.0" dependencies = [ + "bitflags 2.5.0", "concat-string", - "dashmap", - "once_cell", + "dashmap 5.5.3", + "indexmap 2.2.6", + "itoa", "regex", - "rustc-hash", + "rspack_regex", + "rustc-hash 1.1.0", + "serde", + "serde_json", "sugar_path", "swc_core", + "unicase", ] [[package]] @@ -4100,6 +4413,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustc-hash" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" + [[package]] name = "rustc_version" version = "0.2.3" @@ -4124,7 +4443,7 @@ version = "0.38.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac5ffa1efe7548069688cd7028f32591853cd7b5b756d41bcffd2353e4fc75b4" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "errno", "libc", "linux-raw-sys", @@ -4137,6 +4456,19 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +[[package]] +name = "rusty_pool" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ed36cdb20de66d89a17ea04b8883fc7a386f2cf877aaedca5005583ce4876ff" +dependencies = [ + "crossbeam-channel", + "futures", + "futures-channel", + "futures-executor", + "num_cpus", +] + [[package]] name = "ryu" version = "1.0.14" @@ -4160,26 +4492,27 @@ dependencies = [ [[package]] name = "schemars" -version = "0.8.16" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" +checksum = "fc6e7ed6919cb46507fb01ff1654309219f62b4d603822501b0b80d42f6f21ef" dependencies = [ "dyn-clone", "schemars_derive", "serde", "serde_json", + "url", ] [[package]] name = "schemars_derive" -version = "0.8.16" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" +checksum = "185f2b7aa7e02d418e453790dde16890256bbd2bcd04b7dc5348811052b53f49" dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 1.0.109", + "syn 2.0.63", ] [[package]] @@ -4200,6 +4533,12 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" +[[package]] +name = "self_cell" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58bf37232d3bb9a2c4e641ca2a11d83b5062066f88df7fed36c28772046d65ba" + [[package]] name = "semver" version = "0.9.0" @@ -4226,9 +4565,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.197" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] @@ -4250,39 +4589,39 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" dependencies = [ - "half 1.8.3", + "half", "serde", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.63", ] [[package]] name = "serde_derive_internals" -version = "0.26.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +checksum = "330f01ce65a3a5fe59a60c82f3c9a024b573b8a6e875bd233fe5f934e71d54e3" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.63", ] [[package]] name = "serde_json" -version = "1.0.114" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ - "indexmap 2.2.5", + "indexmap 2.2.6", "itoa", "ryu", "serde", @@ -4298,24 +4637,42 @@ dependencies = [ ] [[package]] -name = "serde_yaml" -version = "0.8.26" +name = "serde_with" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b" +checksum = "69cecfa94848272156ea67b2b1a53f20fc7bc638c4a46d2f8abde08f05f4b857" dependencies = [ + "base64 0.22.1", + "chrono", + "hex", "indexmap 1.9.3", - "ryu", + "indexmap 2.2.6", "serde", - "yaml-rust", + "serde_derive", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8fee4991ef4f274617a51ad4af30519438dacb2f56ac773b08a1922ff743350" +dependencies = [ + "darling 0.20.6", + "proc-macro2", + "quote", + "syn 2.0.63", ] [[package]] name = "serde_yaml" -version = "0.9.32" +version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd075d994154d4a774f95b51fb96bdc2832b0ea48425c92546073816cda1f2f" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.2.5", + "indexmap 2.2.6", "itoa", "ryu", "serde", @@ -4323,31 +4680,16 @@ dependencies = [ ] [[package]] -name = "sha-1" -version = "0.10.0" +name = "sha1" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", "cpufeatures", "digest", ] -[[package]] -name = "sha1" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1da05c97445caa12d05e848c4a4fcbbea29e748ac28f7e80e9b010392063770" -dependencies = [ - "sha1_smol", -] - -[[package]] -name = "sha1_smol" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" - [[package]] name = "sha2" version = "0.10.8" @@ -4379,39 +4721,34 @@ dependencies = [ ] [[package]] -name = "shellexpand" -version = "2.1.2" +name = "simd-abstraction" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ccc8076840c4da029af4f87e4e8daeb0fca6b87bbb02e10cb60b791450e11e4" +checksum = "9cadb29c57caadc51ff8346233b5cec1d240b68ce55cf1afc764818791876987" dependencies = [ - "dirs", + "outref 0.1.0", ] [[package]] -name = "simdutf8" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" - -[[package]] -name = "similar" -version = "2.4.0" +name = "simd-json" +version = "0.14.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32fea41aca09ee824cc9724996433064c89f7777e60762749a4170a14abbfa21" +checksum = "89909dd48d17fa49c6fd6ea878b14891f7f2a1a6a12103099f61bb7cb974f8c6" dependencies = [ - "bstr", - "unicode-segmentation", + "getrandom", + "halfbrown", + "ref-cast", + "serde", + "serde_json", + "simdutf8", + "value-trait", ] [[package]] -name = "similar-asserts" -version = "1.5.0" +name = "simdutf8" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e041bb827d1bfca18f213411d51b665309f1afb37a04a5d1464530e13779fc0f" -dependencies = [ - "console", - "similar", -] +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" [[package]] name = "siphasher" @@ -4436,9 +4773,9 @@ checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" [[package]] name = "smallvec" -version = "1.11.2" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "smartstring" @@ -4459,26 +4796,50 @@ checksum = "f67ad224767faa3c7d8b6d91985b78e70a1324408abcb1cfcc2be4c06bc06043" [[package]] name = "smol_str" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74212e6bbe9a4352329b2f68ba3130c15a3f26fe88ff22dbdc6cdd58fa85e99c" +checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" dependencies = [ "serde", ] +[[package]] +name = "smoltcp" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee34c1e1bfc7e9206cc0fb8030a90129b4e319ab53856249bb27642cab914fb3" +dependencies = [ + "bitflags 1.3.2", + "byteorder", + "managed", +] + +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "sourcemap" -version = "6.4.1" +version = "9.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4cbf65ca7dc576cf50e21f8d0712d96d4fcfd797389744b7b222a85cdf5bd90" +checksum = "dab08a862c70980b8e23698b507e272317ae52a608a164a844111f5372374f1f" dependencies = [ + "base64-simd 0.7.0", + "bitvec", "data-encoding", "debugid", "if_chain", + "rustc-hash 1.1.0", "rustc_version 0.2.3", "serde", "serde_json", - "unicode-id", + "unicode-id-start", "url", ] @@ -4520,15 +4881,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "standback" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff" -dependencies = [ - "version_check", -] - [[package]] name = "static-map-macro" version = "0.3.0" @@ -4538,63 +4890,35 @@ dependencies = [ "pmutil", "proc-macro2", "quote", - "syn 2.0.52", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "stdweb" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" -dependencies = [ - "discard", - "rustc_version 0.2.3", - "stdweb-derive", - "stdweb-internal-macros", - "stdweb-internal-runtime", - "wasm-bindgen", + "syn 2.0.63", ] [[package]] -name = "stdweb-derive" -version = "0.5.3" +name = "static-self" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" +checksum = "253e76c8c993a7b1b201b0539228b334582153cd4364292822d2c30776d469c7" dependencies = [ - "proc-macro2", - "quote", - "serde", - "serde_derive", - "syn 1.0.109", + "smallvec", + "static-self-derive", ] [[package]] -name = "stdweb-internal-macros" -version = "0.2.9" +name = "static-self-derive" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" +checksum = "5268c96d4b907c558a9a52d8492522d6c7b559651a5e1d8f2d551e461b9425d5" dependencies = [ - "base-x", "proc-macro2", "quote", - "serde", - "serde_derive", - "serde_json", - "sha1", "syn 1.0.109", ] [[package]] -name = "stdweb-internal-runtime" -version = "0.1.5" +name = "static_assertions" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "str_indices" @@ -4602,42 +4926,16 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9557cb6521e8d009c51a8666f09356f4b817ba9ba0981a305bd86aee47bd35c" -[[package]] -name = "string_cache" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" -dependencies = [ - "new_debug_unreachable", - "once_cell", - "parking_lot", - "phf_shared 0.10.0", - "precomputed-hash", - "serde", -] - -[[package]] -name = "string_cache_codegen" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988" -dependencies = [ - "phf_generator 0.10.0", - "phf_shared 0.10.0", - "proc-macro2", - "quote", -] - [[package]] name = "string_enum" -version = "0.4.2" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b650ea2087d32854a0f20b837fc56ec987a1cb4f758c9757e1171ee9812da63" +checksum = "05e383308aebc257e7d7920224fa055c632478d92744eca77f99be8fa1545b90" dependencies = [ "proc-macro2", "quote", "swc_macros_common", - "syn 2.0.52", + "syn 2.0.63", ] [[package]] @@ -4646,41 +4944,11 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" -[[package]] -name = "styled_components" -version = "0.96.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a0db141a50acf297a815bcd1fe9d958ef56c19aeb36bd12182a7e72567ee499" -dependencies = [ - "Inflector", - "once_cell", - "regex", - "serde", - "swc_atoms", - "swc_common", - "swc_ecma_ast", - "swc_ecma_utils", - "swc_ecma_visit", - "tracing", -] - -[[package]] -name = "substring" -version = "1.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ee6433ecef213b2e72f587ef64a2f5943e7cd16fbd82dbe8bc07486c534c86" -dependencies = [ - "autocfg", -] - [[package]] name = "sugar_path" -version = "0.0.12" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c23ada2c5165fc936136721f5f69c8dac6eceb5407de40262f32934510bd7b9" -dependencies = [ - "once_cell", -] +checksum = "8230d5b8a65a6d4d4a7e5ee8dbdd9312ba447a8b8329689a390a0945d69b57ce" [[package]] name = "supports-color" @@ -4740,28 +5008,28 @@ dependencies = [ [[package]] name = "swc" -version = "0.272.6" +version = "0.284.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267f891db67d4627443f038918e124937709bff5a98be29376441d79452d6af" +checksum = "833bb7f4073f08aec7144619a2cf682413b7a0cc8f21b7e76abd2fd02373685d" dependencies = [ "anyhow", "base64 0.21.7", - "dashmap", + "dashmap 5.5.3", "either", - "indexmap 2.2.5", + "indexmap 2.2.6", "jsonc-parser 0.21.1", "lru", "once_cell", "parking_lot", "pathdiff", "regex", - "rustc-hash", + "rustc-hash 1.1.0", "serde", "serde_json", "sourcemap", "swc_atoms", "swc_cached", - "swc_common", + "swc_common 0.37.4", "swc_compiler_base", "swc_config", "swc_ecma_ast", @@ -4778,27 +5046,43 @@ dependencies = [ "swc_ecma_transforms_optimization", "swc_ecma_utils", "swc_ecma_visit", - "swc_error_reporters", + "swc_error_reporters 0.21.0", "swc_node_comments", "swc_plugin_proxy", "swc_plugin_runner", "swc_timer", - "swc_visit", + "swc_transform_common", + "swc_typescript", + "swc_visit 0.6.1", + "tokio", "tracing", "url", ] +[[package]] +name = "swc_allocator" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc8bd3075d1c6964010333fae9ddcd91ad422a4f8eb8b3206a9b2b6afb4209e" +dependencies = [ + "bumpalo", + "hashbrown 0.14.5", + "ptr_meta", + "rustc-hash 1.1.0", + "triomphe", +] + [[package]] name = "swc_atoms" -version = "0.6.5" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d538eaaa6f085161d088a04cf0a3a5a52c5a7f2b3bd9b83f73f058b0ed357c0" +checksum = "bb6567e4e67485b3e7662b486f1565bdae54bd5b9d6b16b2ba1a9babb1e42125" dependencies = [ "bytecheck", "hstr", "once_cell", "rkyv", - "rustc-hash", + "rustc-hash 1.1.0", "serde", ] @@ -4808,9 +5092,9 @@ version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "630c761c74ac8021490b78578cc2223aa4a568241e26505c27bf0e4fd4ad8ec2" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.11", "anyhow", - "dashmap", + "dashmap 5.5.3", "once_cell", "regex", "serde", @@ -4823,20 +5107,47 @@ dependencies = [ "serde", "serde_json", "swc_core", - "testing", + "testing 0.35.25", ] [[package]] name = "swc_common" -version = "0.33.15" +version = "0.33.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3792c10fa5d3e93a705b31f13fdea4a6e68c3c20d4351e84ed1741b7864399cd" +checksum = "a2f9706038906e66f3919028f9f7a37f3ed552f1b85578e93f4468742e2da438" dependencies = [ - "ahash 0.8.6", - "anyhow", "ast_node", "atty", "better_scoped_tls", + "cfg-if", + "either", + "from_variant", + "new_debug_unreachable", + "num-bigint", + "once_cell", + "parking_lot", + "rustc-hash 1.1.0", + "serde", + "siphasher", + "swc_atoms", + "swc_eq_ignore_macros", + "swc_visit 0.5.14", + "termcolor", + "tracing", + "unicode-width", + "url", +] + +[[package]] +name = "swc_common" +version = "0.37.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70265894dfc70e4f01475d3fd11ddfcd25fae781d7352d1228168072ee6a0a40" +dependencies = [ + "ahash 0.8.11", + "anyhow", + "ast_node", + "better_scoped_tls", "bytecheck", "cfg-if", "either", @@ -4846,13 +5157,14 @@ dependencies = [ "once_cell", "parking_lot", "rkyv", - "rustc-hash", + "rustc-hash 1.1.0", "serde", "siphasher", "sourcemap", + "swc_allocator", "swc_atoms", "swc_eq_ignore_macros", - "swc_visit", + "swc_visit 0.6.1", "termcolor", "tracing", "unicode-width", @@ -4864,26 +5176,32 @@ name = "swc_compiler" version = "0.1.0" dependencies = [ "anyhow", - "dashmap", + "base64 0.22.1", + "dashmap 5.5.3", + "jsonc-parser 0.23.0", "rspack_ast", "swc_config", "swc_core", + "url", ] [[package]] name = "swc_compiler_base" -version = "0.6.5" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9cc48094639d199f8c915b96e52b343aee82cf57f5c628431d2ffe7614daf9b" +checksum = "9859d605bfa3ba8323f37bc4f51839c0e21ea59b657f65865388b0adfeb0a413" dependencies = [ "anyhow", "base64 0.21.7", "once_cell", "pathdiff", + "rustc-hash 1.1.0", "serde", + "serde_json", "sourcemap", + "swc_allocator", "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_config", "swc_ecma_ast", "swc_ecma_codegen", @@ -4895,12 +5213,12 @@ dependencies = [ [[package]] name = "swc_config" -version = "0.1.10" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c29e3b76a63111ef318f161bc413dfc093f21da1afca9ba5cdd6442b7069d65b" +checksum = "4740e53eaf68b101203c1df0937d5161a29f3c13bceed0836ddfe245b72dd000" dependencies = [ "anyhow", - "indexmap 2.2.5", + "indexmap 2.2.6", "serde", "serde_json", "sourcemap", @@ -4910,34 +5228,26 @@ dependencies = [ [[package]] name = "swc_config_macro" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2574f75082322a27d990116cd2a24de52945fc94172b24ca0b3e9e2a6ceb6b" +checksum = "7c5f56139042c1a95b54f5ca48baa0e0172d369bcc9d3d473dad1de36bae8399" dependencies = [ "proc-macro2", "quote", "swc_macros_common", - "syn 2.0.52", + "syn 2.0.63", ] [[package]] name = "swc_core" -version = "0.89.6" +version = "0.101.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0d3b3ef135a76e7476cfd0af40eacad54e3a743f446a79eba60507bb72a9d34" +checksum = "62adeea9d9da142eed5b068eadf67d6ed41bef898465f735c74f5e94f39aed5f" dependencies = [ "swc", + "swc_allocator", "swc_atoms", - "swc_common", - "swc_css_ast", - "swc_css_codegen", - "swc_css_compat", - "swc_css_minifier", - "swc_css_modules", - "swc_css_parser", - "swc_css_prefixer", - "swc_css_utils", - "swc_css_visit", + "swc_common 0.37.4", "swc_ecma_ast", "swc_ecma_codegen", "swc_ecma_parser", @@ -4947,7 +5257,6 @@ dependencies = [ "swc_ecma_transforms_compat", "swc_ecma_transforms_module", "swc_ecma_transforms_optimization", - "swc_ecma_transforms_proposal", "swc_ecma_transforms_react", "swc_ecma_transforms_testing", "swc_ecma_transforms_typescript", @@ -4958,186 +5267,40 @@ dependencies = [ "vergen", ] -[[package]] -name = "swc_css_ast" -version = "0.140.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d2251abcf11f599746478404886cbc50479130b7e0da378f15d8b8f0a0d56ab" -dependencies = [ - "is-macro", - "string_enum", - "swc_atoms", - "swc_common", -] - -[[package]] -name = "swc_css_codegen" -version = "0.151.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a1b6a92955f14f325e856146e624124d722e6ccb4864e607419609b4ae25347" -dependencies = [ - "auto_impl", - "bitflags 2.4.2", - "rustc-hash", - "serde", - "swc_atoms", - "swc_common", - "swc_css_ast", - "swc_css_codegen_macros", - "swc_css_utils", -] - -[[package]] -name = "swc_css_codegen_macros" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0db1d634bcd2df2b694e2bf9320b8f808db3451e35d70e36252966b551a11ef4" -dependencies = [ - "proc-macro2", - "quote", - "swc_macros_common", - "syn 2.0.52", -] - -[[package]] -name = "swc_css_compat" -version = "0.27.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfc8848fc3a730aebaecf26ccfa16a659c253700570d3f66ffc4f83f77f5350" -dependencies = [ - "bitflags 2.4.2", - "once_cell", - "serde", - "serde_json", - "swc_atoms", - "swc_common", - "swc_css_ast", - "swc_css_utils", - "swc_css_visit", -] - -[[package]] -name = "swc_css_minifier" -version = "0.116.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9809f65a7389829c2cafb9f9b9f02fc8a06347f8fcb68cceb7665beba5eb7e11" -dependencies = [ - "serde", - "swc_atoms", - "swc_common", - "swc_css_ast", - "swc_css_utils", - "swc_css_visit", -] - -[[package]] -name = "swc_css_modules" -version = "0.29.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7882efb7a6a12d0872edd1dfd9397d8f3ba3ba9392413ff385a9b3196035b205" -dependencies = [ - "rustc-hash", - "serde", - "swc_atoms", - "swc_common", - "swc_css_ast", - "swc_css_codegen", - "swc_css_parser", - "swc_css_visit", -] - -[[package]] -name = "swc_css_parser" -version = "0.150.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c370f7a814bc9cd4553cb686373d4a4931d308d2aec05684b9f5ed8662c9479" -dependencies = [ - "lexical", - "serde", - "swc_atoms", - "swc_common", - "swc_css_ast", -] - -[[package]] -name = "swc_css_prefixer" -version = "0.153.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8eb7b5aee50481d81b93a4ef2eee4985d6c6589f7f2cc78d2f2ff5c44a080a1" -dependencies = [ - "once_cell", - "preset_env_base", - "serde", - "serde_json", - "swc_atoms", - "swc_common", - "swc_css_ast", - "swc_css_utils", - "swc_css_visit", -] - -[[package]] -name = "swc_css_utils" -version = "0.137.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b71af680ab24a76c54e0cbd9ce99f2d688fa3d7c847220b331e095820a63510" -dependencies = [ - "once_cell", - "serde", - "serde_json", - "swc_atoms", - "swc_common", - "swc_css_ast", - "swc_css_visit", -] - -[[package]] -name = "swc_css_visit" -version = "0.139.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b68d6996acce5884e9c9c3b954f54929140068692a006108bfe75a208dc45e0a" -dependencies = [ - "serde", - "swc_atoms", - "swc_common", - "swc_css_ast", - "swc_visit", -] - [[package]] name = "swc_ecma_ast" -version = "0.111.1" +version = "0.118.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e12b4d0f3b31d293dac16fc13a50f8a282a3bdb658f2a000ffe09b1b638f45c9" +checksum = "ed6c1b94abbaf080a4e4ae47101a83d4eedef90d733dd98e32b361356d3f5e4b" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "bytecheck", "is-macro", "num-bigint", - "phf", + "phf 0.11.2", "rkyv", "scoped-tls", "serde", "string_enum", "swc_atoms", - "swc_common", - "unicode-id", + "swc_common 0.37.4", + "unicode-id-start", ] [[package]] name = "swc_ecma_codegen" -version = "0.147.2" +version = "0.155.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d585ce1ac775bd454058c76db662807ff39fdac56696158482dc0e5d95b7ca0c" +checksum = "644514f303dcad13f7d1c244b50af798e0549f6eb8c53d64dd2ba9824266c868" dependencies = [ "memchr", "num-bigint", "once_cell", - "rustc-hash", "serde", "sourcemap", + "swc_allocator", "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_ecma_ast", "swc_ecma_codegen_macros", "tracing", @@ -5145,24 +5308,24 @@ dependencies = [ [[package]] name = "swc_ecma_codegen_macros" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "394b8239424b339a12012ceb18726ed0244fce6bf6345053cb9320b2791dcaa5" +checksum = "090e409af49c8d1a3c13b3aab1ed09dd4eda982207eb3e63c2ad342f072b49c8" dependencies = [ "proc-macro2", "quote", "swc_macros_common", - "syn 2.0.52", + "syn 2.0.63", ] [[package]] name = "swc_ecma_compat_bugfixes" -version = "0.3.4" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6b916b9fa1410f907cb9c3120d9ddefe1e94f5365ff207cbbb260fad9037038" +checksum = "b9f9cac39f19d6509db921f4b75934aaa64fc84b599416e5c1fcaed1c313132f" dependencies = [ "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_ecma_ast", "swc_ecma_compat_es2015", "swc_ecma_transforms_base", @@ -5174,11 +5337,11 @@ dependencies = [ [[package]] name = "swc_ecma_compat_common" -version = "0.3.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5029cf18d05b77221984df0fce21c81e31d36d4ae360f2df94a7cf8817e7528e" +checksum = "f9acdf402b36f8e83084b10e119d7ba9d07e5229ef39e1343f147db816c7b73e" dependencies = [ - "swc_common", + "swc_common 0.37.4", "swc_ecma_ast", "swc_ecma_utils", "swc_ecma_visit", @@ -5187,18 +5350,18 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2015" -version = "0.3.4" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae6cdbcd73b42e20ad33a9df635ef5fbcf5a24d775790e246ec327cb5ff60227" +checksum = "bd07cbb52c1ac41115c9ddd5a4d046a7388008bd950b61a48df7f7f490f19827" dependencies = [ "arrayvec", - "indexmap 2.2.5", + "indexmap 2.2.6", "is-macro", "serde", "serde_derive", "smallvec", "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_config", "swc_ecma_ast", "swc_ecma_compat_common", @@ -5213,12 +5376,12 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2016" -version = "0.3.4" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6db2e972fc617f2bbfbdf55c4f3e11e20855957253f2096973b4e4061ae97fe" +checksum = "209e347cdc3fb56632a1d882f981f3448f5f529c16d8da9d770207fffda4a8f6" dependencies = [ "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_ecma_ast", "swc_ecma_transforms_base", "swc_ecma_transforms_macros", @@ -5230,13 +5393,13 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2017" -version = "0.3.4" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b12acf9671a08d8c89c9abf28c140c00fefe1d4023ba33171e61511e39da763" +checksum = "8a564f1b5e852a0ac656626ba689d49dd2751ba5b980903154aebc971729959d" dependencies = [ "serde", "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_ecma_ast", "swc_ecma_transforms_base", "swc_ecma_transforms_macros", @@ -5248,13 +5411,13 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2018" -version = "0.3.4" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8287e7473bc0aa3b73ccc211ec640a015f5cc6e4c5ebfff23ada5181861ebf2c" +checksum = "f577f098e7c3738ade709caadb17c9f3bd911ea2ee6cfacca561d12addcc5761" dependencies = [ "serde", "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_ecma_ast", "swc_ecma_compat_common", "swc_ecma_transforms_base", @@ -5267,12 +5430,12 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2019" -version = "0.3.4" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ac21edb2916c4d1334dee6223b8c0b858b0368bc40616e301b9dda9665ad5ea" +checksum = "f9d52253dc2f83a3fca526c387c33e4ff9a8423b68c271414c9f870e1ced3231" dependencies = [ "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_ecma_ast", "swc_ecma_transforms_base", "swc_ecma_utils", @@ -5283,13 +5446,13 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2020" -version = "0.3.4" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f2c002579929769624e6003912d34815343a9c2db4171fc248fbb5c5c2cf179" +checksum = "ed343932876fad34b1d4a13e30c55b94531e89916f45e7c04203bc49a29565b9" dependencies = [ "serde", "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_ecma_ast", "swc_ecma_compat_es2022", "swc_ecma_transforms_base", @@ -5301,12 +5464,12 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2021" -version = "0.3.3" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21957526c2191ddfe1af17360129d2c900f5a26614b0e479706926d82c2db827" +checksum = "0b6b28a2c109466eaa809d9b9a5b81dcbb4e269ba293a9c5c34aabc67b6427bc" dependencies = [ "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_ecma_ast", "swc_ecma_transforms_base", "swc_ecma_utils", @@ -5317,12 +5480,12 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2022" -version = "0.3.3" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c882fee687bceff1f2fcc5acca2f8180aad303d31652650ba2c01da501ecc336" +checksum = "ab3a644e271ea2a9df88e3e456c5c204c4916ef5136b7d946f9cd25607f47ec6" dependencies = [ "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_ecma_ast", "swc_ecma_compat_common", "swc_ecma_transforms_base", @@ -5336,11 +5499,11 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es3" -version = "0.3.4" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a9767a20448d7c8ffa4668c0883842f2dc535faeb7e41ea4004896e29a74194" +checksum = "e55ffadc12067b21524bf7b5d6938021ee918f65f18937ed27245c23544bc910" dependencies = [ - "swc_common", + "swc_common 0.37.4", "swc_ecma_ast", "swc_ecma_transforms_base", "swc_ecma_utils", @@ -5351,13 +5514,13 @@ dependencies = [ [[package]] name = "swc_ecma_ext_transforms" -version = "0.112.2" +version = "0.120.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b973ebc8dd2a6e3a351b41da03249f9ba24b61cb0280ebdaf68acf78ad3e9535" +checksum = "ad03ee53c734eb74757d03c07ec71b1a982261830c9253ef3e2e4a089f9af25d" dependencies = [ - "phf", + "phf 0.11.2", "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_ecma_ast", "swc_ecma_utils", "swc_ecma_visit", @@ -5365,18 +5528,18 @@ dependencies = [ [[package]] name = "swc_ecma_lints" -version = "0.91.3" +version = "0.99.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb591a1cfa9c40c4437d9b2c1e8fc90678de2b430c0ab5c3327f4b04b53b7bca" +checksum = "20c11bcc9e3dc49929500c07c8b0c84a88064847d31e9ee16204b257e6bd315c" dependencies = [ "auto_impl", - "dashmap", + "dashmap 5.5.3", "parking_lot", "rayon", "regex", "serde", "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_config", "swc_ecma_ast", "swc_ecma_utils", @@ -5385,12 +5548,12 @@ dependencies = [ [[package]] name = "swc_ecma_loader" -version = "0.45.17" +version = "0.49.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8452dca827603c1ca73d26549f21af3e4d23241a5bae62ba3ba2ec8d2a8775b3" +checksum = "55fa3d55045b97894bfb04d38aff6d6302ac8a6a38e3bb3dfb0d20475c4974a9" dependencies = [ "anyhow", - "dashmap", + "dashmap 5.5.3", "lru", "normpath", "once_cell", @@ -5401,31 +5564,33 @@ dependencies = [ "serde_json", "swc_atoms", "swc_cached", - "swc_common", + "swc_common 0.37.4", "tracing", ] [[package]] name = "swc_ecma_minifier" -version = "0.191.7" +version = "0.203.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "609547ba63c64b609984f2089a436e2f94488c3751f8496c42940ce4992efd4b" +checksum = "e13ee1a0975dc79d2cb23456bf45c7862b61f9a8890ade3025af8dc728e730db" dependencies = [ "arrayvec", - "indexmap 2.2.5", + "indexmap 2.2.6", "num-bigint", "num_cpus", "once_cell", "parking_lot", + "phf 0.11.2", "radix_fmt", "rayon", "regex", - "rustc-hash", + "rustc-hash 1.1.0", "ryu-js", "serde", "serde_json", + "swc_allocator", "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_config", "swc_ecma_ast", "swc_ecma_codegen", @@ -5441,21 +5606,21 @@ dependencies = [ [[package]] name = "swc_ecma_parser" -version = "0.142.1" +version = "0.149.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c3eedda441af51ca25caebb88837649a40e2a39b763344a53cfedd869740c71" +checksum = "7c7a81df222f44212c72fec4879c0d182c6eac66fb0e180afd05e8be6d920663" dependencies = [ "either", "new_debug_unreachable", "num-bigint", "num-traits", - "phf", + "phf 0.11.2", "serde", "smallvec", "smartstring", "stacker", "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_ecma_ast", "tracing", "typed-arena", @@ -5463,23 +5628,23 @@ dependencies = [ [[package]] name = "swc_ecma_preset_env" -version = "0.205.7" +version = "0.216.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9dd1ed14585df2e8e3f0bfbb8635dee2f1997d7defb7e8a28da3970bd51115" +checksum = "e5c01c4097d54b6992d926474546472f10f1f94799a6eb9b70176fc33e778573" dependencies = [ "anyhow", - "dashmap", - "indexmap 2.2.5", + "dashmap 5.5.3", + "indexmap 2.2.6", "once_cell", "preset_env_base", - "rustc-hash", + "rustc-hash 1.1.0", "semver 1.0.20", "serde", "serde_json", "st-map", "string_enum", "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_ecma_ast", "swc_ecma_transforms", "swc_ecma_utils", @@ -5488,42 +5653,42 @@ dependencies = [ [[package]] name = "swc_ecma_quote_macros" -version = "0.53.2" +version = "0.60.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a24a9f5024cc5dd803acb14e22474c889c982ca19f306bc574704dafc4c1d6fb" +checksum = "9781802c95d3bb1b248ae2641fab85012782bb5236e32600e6e4a00adf90a2dc" dependencies = [ "anyhow", "proc-macro2", "quote", "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_ecma_ast", "swc_ecma_parser", "swc_macros_common", - "syn 2.0.52", + "syn 2.0.63", ] [[package]] name = "swc_ecma_testing" -version = "0.22.17" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b73fd79980ad3182437a62dc0413bcd00e6157a7fcf5a64a86fa264ec6672ba" +checksum = "945faa325af9833b2541d3b0b4e614812677480c2b763c6c6e8c2a42a133b906" dependencies = [ "anyhow", "hex", "sha2", - "testing", + "testing 0.39.0", "tracing", ] [[package]] name = "swc_ecma_transforms" -version = "0.228.7" +version = "0.238.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0076f239ab0c220c792a0cbafa3140ae2e0b58acf1886f7008d59d68de5b78ef" +checksum = "d6a33679b1611630ee41f8ee8b41b9587de4171819698d313f7f8ae2c699f41a" dependencies = [ "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_ecma_ast", "swc_ecma_transforms_base", "swc_ecma_transforms_compat", @@ -5538,21 +5703,21 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_base" -version = "0.136.3" +version = "0.144.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a491da2eaab98914d1f85bd81a35db6432ad0577ae64746bb9e5594cb0b79b47" +checksum = "7c0a71579d030e12fd3cfbfc8712c4ce21afc526f2a759903c77d8df61950f5e" dependencies = [ "better_scoped_tls", - "bitflags 2.4.2", - "indexmap 2.2.5", + "bitflags 2.5.0", + "indexmap 2.2.6", "once_cell", - "phf", + "phf 0.11.2", "rayon", - "rustc-hash", + "rustc-hash 1.1.0", "serde", "smallvec", "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_ecma_ast", "swc_ecma_parser", "swc_ecma_utils", @@ -5562,12 +5727,12 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_classes" -version = "0.125.3" +version = "0.133.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1022bd4545eb9ae2cb9666a3c2cf84c1cfc0a38ec14fb61bbabf660baf60242f" +checksum = "0f37ec04525798a09ce02e52dc15433acee2d86664da0b8ede55bb5cefd95384" dependencies = [ "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_ecma_ast", "swc_ecma_transforms_base", "swc_ecma_utils", @@ -5576,18 +5741,18 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_compat" -version = "0.162.4" +version = "0.170.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de609d44d2e0dfec1968cdf3fed6faaa9e6e1b15191a25b7d70109e32a0db1c0" +checksum = "4bb500b65423646da940e289ad37e7c88332d7194248c33fc63a9e768e104fe5" dependencies = [ "arrayvec", - "indexmap 2.2.5", + "indexmap 2.2.6", "is-macro", "num-bigint", "serde", "smallvec", "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_config", "swc_ecma_ast", "swc_ecma_compat_bugfixes", @@ -5612,34 +5777,34 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_macros" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17e309b88f337da54ef7fe4c5b99c2c522927071f797ee6c9fb8b6bf2d100481" +checksum = "500a1dadad1e0e41e417d633b3d6d5de677c9e0d3159b94ba3348436cdb15aab" dependencies = [ "proc-macro2", "quote", "swc_macros_common", - "syn 2.0.52", + "syn 2.0.63", ] [[package]] name = "swc_ecma_transforms_module" -version = "0.179.7" +version = "0.189.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "844dc5b311b309d40c56c66edab4874c42e1e03b1b6f5c3284539a6a4e428bd4" +checksum = "2b5bddea322502ce309f77b76dcd7994ff700fbba7caf9d12eb6fb7ef98ecd1b" dependencies = [ "Inflector", "anyhow", - "bitflags 2.4.2", - "indexmap 2.2.5", + "bitflags 2.5.0", + "indexmap 2.2.6", "is-macro", - "path-clean 0.1.0", + "path-clean 1.0.1", "pathdiff", "regex", "serde", "swc_atoms", "swc_cached", - "swc_common", + "swc_common 0.37.4", "swc_ecma_ast", "swc_ecma_loader", "swc_ecma_parser", @@ -5651,19 +5816,19 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_optimization" -version = "0.197.7" +version = "0.207.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445efca981669a08cc8bab2bd9d0420eb688e7086d6a4babc6b670473877a2c2" +checksum = "fc9b6dcb79ac6f396988c13ce2f782116aeb92e8ee77656072d1146697f66022" dependencies = [ - "dashmap", - "indexmap 2.2.5", + "dashmap 5.5.3", + "indexmap 2.2.6", "once_cell", "petgraph", "rayon", - "rustc-hash", + "rustc-hash 1.1.0", "serde_json", "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_ecma_ast", "swc_ecma_parser", "swc_ecma_transforms_base", @@ -5676,16 +5841,16 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_proposal" -version = "0.170.7" +version = "0.178.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e2ffc3af6d736769ab1fff18b3f26c67c66bf0d78c1f15cbcd8575d698b16e6" +checksum = "b252ea08cfd11e434f4c625ec95493e06c8b000b50eb8e908d76f3325dd5dfa8" dependencies = [ "either", - "rustc-hash", + "rustc-hash 1.1.0", "serde", "smallvec", "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_ecma_ast", "swc_ecma_transforms_base", "swc_ecma_transforms_classes", @@ -5696,19 +5861,20 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_react" -version = "0.182.6" +version = "0.190.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46493a5f10abf9da23e609a7cbe961f99223d2b640d80caa39ce7ede6d75eb3a" +checksum = "c3e54a8c87d90812bf69b0f07931bb629111a3f24efe83b9190c3a40a5ebc25e" dependencies = [ "base64 0.21.7", - "dashmap", - "indexmap 2.2.5", + "dashmap 5.5.3", + "indexmap 2.2.6", "once_cell", "serde", - "sha-1", + "sha1", "string_enum", + "swc_allocator", "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_config", "swc_ecma_ast", "swc_ecma_parser", @@ -5720,9 +5886,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_testing" -version = "0.139.4" +version = "0.147.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b72b2f0668158820a71d3fda7d0c644db69dda5206d6b833c2b865a87c3b55af" +checksum = "b262ae285569998385b80ba0457a5cacce0208e6e7a3d7ee7dabc939231b0842" dependencies = [ "ansi_term", "anyhow", @@ -5732,7 +5898,7 @@ dependencies = [ "serde_json", "sha2", "sourcemap", - "swc_common", + "swc_common 0.37.4", "swc_ecma_ast", "swc_ecma_codegen", "swc_ecma_parser", @@ -5741,19 +5907,19 @@ dependencies = [ "swc_ecma_utils", "swc_ecma_visit", "tempfile", - "testing", + "testing 0.39.0", ] [[package]] name = "swc_ecma_transforms_typescript" -version = "0.187.7" +version = "0.197.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa929a7518e22fba9859e0cd26563cde6bda8fe5a055fffaa26f3696e934ad34" +checksum = "19b5f73e9996c6f374c05ff724afea6e6b5de03253ef856c321ff47f23717b5e" dependencies = [ "ryu-js", "serde", "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_ecma_ast", "swc_ecma_transforms_base", "swc_ecma_transforms_react", @@ -5763,14 +5929,14 @@ dependencies = [ [[package]] name = "swc_ecma_usage_analyzer" -version = "0.22.2" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9311eb3a2c41c4134b15a69469c096ab715ccdf2eed81f60c91d252514f1bb7f" +checksum = "bbb53b6fec4526660cc460f581b049a7f4bfb26b4b5d70aa0930c70abecf2f46" dependencies = [ - "indexmap 2.2.5", - "rustc-hash", + "indexmap 2.2.6", + "rustc-hash 1.1.0", "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_ecma_ast", "swc_ecma_utils", "swc_ecma_visit", @@ -5780,17 +5946,18 @@ dependencies = [ [[package]] name = "swc_ecma_utils" -version = "0.126.2" +version = "0.134.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f6edc4064cd932c6d267c05f0b161e6aaa4df4f900d5e1db8c92eda8edcc410" +checksum = "cde8f1ef3f7bd53340c7bd679f1ec563a45225ac8fb63f22d6de1ff4b345475d" dependencies = [ - "indexmap 2.2.5", + "indexmap 2.2.6", "num_cpus", "once_cell", "rayon", - "rustc-hash", + "rustc-hash 1.1.0", + "ryu-js", "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_ecma_ast", "swc_ecma_visit", "tracing", @@ -5799,39 +5966,16 @@ dependencies = [ [[package]] name = "swc_ecma_visit" -version = "0.97.1" +version = "0.104.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26ecefeec816318f1d449b4bac2e28a4243a167cc16620e15c3c1f2d91085770" +checksum = "c71f5f97db49b96208805104b381c5e117f55fad5f3d178e626c92934a4d0e36" dependencies = [ + "new_debug_unreachable", "num-bigint", "swc_atoms", - "swc_common", - "swc_ecma_ast", - "swc_visit", - "tracing", -] - -[[package]] -name = "swc_emotion" -version = "0.72.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b759380eee487f70b74126ed51fae2273fbfa27fb51165a31a61a5ee3890a20" -dependencies = [ - "base64 0.13.1", - "byteorder", - "fxhash", - "once_cell", - "radix_fmt", - "regex", - "serde", - "sourcemap", - "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_ecma_ast", - "swc_ecma_codegen", - "swc_ecma_utils", - "swc_ecma_visit", - "swc_trace_macro", + "swc_visit 0.6.1", "tracing", ] @@ -5850,39 +5994,52 @@ checksum = "695a1d8b461033d32429b5befbf0ad4d7a2c4d6ba9cd5ba4e0645c615839e8e4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.63", ] [[package]] name = "swc_error_reporters" -version = "0.17.14" +version = "0.17.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be42e786ee9bda3f72f7d7de791e1d7b49ab7f86ed54fdc5808681ae04406080" +checksum = "72100a5f7b0c178adf7bcc5e7c8ad9d4180f499a5f5bae9faf3f417c7cbc4915" dependencies = [ "anyhow", "miette 4.7.1", "once_cell", "parking_lot", - "swc_common", + "swc_common 0.33.26", +] + +[[package]] +name = "swc_error_reporters" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d049e9256abf29d9fc66d3db3ea44b6815a64ad565ce31e117a74ee96478bb3" +dependencies = [ + "anyhow", + "miette 7.2.0", + "once_cell", + "parking_lot", + "swc_common 0.37.4", ] [[package]] name = "swc_fast_graph" -version = "0.21.15" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c9c9e567014e157af520f74b1a5bc151fece681136754b80b3fec6b908e26a0" +checksum = "357e2c97bb51431d65080f25b436bc4e2fc1a7f64a643bc21a8353e478dc799f" dependencies = [ - "indexmap 2.2.5", + "indexmap 2.2.6", "petgraph", - "rustc-hash", - "swc_common", + "rustc-hash 1.1.0", + "swc_common 0.37.4", ] [[package]] name = "swc_html" -version = "0.136.7" +version = "0.148.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44a4bd6924f713c1534a191109b1072b02779878243371d176ba8b7441373027" +checksum = "706509020207c5e4dc17e9c6c3adcec901ec5e0d06314050643c3efce8be7fb7" dependencies = [ "swc_html_ast", "swc_html_codegen", @@ -5892,27 +6049,27 @@ dependencies = [ [[package]] name = "swc_html_ast" -version = "0.33.14" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08839fe2496ed2a765740b15f126b0555db0fd3632789b2b54045a134eafd213" +checksum = "9c425a3a19e94bd40f94da719691e19be6187a65e1fe6b294fd4d065e841c8e9" dependencies = [ "is-macro", "string_enum", "swc_atoms", - "swc_common", + "swc_common 0.37.4", ] [[package]] name = "swc_html_codegen" -version = "0.42.19" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa6d99502e94be5188d40eceb5a47c9249cda2b1ffacc64e4872807a18f21dab" +checksum = "1ade76d2999f98677284d1a961b41cf8f9405cfe492531164ead3d1c6796c768" dependencies = [ "auto_impl", - "bitflags 2.4.2", - "rustc-hash", + "bitflags 2.5.0", + "rustc-hash 1.1.0", "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_html_ast", "swc_html_codegen_macros", "swc_html_utils", @@ -5920,32 +6077,28 @@ dependencies = [ [[package]] name = "swc_html_codegen_macros" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41912779c72f8381deb1420ab7dab842fde772aeae06f4f0e4a93bd509d4ecfe" +checksum = "e593a6cbb3a49230fbab3171d4493f7d0fb1e20a34d9a9f9e972550690408ba8" dependencies = [ "proc-macro2", "quote", "swc_macros_common", - "syn 2.0.52", + "syn 2.0.63", ] [[package]] name = "swc_html_minifier" -version = "0.133.7" +version = "0.145.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75a03dfc350ea2e19269d2b6756e028b617ef3d7b94ed4cd257aa2f9f4cc9d96" +checksum = "f944d0cf2352767ddee5f65a02c73dadcd2050a75eab8bee45a30f80b318199f" dependencies = [ "once_cell", "serde", "serde_json", "swc_atoms", "swc_cached", - "swc_common", - "swc_css_ast", - "swc_css_codegen", - "swc_css_minifier", - "swc_css_parser", + "swc_common 0.37.4", "swc_ecma_ast", "swc_ecma_codegen", "swc_ecma_minifier", @@ -5961,40 +6114,40 @@ dependencies = [ [[package]] name = "swc_html_parser" -version = "0.39.19" +version = "0.43.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afd4d7e9a40475f375e33c7069623a840b6837119365ed7d463fe51959f0e494" +checksum = "d34cff1743fcfe3f83df6c4f65fa769f991d18372b38b578dc1192560f4b2037" dependencies = [ "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_html_ast", "swc_html_utils", ] [[package]] name = "swc_html_utils" -version = "0.18.14" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98bc6454adf24957138e7cf4ec32b3e46057fd1be4d11b573cc6163fe5060402" +checksum = "5153f5769f3425ecb6ec5f9d26166b5a9e837732450e07db8c4fd9a2c809456f" dependencies = [ "once_cell", "serde", "serde_json", "swc_atoms", - "swc_common", + "swc_common 0.37.4", ] [[package]] name = "swc_html_visit" -version = "0.33.14" +version = "0.37.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e52dcb4153045ed533699aa8b08c9711777e6cc24c245ec25f0a11229364a9a8" +checksum = "698542ee2b4069b2d7fa6f5be7e80d7b85cc39d03e8bd772fd75e6fb4a50aa12" dependencies = [ "serde", "swc_atoms", - "swc_common", + "swc_common 0.37.4", "swc_html_ast", - "swc_visit", + "swc_visit 0.6.1", ] [[package]] @@ -6008,13 +6161,13 @@ dependencies = [ [[package]] name = "swc_macros_common" -version = "0.3.9" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50176cfc1cbc8bb22f41c6fe9d1ec53fbe057001219b5954961b8ad0f336fce9" +checksum = "91745f3561057493d2da768437c427c0e979dff7396507ae02f16c981c4a8466" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.63", ] [[package]] @@ -6026,13 +6179,13 @@ dependencies = [ [[package]] name = "swc_node_comments" -version = "0.20.14" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8058148241150b482cbe8f690f1005663994dc22c9f8f9a651c7aeca9263f35" +checksum = "d016ab18b432523b2a3c104ce3aaf7d869db46c0a41477dbfb6201ddc86c1eb0" dependencies = [ - "dashmap", + "dashmap 5.5.3", "swc_atoms", - "swc_common", + "swc_common 0.37.4", ] [[package]] @@ -6048,22 +6201,22 @@ dependencies = [ name = "swc_plugin_import" version = "0.1.5" dependencies = [ - "Inflector", "handlebars", - "rustc-hash", + "heck 0.5.0", + "rustc-hash 1.1.0", "serde", "swc_core", ] [[package]] name = "swc_plugin_proxy" -version = "0.40.1" +version = "0.47.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d64191ea46b8156c495b77fce87759003d520109535d2fd524fe6d9e4de6238b" +checksum = "07548e19126fbc58b16237e2c8b0075f037774dfdd691fe4c558ba898cfe784b" dependencies = [ "better_scoped_tls", "rkyv", - "swc_common", + "swc_common 0.37.4", "swc_ecma_ast", "swc_trace_macro", "tracing", @@ -6071,9 +6224,9 @@ dependencies = [ [[package]] name = "swc_plugin_runner" -version = "0.105.4" +version = "0.112.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebbc89e7cef4bbdc42be2816b2cacc4af49827a2ec06365bb1ec45b4c8d58576" +checksum = "b919c741b6fe28f9e23ad080aabafadf564ee1a737a4bce27bbba987da1ef4ce" dependencies = [ "anyhow", "enumset", @@ -6082,11 +6235,12 @@ dependencies = [ "parking_lot", "serde", "serde_json", - "swc_common", + "swc_common 0.37.4", "swc_ecma_ast", "swc_plugin_proxy", "tokio", "tracing", + "virtual-fs 0.11.4", "wasmer", "wasmer-cache", "wasmer-compiler-cranelift", @@ -6104,9 +6258,9 @@ dependencies = [ [[package]] name = "swc_timer" -version = "0.21.16" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d15ec9bca22690ba9a373af069e366c9f43e48dd4d328aea6ba138f93ff0276" +checksum = "6b5fb6f8b8b85512aacbb3d7140a828666e0e0b1bcc69bf84000a0cd36306bab" dependencies = [ "tracing", ] @@ -6119,31 +6273,64 @@ checksum = "ff9719b6085dd2824fd61938a881937be14b08f95e2d27c64c825a9f65e052ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.63", +] + +[[package]] +name = "swc_transform_common" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eda3e80e1ad638d3575bc07745a914af13dcb02215098659f864731078271f2c" +dependencies = [ + "better_scoped_tls", + "once_cell", + "rustc-hash 1.1.0", + "serde", + "serde_json", +] + +[[package]] +name = "swc_typescript" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5d043347b109a8aebfe01aaeada4af322304ea0f54ae8e5721df9afcb9305ca" +dependencies = [ + "swc_atoms", + "swc_common 0.37.4", + "swc_ecma_ast", + "thiserror", ] [[package]] name = "swc_visit" -version = "0.5.8" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b27078d8571abe23aa52ef608dd1df89096a37d867cf691cbb4f4c392322b7c9" +checksum = "043d11fe683dcb934583ead49405c0896a5af5face522e4682c16971ef7871b9" dependencies = [ "either", "swc_visit_macros", ] +[[package]] +name = "swc_visit" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e194d14f94121fd08b823d3379eedb3ce455785d9e0c3d2742c59377e283207" +dependencies = [ + "either", +] + [[package]] name = "swc_visit_macros" -version = "0.5.9" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa8bb05975506741555ea4d10c3a3bdb0e2357cd58e1a4a4332b8ebb4b44c34d" +checksum = "92807d840959f39c60ce8a774a3f83e8193c658068e6d270dbe0a05e40e90b41" dependencies = [ "Inflector", - "pmutil", "proc-macro2", "quote", "swc_macros_common", - "syn 2.0.52", + "syn 2.0.63", ] [[package]] @@ -6159,9 +6346,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.52" +version = "2.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" +checksum = "bf5be731623ca1a1fb7d8be6f261a3be6d3e2337b8a1f97be944d020c8fcb704" dependencies = [ "proc-macro2", "quote", @@ -6198,27 +6385,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ "cfg-if", - "fastrand", + "fastrand 2.0.1", "redox_syscall 0.3.5", "rustix", "windows-sys 0.48.0", ] -[[package]] -name = "term_size" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "termcolor" -version = "1.2.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] @@ -6233,6 +6410,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "terminal_size" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +dependencies = [ + "rustix", + "windows-sys 0.48.0", +] + [[package]] name = "termios" version = "0.3.3" @@ -6244,20 +6431,41 @@ dependencies = [ [[package]] name = "testing" -version = "0.35.16" +version = "0.35.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15028f8ec7f95006f4e00e6c5ab6620f322bc6dc208a6cba09afa36375981cec" +dependencies = [ + "ansi_term", + "cargo_metadata 0.15.4", + "difference", + "once_cell", + "pretty_assertions", + "regex", + "serde", + "serde_json", + "swc_common 0.33.26", + "swc_error_reporters 0.17.20", + "testing_macros", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "testing" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42599f638bd2b48c2892cf330862aca433c86286ae776d75c5074ba3b4935ed8" +checksum = "3105e9569b7f674d1107d19494c993aafd19ea51f7a558b96b267b49c9b5f2bf" dependencies = [ "ansi_term", - "cargo_metadata", + "cargo_metadata 0.18.1", "difference", "once_cell", "pretty_assertions", "regex", "serde", "serde_json", - "swc_common", - "swc_error_reporters", + "swc_common 0.37.4", + "swc_error_reporters 0.21.0", "testing_macros", "tracing", "tracing-subscriber", @@ -6265,9 +6473,9 @@ dependencies = [ [[package]] name = "testing_macros" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d3864d4184569c1428645a51a304b3b6e8d3094cd61fb3cce8dfdd9f6d0f72" +checksum = "a39660370116afe46d5ff8bcb01b7afe2140dda3137ef5cb1914681e37a4ee06" dependencies = [ "anyhow", "glob", @@ -6276,7 +6484,7 @@ dependencies = [ "quote", "regex", "relative-path", - "syn 2.0.52", + "syn 2.0.63", ] [[package]] @@ -6290,24 +6498,35 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "textwrap" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" +dependencies = [ + "smawk", + "unicode-linebreak", + "unicode-width", +] + [[package]] name = "thiserror" -version = "1.0.57" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.57" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.63", ] [[package]] @@ -6320,72 +6539,35 @@ dependencies = [ "once_cell", ] -[[package]] -name = "tikv-jemalloc-sys" -version = "0.5.4+5.3.0-patched" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9402443cb8fd499b6f327e40565234ff34dbda27460c5b47db0db77443dd85d1" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "tikv-jemallocator" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "965fe0c26be5c56c94e38ba547249074803efd52adfb66de62107d95aab3eaca" -dependencies = [ - "libc", - "tikv-jemalloc-sys", -] - [[package]] name = "time" -version = "0.2.27" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4752a97f8eebd6854ff91f1c1824cd6160626ac4bd44287f7f4ea2035a02a242" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ - "const_fn", - "libc", - "standback", - "stdweb", + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", "time-macros", - "version_check", - "winapi", -] - -[[package]] -name = "time-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1" -dependencies = [ - "proc-macro-hack", - "time-macros-impl", ] [[package]] -name = "time-macros-impl" +name = "time-core" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f" -dependencies = [ - "proc-macro-hack", - "proc-macro2", - "quote", - "standback", - "syn 1.0.109", -] +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] -name = "tinytemplate" -version = "1.2.1" +name = "time-macros" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ - "serde", - "serde_json", + "num-conv", + "time-core", ] [[package]] @@ -6405,9 +6587,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.36.0" +version = "1.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" dependencies = [ "backtrace", "bytes", @@ -6425,7 +6607,32 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.63", +] + +[[package]] +name = "tokio-stream" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", + "tokio-util", +] + +[[package]] +name = "tokio-util" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", ] [[package]] @@ -6467,7 +6674,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.2.5", + "indexmap 2.2.6", "serde", "serde_spanned", "toml_datetime", @@ -6480,7 +6687,7 @@ version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c1b5fd4128cc8d3e0cb74d4ed9a9cc7c7284becd4df68f5f940e1ad123606f6" dependencies = [ - "indexmap 2.2.5", + "indexmap 2.2.6", "serde", "serde_spanned", "toml_datetime", @@ -6507,14 +6714,14 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.63", ] [[package]] name = "tracing-chrome" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "496b3cd5447f7ff527bbbf19b071ad542a000adf297d4127078b4dfdb931f41a" +checksum = "bf0a738ed5d6450a9fb96e86a23ad808de2b727fd1394585da5cdd6788ffe724" dependencies = [ "serde_json", "tracing-core", @@ -6560,6 +6767,41 @@ dependencies = [ "tracing-log", ] +[[package]] +name = "triomphe" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6631e42e10b40c0690bf92f404ebcfe6e1fdb480391d15f17cc8e96eeed5369" +dependencies = [ + "serde", + "stable_deref_trait", +] + +[[package]] +name = "trybuild" +version = "1.0.96" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33a5f13f11071020bb12de7a16b925d2d58636175c20c11dc5f96cb64bb6c9b3" +dependencies = [ + "dissimilar", + "glob", + "serde", + "serde_derive", + "serde_json", + "termcolor", + "toml 0.8.10", +] + +[[package]] +name = "twox-hash" +version = "1.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" +dependencies = [ + "cfg-if", + "static_assertions", +] + [[package]] name = "typed-arena" version = "2.0.2" @@ -6580,9 +6822,9 @@ checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" [[package]] name = "unicase" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" dependencies = [ "version_check", ] @@ -6599,6 +6841,12 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d70b6494226b36008c8366c288d77190b3fad2eb4c10533139c1c1f461127f1a" +[[package]] +name = "unicode-id-start" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc3882f69607a2ac8cc4de3ee7993d8f68bb06f2974271195065b3bd07f2edea" + [[package]] name = "unicode-ident" version = "1.0.10" @@ -6632,9 +6880,9 @@ checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" [[package]] name = "unicode-xid" @@ -6644,9 +6892,9 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "unsafe-libyaml" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab4c90930b95a82d00dc9e9ac071b4991924390d46cbd0dfe566148667605e4b" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" [[package]] name = "url" @@ -6697,6 +6945,18 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "value-trait" +version = "0.9.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47641b6867a201e598b2f14df9996d97a2ca0af2c34535faded32047e0bc9430" +dependencies = [ + "float-cmp", + "halfbrown", + "itoa", + "ryu", +] + [[package]] name = "vergen" version = "8.2.6" @@ -6715,14 +6975,37 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "virtual-fs" -version = "0.6.0" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2188aeb68d3f631caab9253650fc9e5ac8b4f9e223a3f8726e8b3317eac5f9c7" +dependencies = [ + "async-trait", + "bytes", + "derivative", + "futures", + "getrandom", + "indexmap 1.9.3", + "lazy_static", + "pin-project-lite", + "replace_with", + "shared-buffer", + "slab", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "virtual-fs" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcd74701f37aea30b90a83c90b92bc3850dedb9448836dbcc0960f993bda423b" +checksum = "ab78d839de346a6805017924bb424560c5bf77c4cd7d6f7754b492a4c2ec003f" dependencies = [ "anyhow", "async-trait", "bytes", "derivative", + "dunce", "filetime", "fs_extra", "futures", @@ -6732,6 +7015,7 @@ dependencies = [ "libc", "pin-project-lite", "replace_with", + "shared-buffer", "slab", "thiserror", "tokio", @@ -6739,18 +7023,53 @@ dependencies = [ "webc", ] +[[package]] +name = "virtual-mio" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff8026c9d7575dc9afd8a0907357acb7aa55ec262097fbccae5da42f67773b3c" +dependencies = [ + "async-trait", + "bytes", + "derivative", + "futures", + "mio", + "serde", + "socket2", + "thiserror", + "tracing", +] + [[package]] name = "virtual-net" -version = "0.3.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfac1d64ecfe2d8b295530da2a14af9eb9acccd91d76f3347dee96d745c83661" +checksum = "2e9f12f5b9ddecfc1bf03e91fba7e12ddf7c93c6ccf5e76a7683c89a26a34989" dependencies = [ + "anyhow", "async-trait", + "base64 0.21.7", + "bincode", + "bytecheck", "bytes", + "derivative", + "futures-util", + "pin-project-lite", + "rkyv", + "serde", + "smoltcp", "thiserror", + "tokio", "tracing", + "virtual-mio", ] +[[package]] +name = "vlq" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65dd7eed29412da847b0f78bcec0ac98588165988a8cfe41d4ea1d429f8ccfff" + [[package]] name = "vsimd" version = "0.8.0" @@ -6788,17 +7107,6 @@ dependencies = [ "wai-bindgen-gen-rust", ] -[[package]] -name = "wai-bindgen-gen-wasmer" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f61484185d8c520a86d5a7f7f8265f446617c2f9774b2e20a52de19b6e53432" -dependencies = [ - "heck 0.3.3", - "wai-bindgen-gen-core", - "wai-bindgen-gen-rust", -] - [[package]] name = "wai-bindgen-rust" version = "0.2.3" @@ -6821,33 +7129,6 @@ dependencies = [ "wai-bindgen-gen-rust-wasm", ] -[[package]] -name = "wai-bindgen-wasmer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffd9a8124a3e4e664cb79864fd1eaf24521e15bf8d67509af1bc45e8b510475" -dependencies = [ - "anyhow", - "bitflags 1.3.2", - "once_cell", - "thiserror", - "tracing", - "wai-bindgen-wasmer-impl", - "wasmer", -] - -[[package]] -name = "wai-bindgen-wasmer-impl" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b3488ed88d4dd0e3bf85bad4e27dac6cb31aae5d122a5dda2424803c8dc863a" -dependencies = [ - "proc-macro2", - "syn 1.0.109", - "wai-bindgen-gen-core", - "wai-bindgen-gen-wasmer", -] - [[package]] name = "wai-parser" version = "0.2.3" @@ -6869,9 +7150,9 @@ checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" [[package]] name = "walkdir" -version = "2.3.3" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -6908,29 +7189,6 @@ dependencies = [ "wasm-bindgen-shared", ] -[[package]] -name = "wasm-bindgen-downcast" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dac026d43bcca6e7ce1c0956ba68f59edf6403e8e930a5d891be72c31a44340" -dependencies = [ - "js-sys", - "once_cell", - "wasm-bindgen", - "wasm-bindgen-downcast-macros", -] - -[[package]] -name = "wasm-bindgen-downcast-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5020cfa87c7cecefef118055d44e3c1fc122c7ec25701d528ee458a0b45f38f" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "wasm-bindgen-macro" version = "0.2.84" @@ -6962,18 +7220,18 @@ checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" [[package]] name = "wasm-encoder" -version = "0.40.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d162eb64168969ae90e8668ca0593b0e47667e315aa08e717a9c9574d700d826" +checksum = "1ba64e81215916eaeb48fee292f29401d69235d62d8b8fd92a7b2844ec5ae5f7" dependencies = [ "leb128", ] [[package]] name = "wasmer" -version = "4.0.0" +version = "4.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea790bcdfb4e6e9d1e5ddf75b4699aac62b078fcc9f27f44e1748165ceea67bf" +checksum = "c3a6e0f73e5ae361fe64db607eaf4ab2381d88ad2c1b0bb8cf254cf35d894687" dependencies = [ "bytes", "cfg-if", @@ -6984,10 +7242,11 @@ dependencies = [ "rustc-demangle", "serde", "serde-wasm-bindgen", + "shared-buffer", "target-lexicon", "thiserror", + "tracing", "wasm-bindgen", - "wasm-bindgen-downcast", "wasmer-compiler", "wasmer-compiler-cranelift", "wasmer-derive", @@ -6999,9 +7258,9 @@ dependencies = [ [[package]] name = "wasmer-cache" -version = "4.0.0" +version = "4.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c968d5f47c4eef4597a7315aa9c6b633c285b5c52070722bac58fab75b298f" +checksum = "79fd0889f8844b7c70b8ee8fbf1d1f6ccff99399c6f3d3627048cde04b1ac493" dependencies = [ "blake3", "hex", @@ -7011,32 +7270,38 @@ dependencies = [ [[package]] name = "wasmer-compiler" -version = "4.0.0" +version = "4.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f093937725e242e5529fed27e08ff836c011a9ecc22e6819fb818c2ac6ff5f88" +checksum = "cb1e7c79507f5d55f1afd99984717e8380440cd98e13d542e4d00661f986f2d4" dependencies = [ "backtrace", + "bytes", "cfg-if", "enum-iterator", "enumset", "lazy_static", "leb128", + "libc", "memmap2 0.5.10", "more-asserts", "region", + "rkyv", + "self_cell", + "shared-buffer", "smallvec", "thiserror", "wasmer-types", "wasmer-vm", - "wasmparser 0.95.0", + "wasmparser 0.121.2", "winapi", + "xxhash-rust", ] [[package]] name = "wasmer-compiler-cranelift" -version = "4.0.0" +version = "4.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b27b1670d27158789ebe14e4da3902c72132174884a1c6a3533ce4fd9dd83db" +checksum = "8f3352014573750327646a690d32774312b0e8b7920e7e8ba00c0449eac18390" dependencies = [ "cranelift-codegen", "cranelift-entity", @@ -7051,11 +7316,55 @@ dependencies = [ "wasmer-types", ] +[[package]] +name = "wasmer-config" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a0f70c177b1c5062cfe0f5308c3317751796fef9403c22a0cd7b4cacd4ccd8" +dependencies = [ + "anyhow", + "bytesize", + "derive_builder", + "hex", + "indexmap 2.2.6", + "schemars", + "semver 1.0.20", + "serde", + "serde_cbor", + "serde_json", + "serde_yaml", + "thiserror", + "toml 0.8.10", + "url", +] + +[[package]] +name = "wasmer-config" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d35974065bb02340d7b448f8a4c5a3156b524e3a6b29d59201b940cf4c2c384f" +dependencies = [ + "anyhow", + "bytesize", + "derive_builder", + "hex", + "indexmap 2.2.6", + "schemars", + "semver 1.0.20", + "serde", + "serde_cbor", + "serde_json", + "serde_yaml", + "thiserror", + "toml 0.8.10", + "url", +] + [[package]] name = "wasmer-derive" -version = "4.0.0" +version = "4.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13ae8286cba2acb10065a4dac129c7c7f7bcd24acd6538555d96616eea16bc27" +checksum = "ac6b0b0580cfa1fc7ad58cca3626a742f2b2e5ccd51cfc5de43e8edb0d1daa4c" dependencies = [ "proc-macro-error", "proc-macro2", @@ -7064,59 +7373,73 @@ dependencies = [ ] [[package]] -name = "wasmer-toml" -version = "0.9.2" +name = "wasmer-journal" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d21472954ee9443235ca32522b17fc8f0fe58e2174556266a0d9766db055cc52" +checksum = "577b4a0876dc31138bb8df5cc6c6f622dcd893d5a81552583f107abcbb6eda50" dependencies = [ "anyhow", - "derive_builder 0.12.0", - "indexmap 2.2.5", - "semver 1.0.20", + "async-trait", + "base64 0.21.7", + "bincode", + "bytecheck", + "bytes", + "derivative", + "lz4_flex", + "num_enum", + "rkyv", "serde", - "serde_cbor", "serde_json", - "serde_yaml 0.9.32", "thiserror", - "toml 0.8.10", + "tracing", + "virtual-fs 0.15.0", + "virtual-net", + "wasmer", + "wasmer-wasix-types", ] [[package]] name = "wasmer-types" -version = "4.0.0" +version = "4.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "918d2f0bb5eaa95a80c06be33f21dee92f40f12cd0982da34490d121a99d244b" +checksum = "576442cc3d302ca215fd40aa7826a078571dca7eaa773d8cdedca14a2ec7c9a1" dependencies = [ "bytecheck", "enum-iterator", "enumset", + "getrandom", + "hex", "indexmap 1.9.3", "more-asserts", "rkyv", "serde", + "sha2", "target-lexicon", "thiserror", + "webc", + "xxhash-rust", ] [[package]] name = "wasmer-vm" -version = "4.0.0" +version = "4.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1e000c2cbd4f9805427af5f3b3446574caf89ab3a1e66c2f3579fbde22b072b" +checksum = "6483035d1df84a978cd6c6a35878e913dc8ec6311f8712548a922a75e87957ba" dependencies = [ "backtrace", "cc", "cfg-if", "corosensei", - "dashmap", + "crossbeam-queue", + "dashmap 5.5.3", "derivative", "enum-iterator", "fnv", "indexmap 1.9.3", "lazy_static", "libc", - "mach", - "memoffset 0.8.0", + "mach2", + "memoffset", "more-asserts", "region", "scopeguard", @@ -7127,17 +7450,21 @@ dependencies = [ [[package]] name = "wasmer-wasix" -version = "0.9.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dcd089dcd440141b2edf300ddd61c2d67d052baac8d29256c901f607d44d459" +checksum = "24badb9cbb62a67df4eee4d6d690ba81b5b49e43ac49d2c0d4a97276fc3aacb5" dependencies = [ + "ahash 0.8.11", "anyhow", "async-trait", + "base64 0.21.7", "bincode", + "blake3", + "bytecheck", "bytes", "cfg-if", "cooked-waker", - "dashmap", + "dashmap 5.5.3", "derivative", "futures", "getrandom", @@ -7147,44 +7474,51 @@ dependencies = [ "lazy_static", "libc", "linked_hash_set", + "lz4_flex", + "num_enum", "once_cell", "petgraph", "pin-project", "rand", + "rkyv", + "rusty_pool", "semver 1.0.20", "serde", "serde_cbor", "serde_derive", "serde_json", - "serde_yaml 0.8.26", + "serde_yaml", "sha2", - "shellexpand", + "shared-buffer", "tempfile", - "term_size", + "terminal_size 0.3.0", "termios", "thiserror", "tokio", + "tokio-stream", "tracing", "url", "urlencoding", - "virtual-fs", + "virtual-fs 0.15.0", + "virtual-mio", "virtual-net", - "wai-bindgen-wasmer", "waker-fn", - "wasm-bindgen", "wasmer", + "wasmer-config 0.5.0", + "wasmer-journal", "wasmer-types", "wasmer-wasix-types", "webc", "weezl", "winapi", + "xxhash-rust", ] [[package]] name = "wasmer-wasix-types" -version = "0.9.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a4a519e8f0b878bb4cd2b1bc733235aa6c331b7b4857dd6e0ac3c9a36d942ae" +checksum = "0c8b03288ec41769e99915a2b17611a74ba0680e8806d0710d892f52b4f15d6f" dependencies = [ "anyhow", "bitflags 1.3.2", @@ -7193,6 +7527,7 @@ dependencies = [ "num_enum", "serde", "time", + "tracing", "wai-bindgen-gen-core", "wai-bindgen-gen-rust", "wai-bindgen-gen-rust-wasm", @@ -7205,30 +7540,33 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.95.0" +version = "0.121.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2ea896273ea99b15132414be1da01ab0d8836415083298ecaffbe308eaac87a" +checksum = "9dbe55c8f9d0dbd25d9447a5a889ff90c0cc3feaa7395310d3d826b2c703eaab" dependencies = [ - "indexmap 1.9.3", - "url", + "bitflags 2.5.0", + "indexmap 2.2.6", + "semver 1.0.20", ] [[package]] name = "wasmparser" -version = "0.201.0" +version = "0.207.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84e5df6dba6c0d7fafc63a450f1738451ed7a0b52295d83e868218fa286bf708" +checksum = "e19bb9f8ab07616da582ef8adb24c54f1424c7ec876720b7da9db8ec0626c92c" dependencies = [ - "bitflags 2.4.2", - "indexmap 2.2.5", + "ahash 0.8.11", + "bitflags 2.5.0", + "hashbrown 0.14.5", + "indexmap 2.2.6", "semver 1.0.20", ] [[package]] name = "wast" -version = "70.0.1" +version = "64.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5d415036fe747a32b30c76c8bd6c73f69b7705fb7ebca5f16e852eef0c95802" +checksum = "a259b226fd6910225aa7baeba82f9d9933b6d00f2ce1b49b80fa4214328237cc" dependencies = [ "leb128", "memchr", @@ -7238,37 +7576,30 @@ dependencies = [ [[package]] name = "wat" -version = "1.0.84" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8241f34599d413d2243a21015ab43aef68bfb32a0e447c54eef8d423525ca15e" +checksum = "53253d920ab413fca1c7dc2161d601c79b4fdf631d0ba51dd4343bf9b556c3f6" dependencies = [ "wast", ] -[[package]] -name = "web-sys" -version = "0.3.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - [[package]] name = "webc" -version = "5.8.1" +version = "6.0.0-rc1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "973ca5a91b4fb3e4bb37cfebe03ef9364d0aff2765256abefdb7e79dc9188483" +checksum = "c1fc686c7b43c9bc630a499f6ae1f0a4c4bd656576a53ae8a147b0cc9bc983ad" dependencies = [ "anyhow", "base64 0.21.7", - "byteorder", "bytes", + "cfg-if", + "document-features", "flate2", + "ignore", "indexmap 1.9.3", "leb128", "lexical-sort", + "libc", "once_cell", "path-clean 1.0.1", "rand", @@ -7283,8 +7614,7 @@ dependencies = [ "thiserror", "toml 0.7.8", "url", - "walkdir", - "wasmer-toml", + "wasmer-config 0.2.0", ] [[package]] @@ -7544,36 +7874,12 @@ dependencies = [ "libc", ] -[[package]] -name = "xshell" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce2107fe03e558353b4c71ad7626d58ed82efaf56c54134228608893c77023ad" -dependencies = [ - "xshell-macros", -] - -[[package]] -name = "xshell-macros" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e2c411759b501fb9501aac2b1b2d287a6e93e5bdcf13c25306b23e1b716dd0e" - [[package]] name = "xxhash-rust" version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "927da81e25be1e1a2901d59b81b37dd2efd1fc9c9345a55007f09bf5a2d3ee03" -[[package]] -name = "yaml-rust" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" -dependencies = [ - "linked-hash-map", -] - [[package]] name = "yansi" version = "0.5.1" @@ -7582,20 +7888,20 @@ checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" [[package]] name = "zerocopy" -version = "0.7.25" +version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd369a67c0edfef15010f980c3cbe45d7f651deac2cd67ce097cd801de16557" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.25" +version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2f140bda219a26ccc0cdb03dba58af72590c53b22642577d88a927bc5c87d6b" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.63", ] diff --git a/Cargo.toml b/Cargo.toml index 8e88bf7..fc34743 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,5 @@ +cargo-features = ["trim-paths"] + [workspace] members = [ "crates/.rspack_crates/*", @@ -16,87 +18,175 @@ members = [ ] resolver = "2" +[workspace.package] +categories = ["bundler", "development-tools", "web-programming"] +documentation = "" +homepage = "" +license = "MIT" +repository = "https://github.com/ice-lab/icepack" + [workspace.dependencies] -anyhow = { version = "1.0.80", features = ["backtrace"] } -async-recursion = { version = "1.0.5" } +anyhow = { version = "1.0.81", features = ["backtrace"] } +anymap = { version = "=1.0.0-beta.2" } +async-recursion = { version = "1.1.0" } async-scoped = { version = "0.9.0" } -async-trait = { version = "0.1.77" } -backtrace = "0.3" -better_scoped_tls = { version = "0.1.1" } -bitflags = { version = "2.4.2" } -colored = { version = "2.1.0" } -concat-string = "1.0.1" +async-trait = { version = "0.1.79" } +bitflags = { version = "2.5.0" } +camino = { version = "1.1.8" } +concat-string = { version = "1.0.1" } +css-module-lexer = { version = "0.0.14" } dashmap = { version = "5.5.3" } derivative = { version = "2.2.0" } -derive_builder = { version = "0.20.0" } futures = { version = "0.3.30" } -futures-util = { version = "0.3.30" } glob = { version = "0.3.1" } hashlink = { version = "0.9.0" } -indexmap = { version = "2.2.5" } -insta = { version = "1.36.1" } -itertools = { version = "0.12.1" } +heck = { version = "0.5.0" } +hex = { version = "0.4.3" } +indexmap = { version = "2.2.6" } +indoc = { version = "2.0.5" } +itertools = { version = "0.13.0" } json = { version = "0.12.4" } +lightningcss = { version = "1.0.0-alpha.58" } linked_hash_set = { version = "0.1.4" } -mimalloc-rust = { version = "0.2" } +mimalloc = { version = "0.1.43" } mime_guess = { version = "2.0.4" } once_cell = { version = "1.19.0" } +parcel_sourcemap = { version = "2.1.1" } paste = { version = "1.0" } path-clean = { version = "1.0.1" } pathdiff = { version = "0.2.1" } -preset_env_base = { version = "0.4.11" } -proc-macro2 = { version = "1.0.78" } +proc-macro2 = { version = "1.0.79" } quote = { version = "1.0.35" } -rayon = { version = "1.9.0" } -regex = { version = "1.10.3" } -rkyv = { version = "=0.7.42" } -rspack_sources = { version = "=0.2.12" } +rayon = { version = "1.10.0" } +regex = { version = "1.10.4" } +rspack_sources = { version = "=0.3.2" } rustc-hash = { version = "1.1.0" } -schemars = { version = "0.8.16" } serde = { version = "1.0.197" } -serde_json = { version = "1.0.114" } -similar = { version = "2.4.0" } -sugar_path = { version = "0.0.12" } -syn = { version = "2.0.52" } -testing_macros = { version = "0.2.12" } -tokio = { version = "1.36.0" } +serde_json = { version = "1.0.115" } +simd-json = { version = "0.14.0-rc.2" } +stacker = { version = "0.1.15" } +sugar_path = { version = "1.2.0", features = ["cached_current_dir"] } +syn = { version = "2.0.58" } +tokio = { version = "1.37.0" } tracing = { version = "0.1.40" } tracing-subscriber = { version = "0.3.18" } +unicase = { version = "2.7.0" } url = { version = "2.5.0" } urlencoding = { version = "2.1.3" } ustr = { package = "ustr-fxhash", version = "1.0.0" } xxhash-rust = { version = "0.8.10" } # Pinned -napi = { version = "=2.16.0" } -napi-build = { version = "=2.1.2" } -napi-derive = { version = "=2.16.0" } -napi-sys = { version = "=2.3.0" } -tikv-jemallocator = { version = "=0.5.4", features = ["disable_initial_exec_tls"] } +napi = { package = "napi-h", version = "=2.16.1" } +napi-build = { version = "2" } +napi-derive = { version = "2" } # Must be pinned with the same swc versions -styled_components = { version = "=0.96.3" } -swc_config = { version = "=0.1.10" } -swc_core = { version = "=0.89.6", default-features = false } -swc_css = { version = "=0.157.32" } -swc_ecma_minifier = { version = "=0.191.7", default-features = false } -swc_emotion = { version = "=0.72.2" } -swc_error_reporters = { version = "=0.17.14" } -swc_html = { version = "=0.136.7" } -swc_html_minifier = { version = "=0.133.7" } -swc_node_comments = { version = "=0.20.14" } +#rkyv = { version = "=0.7.44" } # synced with swc wasm plugin +swc_config = { version = "=0.1.15" } +swc_core = { version = "=0.101.4", default-features = false } +swc_ecma_minifier = { version = "=0.203.1", default-features = false } +swc_error_reporters = { version = "=0.21.0" } +swc_html = { version = "=0.148.0" } +swc_html_minifier = { version = "=0.145.0", default-features = false } +swc_node_comments = { version = "=0.24.0" } testing = { version = "^0.35.16" } +rspack_dojang = { version = "0.1.9" } +[workspace.metadata.release] +rate-limit = { existing-packages = 70, new-packages = 70 } [profile.dev] -codegen-units = 16 # debug build will cause runtime panic if codegen-unints is default -debug = 2 +codegen-units = 16 +debug = 2 # debug build will cause runtime panic if codegen-unints is default incremental = true panic = "abort" [profile.release] codegen-units = 1 debug = false -lto = "thin" # Performs “thin” LTO. This is similar to “fat”, but takes substantially less time to run while still achieving performance gains similar to “fat”. -opt-level = 3 -panic = "abort" -strip = true +# Performs “thin” LTO. This is similar to “fat”, but takes substantially less time to run while still achieving performance gains similar to “fat”. +lto = "thin" +opt-level = 3 +panic = "abort" +strip = true + +[profile.release-prod] +inherits = "release" +# Performs “fat” LTO which attempts to perform optimizations across all crates within the dependency graph. +lto = "fat" + +[profile.release-debug] +debug = true +inherits = "release" +strip = false + +# the following lints rules are from https://github.com/biomejs/biome/blob/4bd3d6f09642952ee14445ed56af81a73796cea1/Cargo.toml#L7C1-L75C1 +[workspace.lints.rust] +absolute_paths_not_starting_with_crate = "warn" +dead_code = "warn" +trivial_numeric_casts = "warn" +unused_import_braces = "warn" +unused_lifetimes = "warn" +unused_macro_rules = "warn" + +[workspace.lints.clippy] +cargo_common_metadata = "allow" +empty_docs = "allow" # there are some false positives inside biome_wasm +multiple_crate_versions = "allow" + +# pedantic +checked_conversions = "warn" +cloned_instead_of_copied = "warn" +copy_iterator = "warn" +dbg_macro = "warn" +doc_link_with_quotes = "warn" +empty_enum = "warn" +expl_impl_clone_on_copy = "warn" +explicit_into_iter_loop = "warn" +filter_map_next = "warn" +flat_map_option = "warn" +fn_params_excessive_bools = "warn" +from_iter_instead_of_collect = "warn" +implicit_clone = "warn" +# not sure whether it's necessary +# implicit_hasher = "warn" +index_refutable_slice = "warn" +inefficient_to_string = "warn" +invalid_upcast_comparisons = "warn" +iter_not_returning_iterator = "warn" +large_stack_arrays = "warn" +large_types_passed_by_value = "warn" +macro_use_imports = "warn" +manual_ok_or = "warn" +manual_string_new = "warn" +map_flatten = "warn" +map_unwrap_or = "warn" +mismatching_type_param_order = "warn" +mut_mut = "warn" +naive_bytecount = "warn" +needless_bitwise_bool = "warn" +needless_continue = "warn" +needless_for_each = "warn" +no_effect_underscore_binding = "warn" +ref_binding_to_reference = "warn" +ref_option_ref = "warn" +stable_sort_primitive = "warn" +unnecessary_box_returns = "warn" +unnecessary_join = "warn" +unnested_or_patterns = "warn" +unreadable_literal = "warn" +verbose_bit_mask = "warn" +zero_sized_map_values = "warn" + +# restriction +empty_drop = "warn" +float_cmp_const = "warn" +get_unwrap = "warn" +infinite_loop = "warn" +lossy_float_literal = "warn" +rc_buffer = "warn" +rc_mutex = "warn" +rest_pat_in_fully_bound_structs = "warn" +verbose_file_reads = "warn" +# https://github.com/rustwasm/wasm-bindgen/issues/3944 +#mem_forget = "warn" diff --git a/crates/binding_options/Cargo.toml b/crates/binding_options/Cargo.toml index 336fc4b..eafe057 100644 --- a/crates/binding_options/Cargo.toml +++ b/crates/binding_options/Cargo.toml @@ -3,62 +3,73 @@ name = "binding_options" version = "0.1.0" edition = "2021" +[features] +default = [] +plugin = ["rspack_loader_swc/plugin"] + [dependencies] async-trait = { workspace = true } -better_scoped_tls = { workspace = true } derivative = { workspace = true } glob = { workspace = true } napi = { workspace = true, features = ["async", "tokio_rt", "serde-json", "anyhow"] } napi-derive = { workspace = true } -rspack_binding_options = { path = "../.rspack_crates/rspack_binding_options" } -rspack_hash = { path = "../.rspack_crates/rspack_hash" } -rspack_binding_macros = { path = "../.rspack_crates/rspack_binding_macros" } -rspack_binding_values = { path = "../.rspack_crates/rspack_binding_values" } -rspack_core = { path = "../.rspack_crates/rspack_core" } -rspack_error = { path = "../.rspack_crates/rspack_error" } -rspack_identifier = { path = "../.rspack_crates/rspack_identifier" } -rspack_ids = { path = "../.rspack_crates/rspack_ids" } -rspack_loader_react_refresh = { path = "../.rspack_crates/rspack_loader_react_refresh" } -rspack_loader_runner = { path = "../.rspack_crates/rspack_loader_runner" } -rspack_loader_swc = { path = "../.rspack_crates/rspack_loader_swc" } -rspack_napi_shared = { path = "../.rspack_crates/rspack_napi_shared" } -rspack_plugin_asset = { path = "../.rspack_crates/rspack_plugin_asset" } -rspack_plugin_banner = { path = "../.rspack_crates/rspack_plugin_banner" } -rspack_plugin_copy = { path = "../.rspack_crates/rspack_plugin_copy" } -rspack_plugin_css = { path = "../.rspack_crates/rspack_plugin_css" } -rspack_plugin_devtool = { path = "../.rspack_crates/rspack_plugin_devtool" } -rspack_plugin_ensure_chunk_conditions = { path = "../.rspack_crates/rspack_plugin_ensure_chunk_conditions" } -rspack_plugin_entry = { path = "../.rspack_crates/rspack_plugin_entry" } -rspack_plugin_externals = { path = "../.rspack_crates/rspack_plugin_externals" } -rspack_plugin_hmr = { path = "../.rspack_crates/rspack_plugin_hmr" } -rspack_plugin_html = { path = "../.rspack_crates/rspack_plugin_html" } -rspack_plugin_javascript = { path = "../.rspack_crates/rspack_plugin_javascript" } -rspack_plugin_json = { path = "../.rspack_crates/rspack_plugin_json" } -rspack_plugin_library = { path = "../.rspack_crates/rspack_plugin_library" } -rspack_plugin_limit_chunk_count = { path = "../.rspack_crates/rspack_plugin_limit_chunk_count" } -rspack_plugin_merge_duplicate_chunks = { path = "../.rspack_crates/rspack_plugin_merge_duplicate_chunks" } -rspack_plugin_mf = { path = "../.rspack_crates/rspack_plugin_mf" } -rspack_plugin_progress = { path = "../.rspack_crates/rspack_plugin_progress" } -rspack_plugin_real_content_hash = { path = "../.rspack_crates/rspack_plugin_real_content_hash" } -rspack_plugin_remove_empty_chunks = { path = "../.rspack_crates/rspack_plugin_remove_empty_chunks" } -rspack_plugin_runtime = { path = "../.rspack_crates/rspack_plugin_runtime" } -rspack_plugin_schemes = { path = "../.rspack_crates/rspack_plugin_schemes" } -rspack_plugin_split_chunks = { path = "../.rspack_crates/rspack_plugin_split_chunks" } -rspack_plugin_swc_css_minimizer = { path = "../.rspack_crates/rspack_plugin_swc_css_minimizer" } -rspack_plugin_swc_js_minimizer = { path = "../.rspack_crates/rspack_plugin_swc_js_minimizer" } -rspack_plugin_warn_sensitive_module = { path = "../.rspack_crates/rspack_plugin_warn_sensitive_module" } -rspack_plugin_wasm = { path = "../.rspack_crates/rspack_plugin_wasm" } -rspack_plugin_web_worker_template = { path = "../.rspack_crates/rspack_plugin_web_worker_template" } -rspack_plugin_worker = { path = "../.rspack_crates/rspack_plugin_worker" } -rspack_regex = { path = "../.rspack_crates/rspack_regex" } -rspack_swc_visitors = { path = "../.rspack_crates/rspack_swc_visitors" } +rspack_binding_values = { version = "0.1.0", path = "../.rspack_crates/rspack_binding_values" } +rspack_collections = { version = "0.1.0", path = "../.rspack_crates/rspack_collections" } +rspack_core = { version = "0.1.0", path = "../.rspack_crates/rspack_core" } +rspack_error = { version = "0.1.0", path = "../.rspack_crates/rspack_error" } +rspack_hook = { version = "0.1.0", path = "../.rspack_crates/rspack_hook" } +rspack_ids = { version = "0.1.0", path = "../.rspack_crates/rspack_ids" } +rspack_loader_lightningcss = { version = "0.1.0", path = "../.rspack_crates/rspack_loader_lightningcss" } +rspack_loader_preact_refresh = { version = "0.1.0", path = "../.rspack_crates/rspack_loader_preact_refresh" } +rspack_loader_react_refresh = { version = "0.1.0", path = "../.rspack_crates/rspack_loader_react_refresh" } +rspack_loader_runner = { version = "0.1.0", path = "../.rspack_crates/rspack_loader_runner" } +rspack_loader_swc = { version = "0.1.0", path = "../.rspack_crates/rspack_loader_swc" } +rspack_loader_testing = { version = "0.1.0", path = "../.rspack_crates/rspack_loader_testing" } +rspack_napi = { version = "0.1.0", path = "../.rspack_crates/rspack_napi" } +rspack_napi_macros = { version = "0.1.0", path = "../.rspack_crates/rspack_napi_macros" } +rspack_paths = { version = "0.1.0", path = "../.rspack_crates/rspack_paths" } +rspack_plugin_asset = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_asset" } +rspack_plugin_banner = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_banner" } +rspack_plugin_copy = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_copy" } +rspack_plugin_css = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_css" } +rspack_plugin_devtool = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_devtool" } +rspack_plugin_dynamic_entry = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_dynamic_entry" } +rspack_plugin_ensure_chunk_conditions = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_ensure_chunk_conditions" } +rspack_plugin_entry = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_entry" } +rspack_plugin_externals = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_externals" } +rspack_plugin_extract_css = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_extract_css" } +rspack_plugin_hmr = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_hmr" } +rspack_plugin_html = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_html" } +rspack_plugin_ignore = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_ignore" } +rspack_plugin_javascript = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_javascript" } +rspack_plugin_json = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_json" } +rspack_plugin_lazy_compilation = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_lazy_compilation" } +rspack_plugin_library = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_library" } +rspack_plugin_lightning_css_minimizer = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_lightning_css_minimizer" } +rspack_plugin_limit_chunk_count = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_limit_chunk_count" } +rspack_plugin_merge_duplicate_chunks = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_merge_duplicate_chunks" } +rspack_plugin_mf = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_mf" } +rspack_plugin_no_emit_on_errors = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_no_emit_on_errors" } +rspack_plugin_progress = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_progress" } +rspack_plugin_real_content_hash = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_real_content_hash" } +rspack_plugin_remove_empty_chunks = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_remove_empty_chunks" } +rspack_plugin_runtime = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_runtime" } +rspack_plugin_runtime_chunk = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_runtime_chunk" } +rspack_plugin_schemes = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_schemes" } +rspack_plugin_size_limits = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_size_limits" } +rspack_plugin_split_chunks = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_split_chunks" } +rspack_plugin_swc_js_minimizer = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_swc_js_minimizer" } +rspack_plugin_warn_sensitive_module = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_warn_sensitive_module" } +rspack_plugin_wasm = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_wasm" } +rspack_plugin_web_worker_template = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_web_worker_template" } +rspack_plugin_worker = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_worker" } +rspack_regex = { version = "0.1.0", path = "../.rspack_crates/rspack_regex" } +rspack_hash = { version = "0.1.0", path = "../.rspack_crates/rspack_hash" } loader_compilation = { path = "../loader_compilation" } loader_barrel = { path = "../loader_barrel" } -plugin_manifest = { path = "../plugin_manifest" } rustc-hash = { workspace = true } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } -swc_config = { 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"] } tracing = { workspace = true } diff --git a/crates/binding_options/src/lib.rs b/crates/binding_options/src/lib.rs index 4e0c9dc..73c2422 100644 --- a/crates/binding_options/src/lib.rs +++ b/crates/binding_options/src/lib.rs @@ -1,2 +1,6 @@ +#![feature(try_blocks)] +#![feature(let_chains)] mod options; +mod plugins; pub use options::*; +pub(crate) use plugins::*; diff --git a/crates/binding_options/src/options/js_loader.rs b/crates/binding_options/src/options/js_loader.rs deleted file mode 100644 index a3c85bc..0000000 --- a/crates/binding_options/src/options/js_loader.rs +++ /dev/null @@ -1,99 +0,0 @@ -use std::{ - path::{Path, PathBuf}, - str::FromStr, -}; - -use napi::bindgen_prelude::*; -use rspack_binding_options::JsLoaderContext; -use rspack_core::{rspack_sources::SourceMap, Content, LoaderContext, ResourceData}; -use rustc_hash::FxHashSet as HashSet; - -use crate::get_builtin_loader; - -pub async fn run_builtin_loader( - builtin: String, - options: Option<&str>, - loader_context: JsLoaderContext, -) -> Result { - use rspack_loader_runner::__private::loader::LoaderItemList; - - let loader = get_builtin_loader(&builtin, options); - let loader_item = loader.clone().into(); - let list = &[loader_item]; - let additional_data = { - let mut additional_data = loader_context.additional_data_external.clone(); - if let Some(data) = loader_context - .additional_data - .map(|b| String::from_utf8_lossy(b.as_ref()).to_string()) - { - additional_data.insert(data); - } - additional_data - }; - - let mut cx = LoaderContext { - hot: loader_context.hot, - content: match loader_context.content { - Either::A(_) => None, - Either::B(c) => Some(Content::from(c.as_ref().to_owned())), - }, - resource: &loader_context.resource, - resource_path: Path::new(&loader_context.resource_path), - resource_query: loader_context.resource_query.as_deref(), - resource_fragment: loader_context.resource_fragment.as_deref(), - context: loader_context.context_external.clone(), - source_map: loader_context - .source_map - .map(|s| SourceMap::from_slice(s.as_ref())) - .transpose() - .map_err(|e| Error::from_reason(e.to_string()))?, - additional_data, - cacheable: loader_context.cacheable, - file_dependencies: HashSet::from_iter( - loader_context - .file_dependencies - .iter() - .map(|m| PathBuf::from_str(m).expect("Should convert to path")), - ), - context_dependencies: HashSet::from_iter( - loader_context - .context_dependencies - .iter() - .map(|m| PathBuf::from_str(m).expect("Should convert to path")), - ), - missing_dependencies: HashSet::from_iter( - loader_context - .missing_dependencies - .iter() - .map(|m| PathBuf::from_str(m).expect("Should convert to path")), - ), - build_dependencies: HashSet::from_iter( - loader_context - .build_dependencies - .iter() - .map(|m| PathBuf::from_str(m).expect("Should convert to path")), - ), - asset_filenames: HashSet::from_iter(loader_context.asset_filenames.into_iter()), - // Initialize with no diagnostic - __diagnostics: vec![], - __resource_data: &ResourceData::new(Default::default(), Default::default()), - __loader_items: LoaderItemList(list), - // This is used an hack to `builtin:swc-loader` in order to determine whether to return AST or source. - __loader_index: loader_context.loader_index_from_js.unwrap_or(0) as usize, - __plugins: &[], - }; - if loader_context.is_pitching { - // Builtin loaders dispatched using JS loader-runner does not support pitching. - // This phase is ignored. - } else { - // Run normal loader - loader - .run(&mut cx) - .await - .map_err(|e| Error::from_reason(e.to_string()))?; - // restore the hack - cx.__loader_index = 0; - } - - JsLoaderContext::try_from(&mut cx).map_err(|e| Error::from_reason(e.to_string())) -} \ No newline at end of file diff --git a/crates/binding_options/src/options/mod.rs b/crates/binding_options/src/options/mod.rs index 443359d..2a04eb6 100644 --- a/crates/binding_options/src/options/mod.rs +++ b/crates/binding_options/src/options/mod.rs @@ -1,28 +1,45 @@ use napi_derive::napi; -use rspack_binding_options::{ - RawBuiltins, RawCacheOptions, RawExperiments, RawMode, RawModuleOptions, RawNodeOption, - RawOutputOptions, RawResolveOptions, RawSnapshotOptions, RawStatsOptions, -}; use rspack_core::{ CacheOptions, CompilerOptions, Context, Experiments, IncrementalRebuild, - IncrementalRebuildMakeState, ModuleOptions, Optimization, OutputOptions, Target, TreeShaking, + IncrementalRebuildMakeState, ModuleOptions, OutputOptions, References, Target, }; -use serde::Deserialize; -mod js_loader; -mod raw_features; +mod raw_builtins; +mod raw_cache; +mod raw_devtool; +mod raw_dynamic_entry; +mod raw_experiments; +mod raw_external; +mod raw_mode; mod raw_module; +mod raw_node; mod raw_optimization; +mod raw_output; +mod raw_snapshot; +mod raw_split_chunks; +mod raw_stats; +// mod raw_features; -pub use js_loader::*; -pub use raw_features::*; +pub use raw_builtins::*; +pub use raw_cache::*; +pub use raw_devtool::*; +pub use raw_dynamic_entry::*; +pub use raw_experiments::*; +pub use raw_external::*; +pub use raw_mode::*; pub use raw_module::*; +pub use raw_node::*; pub use raw_optimization::*; +pub use raw_output::*; +pub use raw_snapshot::*; +pub use raw_split_chunks::*; +pub use raw_stats::*; +// pub use raw_features::*; +pub use rspack_binding_values::raw_resolve::*; -#[derive(Deserialize, Debug)] -#[serde(rename_all = "camelCase")] -#[napi(object)] -pub struct RSPackRawOptions { +#[derive(Debug)] +#[napi(object, object_to_js = false)] +pub struct RawOptions { #[napi(ts_type = "undefined | 'production' | 'development' | 'none'")] pub mode: Option, pub target: Vec, @@ -32,7 +49,7 @@ pub struct RSPackRawOptions { pub resolve_loader: RawResolveOptions, pub module: RawModuleOptions, pub devtool: String, - pub optimization: RspackRawOptimizationOptions, + pub optimization: RawOptimizationOptions, pub stats: RawStatsOptions, pub snapshot: RawSnapshotOptions, pub cache: RawCacheOptions, @@ -40,63 +57,40 @@ pub struct RSPackRawOptions { pub node: Option, pub profile: bool, pub bail: bool, - pub builtins: RawBuiltins, - pub features: RawFeatures, +// pub features: RawFeatures, + #[napi(js_name = "__references", ts_type = "Record")] + pub __references: References, } -impl RSPackRawOptions { - pub fn apply( - self, - plugins: &mut Vec, - ) -> rspack_error::Result { - let context: Context = self.context.into(); - let output: OutputOptions = self.output.try_into()?; - let resolve = self.resolve.try_into()?; - let resolve_loader = self.resolve_loader.try_into()?; - let mode = self.mode.unwrap_or_default().into(); - let module: ModuleOptions = self.module.try_into()?; - let target = Target::new(&self.target)?; - let cache = self.cache.into(); +impl TryFrom for CompilerOptions { + type Error = rspack_error::Error; + + fn try_from(value: RawOptions) -> Result { + let context: Context = value.context.into(); + let output: OutputOptions = value.output.try_into()?; + let resolve = value.resolve.try_into()?; + let resolve_loader = value.resolve_loader.try_into()?; + let mode = value.mode.unwrap_or_default().into(); + let module: ModuleOptions = value.module.try_into()?; + let target = Target::new(&value.target)?; + let cache = value.cache.into(); let experiments = Experiments { incremental_rebuild: IncrementalRebuild { - make: if matches!(cache, CacheOptions::Disabled) - || self.experiments.rspack_future.new_treeshaking - { + make: if matches!(cache, CacheOptions::Disabled) { None } else { Some(IncrementalRebuildMakeState::default()) }, emit_asset: true, }, - new_split_chunks: self.experiments.new_split_chunks, - top_level_await: self.experiments.top_level_await, - rspack_future: self.experiments.rspack_future.into(), + layers: value.experiments.layers, + top_level_await: value.experiments.top_level_await, + rspack_future: value.experiments.rspack_future.into(), }; - let optimization: Optimization; - if self.features.split_chunks_strategy.is_some() { - let split_chunk_strategy = SplitChunksStrategy::new( - self.features.split_chunks_strategy.unwrap(), - self.optimization, - ); - optimization = split_chunk_strategy.apply(plugins, context.to_string())?; - } else { - optimization = IS_ENABLE_NEW_SPLIT_CHUNKS.set(&experiments.new_split_chunks, || { - self.optimization.try_into() - })?; - } - let stats = self.stats.into(); - let snapshot = self.snapshot.into(); - let node = self.node.map(|n| n.into()); - - // Add custom plugins. - if self.features.assets_manifest.unwrap_or_default() { - plugins.push(Box::new(plugin_manifest::ManifestPlugin::new())); - } - - let mut builtins = self.builtins.apply(plugins)?; - if experiments.rspack_future.new_treeshaking { - builtins.tree_shaking = TreeShaking::False; - } + let optimization = value.optimization.try_into()?; + let stats = value.stats.into(); + let snapshot = value.snapshot.into(); + let node = value.node.map(|n| n.into()); Ok(CompilerOptions { context, @@ -113,9 +107,9 @@ impl RSPackRawOptions { optimization, node, dev_server: Default::default(), - profile: self.profile, - bail: self.bail, - builtins, + profile: value.profile, + bail: value.bail, + __references: value.__references, }) } } diff --git a/crates/binding_options/src/options/raw_builtins/mod.rs b/crates/binding_options/src/options/raw_builtins/mod.rs new file mode 100644 index 0000000..ff43096 --- /dev/null +++ b/crates/binding_options/src/options/raw_builtins/mod.rs @@ -0,0 +1,517 @@ +mod raw_banner; +mod raw_bundle_info; +mod raw_copy; +mod raw_css_extract; +mod raw_html; +mod raw_ignore; +mod raw_lazy_compilation; +mod raw_lightning_css_minimizer; +mod raw_limit_chunk_count; +mod raw_mf; +mod raw_progress; +mod raw_runtime_chunk; +mod raw_size_limits; +mod raw_swc_js_minimizer; + +use napi::{bindgen_prelude::FromNapiValue, Env, JsUnknown}; +use napi_derive::napi; +use raw_lightning_css_minimizer::RawLightningCssMinimizerRspackPluginOptions; +use rspack_binding_values::entry::JsEntryPluginOptions; +use rspack_core::{BoxPlugin, Plugin, PluginExt}; +use rspack_error::Result; +use rspack_ids::{ + DeterministicChunkIdsPlugin, DeterministicModuleIdsPlugin, NamedChunkIdsPlugin, + NamedModuleIdsPlugin, NaturalChunkIdsPlugin, NaturalModuleIdsPlugin, +}; +use rspack_napi::NapiResultExt; +use rspack_plugin_asset::AssetPlugin; +use rspack_plugin_banner::BannerPlugin; +use rspack_plugin_copy::{CopyRspackPlugin, CopyRspackPluginOptions}; +use rspack_plugin_css::CssPlugin; +use rspack_plugin_devtool::{ + EvalDevToolModulePlugin, EvalSourceMapDevToolPlugin, SourceMapDevToolModuleOptionsPlugin, + SourceMapDevToolModuleOptionsPluginOptions, SourceMapDevToolPlugin, + SourceMapDevToolPluginOptions, +}; +use rspack_plugin_dynamic_entry::DynamicEntryPlugin; +use rspack_plugin_ensure_chunk_conditions::EnsureChunkConditionsPlugin; +use rspack_plugin_entry::EntryPlugin; +use rspack_plugin_externals::{ + electron_target_plugin, http_externals_rspack_plugin, node_target_plugin, ExternalsPlugin, +}; +use rspack_plugin_hmr::HotModuleReplacementPlugin; +use rspack_plugin_html::HtmlRspackPlugin; +use rspack_plugin_ignore::IgnorePlugin; +use rspack_plugin_javascript::{ + api_plugin::APIPlugin, define_plugin::DefinePlugin, provide_plugin::ProvidePlugin, + FlagDependencyExportsPlugin, FlagDependencyUsagePlugin, InferAsyncModulesPlugin, JsPlugin, + MangleExportsPlugin, ModuleConcatenationPlugin, SideEffectsFlagPlugin, +}; +use rspack_plugin_json::JsonPlugin; +use rspack_plugin_library::enable_library_plugin; +use rspack_plugin_lightning_css_minimizer::LightningCssMinimizerRspackPlugin; +use rspack_plugin_limit_chunk_count::LimitChunkCountPlugin; +use rspack_plugin_merge_duplicate_chunks::MergeDuplicateChunksPlugin; +use rspack_plugin_mf::{ + ConsumeSharedPlugin, ContainerPlugin, ContainerReferencePlugin, ModuleFederationRuntimePlugin, + ProvideSharedPlugin, ShareRuntimePlugin, +}; +use rspack_plugin_no_emit_on_errors::NoEmitOnErrorsPlugin; +use rspack_plugin_progress::ProgressPlugin; +use rspack_plugin_real_content_hash::RealContentHashPlugin; +use rspack_plugin_remove_empty_chunks::RemoveEmptyChunksPlugin; +use rspack_plugin_runtime::{ + enable_chunk_loading_plugin, ArrayPushCallbackChunkFormatPlugin, BundlerInfoPlugin, + ChunkPrefetchPreloadPlugin, CommonJsChunkFormatPlugin, ModuleChunkFormatPlugin, RuntimePlugin, +}; +use rspack_plugin_runtime_chunk::RuntimeChunkPlugin; +use rspack_plugin_schemes::{DataUriPlugin, FileUriPlugin}; +use rspack_plugin_size_limits::SizeLimitsPlugin; +use rspack_plugin_swc_js_minimizer::SwcJsMinimizerRspackPlugin; +use rspack_plugin_warn_sensitive_module::WarnCaseSensitiveModulesPlugin; +use rspack_plugin_wasm::{ + enable_wasm_loading_plugin, AsyncWasmPlugin, FetchCompileAsyncWasmPlugin, +}; +use rspack_plugin_web_worker_template::web_worker_template_plugin; +use rspack_plugin_worker::WorkerPlugin; + +pub use self::{ + raw_banner::RawBannerPluginOptions, raw_copy::RawCopyRspackPluginOptions, + raw_html::RawHtmlRspackPluginOptions, raw_ignore::RawIgnorePluginOptions, + raw_limit_chunk_count::RawLimitChunkCountPluginOptions, raw_mf::RawContainerPluginOptions, + raw_progress::RawProgressPluginOptions, + raw_swc_js_minimizer::RawSwcJsMinimizerRspackPluginOptions, +}; +use self::{ + raw_bundle_info::{RawBundlerInfoModeWrapper, RawBundlerInfoPluginOptions}, + raw_css_extract::RawCssExtractPluginOption, + raw_lazy_compilation::{JsBackend, RawLazyCompilationOption}, + raw_mf::{RawConsumeSharedPluginOptions, RawContainerReferencePluginOptions, RawProvideOptions}, + raw_runtime_chunk::RawRuntimeChunkOptions, + raw_size_limits::RawSizeLimitsPluginOptions, +}; +use crate::{ + plugins::{CssExtractRspackAdditionalDataPlugin, JsLoaderRspackPlugin}, + JsLoaderRunner, RawDynamicEntryPluginOptions, RawEvalDevToolModulePluginOptions, + RawExternalItemWrapper, RawExternalsPluginOptions, RawHttpExternalsRspackPluginOptions, + RawSourceMapDevToolPluginOptions, RawSplitChunksOptions, +}; + +#[napi(string_enum)] +#[derive(Debug)] +pub enum BuiltinPluginName { + // webpack also have these plugins + DefinePlugin, + ProvidePlugin, + BannerPlugin, + IgnorePlugin, + ProgressPlugin, + EntryPlugin, + DynamicEntryPlugin, + ExternalsPlugin, + NodeTargetPlugin, + ElectronTargetPlugin, + EnableChunkLoadingPlugin, + EnableLibraryPlugin, + EnableWasmLoadingPlugin, + FetchCompileAsyncWasmPlugin, + ChunkPrefetchPreloadPlugin, + CommonJsChunkFormatPlugin, + ArrayPushCallbackChunkFormatPlugin, + ModuleChunkFormatPlugin, + HotModuleReplacementPlugin, + LimitChunkCountPlugin, + WorkerPlugin, + WebWorkerTemplatePlugin, + MergeDuplicateChunksPlugin, + SplitChunksPlugin, + ShareRuntimePlugin, + ContainerPlugin, + ContainerReferencePlugin, + ProvideSharedPlugin, + ConsumeSharedPlugin, + ModuleFederationRuntimePlugin, + NamedModuleIdsPlugin, + NaturalModuleIdsPlugin, + DeterministicModuleIdsPlugin, + NaturalChunkIdsPlugin, + NamedChunkIdsPlugin, + DeterministicChunkIdsPlugin, + RealContentHashPlugin, + RemoveEmptyChunksPlugin, + EnsureChunkConditionsPlugin, + WarnCaseSensitiveModulesPlugin, + DataUriPlugin, + FileUriPlugin, + RuntimePlugin, + JsonModulesPlugin, + InferAsyncModulesPlugin, + JavascriptModulesPlugin, + AsyncWebAssemblyModulesPlugin, + AssetModulesPlugin, + SourceMapDevToolPlugin, + EvalSourceMapDevToolPlugin, + EvalDevToolModulePlugin, + SideEffectsFlagPlugin, + FlagDependencyExportsPlugin, + FlagDependencyUsagePlugin, + MangleExportsPlugin, + ModuleConcatenationPlugin, + CssModulesPlugin, + APIPlugin, + RuntimeChunkPlugin, + SizeLimitsPlugin, + NoEmitOnErrorsPlugin, + + // rspack specific plugins + // naming format follow XxxRspackPlugin + HttpExternalsRspackPlugin, + CopyRspackPlugin, + HtmlRspackPlugin, + SwcJsMinimizerRspackPlugin, + LightningCssMinimizerRspackPlugin, + BundlerInfoRspackPlugin, + CssExtractRspackPlugin, + + // rspack js adapter plugins + // naming format follow XxxRspackPlugin + JsLoaderRspackPlugin, + LazyCompilationPlugin, +} + +#[napi(object)] +pub struct BuiltinPlugin { + pub name: BuiltinPluginName, + pub options: JsUnknown, + pub can_inherent_from_parent: Option, +} + +impl BuiltinPlugin { + pub fn append_to(self, env: Env, plugins: &mut Vec) -> rspack_error::Result<()> { + match self.name { + // webpack also have these plugins + BuiltinPluginName::DefinePlugin => { + let plugin = DefinePlugin::new(downcast_into(self.options)?).boxed(); + plugins.push(plugin); + } + BuiltinPluginName::ProvidePlugin => { + let plugin = ProvidePlugin::new(downcast_into(self.options)?).boxed(); + plugins.push(plugin); + } + BuiltinPluginName::BannerPlugin => { + let plugin = + BannerPlugin::new(downcast_into::(self.options)?.try_into()?) + .boxed(); + plugins.push(plugin); + } + BuiltinPluginName::IgnorePlugin => { + let plugin = + IgnorePlugin::new(downcast_into::(self.options)?.into()).boxed(); + plugins.push(plugin); + } + BuiltinPluginName::ProgressPlugin => { + let plugin = + ProgressPlugin::new(downcast_into::(self.options)?.into()) + .boxed(); + plugins.push(plugin); + } + BuiltinPluginName::EntryPlugin => { + let plugin_options = downcast_into::(self.options)?; + let context = plugin_options.context.into(); + let entry_request = plugin_options.entry; + let options = plugin_options.options.into(); + let plugin = EntryPlugin::new(context, entry_request, options).boxed(); + plugins.push(plugin); + } + BuiltinPluginName::DynamicEntryPlugin => { + let plugin = DynamicEntryPlugin::new( + downcast_into::(self.options)?.into(), + ) + .boxed(); + plugins.push(plugin); + } + BuiltinPluginName::ExternalsPlugin => { + let plugin_options = downcast_into::(self.options)?; + let externals = plugin_options + .externals + .into_iter() + .map(|e| RawExternalItemWrapper(e).try_into()) + .collect::>>()?; + let plugin = ExternalsPlugin::new(plugin_options.r#type, externals).boxed(); + plugins.push(plugin); + } + BuiltinPluginName::NodeTargetPlugin => plugins.push(node_target_plugin()), + BuiltinPluginName::ElectronTargetPlugin => { + let context = downcast_into::(self.options)?; + electron_target_plugin(context.into(), plugins); + } + BuiltinPluginName::EnableChunkLoadingPlugin => { + let chunk_loading_type = downcast_into::(self.options)?; + enable_chunk_loading_plugin(chunk_loading_type.as_str().into(), plugins); + } + BuiltinPluginName::EnableLibraryPlugin => { + let library_type = downcast_into::(self.options)?; + enable_library_plugin(library_type, plugins); + } + BuiltinPluginName::EnableWasmLoadingPlugin => { + let wasm_loading_type = downcast_into::(self.options)?; + plugins.push(enable_wasm_loading_plugin( + wasm_loading_type.as_str().into(), + )); + } + BuiltinPluginName::FetchCompileAsyncWasmPlugin => { + plugins.push(FetchCompileAsyncWasmPlugin::default().boxed()) + } + BuiltinPluginName::ChunkPrefetchPreloadPlugin => { + plugins.push(ChunkPrefetchPreloadPlugin::default().boxed()); + } + BuiltinPluginName::CommonJsChunkFormatPlugin => { + plugins.push(CommonJsChunkFormatPlugin::default().boxed()); + } + BuiltinPluginName::ArrayPushCallbackChunkFormatPlugin => { + plugins.push(ArrayPushCallbackChunkFormatPlugin::default().boxed()); + } + BuiltinPluginName::ModuleChunkFormatPlugin => { + plugins.push(ModuleChunkFormatPlugin::default().boxed()); + } + BuiltinPluginName::HotModuleReplacementPlugin => { + plugins.push(HotModuleReplacementPlugin::default().boxed()); + } + BuiltinPluginName::LimitChunkCountPlugin => { + let plugin = LimitChunkCountPlugin::new( + downcast_into::(self.options)?.into(), + ) + .boxed(); + plugins.push(plugin); + } + BuiltinPluginName::WorkerPlugin => { + plugins.push(WorkerPlugin::default().boxed()); + } + BuiltinPluginName::WebWorkerTemplatePlugin => { + web_worker_template_plugin(plugins); + } + BuiltinPluginName::MergeDuplicateChunksPlugin => { + plugins.push(MergeDuplicateChunksPlugin::default().boxed()); + } + BuiltinPluginName::SplitChunksPlugin => { + use rspack_plugin_split_chunks::SplitChunksPlugin; + let options = downcast_into::(self.options)?.into(); + plugins.push(SplitChunksPlugin::new(options).boxed()); + } + BuiltinPluginName::ShareRuntimePlugin => { + plugins.push(ShareRuntimePlugin::new(downcast_into::(self.options)?).boxed()) + } + BuiltinPluginName::ContainerPlugin => { + plugins.push( + ContainerPlugin::new(downcast_into::(self.options)?.into()) + .boxed(), + ); + } + BuiltinPluginName::ContainerReferencePlugin => { + plugins.push( + ContainerReferencePlugin::new( + downcast_into::(self.options)?.into(), + ) + .boxed(), + ); + } + BuiltinPluginName::ProvideSharedPlugin => { + let mut provides: Vec<_> = downcast_into::>(self.options)? + .into_iter() + .map(Into::into) + .collect(); + provides.sort_unstable_by_key(|(k, _)| k.to_string()); + plugins.push(ProvideSharedPlugin::new(provides).boxed()) + } + BuiltinPluginName::ConsumeSharedPlugin => plugins.push( + ConsumeSharedPlugin::new( + downcast_into::(self.options)?.into(), + ) + .boxed(), + ), + BuiltinPluginName::ModuleFederationRuntimePlugin => { + plugins.push(ModuleFederationRuntimePlugin::default().boxed()) + } + BuiltinPluginName::NamedModuleIdsPlugin => { + plugins.push(NamedModuleIdsPlugin::default().boxed()) + } + BuiltinPluginName::NaturalModuleIdsPlugin => { + plugins.push(NaturalModuleIdsPlugin::default().boxed()) + } + BuiltinPluginName::DeterministicModuleIdsPlugin => { + plugins.push(DeterministicModuleIdsPlugin::default().boxed()) + } + BuiltinPluginName::NaturalChunkIdsPlugin => { + plugins.push(NaturalChunkIdsPlugin::default().boxed()) + } + BuiltinPluginName::NamedChunkIdsPlugin => { + plugins.push(NamedChunkIdsPlugin::new(None, None).boxed()) + } + BuiltinPluginName::DeterministicChunkIdsPlugin => { + plugins.push(DeterministicChunkIdsPlugin::default().boxed()) + } + BuiltinPluginName::RealContentHashPlugin => { + plugins.push(RealContentHashPlugin::default().boxed()) + } + BuiltinPluginName::RemoveEmptyChunksPlugin => { + plugins.push(RemoveEmptyChunksPlugin::default().boxed()) + } + BuiltinPluginName::EnsureChunkConditionsPlugin => { + plugins.push(EnsureChunkConditionsPlugin::default().boxed()) + } + BuiltinPluginName::WarnCaseSensitiveModulesPlugin => { + plugins.push(WarnCaseSensitiveModulesPlugin::default().boxed()) + } + BuiltinPluginName::DataUriPlugin => plugins.push(DataUriPlugin::default().boxed()), + BuiltinPluginName::FileUriPlugin => plugins.push(FileUriPlugin::default().boxed()), + BuiltinPluginName::RuntimePlugin => plugins.push(RuntimePlugin::default().boxed()), + BuiltinPluginName::JsonModulesPlugin => plugins.push(JsonPlugin.boxed()), + BuiltinPluginName::InferAsyncModulesPlugin => { + plugins.push(InferAsyncModulesPlugin::default().boxed()) + } + BuiltinPluginName::JavascriptModulesPlugin => plugins.push(JsPlugin::default().boxed()), + BuiltinPluginName::AsyncWebAssemblyModulesPlugin => { + plugins.push(AsyncWasmPlugin::default().boxed()) + } + BuiltinPluginName::AssetModulesPlugin => plugins.push(AssetPlugin::default().boxed()), + BuiltinPluginName::SourceMapDevToolPlugin => { + let options: SourceMapDevToolPluginOptions = + downcast_into::(self.options)?.into(); + plugins.push( + SourceMapDevToolModuleOptionsPlugin::new(SourceMapDevToolModuleOptionsPluginOptions { + module: options.module, + cheap: !options.columns, + }) + .boxed(), + ); + plugins.push(SourceMapDevToolPlugin::new(options).boxed()); + } + BuiltinPluginName::EvalSourceMapDevToolPlugin => { + let options: SourceMapDevToolPluginOptions = + downcast_into::(self.options)?.into(); + plugins.push( + SourceMapDevToolModuleOptionsPlugin::new(SourceMapDevToolModuleOptionsPluginOptions { + module: options.module, + cheap: !options.columns, + }) + .boxed(), + ); + plugins.push(EvalSourceMapDevToolPlugin::new(options).boxed()); + } + BuiltinPluginName::EvalDevToolModulePlugin => { + plugins.push( + EvalDevToolModulePlugin::new( + downcast_into::(self.options)?.into(), + ) + .boxed(), + ); + } + BuiltinPluginName::SideEffectsFlagPlugin => { + plugins.push(SideEffectsFlagPlugin::default().boxed()) + } + BuiltinPluginName::FlagDependencyExportsPlugin => { + plugins.push(FlagDependencyExportsPlugin::default().boxed()) + } + BuiltinPluginName::FlagDependencyUsagePlugin => { + plugins.push(FlagDependencyUsagePlugin::new(downcast_into::(self.options)?).boxed()) + } + BuiltinPluginName::MangleExportsPlugin => { + plugins.push(MangleExportsPlugin::new(downcast_into::(self.options)?).boxed()) + } + BuiltinPluginName::ModuleConcatenationPlugin => { + plugins.push(ModuleConcatenationPlugin::default().boxed()) + } + BuiltinPluginName::CssModulesPlugin => plugins.push(CssPlugin::default().boxed()), + BuiltinPluginName::APIPlugin => plugins.push(APIPlugin::default().boxed()), + BuiltinPluginName::RuntimeChunkPlugin => plugins.push( + RuntimeChunkPlugin::new(downcast_into::(self.options)?.into()) + .boxed(), + ), + BuiltinPluginName::SizeLimitsPlugin => { + let plugin = + SizeLimitsPlugin::new(downcast_into::(self.options)?.into()) + .boxed(); + plugins.push(plugin) + } + + // rspack specific plugins + BuiltinPluginName::HttpExternalsRspackPlugin => { + let plugin_options = downcast_into::(self.options)?; + let plugin = http_externals_rspack_plugin(plugin_options.css, plugin_options.web_async); + plugins.push(plugin); + } + BuiltinPluginName::SwcJsMinimizerRspackPlugin => { + let plugin = SwcJsMinimizerRspackPlugin::new( + downcast_into::(self.options)?.try_into()?, + ) + .boxed(); + plugins.push(plugin); + } + BuiltinPluginName::LightningCssMinimizerRspackPlugin => plugins.push( + LightningCssMinimizerRspackPlugin::new( + downcast_into::(self.options)?.try_into()?, + ) + .boxed(), + ), + BuiltinPluginName::CopyRspackPlugin => { + let plugin = CopyRspackPlugin::new( + CopyRspackPluginOptions::from(downcast_into::(self.options)?) + .patterns, + ) + .boxed(); + plugins.push(plugin); + } + BuiltinPluginName::HtmlRspackPlugin => { + let plugin = + HtmlRspackPlugin::new(downcast_into::(self.options)?.into()) + .boxed(); + plugins.push(plugin); + } + BuiltinPluginName::BundlerInfoRspackPlugin => { + let plugin_options = downcast_into::(self.options)?; + plugins.push( + BundlerInfoPlugin::new( + plugin_options.version, + plugin_options.bundler, + RawBundlerInfoModeWrapper(plugin_options.force).into(), + ) + .boxed(), + ) + } + BuiltinPluginName::CssExtractRspackPlugin => { + let additional_data_plugin = CssExtractRspackAdditionalDataPlugin::new(env)?.boxed(); + plugins.push(additional_data_plugin); + let plugin = rspack_plugin_extract_css::plugin::PluginCssExtract::new( + downcast_into::(self.options)?.into(), + ) + .boxed(); + plugins.push(plugin); + } + BuiltinPluginName::JsLoaderRspackPlugin => { + plugins + .push(JsLoaderRspackPlugin::new(downcast_into::(self.options)?).boxed()); + } + BuiltinPluginName::LazyCompilationPlugin => { + let options = downcast_into::(self.options)?; + let js_backend = JsBackend::from(&options); + plugins.push(Box::new( + rspack_plugin_lazy_compilation::plugin::LazyCompilationPlugin::new( + options.cacheable, + js_backend, + options.test.map(|test| test.into()), + options.entries, + options.imports, + ), + ) as Box) + } + BuiltinPluginName::NoEmitOnErrorsPlugin => { + plugins.push(NoEmitOnErrorsPlugin::default().boxed()); + } + } + Ok(()) + } +} + +fn downcast_into(o: JsUnknown) -> Result { + rspack_napi::downcast_into(o).into_rspack_result() +} diff --git a/crates/binding_options/src/options/raw_builtins/raw_banner.rs b/crates/binding_options/src/options/raw_builtins/raw_banner.rs new file mode 100644 index 0000000..36fc238 --- /dev/null +++ b/crates/binding_options/src/options/raw_builtins/raw_banner.rs @@ -0,0 +1,109 @@ +use derivative::Derivative; +use napi::Either; +use napi_derive::napi; +use rspack_binding_values::JsChunk; +use rspack_error::Result; +use rspack_napi::{ + regexp::{JsRegExp, JsRegExpExt}, + threadsafe_function::ThreadsafeFunction, +}; +use rspack_plugin_banner::{ + BannerContent, BannerContentFnCtx, BannerPluginOptions, BannerRule, BannerRules, +}; + +#[napi(object)] +pub struct RawBannerContentFnCtx { + pub hash: String, + pub chunk: JsChunk, + pub filename: String, +} + +impl<'a> From> for RawBannerContentFnCtx { + fn from(value: BannerContentFnCtx) -> Self { + Self { + hash: value.hash.to_string(), + chunk: JsChunk::from(value.chunk), + filename: value.filename.to_string(), + } + } +} + +type RawBannerContent = Either>; +struct RawBannerContentWrapper(RawBannerContent); + +impl TryFrom for BannerContent { + type Error = rspack_error::Error; + fn try_from(value: RawBannerContentWrapper) -> Result { + match value.0 { + Either::A(s) => Ok(Self::String(s)), + Either::B(f) => Ok(BannerContent::Fn(Box::new( + move |ctx: BannerContentFnCtx| { + let ctx = ctx.into(); + let f = f.clone(); + Box::pin(async move { f.call(ctx).await }) + }, + ))), + } + } +} + +type RawBannerRule = Either; +type RawBannerRules = Either>; +struct RawBannerRuleWrapper(RawBannerRule); +struct RawBannerRulesWrapper(RawBannerRules); + +#[derive(Derivative)] +#[derivative(Debug)] +#[napi(object, object_to_js = false)] +pub struct RawBannerPluginOptions { + #[derivative(Debug = "ignore")] + #[napi(ts_type = "string | ((...args: any[]) => any)")] + pub banner: RawBannerContent, + pub entry_only: Option, + pub footer: Option, + pub raw: Option, + pub stage: Option, + #[napi(ts_type = "string | RegExp | (string | RegExp)[]")] + pub test: Option, + #[napi(ts_type = "string | RegExp | (string | RegExp)[]")] + pub include: Option, + #[napi(ts_type = "string | RegExp | (string | RegExp)[]")] + pub exclude: Option, +} + +impl From for BannerRule { + fn from(x: RawBannerRuleWrapper) -> Self { + match x.0 { + Either::A(s) => BannerRule::String(s), + Either::B(r) => BannerRule::Regexp(r.to_rspack_regex()), + } + } +} + +impl From for BannerRules { + fn from(x: RawBannerRulesWrapper) -> Self { + match x.0 { + Either::A(v) => BannerRules::Single(RawBannerRuleWrapper(v).into()), + Either::B(v) => v + .into_iter() + .map(|v| RawBannerRuleWrapper(v).into()) + .collect(), + } + } +} + +impl TryFrom for BannerPluginOptions { + type Error = rspack_error::Error; + fn try_from(value: RawBannerPluginOptions) -> Result { + Ok(BannerPluginOptions { + banner: RawBannerContentWrapper(value.banner).try_into()?, + entry_only: value.entry_only, + footer: value.footer, + raw: value.raw, + stage: value.stage, + test: value.test.map(|v| RawBannerRulesWrapper(v).into()), + include: value.include.map(|v| RawBannerRulesWrapper(v).into()), + exclude: value.exclude.map(|v| RawBannerRulesWrapper(v).into()), + }) + } +} diff --git a/crates/binding_options/src/options/raw_builtins/raw_bundle_info.rs b/crates/binding_options/src/options/raw_builtins/raw_bundle_info.rs new file mode 100644 index 0000000..b3293e0 --- /dev/null +++ b/crates/binding_options/src/options/raw_builtins/raw_bundle_info.rs @@ -0,0 +1,31 @@ +use napi::Either; +use napi_derive::napi; +use rspack_plugin_runtime::BundlerInfoForceMode; +use rustc_hash::FxHashSet; + +type RawBundlerInfoMode = Either>; +pub struct RawBundlerInfoModeWrapper(pub RawBundlerInfoMode); + +#[derive(Debug, Clone)] +#[napi(object)] +pub struct RawBundlerInfoPluginOptions { + pub version: String, + pub bundler: String, + #[napi(ts_type = "boolean | string[]")] + pub force: RawBundlerInfoMode, +} + +impl From for BundlerInfoForceMode { + fn from(x: RawBundlerInfoModeWrapper) -> Self { + match x.0 { + Either::A(v) => { + if v { + BundlerInfoForceMode::All + } else { + BundlerInfoForceMode::Auto + } + } + Either::B(v) => BundlerInfoForceMode::Partial(v.into_iter().collect::>()), + } + } +} diff --git a/crates/binding_options/src/options/raw_builtins/raw_copy.rs b/crates/binding_options/src/options/raw_builtins/raw_copy.rs new file mode 100644 index 0000000..ecf999e --- /dev/null +++ b/crates/binding_options/src/options/raw_builtins/raw_copy.rs @@ -0,0 +1,184 @@ +use derivative::Derivative; +use napi::{bindgen_prelude::Buffer, Either}; +use napi_derive::napi; +use rspack_core::rspack_sources::RawSource; +use rspack_napi::threadsafe_function::ThreadsafeFunction; +use rspack_plugin_copy::{ + CopyGlobOptions, CopyPattern, CopyRspackPluginOptions, Info, Related, ToOption, ToType, + Transformer, +}; + +type RawTransformer = ThreadsafeFunction<(Buffer, String), Either>; + +type RawToFn = ThreadsafeFunction; + +type RawTo = Either; + +#[derive(Debug, Clone)] +#[napi(object)] +pub struct RawToOptions { + pub context: String, + pub absolute_filename: String, +} + +#[derive(Derivative)] +#[derivative(Debug, Clone)] +#[napi(object, object_to_js = false)] +pub struct RawCopyPattern { + pub from: String, + #[derivative(Debug = "ignore")] + #[napi( + ts_type = "string | ((pathData: { context: string; absoluteFilename?: string }) => string | Promise)" + )] + pub to: Option, + pub context: Option, + pub to_type: Option, + pub no_error_on_missing: bool, + pub force: bool, + pub priority: i32, + pub glob_options: RawCopyGlobOptions, + pub info: Option, + #[derivative(Debug = "ignore")] + #[napi( + ts_type = "(input: Buffer, absoluteFilename: string) => string | Buffer | Promise | Promise" + )] + pub transform: Option, +} + +#[derive(Debug, Clone)] +#[napi(object)] +pub struct RawInfo { + pub immutable: Option, + pub minimized: Option, + pub chunk_hash: Option>, + pub content_hash: Option>, + pub development: Option, + pub hot_module_replacement: Option, + pub related: Option, + pub version: Option, +} + +#[derive(Debug, Clone)] +#[napi(object)] +pub struct RawRelated { + pub source_map: Option, +} + +#[derive(Debug, Clone)] +#[napi(object)] +pub struct RawCopyGlobOptions { + pub case_sensitive_match: Option, + pub dot: Option, + pub ignore: Option>, +} + +#[derive(Debug)] +#[napi(object, object_to_js = false)] +pub struct RawCopyRspackPluginOptions { + pub patterns: Vec, +} + +impl From for CopyPattern { + fn from(value: RawCopyPattern) -> Self { + let RawCopyPattern { + from, + to, + context, + to_type, + no_error_on_missing, + force, + priority, + glob_options, + info, + transform, + } = value; + + Self { + from, + to: to.map(|to| match to { + Either::A(s) => ToOption::String(s), + Either::B(f) => ToOption::Fn(Box::new(move |ctx| { + let f = f.clone(); + Box::pin(async move { + f.call(RawToOptions { + context: ctx.context.as_str().to_owned(), + absolute_filename: ctx.absolute_filename.as_str().to_owned(), + }) + .await + }) + })), + }), + context: context.map(Into::into), + to_type: if let Some(to_type) = to_type { + match to_type.to_lowercase().as_str() { + "dir" => Some(ToType::Dir), + "file" => Some(ToType::File), + "template" => Some(ToType::Template), + _ => { + //TODO how should we handle wrong input ? + None + } + } + } else { + None + }, + no_error_on_missing, + info: info.map(Into::into), + force, + priority, + glob_options: CopyGlobOptions { + case_sensitive_match: glob_options.case_sensitive_match, + dot: glob_options.dot, + ignore: glob_options.ignore.map(|ignore| { + ignore + .into_iter() + .map(|filter| glob::Pattern::new(filter.as_ref()).expect("Invalid pattern option")) + .collect() + }), + }, + transform: transform.map(|transformer| { + Transformer::Fn(Box::new(move |input, absolute_filename| { + let f = transformer.clone(); + + fn convert_to_enum(input: Either) -> RawSource { + match input { + Either::A(s) => RawSource::from(s), + Either::B(b) => RawSource::from(b.to_vec()), + } + } + + Box::pin(async move { + f.call((input.into(), absolute_filename.to_owned())) + .await + .map(convert_to_enum) + }) + })) + }), + } + } +} + +impl From for CopyRspackPluginOptions { + fn from(val: RawCopyRspackPluginOptions) -> Self { + Self { + patterns: val.patterns.into_iter().map(Into::into).collect(), + } + } +} + +impl From for Info { + fn from(value: RawInfo) -> Self { + Self { + immutable: value.immutable, + minimized: value.minimized, + chunk_hash: value.chunk_hash, + content_hash: value.content_hash, + development: value.development, + hot_module_replacement: value.hot_module_replacement, + related: value.related.map(|r| Related { + source_map: r.source_map, + }), + version: value.version, + } + } +} diff --git a/crates/binding_options/src/options/raw_builtins/raw_css_extract.rs b/crates/binding_options/src/options/raw_builtins/raw_css_extract.rs new file mode 100644 index 0000000..2a18caa --- /dev/null +++ b/crates/binding_options/src/options/raw_builtins/raw_css_extract.rs @@ -0,0 +1,41 @@ +use std::collections::HashMap; + +use napi_derive::napi; +use rspack_binding_values::JsFilename; +use rspack_plugin_extract_css::plugin::{CssExtractOptions, InsertType}; + +#[napi(object, object_to_js = false)] +pub struct RawCssExtractPluginOption { + pub filename: JsFilename, + pub chunk_filename: JsFilename, + pub ignore_order: bool, + pub insert: Option, + pub attributes: HashMap, + pub link_type: Option, + pub runtime: bool, + pub pathinfo: bool, +} + +impl From for CssExtractOptions { + fn from(value: RawCssExtractPluginOption) -> Self { + Self { + filename: value.filename.into(), + chunk_filename: value.chunk_filename.into(), + ignore_order: value.ignore_order, + insert: value + .insert + .map(|insert| { + if insert.starts_with("function") || insert.starts_with('(') { + InsertType::Fn(insert) + } else { + InsertType::Selector(insert) + } + }) + .unwrap_or(InsertType::Default), + attributes: value.attributes.into_iter().collect(), + link_type: value.link_type, + runtime: value.runtime, + pathinfo: value.pathinfo, + } + } +} diff --git a/crates/binding_options/src/options/raw_builtins/raw_html.rs b/crates/binding_options/src/options/raw_builtins/raw_html.rs new file mode 100644 index 0000000..9c9ffd6 --- /dev/null +++ b/crates/binding_options/src/options/raw_builtins/raw_html.rs @@ -0,0 +1,132 @@ +use std::collections::HashMap; +use std::str::FromStr; + +use napi::bindgen_prelude::Either3; +use napi_derive::napi; +use rspack_napi::threadsafe_function::ThreadsafeFunction; +use rspack_plugin_html::config::HtmlInject; +use rspack_plugin_html::config::HtmlRspackPluginBaseOptions; +use rspack_plugin_html::config::HtmlRspackPluginOptions; +use rspack_plugin_html::config::HtmlScriptLoading; +use rspack_plugin_html::config::TemplateParameterFn; +use rspack_plugin_html::config::TemplateParameters; +use rspack_plugin_html::config::TemplateRenderFn; +use rspack_plugin_html::sri::HtmlSriHashFunction; + +pub type RawHtmlScriptLoading = String; +pub type RawHtmlInject = String; +pub type RawHtmlSriHashFunction = String; +pub type RawHtmlFilename = String; + +type RawTemplateRenderFn = ThreadsafeFunction; + +type RawTemplateParameter = + Either3, bool, ThreadsafeFunction>; + +#[derive(Debug)] +#[napi(object, object_to_js = false)] +pub struct RawHtmlRspackPluginOptions { + /// emitted file name in output path + #[napi(ts_type = "string")] + pub filename: Option, + /// template html file + pub template: Option, + #[napi(ts_type = "(data: string) => Promise")] + pub template_fn: Option, + pub template_content: Option, + #[napi(ts_type = "boolean | Record | ((params: string) => Promise)")] + pub template_parameters: Option, + /// "head", "body" or "false" + #[napi(ts_type = "\"head\" | \"body\" | \"false\"")] + pub inject: RawHtmlInject, + /// path or `auto` + pub public_path: Option, + /// `blocking`, `defer`, `module` or `systemjs-module` + #[napi(ts_type = "\"blocking\" | \"defer\" | \"module\" | \"systemjs-module\"")] + pub script_loading: RawHtmlScriptLoading, + + /// entry_chunk_name (only entry chunks are supported) + pub chunks: Option>, + pub exclude_chunks: Option>, + #[napi(ts_type = "\"sha256\" | \"sha384\" | \"sha512\"")] + pub sri: Option, + pub minify: Option, + pub title: Option, + pub favicon: Option, + pub meta: Option>>, + pub hash: Option, + pub base: Option, +} + +impl From for HtmlRspackPluginOptions { + fn from(value: RawHtmlRspackPluginOptions) -> Self { + let inject = HtmlInject::from_str(&value.inject).expect("Invalid inject value"); + + let script_loading = + HtmlScriptLoading::from_str(&value.script_loading).expect("Invalid script_loading value"); + + let sri = value.sri.as_ref().map(|s| { + HtmlSriHashFunction::from_str(s).unwrap_or_else(|_| panic!("Invalid sri value: {s}")) + }); + + HtmlRspackPluginOptions { + filename: value.filename.unwrap_or_else(|| String::from("index.html")), + template: value.template, + template_fn: value.template_fn.map(|func| TemplateRenderFn { + inner: Box::new(move |data| { + let f = func.clone(); + Box::pin(async move { f.call(data).await }) + }), + }), + template_content: value.template_content, + template_parameters: match value.template_parameters { + Some(parameters) => match parameters { + Either3::A(data) => TemplateParameters::Map(data), + Either3::B(enabled) => { + if enabled { + TemplateParameters::Map(Default::default()) + } else { + TemplateParameters::Disabled + } + } + Either3::C(func) => TemplateParameters::Function(TemplateParameterFn { + inner: Box::new(move |data| { + let f = func.clone(); + Box::pin(async move { f.call(data).await }) + }), + }), + }, + None => TemplateParameters::Map(Default::default()), + }, + inject, + public_path: value.public_path, + script_loading, + chunks: value.chunks, + exclude_chunks: value.exclude_chunks, + sri, + minify: value.minify, + title: value.title, + favicon: value.favicon, + meta: value.meta, + hash: value.hash, + base: value.base.map(|v| v.into()), + } + } +} + +#[derive(Debug)] +#[napi(object)] +pub struct RawHtmlRspackPluginBaseOptions { + pub href: Option, + #[napi(ts_type = "\"_self\" | \"_blank\" | \"_parent\" | \"_top\"")] + pub target: Option, +} + +impl From for HtmlRspackPluginBaseOptions { + fn from(value: RawHtmlRspackPluginBaseOptions) -> Self { + HtmlRspackPluginBaseOptions { + href: value.href, + target: value.target, + } + } +} diff --git a/crates/binding_options/src/options/raw_builtins/raw_ignore.rs b/crates/binding_options/src/options/raw_builtins/raw_ignore.rs new file mode 100644 index 0000000..c1272f7 --- /dev/null +++ b/crates/binding_options/src/options/raw_builtins/raw_ignore.rs @@ -0,0 +1,42 @@ +use derivative::Derivative; +use napi_derive::napi; +use rspack_napi::{ + regexp::{JsRegExp, JsRegExpExt}, + threadsafe_function::ThreadsafeFunction, +}; +use rspack_plugin_ignore::{CheckResourceContent, IgnorePluginOptions}; + +type RawCheckResource = ThreadsafeFunction<(String, String), bool>; + +#[derive(Derivative)] +#[derivative(Debug)] +#[napi(object, object_to_js = false)] +pub struct RawIgnorePluginOptions { + #[napi(ts_type = "RegExp")] + pub resource_reg_exp: Option, + #[napi(ts_type = "RegExp")] + pub context_reg_exp: Option, + #[napi(ts_type = "(resource: string, context: string) => boolean")] + pub check_resource: Option, +} + +impl From for IgnorePluginOptions { + fn from(value: RawIgnorePluginOptions) -> Self { + Self { + resource_reg_exp: value + .resource_reg_exp + .map(|resource_reg_exp| resource_reg_exp.to_rspack_regex()), + context_reg_exp: value + .context_reg_exp + .map(|context_reg_exp| context_reg_exp.to_rspack_regex()), + + check_resource: value.check_resource.map(|check_resource| { + CheckResourceContent::Fn(Box::new(move |resource, context| { + let f = check_resource.clone(); + + Box::pin(async move { f.call((resource.to_owned(), context.to_owned())).await }) + })) + }), + } + } +} diff --git a/crates/binding_options/src/options/raw_builtins/raw_lazy_compilation.rs b/crates/binding_options/src/options/raw_builtins/raw_lazy_compilation.rs new file mode 100644 index 0000000..da10223 --- /dev/null +++ b/crates/binding_options/src/options/raw_builtins/raw_lazy_compilation.rs @@ -0,0 +1,133 @@ +use napi::{ + bindgen_prelude::{FromNapiValue, ToNapiValue, ValidateNapiValue}, + Either, +}; +use napi_derive::napi; +use rspack_binding_values::{JsModule, RawRegex, ToJsModule}; +use rspack_core::ModuleIdentifier; +use rspack_napi::threadsafe_function::ThreadsafeFunction; +use rspack_plugin_lazy_compilation::{ + backend::{Backend, ModuleInfo}, + plugin::{LazyCompilationTest, LazyCompilationTestCheck}, +}; +use rspack_regex::RspackRegex; + +#[derive(Debug)] +pub struct RawLazyCompilationTest>>( + pub Either, +); + +impl FromNapiValue for RawLazyCompilationTest { + unsafe fn from_napi_value( + env: napi::sys::napi_env, + napi_val: napi::sys::napi_value, + ) -> napi::Result { + Ok(Self(Either::from_napi_value(env, napi_val)?)) + } +} + +impl ToNapiValue for RawLazyCompilationTest { + unsafe fn to_napi_value( + env: napi::sys::napi_env, + val: Self, + ) -> napi::Result { + Either::to_napi_value(env, val.0) + } +} + +#[derive(Debug)] +pub struct LazyCompilationTestFn { + tsfn: ThreadsafeFunction>, +} + +impl LazyCompilationTestCheck for LazyCompilationTestFn { + fn test(&self, m: &dyn rspack_core::Module) -> bool { + let res = self + .tsfn + .blocking_call_with_sync( + m.to_js_module() + .expect("failed to convert module to js module"), + ) + .expect("failed to invoke lazyCompilation.test"); + + res.unwrap_or(false) + } +} + +impl From for LazyCompilationTest { + fn from(value: RawLazyCompilationTest) -> Self { + match value.0 { + Either::A(regex) => Self::Regex( + RspackRegex::with_flags(®ex.source, ®ex.flags).unwrap_or_else(|_| { + let msg = format!("[lazyCompilation]incorrect regex {:?}", regex); + panic!("{msg}"); + }), + ), + Either::B(tsfn) => Self::Fn(LazyCompilationTestFn { tsfn }), + } + } +} + +#[napi(object)] +pub struct RawModuleInfo { + pub active: bool, + pub client: String, + pub data: String, +} + +#[napi(object, object_to_js = false)] +pub struct RawLazyCompilationOption { + pub module: ThreadsafeFunction, + pub test: Option, + pub entries: bool, + pub imports: bool, + pub cacheable: bool, +} + +#[napi(object)] +pub struct RawModuleArg { + pub module: String, + pub path: String, +} + +pub(crate) struct JsBackend { + module: ThreadsafeFunction, +} + +impl std::fmt::Debug for JsBackend { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("JsBackend").finish() + } +} + +impl From<&RawLazyCompilationOption> for JsBackend { + fn from(value: &RawLazyCompilationOption) -> Self { + Self { + module: value.module.clone(), + } + } +} + +#[async_trait::async_trait] +impl Backend for JsBackend { + async fn module( + &mut self, + identifier: ModuleIdentifier, + path: String, + ) -> rspack_error::Result { + let module_info = self + .module + .call(RawModuleArg { + module: identifier.to_string(), + path, + }) + .await + .expect("channel should have result"); + + Ok(ModuleInfo { + active: module_info.active, + client: module_info.client, + data: module_info.data, + }) + } +} diff --git a/crates/binding_options/src/options/raw_builtins/raw_lightning_css_minimizer.rs b/crates/binding_options/src/options/raw_builtins/raw_lightning_css_minimizer.rs new file mode 100644 index 0000000..3fa4058 --- /dev/null +++ b/crates/binding_options/src/options/raw_builtins/raw_lightning_css_minimizer.rs @@ -0,0 +1,113 @@ +use napi_derive::napi; +use rspack_binding_values::{into_asset_conditions, RawAssetConditions}; +use rspack_error::Result; +use rspack_plugin_lightning_css_minimizer::{ + Draft, MinimizerOptions, NonStandard, PluginOptions, PseudoClasses, +}; + +#[derive(Debug)] +#[napi(object)] +pub struct RawLightningCssMinimizerRspackPluginOptions { + #[napi(ts_type = "string | RegExp | (string | RegExp)[]")] + pub test: Option, + #[napi(ts_type = "string | RegExp | (string | RegExp)[]")] + pub include: Option, + #[napi(ts_type = "string | RegExp | (string | RegExp)[]")] + pub exclude: Option, + pub remove_unused_local_idents: bool, + pub minimizer_options: RawLightningCssMinimizerOptions, +} + +#[derive(Debug)] +#[napi(object)] +pub struct RawLightningCssMinimizerOptions { + pub error_recovery: bool, + pub targets: Option>, + pub include: Option, + pub exclude: Option, + pub draft: Option, + pub non_standard: Option, + pub pseudo_classes: Option, + pub unused_symbols: Vec, +} + +#[derive(Debug)] +#[napi(object)] +pub struct RawLightningCssBrowsers { + pub android: Option, + pub chrome: Option, + pub edge: Option, + pub firefox: Option, + pub ie: Option, + #[napi(js_name = "ios_saf")] + pub ios_saf: Option, + pub opera: Option, + pub safari: Option, + pub samsung: Option, +} + +#[derive(Debug)] +#[napi(object)] +pub struct RawDraft { + pub custom_media: bool, +} + +#[derive(Debug)] +#[napi(object)] +pub struct RawNonStandard { + pub deep_selector_combinator: bool, +} + +#[derive(Debug)] +#[napi(object)] +pub struct RawLightningCssPseudoClasses { + pub hover: Option, + pub active: Option, + pub focus: Option, + pub focus_visible: Option, + pub focus_within: Option, +} + +impl TryFrom for PluginOptions { + type Error = rspack_error::Error; + + fn try_from(value: RawLightningCssMinimizerRspackPluginOptions) -> Result { + Ok(Self { + test: value.test.map(into_asset_conditions), + include: value.include.map(into_asset_conditions), + exclude: value.exclude.map(into_asset_conditions), + remove_unused_local_idents: value.remove_unused_local_idents, + minimizer_options: MinimizerOptions { + error_recovery: value.minimizer_options.error_recovery, + targets: value + .minimizer_options + .targets + .map(|t| { + rspack_loader_lightningcss::lightningcss::targets::Browsers::from_browserslist(t) + }) + .transpose() + .map_err(|e| rspack_error::error!("Failed to parse browserslist: {}", e))? + .flatten(), + include: value.minimizer_options.include, + exclude: value.minimizer_options.exclude, + draft: value.minimizer_options.draft.map(|d| Draft { + custom_media: d.custom_media, + }), + non_standard: value.minimizer_options.non_standard.map(|n| NonStandard { + deep_selector_combinator: n.deep_selector_combinator, + }), + pseudo_classes: value + .minimizer_options + .pseudo_classes + .map(|p| PseudoClasses { + hover: p.hover, + active: p.active, + focus: p.focus, + focus_visible: p.focus_visible, + focus_within: p.focus_within, + }), + unused_symbols: value.minimizer_options.unused_symbols, + }, + }) + } +} diff --git a/crates/binding_options/src/options/raw_builtins/raw_limit_chunk_count.rs b/crates/binding_options/src/options/raw_builtins/raw_limit_chunk_count.rs new file mode 100644 index 0000000..887b3d8 --- /dev/null +++ b/crates/binding_options/src/options/raw_builtins/raw_limit_chunk_count.rs @@ -0,0 +1,23 @@ +use napi_derive::napi; +use rspack_plugin_limit_chunk_count::LimitChunkCountPluginOptions; + +#[derive(Debug, Clone)] +#[napi(object)] +pub struct RawLimitChunkCountPluginOptions { + // Constant overhead for a chunk. + pub chunk_overhead: Option, + // Multiplicator for initial chunks. + pub entry_chunk_multiplicator: Option, + // Limit the maximum number of chunks using a value greater greater than or equal to 1. + pub max_chunks: f64, +} + +impl From for LimitChunkCountPluginOptions { + fn from(value: RawLimitChunkCountPluginOptions) -> Self { + Self { + chunk_overhead: value.chunk_overhead, + entry_chunk_multiplicator: value.entry_chunk_multiplicator, + max_chunks: value.max_chunks as usize, + } + } +} diff --git a/crates/binding_options/src/options/raw_builtins/raw_mf.rs b/crates/binding_options/src/options/raw_builtins/raw_mf.rs new file mode 100644 index 0000000..f4e7822 --- /dev/null +++ b/crates/binding_options/src/options/raw_builtins/raw_mf.rs @@ -0,0 +1,209 @@ +use std::sync::Arc; + +use napi::Either; +use napi_derive::napi; +use rspack_binding_values::{ + entry::{JsEntryRuntime, JsEntryRuntimeWrapper}, + library::JsLibraryOptions, +}; +use rspack_plugin_mf::{ + ConsumeOptions, ConsumeSharedPluginOptions, ConsumeVersion, ContainerPluginOptions, + ContainerReferencePluginOptions, ExposeOptions, ProvideOptions, ProvideVersion, RemoteOptions, +}; + +#[derive(Debug)] +#[napi(object)] +pub struct RawContainerPluginOptions { + pub name: String, + pub share_scope: String, + pub library: JsLibraryOptions, + #[napi(ts_type = "false | string")] + pub runtime: Option, + pub filename: Option, + pub exposes: Vec, + pub enhanced: bool, +} + +impl From for ContainerPluginOptions { + fn from(value: RawContainerPluginOptions) -> Self { + Self { + name: value.name, + share_scope: value.share_scope, + library: value.library.into(), + runtime: value.runtime.map(|r| JsEntryRuntimeWrapper(r).into()), + filename: value.filename.map(|f| f.into()), + exposes: value.exposes.into_iter().map(|e| e.into()).collect(), + enhanced: value.enhanced, + } + } +} + +#[derive(Debug, Clone)] +#[napi(object)] +pub struct RawExposeOptions { + pub key: String, + pub name: Option, + pub import: Vec, +} + +impl From for (String, ExposeOptions) { + fn from(value: RawExposeOptions) -> Self { + ( + value.key, + ExposeOptions { + name: value.name, + import: value.import, + }, + ) + } +} + +#[derive(Debug)] +#[napi(object)] +pub struct RawContainerReferencePluginOptions { + pub remote_type: String, + pub remotes: Vec, + pub share_scope: Option, + pub enhanced: bool, +} + +impl From for ContainerReferencePluginOptions { + fn from(value: RawContainerReferencePluginOptions) -> Self { + Self { + remote_type: value.remote_type, + remotes: value.remotes.into_iter().map(|e| e.into()).collect(), + share_scope: value.share_scope, + enhanced: value.enhanced, + } + } +} + +#[derive(Debug)] +#[napi(object)] +pub struct RawRemoteOptions { + pub key: String, + pub external: Vec, + pub share_scope: String, +} + +impl From for (String, RemoteOptions) { + fn from(value: RawRemoteOptions) -> Self { + ( + value.key, + RemoteOptions { + external: value.external, + share_scope: value.share_scope, + }, + ) + } +} + +#[derive(Debug)] +#[napi(object)] +pub struct RawProvideOptions { + pub key: String, + pub share_key: String, + pub share_scope: String, + #[napi(ts_type = "string | false | undefined")] + pub version: Option, + pub eager: bool, + pub singleton: Option, + #[napi(ts_type = "string | false | undefined")] + pub required_version: Option, + pub strict_version: Option, +} + +impl From for (String, ProvideOptions) { + fn from(value: RawProvideOptions) -> Self { + ( + value.key, + ProvideOptions { + share_key: value.share_key, + share_scope: value.share_scope, + version: value.version.map(|v| RawVersionWrapper(v).into()), + eager: value.eager, + singleton: value.singleton, + required_version: value.required_version.map(|v| RawVersionWrapper(v).into()), + strict_version: value.strict_version, + }, + ) + } +} + +#[derive(Debug)] +#[napi(object)] +pub struct RawConsumeSharedPluginOptions { + pub consumes: Vec, + pub enhanced: bool, +} + +impl From for ConsumeSharedPluginOptions { + fn from(value: RawConsumeSharedPluginOptions) -> Self { + Self { + consumes: value + .consumes + .into_iter() + .map(|c| c.into()) + .map(|(k, v)| (k, Arc::new(v))) + .collect(), + enhanced: value.enhanced, + } + } +} + +#[derive(Debug)] +#[napi(object)] +pub struct RawConsumeOptions { + pub key: String, + pub import: Option, + pub import_resolved: Option, + pub share_key: String, + pub share_scope: String, + #[napi(ts_type = "string | false | undefined")] + pub required_version: Option, + pub package_name: Option, + pub strict_version: bool, + pub singleton: bool, + pub eager: bool, +} + +impl From for (String, ConsumeOptions) { + fn from(value: RawConsumeOptions) -> Self { + ( + value.key, + ConsumeOptions { + import: value.import, + import_resolved: value.import_resolved, + share_key: value.share_key, + share_scope: value.share_scope, + required_version: value.required_version.map(|v| RawVersionWrapper(v).into()), + package_name: value.package_name, + strict_version: value.strict_version, + singleton: value.singleton, + eager: value.eager, + }, + ) + } +} + +pub type RawVersion = Either; + +struct RawVersionWrapper(RawVersion); + +impl From for ProvideVersion { + fn from(value: RawVersionWrapper) -> Self { + match value.0 { + Either::A(s) => ProvideVersion::Version(s), + Either::B(_) => ProvideVersion::False, + } + } +} + +impl From for ConsumeVersion { + fn from(value: RawVersionWrapper) -> Self { + match value.0 { + Either::A(s) => ConsumeVersion::Version(s), + Either::B(_) => ConsumeVersion::False, + } + } +} diff --git a/crates/binding_options/src/options/raw_builtins/raw_progress.rs b/crates/binding_options/src/options/raw_builtins/raw_progress.rs new file mode 100644 index 0000000..46de539 --- /dev/null +++ b/crates/binding_options/src/options/raw_builtins/raw_progress.rs @@ -0,0 +1,33 @@ +use napi::Either; +use napi_derive::napi; +use rspack_plugin_progress::ProgressPluginOptions; + +#[derive(Debug, Clone)] +#[napi(object)] +pub struct RawProgressPluginOptions { + // the prefix name of progress bar + pub prefix: String, + // tells ProgressPlugin to collect profile data for progress steps. + pub profile: bool, + // the template of progress bar + pub template: String, + // the tick string sequence for spinners, if it's string then it will be split into characters + pub tick: Option>>, + // the progress characters + pub progress_chars: String, +} + +impl From for ProgressPluginOptions { + fn from(value: RawProgressPluginOptions) -> Self { + Self { + prefix: value.prefix, + profile: value.profile, + template: value.template, + progress_chars: value.progress_chars, + tick_strings: value.tick.map(|tick| match tick { + Either::A(str) => str.chars().map(|c| c.to_string()).collect(), + Either::B(vec) => vec, + }), + } + } +} diff --git a/crates/binding_options/src/options/raw_builtins/raw_runtime_chunk.rs b/crates/binding_options/src/options/raw_builtins/raw_runtime_chunk.rs new file mode 100644 index 0000000..0cd75ea --- /dev/null +++ b/crates/binding_options/src/options/raw_builtins/raw_runtime_chunk.rs @@ -0,0 +1,51 @@ +use napi::Either; +use napi_derive::napi; +use rspack_napi::threadsafe_function::ThreadsafeFunction; +use rspack_plugin_runtime_chunk::{RuntimeChunkName, RuntimeChunkOptions}; + +#[napi(object, object_to_js = false)] +pub struct RawRuntimeChunkOptions { + #[napi(ts_type = "string | ((entrypoint: { name: string }) => string)")] + pub name: RawRuntimeChunkName, +} + +impl From for RuntimeChunkOptions { + fn from(value: RawRuntimeChunkOptions) -> Self { + Self { + name: RawRuntimeChunkNameWrapper(value.name).into(), + } + } +} + +type RawRuntimeChunkName = Either>; +struct RawRuntimeChunkNameWrapper(RawRuntimeChunkName); + +#[napi(object)] +pub struct RawRuntimeChunkNameFnCtx { + pub name: String, +} + +impl From for RuntimeChunkName { + fn from(value: RawRuntimeChunkNameWrapper) -> Self { + match value.0 { + Either::A(s) => { + if s == "single" { + Self::Single + } else if s == "multiple" { + Self::Multiple + } else { + Self::String(s) + } + } + Either::B(f) => RuntimeChunkName::Fn(Box::new(move |name| { + let f = f.clone(); + Box::pin(async move { + f.call(RawRuntimeChunkNameFnCtx { + name: name.to_string(), + }) + .await + }) + })), + } + } +} diff --git a/crates/binding_options/src/options/raw_builtins/raw_size_limits.rs b/crates/binding_options/src/options/raw_builtins/raw_size_limits.rs new file mode 100644 index 0000000..f74923d --- /dev/null +++ b/crates/binding_options/src/options/raw_builtins/raw_size_limits.rs @@ -0,0 +1,35 @@ +use derivative::Derivative; +use napi_derive::napi; +use rspack_napi::threadsafe_function::ThreadsafeFunction; +use rspack_plugin_size_limits::{AssetFilterFn, SizeLimitsPluginOptions}; + +#[derive(Derivative)] +#[derivative(Debug)] +#[napi(object, object_to_js = false)] +pub struct RawSizeLimitsPluginOptions { + #[derivative(Debug = "ignore")] + #[napi(ts_type = "(assetFilename: string) => boolean")] + pub asset_filter: Option>, + #[napi(ts_type = "\"error\" | \"warning\"")] + pub hints: Option, + pub max_asset_size: Option, + pub max_entrypoint_size: Option, +} + +impl From for SizeLimitsPluginOptions { + fn from(value: RawSizeLimitsPluginOptions) -> Self { + SizeLimitsPluginOptions { + asset_filter: value.asset_filter.map(|asset_filter| { + let asset_filter_fn: AssetFilterFn = Box::new(move |name| { + let f = asset_filter.clone(); + + Box::pin(async move { f.call(name.to_owned()).await }) + }); + asset_filter_fn + }), + hints: value.hints, + max_asset_size: value.max_asset_size, + max_entrypoint_size: value.max_entrypoint_size, + } + } +} diff --git a/crates/binding_options/src/options/raw_builtins/raw_swc_js_minimizer.rs b/crates/binding_options/src/options/raw_builtins/raw_swc_js_minimizer.rs new file mode 100644 index 0000000..87a8ed5 --- /dev/null +++ b/crates/binding_options/src/options/raw_builtins/raw_swc_js_minimizer.rs @@ -0,0 +1,95 @@ +use napi::Either; +use napi_derive::napi; +use rspack_binding_values::{into_asset_conditions, RawAssetConditions}; +use rspack_error::{miette::IntoDiagnostic, Result}; +use rspack_plugin_swc_js_minimizer::{ + ExtractComments, MinimizerOptions, OptionWrapper, PluginOptions, +}; +use serde::de::DeserializeOwned; +use swc_core::base::BoolOrDataConfig; + +#[derive(Debug)] +#[napi(object)] +pub struct RawExtractComments { + pub banner: Option>, + pub condition: Option, +} + +#[derive(Debug)] +#[napi(object, object_to_js = false)] +pub struct RawSwcJsMinimizerRspackPluginOptions { + #[napi(ts_type = "string | RegExp | (string | RegExp)[]")] + pub test: Option, + #[napi(ts_type = "string | RegExp | (string | RegExp)[]")] + pub include: Option, + #[napi(ts_type = "string | RegExp | (string | RegExp)[]")] + pub exclude: Option, + pub extract_comments: Option, + pub minimizer_options: RawSwcJsMinimizerOptions, +} + +#[derive(Debug)] +#[napi(object, object_to_js = false)] +pub struct RawSwcJsMinimizerOptions { + pub compress: serde_json::Value, + pub mangle: serde_json::Value, + pub format: serde_json::Value, + pub module: Option, + pub minify: Option, +} + +fn try_deserialize_into(value: serde_json::Value) -> Result +where + T: DeserializeOwned, +{ + serde_json::from_value(value).into_diagnostic() +} + +fn into_extract_comments(c: Option) -> Option { + let c = c?; + let condition = c.condition?; + let banner = match c.banner { + Some(banner) => match banner { + Either::A(s) => OptionWrapper::Custom(s), + Either::B(b) => { + if b { + OptionWrapper::Default + } else { + OptionWrapper::Disabled + } + } + }, + None => OptionWrapper::Default, + }; + + Some(ExtractComments { condition, banner }) +} + +impl TryFrom for PluginOptions { + type Error = rspack_error::Error; + + fn try_from(value: RawSwcJsMinimizerRspackPluginOptions) -> Result { + let compress = try_deserialize_into::< + BoolOrDataConfig, + >(value.minimizer_options.compress)? + .or(|| BoolOrDataConfig::from_bool(true)); + let mangle = try_deserialize_into::< + BoolOrDataConfig, + >(value.minimizer_options.mangle)? + .or(|| BoolOrDataConfig::from_bool(true)); + Ok(Self { + extract_comments: into_extract_comments(value.extract_comments), + test: value.test.map(into_asset_conditions), + include: value.include.map(into_asset_conditions), + exclude: value.exclude.map(into_asset_conditions), + minimizer_options: MinimizerOptions { + compress, + mangle, + format: try_deserialize_into(value.minimizer_options.format)?, + module: value.minimizer_options.module, + minify: value.minimizer_options.minify, + ..Default::default() + }, + }) + } +} diff --git a/crates/binding_options/src/options/raw_cache.rs b/crates/binding_options/src/options/raw_cache.rs new file mode 100644 index 0000000..2908713 --- /dev/null +++ b/crates/binding_options/src/options/raw_cache.rs @@ -0,0 +1,46 @@ +use napi_derive::napi; +use rspack_core::{CacheOptions, FileSystemCacheOptions, MemoryCacheOptions}; + +#[derive(Debug, Default)] +#[napi(object, object_to_js = false)] +pub struct RawCacheOptions { + pub r#type: &'static str, + pub max_generations: u32, + pub max_age: u32, + pub profile: bool, + pub build_dependencies: Vec, + pub cache_directory: String, + pub cache_location: String, + pub name: String, + pub version: String, +} + +impl From for CacheOptions { + fn from(value: RawCacheOptions) -> CacheOptions { + let RawCacheOptions { + r#type, + max_generations, + max_age, + profile, + build_dependencies, + cache_directory, + cache_location, + name, + version, + } = value; + + match r#type { + "memory" => CacheOptions::Memory(MemoryCacheOptions { max_generations }), + "filesystem" => CacheOptions::FileSystem(FileSystemCacheOptions { + max_age, + profile, + build_dependencies, + cache_directory, + cache_location, + name, + version, + }), + _ => CacheOptions::Disabled, + } + } +} diff --git a/crates/binding_options/src/options/raw_devtool.rs b/crates/binding_options/src/options/raw_devtool.rs new file mode 100644 index 0000000..5f72d67 --- /dev/null +++ b/crates/binding_options/src/options/raw_devtool.rs @@ -0,0 +1,179 @@ +use std::sync::Arc; + +use napi::bindgen_prelude::{Either3, Null}; +use napi::Either; +use napi_derive::napi; +use rspack_core::PathData; +use rspack_napi::threadsafe_function::ThreadsafeFunction; +use rspack_plugin_devtool::{ + Append, EvalDevToolModulePluginOptions, ModuleFilenameTemplate, ModuleFilenameTemplateFnCtx, + SourceMapDevToolPluginOptions, TestFn, +}; +use tokio::runtime::Handle; + +type RawAppend = Either3>; + +#[derive(Debug, Clone)] +#[napi(object)] +pub struct RawPathData { + pub filename: Option, + pub content_hash: Option, + pub url: Option, +} + +impl From> for RawPathData { + fn from(ctx: PathData) -> Self { + RawPathData { + filename: ctx.filename.map(|s| s.to_string()), + content_hash: ctx.content_hash.map(|s| s.to_string()), + url: ctx.url.map(|s| s.to_string()), + } + } +} + +fn normalize_raw_append(raw: RawAppend) -> Append { + match raw { + Either3::A(str) => Append::String(str), + Either3::B(_) => Append::Disabled, + Either3::C(v) => Append::Fn(Box::new(move |ctx| { + let v = v.clone(); + let value = ctx.into(); + Box::pin(async move { v.call(value).await }) + })), + } +} + +type RawFilename = Either3; + +type RawModuleFilenameTemplate = + Either>; + +#[derive(Debug, Clone)] +#[napi(object)] +pub struct RawModuleFilenameTemplateFnCtx { + pub identifier: String, + pub short_identifier: String, + pub resource: String, + pub resource_path: String, + pub absolute_resource_path: String, + pub loaders: String, + pub all_loaders: String, + pub query: String, + pub module_id: String, + pub hash: String, + pub namespace: String, +} + +impl From for RawModuleFilenameTemplateFnCtx { + fn from(ctx: ModuleFilenameTemplateFnCtx) -> Self { + RawModuleFilenameTemplateFnCtx { + identifier: ctx.identifier, + short_identifier: ctx.short_identifier, + resource: ctx.resource, + resource_path: ctx.resource_path, + absolute_resource_path: ctx.absolute_resource_path, + loaders: ctx.loaders, + all_loaders: ctx.all_loaders, + query: ctx.query, + module_id: ctx.module_id, + hash: ctx.hash, + namespace: ctx.namespace, + } + } +} + +fn normalize_raw_module_filename_template( + raw: RawModuleFilenameTemplate, +) -> ModuleFilenameTemplate { + match raw { + Either::A(str) => ModuleFilenameTemplate::String(str), + Either::B(v) => ModuleFilenameTemplate::Fn(Arc::new(move |ctx| { + let v = v.clone(); + Box::pin(async move { v.call(ctx.into()).await }) + })), + } +} + +fn normalize_raw_test(raw: ThreadsafeFunction) -> TestFn { + let handle = Handle::current(); + Box::new(move |ctx| handle.block_on(raw.call(ctx))) +} + +#[napi(object, object_to_js = false)] +pub struct RawSourceMapDevToolPluginOptions { + #[napi(ts_type = "(false | null) | string | Function")] + pub append: Option, + pub columns: Option, + #[napi(ts_type = "string | ((info: RawModuleFilenameTemplateFnCtx) => string)")] + pub fallback_module_filename_template: Option, + pub file_context: Option, + #[napi(ts_type = "(false | null) | string")] + pub filename: Option, + pub module: Option, + #[napi(ts_type = "string | ((info: RawModuleFilenameTemplateFnCtx) => string)")] + pub module_filename_template: Option, + pub namespace: Option, + pub no_sources: Option, + pub public_path: Option, + pub source_root: Option, + #[napi(ts_type = "(text: string) => boolean")] + pub test: Option>, +} + +impl From for SourceMapDevToolPluginOptions { + fn from(opts: RawSourceMapDevToolPluginOptions) -> Self { + let append = opts.append.map(normalize_raw_append); + let test = opts.test.map(normalize_raw_test); + let filename = opts.filename.and_then(|raw| match raw { + Either3::A(_) | Either3::B(_) => None, + Either3::C(s) => Some(s), + }); + + let module_filename_template = opts + .module_filename_template + .map(normalize_raw_module_filename_template); + let fallback_module_filename_template = opts + .fallback_module_filename_template + .map(normalize_raw_module_filename_template); + + let columns = opts.columns.unwrap_or(true); + let no_sources = opts.no_sources.unwrap_or(false); + + Self { + append, + columns, + fallback_module_filename_template, + file_context: opts.file_context, + filename, + namespace: opts.namespace, + no_sources, + public_path: opts.public_path, + module_filename_template, + module: opts.module.unwrap_or(true), + source_root: opts.source_root, + test, + } + } +} + +#[napi(object, object_to_js = false)] +pub struct RawEvalDevToolModulePluginOptions { + pub namespace: Option, + #[napi(ts_type = "string | ((info: RawModuleFilenameTemplateFnCtx) => string)")] + pub module_filename_template: Option, + pub source_url_comment: Option, +} + +impl From for EvalDevToolModulePluginOptions { + fn from(opts: RawEvalDevToolModulePluginOptions) -> Self { + let module_filename_template = opts + .module_filename_template + .map(normalize_raw_module_filename_template); + + Self { + namespace: opts.namespace, + source_url_comment: opts.source_url_comment, + module_filename_template, + } + } +} diff --git a/crates/binding_options/src/options/raw_dynamic_entry.rs b/crates/binding_options/src/options/raw_dynamic_entry.rs new file mode 100644 index 0000000..7da0f93 --- /dev/null +++ b/crates/binding_options/src/options/raw_dynamic_entry.rs @@ -0,0 +1,45 @@ +use napi_derive::napi; +use rspack_binding_values::entry::JsEntryOptions; +use rspack_napi::threadsafe_function::ThreadsafeFunction; +use rspack_plugin_dynamic_entry::{DynamicEntryPluginOptions, EntryDynamicResult}; + +#[derive(Debug)] +#[napi(object, object_to_js = false)] +pub struct RawEntryDynamicResult { + pub import: Vec, + pub options: JsEntryOptions, +} + +pub type RawEntryDynamic = ThreadsafeFunction<(), Vec>; + +#[derive(Debug)] +#[napi(object, object_to_js = false)] +pub struct RawDynamicEntryPluginOptions { + pub context: String, + #[napi(ts_type = "() => Promise")] + pub entry: RawEntryDynamic, +} + +impl From for DynamicEntryPluginOptions { + fn from(opts: RawDynamicEntryPluginOptions) -> Self { + Self { + context: opts.context.into(), + entry: Box::new(move || { + let f = opts.entry.clone(); + Box::pin(async move { + let raw_result = f.call(()).await?; + let result = raw_result + .into_iter() + .map( + |RawEntryDynamicResult { import, options }| EntryDynamicResult { + import, + options: options.into(), + }, + ) + .collect::>(); + Ok(result) + }) + }), + } + } +} diff --git a/crates/binding_options/src/options/raw_experiments.rs b/crates/binding_options/src/options/raw_experiments.rs new file mode 100644 index 0000000..086bcca --- /dev/null +++ b/crates/binding_options/src/options/raw_experiments.rs @@ -0,0 +1,25 @@ +use napi_derive::napi; +use rspack_core::RspackFuture; + +#[allow(clippy::empty_structs_with_brackets)] +#[derive(Debug, Default)] +#[napi(object)] +pub struct RawRspackFuture { + pub new_incremental: bool, +} + +#[derive(Debug, Default)] +#[napi(object)] +pub struct RawExperiments { + pub layers: bool, + pub top_level_await: bool, + pub rspack_future: RawRspackFuture, +} + +impl From for RspackFuture { + fn from(value: RawRspackFuture) -> Self { + Self { + new_incremental: value.new_incremental, + } + } +} diff --git a/crates/binding_options/src/options/raw_external.rs b/crates/binding_options/src/options/raw_external.rs new file mode 100644 index 0000000..8271288 --- /dev/null +++ b/crates/binding_options/src/options/raw_external.rs @@ -0,0 +1,123 @@ +use std::collections::HashMap; +use std::fmt::Debug; + +use napi::bindgen_prelude::Either4; +use napi_derive::napi; +use rspack_core::ExternalItemFnCtx; +use rspack_core::{ExternalItem, ExternalItemFnResult, ExternalItemValue}; +use rspack_napi::regexp::{JsRegExp, JsRegExpExt}; +use rspack_napi::threadsafe_function::ThreadsafeFunction; + +#[napi(object)] +pub struct RawHttpExternalsRspackPluginOptions { + pub css: bool, + pub web_async: bool, +} + +#[napi(object, object_to_js = false)] +pub struct RawExternalsPluginOptions { + pub r#type: String, + #[napi( + ts_type = "(string | RegExp | Record> | ((...args: any[]) => any))[]" + )] + pub externals: Vec, +} + +type RawExternalItem = Either4< + String, + JsRegExp, + HashMap, + ThreadsafeFunction, +>; +type RawExternalItemValue = Either4, HashMap>>; +pub(crate) struct RawExternalItemWrapper(pub(crate) RawExternalItem); +struct RawExternalItemValueWrapper(RawExternalItemValue); + +impl From for ExternalItemValue { + fn from(value: RawExternalItemValueWrapper) -> Self { + match value.0 { + Either4::A(v) => Self::String(v), + Either4::B(v) => Self::Bool(v), + Either4::C(v) => Self::Array(v), + Either4::D(v) => Self::Object(v.into_iter().collect()), + } + } +} + +#[derive(Debug, Clone)] +#[napi(object)] +pub struct RawExternalItemFnResult { + pub external_type: Option, + // sadly, napi.rs does not support type alias at the moment. Need to add Either here + #[napi(ts_type = "string | boolean | string[] | Record")] + pub result: Option, +} + +impl From for ExternalItemFnResult { + fn from(value: RawExternalItemFnResult) -> Self { + Self { + external_type: value.external_type, + result: value.result.map(|v| RawExternalItemValueWrapper(v).into()), + } + } +} + +#[derive(Debug, Clone)] +#[napi(object)] +pub struct ContextInfo { + pub issuer: String, +} + +#[derive(Debug, Clone)] +#[napi(object)] +pub struct RawExternalItemFnCtx { + pub request: String, + pub context: String, + pub dependency_type: String, + pub context_info: ContextInfo, +} + +impl From for RawExternalItemFnCtx { + fn from(value: ExternalItemFnCtx) -> Self { + Self { + request: value.request, + dependency_type: value.dependency_type, + context: value.context, + context_info: ContextInfo { + issuer: value.context_info.issuer, + }, + } + } +} + +impl TryFrom for ExternalItem { + type Error = rspack_error::Error; + + #[allow(clippy::unwrap_in_result)] + fn try_from(value: RawExternalItemWrapper) -> rspack_error::Result { + match value.0 { + Either4::A(v) => Ok(Self::String(v)), + Either4::B(v) => Ok(Self::RegExp(v.to_rspack_regex())), + Either4::C(v) => Ok(Self::Object( + v.into_iter() + .map(|(k, v)| (k, RawExternalItemValueWrapper(v).into())) + .collect(), + )), + Either4::D(v) => Ok(Self::Fn(Box::new(move |ctx: ExternalItemFnCtx| { + let v = v.clone(); + Box::pin(async move { v.call(ctx.into()).await.map(|r| r.into()) }) + }))), + } + } +} + +#[derive(Debug, Clone)] +#[napi(object)] +pub struct RawExternalsPresets { + pub node: bool, + pub web: bool, + pub electron: bool, + pub electron_main: bool, + pub electron_preload: bool, + pub electron_renderer: bool, +} diff --git a/crates/binding_options/src/options/raw_features.rs b/crates/binding_options/src/options/raw_features.rs index 219f6e6..d1eb6f5 100644 --- a/crates/binding_options/src/options/raw_features.rs +++ b/crates/binding_options/src/options/raw_features.rs @@ -3,16 +3,16 @@ use std::{hash::Hasher, sync::Arc}; use napi_derive::napi; use rspack_core::{ BoxPlugin, Filename, MangleExportsOption, Module, ModuleType, Optimization, PluginExt, - SideEffectOption, SourceType, UsedExportsOption, + SideEffectOption, SourceType, UsedExportsOption, Compilation }; -use rspack_hash::{HashDigest, HashFunction, RspackHash}; +use rspack_hash::{HashDigest, HashFunction, RspackHash, RspackHashDigest}; use rspack_plugin_split_chunks::{ CacheGroup, CacheGroupTest, CacheGroupTestFnCtx, ChunkNameGetter, PluginOptions, }; use rspack_regex::RspackRegex; use serde::Deserialize; -use crate::RspackRawOptimizationOptions; +use crate::RawOptimizationOptions; pub struct SplitChunksStrategy { strategy: RawStrategyOptions, @@ -25,10 +25,12 @@ pub struct SplitChunksStrategy { concatenate_modules: bool, } -fn get_modules_size(module: &dyn Module) -> f64 { +fn get_modules_size(modules: &[&dyn Module], compilation: &Compilation) -> f64 { let mut size = 0f64; - for source_type in module.source_types() { - size += module.size(source_type); + for module in modules { + for source_type in module.source_types() { + size += module.size(Some(source_type), compilation); + } } size } @@ -52,16 +54,18 @@ fn get_plugin_options( name: ChunkNameGetter::String("framework".to_string()), chunk_filter: rspack_plugin_split_chunks::create_all_chunk_filter(), priority: 40.0, - test: CacheGroupTest::Fn(Arc::new(move |ctx: CacheGroupTestFnCtx| -> Option { - Some(ctx.module.name_for_condition().map_or(false, |name| { + test: CacheGroupTest::Fn(Arc::new(move |ctx: CacheGroupTestFnCtx| { + Ok(Some(ctx.module.name_for_condition().map_or(false, |name| { strategy .top_level_frameworks .iter() .any(|framework| name.starts_with(framework)) - })) + }))) })), - max_initial_requests: 25, - max_async_requests: 25, + used_exports: true, + layer: rspack_plugin_split_chunks::create_default_module_layer_filter(), + max_initial_requests: 25.0, + max_async_requests: 25.0, reuse_existing_chunk: true, min_chunks: 1, // When enfoce is true, all size should be set to SplitChunkSizes::empty(). @@ -77,9 +81,16 @@ fn get_plugin_options( key: String::from("lib"), name: ChunkNameGetter::Fn(Arc::new(move |ctx| { let mut hash = RspackHash::new(&HashFunction::Xxhash64); + let mut hash_digest: Option = None; match ctx.module.module_type() { ModuleType::Css | ModuleType::CssModule | ModuleType::CssAuto => { - ctx.module.update_hash(&mut hash); + if ctx.module.build_info().is_some() { + hash_digest = ctx.module.build_info().unwrap().hash.clone(); + } else { + let options = rspack_core::LibIdentOptions { context: &context }; + let lib_ident = ctx.module.lib_ident(options); + hash.write(lib_ident.unwrap().as_bytes()); + } } _ => { let options = rspack_core::LibIdentOptions { context: &context }; @@ -87,23 +98,29 @@ fn get_plugin_options( hash.write(lib_ident.unwrap().as_bytes()); } } - Some(hash.digest(&HashDigest::Hex).rendered(8).to_string()) + Ok(Some(if hash_digest.is_some() { + hash_digest.unwrap().rendered(8).to_string() + } else { + hash.digest(&HashDigest::Hex).rendered(8).to_string() + })) })), chunk_filter: rspack_plugin_split_chunks::create_all_chunk_filter(), test: CacheGroupTest::Fn(Arc::new(move |ctx| { - Some( + Ok(Some( ctx .module .name_for_condition() .map_or(false, |name| re_node_modules.test(&name)) - && get_modules_size(ctx.module) > 160000.0, - ) + && get_modules_size(&[ctx.module], ctx.compilation) > 160000.0, + )) })), priority: 30.0, min_chunks: 1, reuse_existing_chunk: true, - max_initial_requests: 25, - max_async_requests: 25, + used_exports: true, + layer: rspack_plugin_split_chunks::create_default_module_layer_filter(), + max_initial_requests: 25.0, + max_async_requests: 25.0, min_size: create_sizes(Some(20000.0)), max_async_size: SplitChunkSizes::default(), max_initial_size: SplitChunkSizes::default(), @@ -137,7 +154,7 @@ pub trait FeatureApply { } impl SplitChunksStrategy { - pub fn new(strategy: RawStrategyOptions, option: RspackRawOptimizationOptions) -> Self { + pub fn new(strategy: RawStrategyOptions, option: RawOptimizationOptions) -> Self { Self { strategy, remove_available_modules: option.remove_available_modules, @@ -191,4 +208,4 @@ pub struct RawStrategyOptions { pub struct RawFeatures { pub split_chunks_strategy: Option, pub assets_manifest: Option, -} +} \ No newline at end of file diff --git a/crates/binding_options/src/options/raw_mode.rs b/crates/binding_options/src/options/raw_mode.rs new file mode 100644 index 0000000..4a7c326 --- /dev/null +++ b/crates/binding_options/src/options/raw_mode.rs @@ -0,0 +1 @@ +pub type RawMode = &'static str; diff --git a/crates/binding_options/src/options/raw_module.rs b/crates/binding_options/src/options/raw_module.rs deleted file mode 100644 index 493599c..0000000 --- a/crates/binding_options/src/options/raw_module.rs +++ /dev/null @@ -1,49 +0,0 @@ -use std::sync::Arc; - -use loader_barrel::BARREL_LOADER_IDENTIFIER; -use loader_compilation::COMPILATION_LOADER_IDENTIFIER; -use rspack_core::BoxLoader; -use rspack_loader_react_refresh::REACT_REFRESH_LOADER_IDENTIFIER; -use rspack_loader_swc::SWC_LOADER_IDENTIFIER; - -pub fn get_builtin_loader(builtin: &str, options: Option<&str>) -> BoxLoader { - if builtin.starts_with(SWC_LOADER_IDENTIFIER) { - return Arc::new( - rspack_loader_swc::SwcLoader::new( - serde_json::from_str(options.unwrap_or("{}")).unwrap_or_else(|e| { - panic!("Could not parse builtin:swc-loader options:{options:?},error: {e:?}") - }), - ) - .with_identifier(builtin.into()), - ); - } - if builtin.starts_with(REACT_REFRESH_LOADER_IDENTIFIER) { - return Arc::new( - rspack_loader_react_refresh::ReactRefreshLoader::default().with_identifier(builtin.into()), - ); - } - - if builtin.starts_with(COMPILATION_LOADER_IDENTIFIER) { - return Arc::new( - loader_compilation::CompilationLoader::new( - serde_json::from_str(options.unwrap_or("{}")).unwrap_or_else(|e| { - panic!("Could not parse builtin:compilation-loader options:{options:?},error: {e:?}") - }), - ) - .with_identifier(builtin.into()), - ); - } - - if builtin.starts_with(BARREL_LOADER_IDENTIFIER) { - return Arc::new( - loader_barrel::BarrelLoader::new( - serde_json::from_str(options.unwrap_or("{}")).unwrap_or_else(|e| { - panic!("Could not parse builtin:barrel-loader options:{options:?},error: {e:?}") - }), - ) - .with_identifier(builtin.into()), - ); - } - - unreachable!("Unexpected builtin loader: {builtin}") -} diff --git a/crates/binding_options/src/options/raw_module/mod.rs b/crates/binding_options/src/options/raw_module/mod.rs new file mode 100644 index 0000000..d2d88ae --- /dev/null +++ b/crates/binding_options/src/options/raw_module/mod.rs @@ -0,0 +1,864 @@ +use std::fmt::Formatter; +use std::{collections::HashMap, fmt::Debug, sync::Arc}; + +use derivative::Derivative; +use napi::bindgen_prelude::Either3; +use napi::Either; +use napi_derive::napi; +use rspack_binding_values::{JsFilename, RawRegex}; +use rspack_core::{ + AssetGeneratorDataUrl, AssetGeneratorDataUrlFnArgs, AssetGeneratorDataUrlOptions, + AssetGeneratorOptions, AssetInlineGeneratorOptions, AssetParserDataUrl, + AssetParserDataUrlOptions, AssetParserOptions, AssetResourceGeneratorOptions, + CssAutoGeneratorOptions, CssAutoParserOptions, CssGeneratorOptions, CssModuleGeneratorOptions, + CssModuleParserOptions, CssParserOptions, DescriptionData, DynamicImportFetchPriority, + DynamicImportMode, ExportPresenceMode, FuncUseCtx, GeneratorOptions, + GeneratorOptionsByModuleType, JavascriptParserOptions, JavascriptParserOrder, + JavascriptParserUrl, ModuleNoParseRule, ModuleNoParseRules, ModuleNoParseTestFn, ModuleOptions, + ModuleRule, ModuleRuleEffect, ModuleRuleEnforce, ModuleRuleUse, ModuleRuleUseLoader, ModuleType, + OverrideStrict, ParserOptions, ParserOptionsByModuleType, +}; +use rspack_error::error; +use rspack_napi::regexp::{JsRegExp, JsRegExpExt}; +use rspack_napi::threadsafe_function::ThreadsafeFunction; +use tokio::runtime::Handle; + +use crate::RawResolveOptions; + +/// `loader` is for both JS and Rust loaders. +/// `options` is +/// - a `None` on rust side and handled by js side `getOptions` when +/// using with `loader`. +/// - a `Some(string)` on rust side, deserialized by `serde_json::from_str` +/// and passed to rust side loader in [get_builtin_loader] when using with +/// `builtin_loader`. +#[napi(object)] +pub struct RawModuleRuleUse { + pub loader: String, + pub options: Option, +} + +impl Debug for RawModuleRuleUse { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("RawModuleRuleUse") + .field("loader", &self.loader) + .field("options", &self.options) + .finish() + } +} + +#[rspack_napi_macros::tagged_union] +pub enum RawRuleSetCondition { + string(String), + regexp(RawRegex), + logical(Vec), + array(Vec), + #[napi(ts_type = r#"(value: string) => boolean"#)] + func(ThreadsafeFunction), +} + +impl Debug for RawRuleSetCondition { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + RawRuleSetCondition::string(s) => write!(f, "RawRuleSetCondition::string({:?})", s), + RawRuleSetCondition::regexp(r) => write!(f, "RawRuleSetCondition::regexp({:?})", r), + RawRuleSetCondition::logical(l) => write!(f, "RawRuleSetCondition::logical({:?})", l), + RawRuleSetCondition::array(a) => write!(f, "RawRuleSetCondition::array({:?})", a), + RawRuleSetCondition::func(_) => write!(f, "RawRuleSetCondition::func(...)"), + } + } +} + +#[derive(Debug, Default)] +#[napi(object, object_to_js = false)] +pub struct RawRuleSetLogicalConditions { + pub and: Option>, + pub or: Option>, + pub not: Option, +} + +impl TryFrom for rspack_core::RuleSetLogicalConditions { + type Error = rspack_error::Error; + + fn try_from(value: RawRuleSetLogicalConditions) -> rspack_error::Result { + Ok(Self { + and: value + .and + .map(|i| { + i.into_iter() + .map(TryFrom::try_from) + .collect::>>() + }) + .transpose()?, + or: value + .or + .map(|i| { + i.into_iter() + .map(TryFrom::try_from) + .collect::>>() + }) + .transpose()?, + not: value.not.map(TryFrom::try_from).transpose()?, + }) + } +} + +impl TryFrom for rspack_core::RuleSetCondition { + type Error = rspack_error::Error; + + fn try_from(x: RawRuleSetCondition) -> rspack_error::Result { + let result = match x { + RawRuleSetCondition::string(s) => Self::String(s), + RawRuleSetCondition::regexp(r) => { + let reg = rspack_regex::RspackRegex::with_flags(&r.source, &r.flags)?; + Self::Regexp(reg) + } + RawRuleSetCondition::logical(mut l) => { + let l = l.get_mut(0).ok_or_else(|| { + error!("TODO: use Box after https://github.com/napi-rs/napi-rs/issues/1500 landed") + })?; + let l = std::mem::take(l); + Self::Logical(Box::new(rspack_core::RuleSetLogicalConditions::try_from( + l, + )?)) + } + RawRuleSetCondition::array(a) => Self::Array( + a.into_iter() + .map(|i| i.try_into()) + .collect::>>()?, + ), + RawRuleSetCondition::func(f) => Self::Func(Box::new(move |data| { + let data = data.to_value(); + let f = f.clone(); + Box::pin(async move { f.call(data).await }) + })), + }; + + Ok(result) + } +} + +type ThreadsafeUse = ThreadsafeFunction>; + +#[derive(Derivative)] +#[derivative(Debug, Default)] +#[napi(object, object_to_js = false)] +pub struct RawModuleRule { + /// A conditional match matching an absolute path + query + fragment. + /// Note: + /// This is a custom matching rule not initially designed by webpack. + /// Only for single-threaded environment interoperation purpose. + pub rspack_resource: Option, + /// A condition matcher matching an absolute path. + pub test: Option, + pub include: Option, + pub exclude: Option, + /// A condition matcher matching an absolute path. + pub resource: Option, + /// A condition matcher against the resource query. + pub resource_query: Option, + pub resource_fragment: Option, + pub description_data: Option>, + pub with: Option>, + pub side_effects: Option, + #[napi(ts_type = "RawModuleRuleUse[] | ((arg: RawFuncUseCtx) => RawModuleRuleUse[])")] + pub r#use: Option, ThreadsafeUse>>, + pub r#type: Option, + pub layer: Option, + pub parser: Option, + pub generator: Option, + pub resolve: Option, + pub issuer: Option, + pub issuer_layer: Option, + pub dependency: Option, + pub scheme: Option, + pub mimetype: Option, + pub one_of: Option>, + pub rules: Option>, + /// Specifies the category of the loader. No value means normal loader. + #[napi(ts_type = "'pre' | 'post'")] + pub enforce: Option, +} + +#[derive(Debug, Default)] +#[napi(object)] +pub struct RawParserOptions { + #[napi( + ts_type = r#""asset" | "css" | "css/auto" | "css/module" | "javascript" | "javascript/auto" | "javascript/dynamic" | "javascript/esm""# + )] + pub r#type: String, + pub asset: Option, + pub css: Option, + pub css_auto: Option, + pub css_module: Option, + pub javascript: Option, +} + +impl From for ParserOptions { + fn from(value: RawParserOptions) -> Self { + match value.r#type.as_str() { + "asset" => Self::Asset( + value + .asset + .expect("should have an \"asset\" when RawParserOptions.type is \"asset\"") + .into(), + ), + "javascript" | "javascript/auto" | "javascript/dynamic" | "javascript/esm" => { + Self::Javascript( + value + .javascript + .expect("should have an \"javascript\" when RawParserOptions.type is \"javascript\"") + .into(), + ) + } + "css" => Self::Css( + value + .css + .expect("should have an \"css\" when RawParserOptions.type is \"css\"") + .into(), + ), + "css/auto" => Self::CssAuto( + value + .css_auto + .expect("should have an \"css_auto\" when RawParserOptions.type is \"css/auto\"") + .into(), + ), + "css/module" => Self::CssModule( + value + .css_module + .expect("should have an \"css_module\" when RawParserOptions.type is \"css/module\"") + .into(), + ), + _ => panic!( + "Failed to resolve the RawParserOptions.type {}.", + value.r#type + ), + } + } +} + +#[derive(Debug, Default)] +#[napi(object)] +pub struct RawJavascriptParserOptions { + pub dynamic_import_mode: String, + pub dynamic_import_preload: String, + pub dynamic_import_prefetch: String, + pub dynamic_import_fetch_priority: Option, + pub url: String, + pub expr_context_critical: bool, + pub wrapped_context_critical: bool, + pub exports_presence: Option, + pub import_exports_presence: Option, + pub reexport_exports_presence: Option, + pub strict_export_presence: bool, + pub worker: Vec, + pub override_strict: Option, + pub import_meta: bool, +} + +impl From for JavascriptParserOptions { + fn from(value: RawJavascriptParserOptions) -> Self { + Self { + dynamic_import_mode: DynamicImportMode::from(value.dynamic_import_mode.as_str()), + dynamic_import_preload: JavascriptParserOrder::from(value.dynamic_import_preload.as_str()), + dynamic_import_prefetch: JavascriptParserOrder::from(value.dynamic_import_prefetch.as_str()), + dynamic_import_fetch_priority: value + .dynamic_import_fetch_priority + .map(|x| DynamicImportFetchPriority::from(x.as_str())), + url: JavascriptParserUrl::from(value.url.as_str()), + expr_context_critical: value.expr_context_critical, + wrapped_context_critical: value.wrapped_context_critical, + exports_presence: value + .exports_presence + .map(|e| ExportPresenceMode::from(e.as_str())), + import_exports_presence: value + .import_exports_presence + .map(|e| ExportPresenceMode::from(e.as_str())), + reexport_exports_presence: value + .reexport_exports_presence + .map(|e| ExportPresenceMode::from(e.as_str())), + strict_export_presence: value.strict_export_presence, + worker: value.worker, + override_strict: value + .override_strict + .map(|e| OverrideStrict::from(e.as_str())), + import_meta: value.import_meta, + } + } +} + +#[derive(Debug, Default)] +#[napi(object)] +pub struct RawAssetParserOptions { + pub data_url_condition: Option, +} + +impl From for AssetParserOptions { + fn from(value: RawAssetParserOptions) -> Self { + Self { + data_url_condition: value.data_url_condition.map(|i| i.into()), + } + } +} + +#[derive(Debug, Default)] +#[napi(object)] +pub struct RawAssetParserDataUrl { + #[napi(ts_type = r#""options""#)] + pub r#type: String, + pub options: Option, + // TODO: pub function +} + +impl From for AssetParserDataUrl { + fn from(value: RawAssetParserDataUrl) -> Self { + match value.r#type.as_str() { + "options" => Self::Options( + value + .options + .expect("should have an \"options\" when RawAssetParserDataUrl.type is \"options\"") + .into(), + ), + _ => panic!( + "Failed to resolve the RawAssetParserDataUrl.type {}. Expected type is `options`.", + value.r#type + ), + } + } +} + +#[derive(Debug, Clone, Default)] +#[napi(object)] +pub struct RawAssetParserDataUrlOptions { + pub max_size: Option, +} + +impl From for AssetParserDataUrlOptions { + fn from(value: RawAssetParserDataUrlOptions) -> Self { + Self { + max_size: value.max_size, + } + } +} + +#[derive(Debug, Default)] +#[napi(object)] +pub struct RawCssParserOptions { + pub named_exports: Option, +} + +impl From for CssParserOptions { + fn from(value: RawCssParserOptions) -> Self { + Self { + named_exports: value.named_exports, + } + } +} + +#[derive(Debug, Default)] +#[napi(object)] +pub struct RawCssAutoParserOptions { + pub named_exports: Option, +} + +impl From for CssAutoParserOptions { + fn from(value: RawCssAutoParserOptions) -> Self { + Self { + named_exports: value.named_exports, + } + } +} + +#[derive(Debug, Default)] +#[napi(object)] +pub struct RawCssModuleParserOptions { + pub named_exports: Option, +} + +impl From for CssModuleParserOptions { + fn from(value: RawCssModuleParserOptions) -> Self { + Self { + named_exports: value.named_exports, + } + } +} + +#[derive(Debug, Default)] +#[napi(object, object_to_js = false)] +pub struct RawGeneratorOptions { + #[napi( + ts_type = r#""asset" | "asset/inline" | "asset/resource" | "css" | "css/auto" | "css/module""# + )] + pub r#type: String, + pub asset: Option, + pub asset_inline: Option, + pub asset_resource: Option, + pub css: Option, + pub css_auto: Option, + pub css_module: Option, +} + +impl From for GeneratorOptions { + fn from(value: RawGeneratorOptions) -> Self { + match value.r#type.as_str() { + "asset" => Self::Asset( + value + .asset + .expect("should have an \"asset\" when RawGeneratorOptions.type is \"asset\"") + .into(), + ), + "asset/inline" => Self::AssetInline( + value + .asset_inline + .expect( + "should have an \"asset_inline\" when RawGeneratorOptions.type is \"asset/inline\"", + ) + .into(), + ), + "asset/resource" => Self::AssetResource( + value + .asset_resource + .expect( + "should have an \"asset_resource\" when RawGeneratorOptions.type is \"asset/resource\"", + ) + .into(), + ), + "css" => Self::Css( + value + .css + .expect("should have an \"css\" when RawGeneratorOptions.type is \"css\"") + .into(), + ), + "css/auto" => Self::CssAuto( + value + .css_auto + .expect("should have an \"css_auto\" when RawGeneratorOptions.type is \"css/auto\"") + .into(), + ), + "css/module" => Self::CssModule( + value + .css_module + .expect("should have an \"css_module\" when RawGeneratorOptions.type is \"css/module\"") + .into(), + ), + _ => panic!( + r#"Failed to resolve the RawGeneratorOptions.type {}."#, + value.r#type + ), + } + } +} + +#[derive(Derivative, Default)] +#[derivative(Debug)] +#[napi(object, object_to_js = false)] +pub struct RawAssetGeneratorOptions { + pub emit: Option, + pub filename: Option, + #[napi(ts_type = "\"auto\" | JsFilename")] + pub public_path: Option, + #[derivative(Debug = "ignore")] + #[napi( + ts_type = "RawAssetGeneratorDataUrlOptions | ((arg: RawAssetGeneratorDataUrlFnArgs) => string)" + )] + pub data_url: Option, +} + +impl From for AssetGeneratorOptions { + fn from(value: RawAssetGeneratorOptions) -> Self { + Self { + emit: value.emit, + filename: value.filename.map(|i| i.into()), + public_path: value.public_path.map(|i| i.into()), + data_url: value + .data_url + .map(|i| RawAssetGeneratorDataUrlWrapper(i).into()), + } + } +} + +#[derive(Derivative, Default)] +#[derivative(Debug)] +#[napi(object, object_to_js = false)] +pub struct RawAssetInlineGeneratorOptions { + #[derivative(Debug = "ignore")] + #[napi( + ts_type = "RawAssetGeneratorDataUrlOptions | ((arg: RawAssetGeneratorDataUrlFnArgs) => string)" + )] + pub data_url: Option, +} + +impl From for AssetInlineGeneratorOptions { + fn from(value: RawAssetInlineGeneratorOptions) -> Self { + Self { + data_url: value + .data_url + .map(|i| RawAssetGeneratorDataUrlWrapper(i).into()), + } + } +} + +#[derive(Debug, Default)] +#[napi(object, object_to_js = false)] +pub struct RawAssetResourceGeneratorOptions { + pub emit: Option, + pub filename: Option, + #[napi(ts_type = "\"auto\" | JsFilename")] + pub public_path: Option, +} + +impl From for AssetResourceGeneratorOptions { + fn from(value: RawAssetResourceGeneratorOptions) -> Self { + Self { + emit: value.emit, + filename: value.filename.map(|i| i.into()), + public_path: value.public_path.map(|i| i.into()), + } + } +} + +type RawAssetGeneratorDataUrl = Either< + RawAssetGeneratorDataUrlOptions, + ThreadsafeFunction, +>; +struct RawAssetGeneratorDataUrlWrapper(RawAssetGeneratorDataUrl); + +#[derive(Debug, Clone)] +#[napi(object)] +pub struct RawAssetGeneratorDataUrlFnArgs { + pub filename: String, + pub content: String, +} + +impl From for RawAssetGeneratorDataUrlFnArgs { + fn from(value: AssetGeneratorDataUrlFnArgs) -> Self { + Self { + filename: value.filename, + content: value.content, + } + } +} + +impl From for AssetGeneratorDataUrl { + fn from(value: RawAssetGeneratorDataUrlWrapper) -> Self { + let handle = Handle::current(); + match value.0 { + Either::A(a) => Self::Options(a.into()), + Either::B(b) => Self::Func(Arc::new(move |ctx| handle.block_on(b.call(ctx.into())))), + } + } +} + +#[derive(Debug, Default)] +#[napi(object)] +pub struct RawAssetGeneratorDataUrlOptions { + #[napi(ts_type = r#""base64" | "false" | undefined"#)] + pub encoding: Option, + pub mimetype: Option, +} + +impl From for AssetGeneratorDataUrlOptions { + fn from(value: RawAssetGeneratorDataUrlOptions) -> Self { + Self { + encoding: value.encoding.map(|i| i.into()), + mimetype: value.mimetype, + } + } +} + +#[derive(Debug, Default)] +#[napi(object)] +pub struct RawCssGeneratorOptions { + pub exports_only: Option, + pub es_module: Option, +} + +impl From for CssGeneratorOptions { + fn from(value: RawCssGeneratorOptions) -> Self { + Self { + exports_only: value.exports_only, + es_module: value.es_module, + } + } +} + +#[derive(Debug, Default)] +#[napi(object)] +pub struct RawCssAutoGeneratorOptions { + #[napi(ts_type = r#""as-is" | "camel-case" | "camel-case-only" | "dashes" | "dashes-only""#)] + pub exports_convention: Option, + pub exports_only: Option, + pub local_ident_name: Option, + pub es_module: Option, +} + +impl From for CssAutoGeneratorOptions { + fn from(value: RawCssAutoGeneratorOptions) -> Self { + Self { + exports_convention: value.exports_convention.map(|n| n.into()), + exports_only: value.exports_only, + local_ident_name: value.local_ident_name.map(|n| n.into()), + es_module: value.es_module, + } + } +} + +#[derive(Debug, Default)] +#[napi(object)] +pub struct RawCssModuleGeneratorOptions { + #[napi(ts_type = r#""as-is" | "camel-case" | "camel-case-only" | "dashes" | "dashes-only""#)] + pub exports_convention: Option, + pub exports_only: Option, + pub local_ident_name: Option, + pub es_module: Option, +} + +impl From for CssModuleGeneratorOptions { + fn from(value: RawCssModuleGeneratorOptions) -> Self { + Self { + exports_convention: value.exports_convention.map(|n| n.into()), + exports_only: value.exports_only, + local_ident_name: value.local_ident_name.map(|n| n.into()), + es_module: value.es_module, + } + } +} + +#[napi(object, object_to_js = false)] +pub struct RawModuleOptions { + pub rules: Vec, + pub parser: Option>, + pub generator: Option>, + #[napi( + ts_type = "string | RegExp | ((request: string) => boolean) | (string | RegExp | ((request: string) => boolean))[]" + )] + pub no_parse: Option, +} + +impl Debug for RawModuleOptions { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("RawModuleOptions") + .field("rules", &self.rules) + .field("parser", &self.parser) + .field("generator", &self.generator) + .field("no_parse", &"...") + .finish() + } +} + +#[derive(Debug, Clone)] +#[napi(object)] +pub struct RawFuncUseCtx { + pub resource: Option, + pub real_resource: Option, + pub resource_query: Option, + pub issuer: Option, +} + +impl From for RawFuncUseCtx { + fn from(value: FuncUseCtx) -> Self { + Self { + resource: value.resource, + real_resource: value.real_resource, + resource_query: value.resource_query, + issuer: value.issuer.map(|s| s.to_string()), + } + } +} + +impl TryFrom for ModuleRule { + type Error = rspack_error::Error; + + fn try_from(value: RawModuleRule) -> rspack_error::Result { + let uses = value.r#use.map(|raw| match raw { + Either::A(array) => { + let uses = array + .into_iter() + .map(|rule_use| ModuleRuleUseLoader { + loader: rule_use.loader, + options: rule_use.options, + }) + .collect::>(); + Ok::(ModuleRuleUse::Array(uses)) + } + Either::B(tsfn) => Ok::(ModuleRuleUse::Func(Box::new( + move |ctx: FuncUseCtx| { + let tsfn = tsfn.clone(); + Box::pin(async move { + tsfn.call(ctx.into()).await.map(|uses| { + uses + .into_iter() + .map(|rule_use| ModuleRuleUseLoader { + loader: rule_use.loader, + options: rule_use.options, + }) + .collect::>() + }) + }) + }, + ))), + }); + + let module_type = value.r#type.map(|t| (&*t).into()); + + let one_of = value + .one_of + .map(|one_of| { + one_of + .into_iter() + .map(|raw| raw.try_into()) + .collect::>>() + }) + .transpose()?; + + let rules = value + .rules + .map(|rule| { + rule + .into_iter() + .map(|raw| raw.try_into()) + .collect::>>() + }) + .transpose()?; + + let description_data = value + .description_data + .map(|data| { + data + .into_iter() + .map(|(k, v)| Ok((k, v.try_into()?))) + .collect::>() + }) + .transpose()?; + + let with = value + .with + .map(|data| { + data + .into_iter() + .map(|(k, v)| Ok((k, v.try_into()?))) + .collect::>() + }) + .transpose()?; + + let enforce = value + .enforce + .map(|enforce| match &*enforce { + "pre" => Ok(ModuleRuleEnforce::Pre), + "post" => Ok(ModuleRuleEnforce::Post), + _ => Err(error!( + "Unsupported Rule.enforce type, supported: 'pre' | 'post' | undefined" + )), + }) + .transpose()? + .unwrap_or_default(); + + Ok(ModuleRule { + rspack_resource: value + .rspack_resource + .map(|raw| raw.try_into()) + .transpose()?, + test: value.test.map(|raw| raw.try_into()).transpose()?, + include: value.include.map(|raw| raw.try_into()).transpose()?, + exclude: value.exclude.map(|raw| raw.try_into()).transpose()?, + resource_query: value.resource_query.map(|raw| raw.try_into()).transpose()?, + resource_fragment: value + .resource_fragment + .map(|raw| raw.try_into()) + .transpose()?, + resource: value.resource.map(|raw| raw.try_into()).transpose()?, + description_data, + with, + issuer: value.issuer.map(|raw| raw.try_into()).transpose()?, + issuer_layer: value.issuer_layer.map(|raw| raw.try_into()).transpose()?, + dependency: value.dependency.map(|raw| raw.try_into()).transpose()?, + scheme: value.scheme.map(|raw| raw.try_into()).transpose()?, + mimetype: value.mimetype.map(|raw| raw.try_into()).transpose()?, + one_of, + rules, + effect: ModuleRuleEffect { + r#use: uses.transpose()?.unwrap_or_default(), + r#type: module_type, + layer: value.layer, + parser: value.parser.map(|raw| raw.into()), + generator: value.generator.map(|raw| raw.into()), + resolve: value.resolve.map(|raw| raw.try_into()).transpose()?, + side_effects: value.side_effects, + enforce, + }, + }) + } +} + +impl TryFrom for ModuleOptions { + type Error = rspack_error::Error; + + fn try_from(value: RawModuleOptions) -> rspack_error::Result { + let rules = value + .rules + .into_iter() + .map(|rule| rule.try_into()) + .collect::>>()?; + Ok(ModuleOptions { + rules, + parser: value + .parser + .map(|x| { + x.into_iter() + .map(|(k, v)| Ok((ModuleType::from(k.as_str()), v.into()))) + .collect::>() + }) + .transpose()?, + generator: value + .generator + .map(|x| { + x.into_iter() + .map(|(k, v)| Ok((ModuleType::from(k.as_str()), v.into()))) + .collect::>() + }) + .transpose()?, + no_parse: value + .no_parse + .map(|x| RawModuleNoParseRulesWrapper(x).into()), + }) + } +} + +type RawModuleNoParseRule = Either3>>; +type RawModuleNoParseRules = Either>; + +struct RawModuleNoParseRuleWrapper(RawModuleNoParseRule); + +struct RawModuleNoParseRulesWrapper(RawModuleNoParseRules); + +fn js_func_to_no_parse_test_func( + v: ThreadsafeFunction>, +) -> ModuleNoParseTestFn { + Box::new(move |s| { + let v = v.clone(); + Box::pin(async move { v.call(s).await.map(|v| v.unwrap_or_default()) }) + }) +} + +impl From for ModuleNoParseRule { + fn from(x: RawModuleNoParseRuleWrapper) -> Self { + match x.0 { + Either3::A(v) => Self::AbsPathPrefix(v), + Either3::B(v) => Self::Regexp(v.to_rspack_regex()), + Either3::C(v) => Self::TestFn(js_func_to_no_parse_test_func(v)), + } + } +} + +impl From for ModuleNoParseRules { + fn from(x: RawModuleNoParseRulesWrapper) -> Self { + match x.0 { + Either::A(v) => Self::Rule(RawModuleNoParseRuleWrapper(v).into()), + Either::B(v) => Self::Rules( + v.into_iter() + .map(|r| RawModuleNoParseRuleWrapper(r).into()) + .collect(), + ), + } + } +} diff --git a/crates/binding_options/src/options/raw_node.rs b/crates/binding_options/src/options/raw_node.rs new file mode 100644 index 0000000..3855e28 --- /dev/null +++ b/crates/binding_options/src/options/raw_node.rs @@ -0,0 +1,20 @@ +use napi_derive::napi; +use rspack_core::NodeOption; + +#[derive(Debug, Default)] +#[napi(object)] +pub struct RawNodeOption { + pub dirname: String, + pub filename: String, + pub global: String, +} + +impl From for NodeOption { + fn from(value: RawNodeOption) -> Self { + Self { + dirname: value.dirname, + filename: value.filename, + global: value.global, + } + } +} diff --git a/crates/binding_options/src/options/raw_optimization.rs b/crates/binding_options/src/options/raw_optimization.rs index e9b6f19..2a6d385 100644 --- a/crates/binding_options/src/options/raw_optimization.rs +++ b/crates/binding_options/src/options/raw_optimization.rs @@ -1,14 +1,9 @@ -use better_scoped_tls::scoped_tls; use napi_derive::napi; use rspack_core::{MangleExportsOption, Optimization, SideEffectOption, UsedExportsOption}; -use serde::Deserialize; -scoped_tls!(pub(crate) static IS_ENABLE_NEW_SPLIT_CHUNKS: bool); - -#[derive(Deserialize, Debug, Default)] -#[serde(rename_all = "camelCase")] +#[derive(Debug, Default)] #[napi(object)] -pub struct RspackRawOptimizationOptions { +pub struct RawOptimizationOptions { pub remove_available_modules: bool, pub side_effects: String, pub used_exports: String, @@ -18,10 +13,10 @@ pub struct RspackRawOptimizationOptions { pub concatenate_modules: bool, } -impl TryFrom for Optimization { +impl TryFrom for Optimization { type Error = rspack_error::Error; - fn try_from(value: RspackRawOptimizationOptions) -> rspack_error::Result { + fn try_from(value: RawOptimizationOptions) -> rspack_error::Result { Ok(Optimization { remove_available_modules: value.remove_available_modules, side_effects: SideEffectOption::from(value.side_effects.as_str()), diff --git a/crates/binding_options/src/options/raw_output.rs b/crates/binding_options/src/options/raw_output.rs new file mode 100644 index 0000000..63a77e2 --- /dev/null +++ b/crates/binding_options/src/options/raw_output.rs @@ -0,0 +1,165 @@ +use napi::Either; +use napi_derive::napi; +use rspack_binding_values::library::JsLibraryOptions; +use rspack_binding_values::JsFilename; +use rspack_core::{CrossOriginLoading, Environment, PathInfo}; +use rspack_core::{OutputOptions, TrustedTypes}; + +#[derive(Debug)] +#[napi(object)] +pub struct RawTrustedTypes { + pub policy_name: Option, +} + +impl From for TrustedTypes { + fn from(value: RawTrustedTypes) -> Self { + Self { + policy_name: value.policy_name, + } + } +} + +#[derive(Debug, Clone)] +#[napi(object)] +pub struct RawCrossOriginLoading { + #[napi(ts_type = r#""bool" | "string""#)] + pub r#type: String, + pub string_payload: Option, + pub bool_payload: Option, +} + +impl From for CrossOriginLoading { + fn from(value: RawCrossOriginLoading) -> Self { + match value.r#type.as_str() { + "string" => Self::Enable( + value + .string_payload + .expect("should have a string_payload when RawCrossOriginLoading.type is \"string\""), + ), + "bool" => Self::Disable, + _ => unreachable!(), + } + } +} + +#[derive(Debug, Clone)] +#[napi(object)] +pub struct RawEnvironment { + pub r#const: Option, + pub arrow_function: Option, +} + +impl From for Environment { + fn from(value: RawEnvironment) -> Self { + Self { + r#const: value.r#const, + arrow_function: value.arrow_function, + } + } +} + +#[derive(Debug)] +#[napi(object, object_to_js = false)] +pub struct RawOutputOptions { + pub path: String, + #[napi(ts_type = "boolean | \"verbose\"")] + pub pathinfo: Either, + pub clean: bool, + #[napi(ts_type = "\"auto\" | JsFilename")] + pub public_path: JsFilename, + pub asset_module_filename: JsFilename, + pub wasm_loading: String, + pub enabled_wasm_loading_types: Vec, + pub webassembly_module_filename: String, + pub filename: JsFilename, + pub chunk_filename: JsFilename, + pub cross_origin_loading: RawCrossOriginLoading, + pub css_filename: JsFilename, + pub css_chunk_filename: JsFilename, + pub css_head_data_compression: bool, + pub hot_update_main_filename: String, + pub hot_update_chunk_filename: String, + pub hot_update_global: String, + pub unique_name: String, + pub chunk_loading_global: String, + pub library: Option, + pub strict_module_error_handling: bool, + pub enabled_library_types: Option>, + pub global_object: String, + pub import_function_name: String, + pub import_meta_name: String, + pub iife: bool, + pub module: bool, + pub chunk_loading: String, + pub chunk_load_timeout: u32, + pub charset: bool, + pub enabled_chunk_loading_types: Option>, + pub trusted_types: Option, + pub source_map_filename: String, + pub hash_function: String, + pub hash_digest: String, + pub hash_digest_length: u32, + pub hash_salt: Option, + pub async_chunks: bool, + pub worker_chunk_loading: String, + pub worker_wasm_loading: String, + pub worker_public_path: String, + #[napi(ts_type = r#""module" | "text/javascript" | "false""#)] + pub script_type: String, + pub environment: RawEnvironment, +} + +impl TryFrom for OutputOptions { + type Error = rspack_error::Error; + + fn try_from(value: RawOutputOptions) -> rspack_error::Result { + let pathinfo = match value.pathinfo { + Either::A(b) => PathInfo::Bool(b), + Either::B(s) => PathInfo::String(s), + }; + + Ok(OutputOptions { + path: value.path.into(), + pathinfo, + clean: value.clean, + public_path: value.public_path.into(), + asset_module_filename: value.asset_module_filename.into(), + wasm_loading: value.wasm_loading.as_str().into(), + webassembly_module_filename: value.webassembly_module_filename.into(), + unique_name: value.unique_name, + chunk_loading: value.chunk_loading.as_str().into(), + chunk_loading_global: value.chunk_loading_global.as_str().into(), + filename: value.filename.into(), + chunk_filename: value.chunk_filename.into(), + cross_origin_loading: value.cross_origin_loading.into(), + css_filename: value.css_filename.into(), + css_chunk_filename: value.css_chunk_filename.into(), + css_head_data_compression: value.css_head_data_compression, + hot_update_main_filename: value.hot_update_main_filename.into(), + hot_update_chunk_filename: value.hot_update_chunk_filename.into(), + hot_update_global: value.hot_update_global, + library: value.library.map(Into::into), + strict_module_error_handling: value.strict_module_error_handling, + enabled_library_types: value.enabled_library_types, + global_object: value.global_object, + import_function_name: value.import_function_name, + import_meta_name: value.import_meta_name, + iife: value.iife, + module: value.module, + trusted_types: value.trusted_types.map(Into::into), + source_map_filename: value.source_map_filename.into(), + hash_function: value.hash_function.as_str().into(), + hash_digest: value.hash_digest.as_str().into(), + hash_digest_length: value.hash_digest_length as usize, + hash_salt: value.hash_salt.into(), + async_chunks: value.async_chunks, + worker_chunk_loading: value.worker_chunk_loading.as_str().into(), + worker_wasm_loading: value.worker_wasm_loading.as_str().into(), + worker_public_path: value.worker_public_path, + script_type: value.script_type, + environment: value.environment.into(), + charset: value.charset, + chunk_load_timeout: value.chunk_load_timeout, + }) + } +} diff --git a/crates/binding_options/src/options/raw_snapshot.rs b/crates/binding_options/src/options/raw_snapshot.rs new file mode 100644 index 0000000..8d368ad --- /dev/null +++ b/crates/binding_options/src/options/raw_snapshot.rs @@ -0,0 +1,12 @@ +use napi_derive::napi; +use rspack_core::SnapshotOptions; + +#[derive(Debug, Default)] +#[napi(object)] +pub struct RawSnapshotOptions; + +impl From for SnapshotOptions { + fn from(_value: RawSnapshotOptions) -> Self { + SnapshotOptions + } +} diff --git a/crates/binding_options/src/options/raw_split_chunks/mod.rs b/crates/binding_options/src/options/raw_split_chunks/mod.rs new file mode 100644 index 0000000..ec7ad61 --- /dev/null +++ b/crates/binding_options/src/options/raw_split_chunks/mod.rs @@ -0,0 +1,324 @@ +mod raw_split_chunk_cache_group_test; +mod raw_split_chunk_chunks; +mod raw_split_chunk_name; +mod raw_split_chunk_size; + +use std::sync::Arc; + +use derivative::Derivative; +use napi::{Either, JsString}; +use napi_derive::napi; +use raw_split_chunk_name::normalize_raw_chunk_name; +use raw_split_chunk_name::RawChunkOptionName; +use rspack_core::Filename; +use rspack_core::SourceType; +use rspack_core::DEFAULT_DELIMITER; +use rspack_napi::regexp::{JsRegExp, JsRegExpExt}; +use rspack_napi::string::JsStringExt; +use rspack_plugin_split_chunks::ChunkNameGetter; + +use self::raw_split_chunk_cache_group_test::default_cache_group_test; +use self::raw_split_chunk_cache_group_test::normalize_raw_cache_group_test; +use self::raw_split_chunk_cache_group_test::RawCacheGroupTest; +use self::raw_split_chunk_chunks::{create_chunks_filter, Chunks}; +use self::raw_split_chunk_name::default_chunk_option_name; +use self::raw_split_chunk_size::RawSplitChunkSizes; + +#[derive(Derivative)] +#[napi(object, object_to_js = false)] +#[derivative(Debug)] +pub struct RawSplitChunksOptions { + pub fallback_cache_group: Option, + #[napi(ts_type = "string | false | Function")] + #[derivative(Debug = "ignore")] + pub name: Option, + pub cache_groups: Option>, + /// What kind of chunks should be selected. + #[napi(ts_type = "RegExp | 'async' | 'initial' | 'all' | Function")] + #[derivative(Debug = "ignore")] + pub chunks: Option, + pub used_exports: Option, + pub automatic_name_delimiter: Option, + pub max_async_requests: Option, + pub max_initial_requests: Option, + pub default_size_types: Vec, + pub min_chunks: Option, + pub hide_path_info: Option, + pub min_size: Option>, + // pub min_size_reduction: usize, + pub enforce_size_threshold: Option, + pub min_remaining_size: Option>, + // layer: String, + pub max_size: Option>, + pub max_async_size: Option>, + pub max_initial_size: Option>, +} + +#[derive(Derivative)] +#[napi(object, object_to_js = false)] +#[derivative(Debug)] +pub struct RawCacheGroupOptions { + pub key: String, + pub priority: Option, + // pub reuse_existing_chunk: Option, + // pub r#type: SizeType, + #[napi(ts_type = "RegExp | string | Function")] + #[derivative(Debug = "ignore")] + pub test: Option, + pub filename: Option, + // pub enforce: bool, + pub id_hint: Option, + /// What kind of chunks should be selected. + #[napi(ts_type = "RegExp | 'async' | 'initial' | 'all'")] + #[derivative(Debug = "ignore")] + pub chunks: Option, + #[napi(ts_type = "RegExp | string")] + #[derivative(Debug = "ignore")] + pub r#type: Option>, + #[napi(ts_type = "RegExp | string")] + #[derivative(Debug = "ignore")] + pub layer: Option>, + pub automatic_name_delimiter: Option, + // pub max_async_requests: usize, + // pub max_initial_requests: usize, + pub min_chunks: Option, + pub min_size: Option>, + // pub min_size_reduction: usize, + // pub enforce_size_threshold: usize, + // pub min_remaining_size: usize, + // layer: String, + pub max_size: Option>, + pub max_async_size: Option>, + pub max_initial_size: Option>, + pub max_async_requests: Option, + pub max_initial_requests: Option, + #[napi(ts_type = "string | false | Function")] + #[derivative(Debug = "ignore")] + pub name: Option, + // used_exports: bool, + pub reuse_existing_chunk: Option, + pub enforce: Option, + pub used_exports: Option, +} + +impl From for rspack_plugin_split_chunks::PluginOptions { + fn from(raw_opts: RawSplitChunksOptions) -> Self { + use rspack_plugin_split_chunks::SplitChunkSizes; + + let mut cache_groups = vec![]; + + let overall_chunk_filter = raw_opts.chunks.map(create_chunks_filter); + + let overall_min_chunks = raw_opts.min_chunks.unwrap_or(1); + + let overall_name_getter = raw_opts.name.map_or(default_chunk_option_name(), |name| { + normalize_raw_chunk_name(name) + }); + + let default_size_types = raw_opts + .default_size_types + .into_iter() + .map(|size_type| SourceType::from(size_type.as_str())) + .collect::>(); + + let create_sizes = |size: Option>| match size { + Some(Either::A(size)) => SplitChunkSizes::with_initial_value(&default_size_types, size), + Some(Either::B(sizes)) => sizes.into(), + None => SplitChunkSizes::default(), + }; + + let empty_sizes = SplitChunkSizes::empty(); + + let overall_min_size = create_sizes(raw_opts.min_size); + + let overall_max_size = create_sizes(raw_opts.max_size); + + let overall_max_async_size = create_sizes(raw_opts.max_async_size).merge(&overall_max_size); + + let overall_max_initial_size = create_sizes(raw_opts.max_initial_size).merge(&overall_max_size); + + let overall_automatic_name_delimiter = raw_opts + .automatic_name_delimiter + .unwrap_or(DEFAULT_DELIMITER.to_string()); + + cache_groups.extend( + raw_opts + .cache_groups + .unwrap_or_default() + .into_iter() + .map(|v| { + let enforce = v.enforce.unwrap_or_default(); + + let min_size = create_sizes(v.min_size).merge(if enforce { + &empty_sizes + } else { + &overall_min_size + }); + + let max_size = create_sizes(v.max_size); + + let max_async_size = create_sizes(v.max_async_size) + .merge(&max_size) + .merge(if enforce { + &empty_sizes + } else { + &overall_max_async_size + }); + + let max_initial_size = + create_sizes(v.max_initial_size) + .merge(&max_size) + .merge(if enforce { + &empty_sizes + } else { + &overall_max_initial_size + }); + + let min_chunks = if enforce { + 1 + } else { + v.min_chunks.unwrap_or(overall_min_chunks) + }; + + let r#type = v + .r#type + .map(create_module_type_filter) + .unwrap_or_else(rspack_plugin_split_chunks::create_default_module_type_filter); + + let layer = v + .layer + .map(create_module_layer_filter) + .unwrap_or_else(rspack_plugin_split_chunks::create_default_module_layer_filter); + + let mut name = v.name.map_or(default_chunk_option_name(), |name| { + normalize_raw_chunk_name(name) + }); + if matches!(name, ChunkNameGetter::Disabled) { + name = overall_name_getter.clone(); + } + rspack_plugin_split_chunks::CacheGroup { + id_hint: v.id_hint.unwrap_or_else(|| v.key.clone()), + key: v.key, + name, + priority: v.priority.unwrap_or(0) as f64, + test: v.test.map_or(default_cache_group_test(), |test| { + normalize_raw_cache_group_test(test) + }), + chunk_filter: v.chunks.map(create_chunks_filter).unwrap_or_else(|| { + overall_chunk_filter + .clone() + .unwrap_or_else(rspack_plugin_split_chunks::create_async_chunk_filter) + }), + min_chunks, + min_size, + automatic_name_delimiter: v + .automatic_name_delimiter + .unwrap_or(overall_automatic_name_delimiter.clone()), + filename: v.filename.map(Filename::from), + reuse_existing_chunk: v.reuse_existing_chunk.unwrap_or(false), + max_async_requests: v.max_async_requests.unwrap_or(f64::INFINITY), + max_initial_requests: v.max_initial_requests.unwrap_or(f64::INFINITY), + max_async_size, + max_initial_size, + r#type, + layer, + used_exports: v + .used_exports + .unwrap_or_else(|| raw_opts.used_exports.unwrap_or_default()), + } + }), + ); + + let raw_fallback_cache_group = raw_opts.fallback_cache_group.unwrap_or_default(); + + let fallback_chunks_filter = raw_fallback_cache_group.chunks.map(create_chunks_filter); + + let fallback_min_size = + create_sizes(raw_fallback_cache_group.min_size).merge(&overall_min_size); + + let fallback_max_size = create_sizes(raw_fallback_cache_group.max_size); + + let fallback_max_async_size = create_sizes(raw_fallback_cache_group.max_async_size) + .merge(&fallback_max_size) + .merge(&overall_max_async_size) + .merge(&overall_max_size); + + let fallback_max_initial_size = create_sizes(raw_fallback_cache_group.max_initial_size) + .merge(&fallback_max_size) + .merge(&overall_max_initial_size) + .merge(&overall_max_size); + + rspack_plugin_split_chunks::PluginOptions { + cache_groups, + fallback_cache_group: rspack_plugin_split_chunks::FallbackCacheGroup { + chunks_filter: fallback_chunks_filter.unwrap_or_else(|| { + overall_chunk_filter + .clone() + .unwrap_or_else(rspack_plugin_split_chunks::create_all_chunk_filter) + }), + min_size: fallback_min_size, + max_async_size: fallback_max_async_size, + max_initial_size: fallback_max_initial_size, + automatic_name_delimiter: raw_fallback_cache_group + .automatic_name_delimiter + .unwrap_or(overall_automatic_name_delimiter.clone()), + }, + hide_path_info: raw_opts.hide_path_info, + } + } +} + +#[derive(Default, Derivative)] +#[napi(object, object_to_js = false)] +#[derivative(Debug)] +pub struct RawFallbackCacheGroupOptions { + #[napi(ts_type = "RegExp | 'async' | 'initial' | 'all'")] + #[derivative(Debug = "ignore")] + pub chunks: Option, + pub min_size: Option>, + pub max_size: Option>, + pub max_async_size: Option>, + pub max_initial_size: Option>, + pub automatic_name_delimiter: Option, +} + +fn create_module_type_filter( + raw: Either, +) -> rspack_plugin_split_chunks::ModuleTypeFilter { + match raw { + Either::A(js_reg) => { + let regex = js_reg.to_rspack_regex(); + Arc::new(move |m| regex.test(m.module_type().as_str())) + } + Either::B(js_str) => { + let type_str = js_str.into_string(); + Arc::new(move |m| m.module_type().as_str() == type_str.as_str()) + } + } +} + +fn create_module_layer_filter( + raw: Either, +) -> rspack_plugin_split_chunks::ModuleLayerFilter { + match raw { + Either::A(js_reg) => { + let regex = js_reg.to_rspack_regex(); + Arc::new(move |m| { + m.get_layer() + .map(|layer| regex.test(layer)) + .unwrap_or_default() + }) + } + Either::B(js_str) => { + let test = js_str.into_string(); + Arc::new(move |m| { + let layer = m.get_layer(); + if let Some(layer) = layer { + layer.starts_with(&test) + } else { + test.is_empty() + } + }) + } + } +} diff --git a/crates/binding_options/src/options/raw_split_chunks/raw_split_chunk_cache_group_test.rs b/crates/binding_options/src/options/raw_split_chunks/raw_split_chunk_cache_group_test.rs new file mode 100644 index 0000000..19e7d67 --- /dev/null +++ b/crates/binding_options/src/options/raw_split_chunks/raw_split_chunk_cache_group_test.rs @@ -0,0 +1,49 @@ +use std::sync::Arc; + +use napi::bindgen_prelude::{Either3, FromNapiValue}; +use napi_derive::napi; +use rspack_binding_values::ModuleDTOWrapper; +use rspack_napi::regexp::{JsRegExp, JsRegExpExt}; +use rspack_napi::threadsafe_function::ThreadsafeFunction; +use rspack_plugin_split_chunks::{CacheGroupTest, CacheGroupTestFnCtx}; +use tokio::runtime::Handle; + +pub(super) type RawCacheGroupTest = + Either3>>; + +#[napi(object, object_from_js = false)] +pub struct JsCacheGroupTestCtx { + #[napi(ts_type = "ModuleDTO")] + pub module: ModuleDTOWrapper, +} + +impl FromNapiValue for JsCacheGroupTestCtx { + unsafe fn from_napi_value( + _env: napi::sys::napi_env, + _napi_val: napi::sys::napi_value, + ) -> napi::Result { + unreachable!() + } +} + +impl<'a> From> for JsCacheGroupTestCtx { + fn from(value: CacheGroupTestFnCtx<'a>) -> Self { + JsCacheGroupTestCtx { + module: ModuleDTOWrapper::new(value.module.identifier(), value.compilation), + } + } +} + +pub(super) fn normalize_raw_cache_group_test(raw: RawCacheGroupTest) -> CacheGroupTest { + let handle = Handle::current(); + match raw { + Either3::A(str) => CacheGroupTest::String(str), + Either3::B(regexp) => CacheGroupTest::RegExp(regexp.to_rspack_regex()), + Either3::C(v) => CacheGroupTest::Fn(Arc::new(move |ctx| handle.block_on(v.call(ctx.into())))), + } +} + +#[inline] +pub(super) fn default_cache_group_test() -> CacheGroupTest { + CacheGroupTest::Enabled +} diff --git a/crates/binding_options/src/options/raw_split_chunks/raw_split_chunk_chunks.rs b/crates/binding_options/src/options/raw_split_chunks/raw_split_chunk_chunks.rs new file mode 100644 index 0000000..c6eef7f --- /dev/null +++ b/crates/binding_options/src/options/raw_split_chunks/raw_split_chunk_chunks.rs @@ -0,0 +1,24 @@ +use std::sync::Arc; + +use napi::{bindgen_prelude::Either3, JsString}; +use rspack_binding_values::JsChunk; +use rspack_napi::regexp::{JsRegExp, JsRegExpExt}; +use rspack_napi::string::JsStringExt; +use rspack_napi::threadsafe_function::ThreadsafeFunction; +use tokio::runtime::Handle; + +pub type Chunks = Either3>; + +pub fn create_chunks_filter(raw: Chunks) -> rspack_plugin_split_chunks::ChunkFilter { + let handle = Handle::current(); + match raw { + Either3::A(reg) => { + rspack_plugin_split_chunks::create_regex_chunk_filter_from_str(reg.to_rspack_regex()) + } + Either3::B(js_str) => { + let js_str = js_str.into_string(); + rspack_plugin_split_chunks::create_chunk_filter_from_str(&js_str) + } + Either3::C(f) => Arc::new(move |chunk, _| handle.block_on(f.call(JsChunk::from(chunk)))), + } +} diff --git a/crates/binding_options/src/options/raw_split_chunks/raw_split_chunk_name.rs b/crates/binding_options/src/options/raw_split_chunks/raw_split_chunk_name.rs new file mode 100644 index 0000000..1a017bf --- /dev/null +++ b/crates/binding_options/src/options/raw_split_chunks/raw_split_chunk_name.rs @@ -0,0 +1,50 @@ +use std::sync::Arc; + +use napi::bindgen_prelude::Either3; +use napi_derive::napi; +use rspack_binding_values::{JsChunk, JsModule, ToJsModule}; +use rspack_core::Chunk; +use rspack_napi::threadsafe_function::ThreadsafeFunction; +use rspack_plugin_split_chunks::{ChunkNameGetter, ChunkNameGetterFnCtx}; +use tokio::runtime::Handle; + +pub(super) type RawChunkOptionName = + Either3>>; + +#[inline] +pub(super) fn default_chunk_option_name() -> ChunkNameGetter { + ChunkNameGetter::Disabled +} + +#[napi(object)] +pub struct RawChunkOptionNameCtx { + pub module: JsModule, + pub chunks: Vec, + pub cache_group_key: String, +} + +impl<'a> From> for RawChunkOptionNameCtx { + fn from(value: ChunkNameGetterFnCtx<'a>) -> Self { + RawChunkOptionNameCtx { + module: value + .module + .to_js_module() + .expect("should convert js success"), + chunks: value + .chunks + .iter() + .map(|chunk: &&Chunk| JsChunk::from(chunk)) + .collect(), + cache_group_key: value.cache_group_key.to_string(), + } + } +} + +pub(super) fn normalize_raw_chunk_name(raw: RawChunkOptionName) -> ChunkNameGetter { + let handle = Handle::current(); + match raw { + Either3::A(str) => ChunkNameGetter::String(str), + Either3::B(_) => ChunkNameGetter::Disabled, // FIXME: when set bool is true? + Either3::C(v) => ChunkNameGetter::Fn(Arc::new(move |ctx| handle.block_on(v.call(ctx.into())))), + } +} diff --git a/crates/binding_options/src/options/raw_split_chunks/raw_split_chunk_size.rs b/crates/binding_options/src/options/raw_split_chunks/raw_split_chunk_size.rs new file mode 100644 index 0000000..0a7d8e8 --- /dev/null +++ b/crates/binding_options/src/options/raw_split_chunks/raw_split_chunk_size.rs @@ -0,0 +1,22 @@ +use std::collections::HashMap; + +use derivative::Derivative; +use napi_derive::napi; +use rspack_plugin_split_chunks::SplitChunkSizes; + +#[derive(Derivative)] +#[napi(object, object_to_js = false)] +#[derivative(Debug)] +pub struct RawSplitChunkSizes { + pub sizes: HashMap, +} + +impl From for SplitChunkSizes { + fn from(sizes: RawSplitChunkSizes) -> Self { + let mut split_chunk_sizes = SplitChunkSizes::default(); + for (chunk_name, size) in sizes.sizes { + split_chunk_sizes.insert((*chunk_name).into(), size); + } + split_chunk_sizes + } +} diff --git a/crates/binding_options/src/options/raw_stats.rs b/crates/binding_options/src/options/raw_stats.rs new file mode 100644 index 0000000..88768fd --- /dev/null +++ b/crates/binding_options/src/options/raw_stats.rs @@ -0,0 +1,16 @@ +use napi_derive::napi; +use rspack_core::StatsOptions; + +#[derive(Debug, Default)] +#[napi(object)] +pub struct RawStatsOptions { + pub colors: bool, +} + +impl From for StatsOptions { + fn from(value: RawStatsOptions) -> Self { + Self { + colors: value.colors, + } + } +} diff --git a/crates/binding_options/src/plugins/css_extract_additional_data.rs b/crates/binding_options/src/plugins/css_extract_additional_data.rs new file mode 100644 index 0000000..55a81a3 --- /dev/null +++ b/crates/binding_options/src/plugins/css_extract_additional_data.rs @@ -0,0 +1,85 @@ +use std::fmt::Debug; + +use napi::{bindgen_prelude::Unknown, Env}; +use rspack_core::{ + ApplyContext, CompilerOptions, NormalModuleAdditionalData, Plugin, PluginContext, +}; +use rspack_error::Result; +use rspack_hook::{plugin, plugin_hook}; +use rspack_loader_runner::AdditionalData; +use rspack_napi::{threadsafe_js_value_ref::ThreadsafeJsValueRef, JsCallback, NapiResultExt}; +use rspack_plugin_extract_css::CssExtractJsonDataList; +use tokio::sync::oneshot; + +#[plugin] +pub(crate) struct CssExtractRspackAdditionalDataPlugin { + js_callback: JsCallback>, +} + +impl CssExtractRspackAdditionalDataPlugin { + pub fn new(env: Env) -> Result { + Ok(Self::new_inner( + unsafe { JsCallback::new(env.raw()) }.into_rspack_result()?, + )) + } +} + +impl Debug for CssExtractRspackAdditionalDataPlugin { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "CssExtractRspackAdditionalDataPlugin(..)") + } +} + +#[plugin_hook(NormalModuleAdditionalData for CssExtractRspackAdditionalDataPlugin)] +async fn additional_data(&self, additional_data: &mut AdditionalData) -> Result<()> { + if !additional_data.contains::>() { + return Ok(()); + } + let (tx, rx) = oneshot::channel::(); + let mut old_data = std::mem::take(additional_data); + self.js_callback.call(Box::new(move |env| { + if let Some(data) = old_data.get::>() + && let Ok(data) = data.get(env) + && let Ok(data) = data.coerce_to_object() + && let Ok(Some(data)) = data.get::<_, String>("css-extract-rspack-plugin") + { + let data_list: Vec = data + .split("__RSPACK_CSS_EXTRACT_SEP__") + .map(|info| { + serde_json::from_str(info) + .unwrap_or_else(|e| panic!("failed to parse CssExtractJsonData: {}", e)) + }) + .collect(); + + old_data.insert(CssExtractJsonDataList(data_list)); + }; + tx.send(old_data) + .expect("should send `additional_data` for `CssExtractRspackAdditionalDataPlugin`"); + })); + let new_data = rx + .await + .expect("should receive `additional_data` for `CssExtractRspackAdditionalDataPlugin`"); + // ignore the default value here + let _ = std::mem::replace(additional_data, new_data); + Ok(()) +} + +#[async_trait::async_trait] +impl Plugin for CssExtractRspackAdditionalDataPlugin { + fn name(&self) -> &'static str { + "CssExtractRspackAdditionalDataPlugin" + } + + fn apply( + &self, + ctx: PluginContext<&mut ApplyContext>, + _options: &mut CompilerOptions, + ) -> Result<()> { + ctx + .context + .normal_module_hooks + .additional_data + .tap(additional_data::new(self)); + Ok(()) + } +} diff --git a/crates/binding_options/src/plugins/js_loader/context.rs b/crates/binding_options/src/plugins/js_loader/context.rs new file mode 100644 index 0000000..7f948a0 --- /dev/null +++ b/crates/binding_options/src/plugins/js_loader/context.rs @@ -0,0 +1,139 @@ +use napi::bindgen_prelude::*; +use napi_derive::napi; +use rspack_binding_values::{JsModule, JsResourceData, ToJsModule as _}; +use rspack_core::{LoaderContext, RunnerContext}; +use rspack_error::error; +use rspack_loader_runner::{LoaderItem, State as LoaderState}; +use rspack_napi::threadsafe_js_value_ref::ThreadsafeJsValueRef; + +#[napi(object)] +pub struct JsLoaderItem { + pub request: String, + pub r#type: String, + + // data + pub data: serde_json::Value, + + // status + pub normal_executed: bool, + pub pitch_executed: bool, +} + +impl From<&LoaderItem> for JsLoaderItem { + fn from(value: &LoaderItem) -> Self { + JsLoaderItem { + request: value.request().to_string(), + r#type: value.r#type().to_string(), + + data: value.data().clone(), + normal_executed: value.normal_executed(), + pitch_executed: value.pitch_executed(), + } + } +} + +#[napi(string_enum)] +pub enum JsLoaderState { + Pitching, + Normal, +} + +impl From for JsLoaderState { + fn from(value: LoaderState) -> Self { + match value { + LoaderState::Init | LoaderState::ProcessResource | LoaderState::Finished => { + panic!("Unexpected loader runner state: {value:?}") + } + LoaderState::Pitching => JsLoaderState::Pitching, + LoaderState::Normal => JsLoaderState::Normal, + } + } +} + +#[napi(object)] +pub struct JsLoaderContext { + #[napi(ts_type = "Readonly")] + pub resource_data: JsResourceData, + /// Will be deprecated. Use module.module_identifier instead + #[napi(js_name = "_moduleIdentifier", ts_type = "Readonly")] + pub module_identifier: String, + #[napi(js_name = "_module")] + pub module: JsModule, + #[napi(ts_type = "Readonly")] + pub hot: bool, + + /// Content maybe empty in pitching stage + pub content: Either, + #[napi(ts_type = "any")] + pub additional_data: Option>, + pub source_map: Option, + pub cacheable: bool, + pub file_dependencies: Vec, + pub context_dependencies: Vec, + pub missing_dependencies: Vec, + pub build_dependencies: Vec, + + pub loader_items: Vec, + pub loader_index: i32, + #[napi(ts_type = "Readonly")] + pub loader_state: JsLoaderState, +} + +impl TryFrom<&mut LoaderContext> for JsLoaderContext { + type Error = rspack_error::Error; + + fn try_from( + cx: &mut rspack_core::LoaderContext, + ) -> std::result::Result { + Ok(JsLoaderContext { + resource_data: cx.resource_data.as_ref().into(), + module_identifier: cx.context.module.module_identifier.to_string(), + module: cx + .context + .module + .to_js_module() + .expect("CompilerModuleContext::to_js_module should not fail."), + hot: cx.hot, + content: match &cx.content { + Some(c) => Either::B(c.to_owned().into_bytes().into()), + None => Either::A(Null), + }, + additional_data: cx + .additional_data + .get::>() + .cloned(), + source_map: cx + .source_map + .clone() + .map(|v| v.to_json()) + .transpose() + .map_err(|e| error!(e.to_string()))? + .map(|v| v.into_bytes().into()), + cacheable: cx.cacheable, + file_dependencies: cx + .file_dependencies + .iter() + .map(|i| i.to_string_lossy().to_string()) + .collect(), + context_dependencies: cx + .context_dependencies + .iter() + .map(|i| i.to_string_lossy().to_string()) + .collect(), + missing_dependencies: cx + .missing_dependencies + .iter() + .map(|i| i.to_string_lossy().to_string()) + .collect(), + build_dependencies: cx + .build_dependencies + .iter() + .map(|i| i.to_string_lossy().to_string()) + .collect(), + + loader_items: cx.loader_items.iter().map(Into::into).collect(), + loader_index: cx.loader_index, + loader_state: cx.state().into(), + }) + } +} diff --git a/crates/binding_options/src/plugins/js_loader/mod.rs b/crates/binding_options/src/plugins/js_loader/mod.rs new file mode 100644 index 0000000..c605405 --- /dev/null +++ b/crates/binding_options/src/plugins/js_loader/mod.rs @@ -0,0 +1,60 @@ +mod context; +mod resolver; +mod scheduler; + +use std::fmt::Debug; + +pub use context::JsLoaderContext; +use napi::bindgen_prelude::*; +use rspack_core::{ApplyContext, CompilerOptions, Plugin, PluginContext}; +use rspack_error::Result; +use rspack_hook::plugin; +use rspack_napi::threadsafe_function::ThreadsafeFunction; + +pub type JsLoaderRunner = ThreadsafeFunction>; + +#[plugin] +pub(crate) struct JsLoaderRspackPlugin { + pub(crate) runner: JsLoaderRunner, +} + +impl JsLoaderRspackPlugin { + pub fn new(runner: JsLoaderRunner) -> Self { + Self::new_inner(runner) + } +} + +impl Debug for JsLoaderRspackPlugin { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("JsLoaderResolver").finish() + } +} + +impl Plugin for JsLoaderRspackPlugin { + fn name(&self) -> &'static str { + "rspack.JsLoaderRspackPlugin" + } + + fn apply( + &self, + ctx: PluginContext<&mut ApplyContext>, + _options: &mut CompilerOptions, + ) -> Result<()> { + ctx + .context + .normal_module_factory_hooks + .resolve_loader + .tap(resolver::resolve_loader::new(self)); + ctx + .context + .normal_module_hooks + .loader_should_yield + .tap(scheduler::loader_should_yield::new(self)); + ctx + .context + .normal_module_hooks + .loader_yield + .tap(scheduler::loader_yield::new(self)); + Ok(()) + } +} diff --git a/crates/binding_options/src/plugins/js_loader/resolver.rs b/crates/binding_options/src/plugins/js_loader/resolver.rs new file mode 100644 index 0000000..c0b31d6 --- /dev/null +++ b/crates/binding_options/src/plugins/js_loader/resolver.rs @@ -0,0 +1,178 @@ +use std::sync::Arc; + +use rspack_collections::{Identifiable, Identifier}; +use rspack_core::{ + BoxLoader, Context, Loader, ModuleRuleUseLoader, NormalModuleFactoryResolveLoader, ResolveResult, + Resolver, Resource, RunnerContext, BUILTIN_LOADER_PREFIX, +}; +use rspack_error::{ + error, + miette::{miette, LabeledSpan, SourceOffset}, + Result, +}; +use rspack_hook::plugin_hook; +use rspack_loader_lightningcss::{config::Config, LIGHTNINGCSS_LOADER_IDENTIFIER}; +use rspack_loader_preact_refresh::PREACT_REFRESH_LOADER_IDENTIFIER; +use rspack_loader_react_refresh::REACT_REFRESH_LOADER_IDENTIFIER; +use rspack_loader_swc::SWC_LOADER_IDENTIFIER; +use loader_compilation::COMPILATION_LOADER_IDENTIFIER; +use loader_barrel::BARREL_LOADER_IDENTIFIER; +use rspack_paths::Utf8Path; + +use super::{JsLoaderRspackPlugin, JsLoaderRspackPluginInner}; + +#[derive(Debug)] +pub struct JsLoader(pub Identifier); + +impl Loader for JsLoader {} + +impl Identifiable for JsLoader { + fn identifier(&self) -> Identifier { + self.0 + } +} +// convert serde_error to miette report for pretty error +pub fn serde_error_to_miette( + e: serde_json::Error, + content: Arc, + msg: &str, +) -> rspack_error::miette::Report { + let offset = SourceOffset::from_location(content.as_ref(), e.line(), e.column()); + let span = LabeledSpan::at_offset(offset.offset(), e.to_string()); + miette!(labels = vec![span], "{msg}").with_source_code(content.clone()) +} +pub fn get_builtin_loader(builtin: &str, options: Option<&str>) -> Result { + let options: Arc = options.unwrap_or("{}").into(); + if builtin.starts_with(SWC_LOADER_IDENTIFIER) { + return Ok(Arc::new( + rspack_loader_swc::SwcLoader::new(serde_json::from_str(options.as_ref()).map_err(|e| { + serde_error_to_miette(e, options, "failed to parse builtin:swc-loader options") + })?) + .with_identifier(builtin.into()), + )); + } + + if builtin.starts_with(COMPILATION_LOADER_IDENTIFIER) { + return Ok(Arc::new( + loader_compilation::CompilationLoader::new(serde_json::from_str(options.as_ref()).map_err(|e| { + serde_error_to_miette(e, options, "failed to parse builtin:compilation-loader options") + })?) + .with_identifier(builtin.into()), + )); + } + + if builtin.starts_with(BARREL_LOADER_IDENTIFIER) { + return Ok(Arc::new( + loader_barrel::BarrelLoader::new(serde_json::from_str(options.as_ref()).map_err(|e| { + serde_error_to_miette(e, options, "failed to parse builtin:barrel-loader options") + })?) + .with_identifier(builtin.into()), + )); + } + + if builtin.starts_with(LIGHTNINGCSS_LOADER_IDENTIFIER) { + let config: rspack_loader_lightningcss::config::RawConfig = + serde_json::from_str(options.as_ref()).map_err(|e| { + serde_error_to_miette( + e, + options, + "Could not parse builtin:lightningcss-loader options", + ) + })?; + // TODO: builtin-loader supports function + return Ok(Arc::new( + rspack_loader_lightningcss::LightningCssLoader::new(None, Config::try_from(config)?, builtin), + )); + } + + if builtin.starts_with(REACT_REFRESH_LOADER_IDENTIFIER) { + return Ok(Arc::new( + rspack_loader_react_refresh::ReactRefreshLoader::default().with_identifier(builtin.into()), + )); + } + if builtin.starts_with(PREACT_REFRESH_LOADER_IDENTIFIER) { + return Ok(Arc::new( + rspack_loader_preact_refresh::PreactRefreshLoader::default().with_identifier(builtin.into()), + )); + } + if builtin.starts_with(rspack_loader_testing::SIMPLE_ASYNC_LOADER_IDENTIFIER) { + return Ok(Arc::new(rspack_loader_testing::SimpleAsyncLoader)); + } + if builtin.starts_with(rspack_loader_testing::SIMPLE_LOADER_IDENTIFIER) { + return Ok(Arc::new(rspack_loader_testing::SimpleLoader)); + } + if builtin.starts_with(rspack_loader_testing::PITCHING_LOADER_IDENTIFIER) { + return Ok(Arc::new(rspack_loader_testing::PitchingLoader)); + } + unreachable!("Unexpected builtin loader: {builtin}") +} + +#[plugin_hook(NormalModuleFactoryResolveLoader for JsLoaderRspackPlugin)] +pub(crate) async fn resolve_loader( + &self, + context: &Context, + resolver: &Resolver, + l: &ModuleRuleUseLoader, +) -> Result> { + let context = context.as_path(); + let loader_request = &l.loader; + let loader_options = l.options.as_deref(); + let mut rest = None; + let prev = if let Some(index) = loader_request.find('?') { + rest = Some(&loader_request[index..]); + Utf8Path::new(&loader_request[0..index]) + } else { + Utf8Path::new(loader_request) + }; + + // FIXME: not belong to napi + if loader_request.starts_with(BUILTIN_LOADER_PREFIX) { + return get_builtin_loader(loader_request, loader_options).map(Some); + } + + let resolve_result = resolver + .resolve(context.as_std_path(), prev.as_str()) + .map_err(|err| error!("Failed to resolve loader: {prev} in {context}, error: {err:?}"))?; + + match resolve_result { + ResolveResult::Resource(resource) => { + let Resource { + path, + query, + description_data, + .. + } = resource; + // Pitfall: `Path::ends_with` is different from `str::ends_with` + // So we need to convert `PathBuf` to `&str` + // Use `str::ends_with` instead of `Path::extension` to avoid unnecessary allocation + let path = path.as_str(); + + let r#type = if path.ends_with(".mjs") { + Some("module") + } else if path.ends_with(".cjs") { + Some("commonjs") + } else { + description_data + .as_ref() + .and_then(|data| data.json().get("type").and_then(|t| t.as_str())) + }; + // favor explicit loader query over aliased query, see webpack issue-3320 + let resource = if let Some(rest) = rest + && !rest.is_empty() + { + format!("{path}{rest}") + } else { + format!("{path}{query}") + }; + let ident = if let Some(ty) = r#type { + format!("{ty}|{resource}") + } else { + resource + }; + Ok(Some(Arc::new(JsLoader(ident.into())))) + } + ResolveResult::Ignored => Err(error!( + "Failed to resolve loader: loader_request={prev}, context={context}" + )), + } +} diff --git a/crates/binding_options/src/plugins/js_loader/scheduler.rs b/crates/binding_options/src/plugins/js_loader/scheduler.rs new file mode 100644 index 0000000..b3d4046 --- /dev/null +++ b/crates/binding_options/src/plugins/js_loader/scheduler.rs @@ -0,0 +1,99 @@ +use napi::Either; +use rspack_core::{ + LoaderContext, NormalModuleLoaderShouldYield, NormalModuleLoaderStartYielding, RunnerContext, + BUILTIN_LOADER_PREFIX, +}; +use rspack_error::{error, Result}; +use rspack_hook::plugin_hook; +use rspack_loader_runner::State as LoaderState; + +use super::{JsLoaderContext, JsLoaderRspackPlugin, JsLoaderRspackPluginInner}; + +#[plugin_hook(NormalModuleLoaderShouldYield for JsLoaderRspackPlugin)] +pub(crate) fn loader_should_yield( + &self, + loader_context: &LoaderContext, +) -> Result> { + match loader_context.state() { + s @ LoaderState::Init | s @ LoaderState::ProcessResource | s @ LoaderState::Finished => { + panic!("Unexpected loader runner state: {s:?}") + } + LoaderState::Pitching | LoaderState::Normal => { + return Ok(Some( + !loader_context + .current_loader() + .request() + .starts_with(BUILTIN_LOADER_PREFIX), + )) + } + } +} + +#[plugin_hook(NormalModuleLoaderStartYielding for JsLoaderRspackPlugin)] +pub(crate) async fn loader_yield( + &self, + loader_context: &mut LoaderContext, +) -> Result<()> { + let new_cx = self + .runner + .call_with_promise(loader_context.try_into()?) + .await?; + merge_loader_context(loader_context, new_cx)?; + Ok(()) +} + +pub(crate) fn merge_loader_context( + to: &mut LoaderContext, + mut from: JsLoaderContext, +) -> Result<()> { + if let Some(data) = &from.additional_data { + to.additional_data.insert(data.clone()); + } + to.cacheable = from.cacheable; + to.file_dependencies = from.file_dependencies.into_iter().map(Into::into).collect(); + to.context_dependencies = from + .context_dependencies + .into_iter() + .map(Into::into) + .collect(); + to.missing_dependencies = from + .missing_dependencies + .into_iter() + .map(Into::into) + .collect(); + to.build_dependencies = from + .build_dependencies + .into_iter() + .map(Into::into) + .collect(); + to.content = match from.content { + Either::A(_) => None, + Either::B(c) => Some(rspack_core::Content::from(Into::>::into(c))), + }; + to.source_map = from + .source_map + .as_ref() + .map(|s| rspack_core::rspack_sources::SourceMap::from_slice(s)) + .transpose() + .map_err(|e| error!(e.to_string()))?; + + // update loader status + to.loader_items = to + .loader_items + .drain(..) + .zip(from.loader_items.drain(..)) + .map(|(mut to, from)| { + if from.normal_executed { + to.set_normal_executed() + } + if from.pitch_executed { + to.set_pitch_executed() + } + to.set_data(from.data); + to + }) + .collect(); + to.loader_index = from.loader_index; + + Ok(()) +} diff --git a/crates/binding_options/src/plugins/mod.rs b/crates/binding_options/src/plugins/mod.rs new file mode 100644 index 0000000..06ac0bd --- /dev/null +++ b/crates/binding_options/src/plugins/mod.rs @@ -0,0 +1,4 @@ +mod css_extract_additional_data; +mod js_loader; +pub(super) use css_extract_additional_data::CssExtractRspackAdditionalDataPlugin; +pub(super) use js_loader::{JsLoaderRspackPlugin, JsLoaderRunner}; diff --git a/crates/loader_barrel/Cargo.toml b/crates/loader_barrel/Cargo.toml index b36ea3e..f2c7789 100644 --- a/crates/loader_barrel/Cargo.toml +++ b/crates/loader_barrel/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" [dependencies] lazy_static = "1.4.0" serde_json = { workspace = true } +stacker = { workspace = true } futures = { workspace = true } regex = { workspace = true } anyhow = { workspace = true } diff --git a/crates/loader_barrel/src/lib.rs b/crates/loader_barrel/src/lib.rs index 3e667b6..804219b 100644 --- a/crates/loader_barrel/src/lib.rs +++ b/crates/loader_barrel/src/lib.rs @@ -1,3 +1,5 @@ +#![feature(let_chains)] + use std::future::Future; use std::pin::Pin; use std::{ @@ -9,7 +11,7 @@ use std::{ use lazy_static::lazy_static; use regex::Regex; use rspack_core::{ - DependencyCategory, LoaderRunnerContext, ResolveOptionsWithDependencyType, ResolveResult, + DependencyCategory, RunnerContext, ResolveOptionsWithDependencyType, ResolveResult, Resolver, }; use rspack_error::{error, AnyhowError, Result}; @@ -24,7 +26,7 @@ use swc_core::{ base::config::{Options, OutputCharset}, ecma::{ ast::EsVersion, - parser::{Syntax, TsConfig}, + parser::{Syntax, TsSyntax}, }, }; use swc_optimize_barrel::optimize_barrel; @@ -57,6 +59,112 @@ impl BarrelLoader { self.identifier = identifier; self } + + async fn loader_impl(&self, loader_context: &mut LoaderContext) -> Result<()> { + let resource_path = loader_context + .resource_path() + .map(|p| p.to_path_buf()) + .unwrap_or_default(); + + let resolver = loader_context + .context + .resolver_factory + .get(ResolveOptionsWithDependencyType { + resolve_options: None, + resolve_to_context: false, + dependency_category: DependencyCategory::Esm, + }); + + let Some(content) = std::mem::take(&mut loader_context.content) else { + return Ok(()); + }; + + let source = content.try_into_string()?; + + let result = { + // Get barrel mapping + let mut mapping_result = GLOBAL_TRANSFORM_MAPPING.lock().await; + let resource_key = resource_path.as_str(); + if mapping_result.contains_key(resource_key) { + mapping_result.get(resource_key).cloned() + } else { + let visited = HashSet::new(); + let ret = get_barrel_map( + visited, + resolver, + resource_path.clone().into_std_path_buf(), + self.loader_options.cache_dir.clone(), + false, + Some(source), + ) + .await?; + if let Some(mapping) = ret.clone() { + mapping_result.insert(resource_key.to_string(), mapping); + } + ret + } + }; + let mut export_map = HashMap::new(); + if let Some(TransformMapping { + export_list, + wildcard_exports, + is_client_entry, + }) = result + { + export_list.iter().for_each(|list| { + let key = list[0].clone(); + let value = (list[1].clone(), list[2].clone()); + export_map.insert(key, value); + }); + + let names = &self.loader_options.names; + let mut missed_names = vec![]; + let mut output = if is_client_entry { + String::from("\"use client;\"\n") + } else { + String::from("") + }; + names.iter().for_each(|n| { + if export_map.contains_key(n) { + let (file_path, orig) = export_map.get(n).unwrap(); + if orig == "*" { + output.push_str(&format!("\nexport * as {} from '{}';", n, file_path)); + } else if orig == "default" { + output.push_str(&format!( + "\nexport {{ default as {} }} from '{}';", + n, file_path + )); + } else if orig == n { + output.push_str(&format!("\nexport {{ {} }} from '{}';", n, file_path)); + } else { + output.push_str(&format!( + "\nexport {{ {} as {} }} from '{}';", + orig, n, file_path + )); + } + } else { + missed_names.push(n.as_str()); + } + }); + + if missed_names.len() > 0 { + wildcard_exports.iter().for_each(|n| { + let mut missed_str = String::from(&missed_names.join(" ,")); + missed_str.push_str("&wildcard"); + let req = n.replace("__PLACEHOLDER__", &missed_str); + output.push_str(&format!("\nexport * from '{}';", req)); + }); + } + loader_context.content = Some(Content::from(output)); + } else { + let reexport_str = format!( + "export * from '{}';", + resource_path.to_string() + ); + loader_context.content = Some(Content::from(reexport_str)); + } + Ok(()) + } } #[derive(Debug, Clone)] @@ -98,7 +206,7 @@ async fn get_barrel_map( let file_extension = file.extension().unwrap(); let ts_extensions = vec!["tsx", "ts", "mts"]; if ts_extensions.iter().any(|ext| ext == &file_extension) { - swc_options.config.jsc.syntax = Some(Syntax::Typescript(TsConfig { + swc_options.config.jsc.syntax = Some(Syntax::Typescript(TsSyntax { tsx: true, decorators: true, ..Default::default() @@ -116,9 +224,13 @@ async fn get_barrel_map( }) }) .map_err(AnyhowError::from)?; + let input_source_map = c + .input_source_map(&built.input_source_map) + .map_err(|e| error!(e.to_string()))?; let codegen_options = ast::CodegenOptions { target: Some(built.target), minify: Some(built.minify), + input_source_map: input_source_map.as_ref(), ascii_only: built .output .charset @@ -191,7 +303,7 @@ async fn get_barrel_map( let res = get_barrel_map_boxed( visited.clone(), resolver.clone(), - resource.path, + resource.path.as_std_path().to_path_buf(), cache_dir.clone(), true, None, @@ -238,105 +350,20 @@ fn get_barrel_map_boxed( } #[async_trait::async_trait] -impl Loader for BarrelLoader { - async fn run(&self, loader_context: &mut LoaderContext<'_, LoaderRunnerContext>) -> Result<()> { - let resource_path: std::path::PathBuf = loader_context.resource_path.to_path_buf(); - - let resolver = loader_context - .context - .resolver_factory - .get(ResolveOptionsWithDependencyType { - resolve_options: None, - resolve_to_context: false, - dependency_category: DependencyCategory::Esm, - }); - - let content = std::mem::take(&mut loader_context.content).expect("content should be available"); - let source = content.try_into_string()?; - - let result = { - // Get barrel mapping - let mut mapping_result = GLOBAL_TRANSFORM_MAPPING.lock().await; - let resource_key = &resource_path.to_string_lossy().to_string(); - if mapping_result.contains_key(resource_key) { - mapping_result.get(resource_key).cloned() - } else { - let visited = HashSet::new(); - let ret = get_barrel_map( - visited, - resolver, - resource_path.clone(), - self.loader_options.cache_dir.clone(), - false, - Some(source), - ) - .await?; - if let Some(mapping) = ret.clone() { - mapping_result.insert(resource_key.to_string(), mapping); - } - ret - } - }; - let mut export_map = HashMap::new(); - if let Some(TransformMapping { - export_list, - wildcard_exports, - is_client_entry, - }) = result +impl Loader for BarrelLoader { + async fn run(&self, loader_context: &mut LoaderContext) -> Result<()> { + #[allow(unused_mut)] + let inner = async { self.loader_impl(loader_context).await }; + #[cfg(debug_assertions)] { - export_list.iter().for_each(|list| { - let key = list[0].clone(); - let value = (list[1].clone(), list[2].clone()); - export_map.insert(key, value); - }); - - let names = &self.loader_options.names; - let mut missed_names = vec![]; - let mut output = if is_client_entry { - String::from("\"use client;\"\n") - } else { - String::from("") - }; - names.iter().for_each(|n| { - if export_map.contains_key(n) { - let (file_path, orig) = export_map.get(n).unwrap(); - if orig == "*" { - output.push_str(&format!("\nexport * as {} from '{}';", n, file_path)); - } else if orig == "default" { - output.push_str(&format!( - "\nexport {{ default as {} }} from '{}';", - n, file_path - )); - } else if orig == n { - output.push_str(&format!("\nexport {{ {} }} from '{}';", n, file_path)); - } else { - output.push_str(&format!( - "\nexport {{ {} as {} }} from '{}';", - orig, n, file_path - )); - } - } else { - missed_names.push(n.as_str()); - } - }); - - if missed_names.len() > 0 { - wildcard_exports.iter().for_each(|n| { - let mut missed_str = String::from(&missed_names.join(" ,")); - missed_str.push_str("&wildcard"); - let req = n.replace("__PLACEHOLDER__", &missed_str); - output.push_str(&format!("\nexport * from '{}';", req)); - }); - } - loader_context.content = Some(Content::from(output)); - } else { - let reexport_str = format!( - "export * from '{}';", - resource_path.to_string_lossy().to_string() - ); - loader_context.content = Some(Content::from(reexport_str)); + stacker::maybe_grow( + 2 * 1024 * 1024, /* 2mb */ + 4 * 1024 * 1024, /* 4mb */ + || async { inner.await } + ).await } - Ok(()) + #[cfg(not(debug_assertions))] + inner.await } } diff --git a/crates/loader_compilation/Cargo.toml b/crates/loader_compilation/Cargo.toml index f3924ea..06b4067 100644 --- a/crates/loader_compilation/Cargo.toml +++ b/crates/loader_compilation/Cargo.toml @@ -9,7 +9,6 @@ edition = "2021" anyhow = { workspace = true } async-trait = { workspace = true } either = "1" -lazy_static = "1.4.0" once_cell = { workspace = true } rspack_ast = { path = "../.rspack_crates/rspack_ast" } rspack_core = { path = "../.rspack_crates/rspack_core" } @@ -19,6 +18,7 @@ rspack_plugin_javascript = { path = "../.rspack_crates/rspack_plugin_javascript" rspack_regex = { path = "../.rspack_crates/rspack_regex" } rspack_util = { path = "../.rspack_crates/rspack_util" } regex = { workspace = true } +stacker = { workspace = true } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } swc_config = { workspace = true } @@ -27,7 +27,6 @@ swc_core = { workspace = true, features = [ "ecma_ast", "common" ] } -swc_emotion = { workspace = true } xxhash-rust = { workspace = true, features = ["xxh32"] } swc_compiler = { path = "../swc_compiler" } swc_env_replacement = { path = "../swc_env_replacement" } @@ -35,8 +34,8 @@ swc_keep_export = { path = "../swc_keep_export" } swc_remove_export = { path = "../swc_remove_export" } swc_named_import_transform = { path = "../swc_named_import_transform" } swc_change_package_import = { path = "../swc_change_package_import" } +tokio = { workspace = true } [dev-dependencies] indexmap = { workspace = true } -tokio = { workspace = true, features = ["rt", "rt-multi-thread", "macros", "test-util", "parking_lot"] } -rspack_testing = { path = "../.rspack_crates/rspack_testing" } \ No newline at end of file +tokio = { workspace = true, features = ["rt", "rt-multi-thread", "macros", "test-util", "parking_lot"] } \ No newline at end of file diff --git a/crates/loader_compilation/src/lib.rs b/crates/loader_compilation/src/lib.rs index 9e8daa0..c119f74 100644 --- a/crates/loader_compilation/src/lib.rs +++ b/crates/loader_compilation/src/lib.rs @@ -1,28 +1,24 @@ -use std::{collections::HashMap, path::Path, sync::Mutex}; +#![feature(let_chains)] -use lazy_static::lazy_static; -use rspack_ast::RspackAst; -use rspack_core::{ - rspack_sources::SourceMap, LoaderRunnerContext, LoadersShouldAlwaysGiveContent, Mode, -}; +use std::default::Default; +use std::path::Path; +use serde::Deserialize; +use swc_compiler::{IntoJsAst, SwcCompiler}; +use rspack_core::{rspack_sources::SourceMap, Mode, RunnerContext}; use rspack_error::{error, AnyhowError, Diagnostic, Result}; use rspack_loader_runner::{Identifiable, Identifier, Loader, LoaderContext}; -use rspack_plugin_javascript::{ - ast::{self, SourceMapConfig}, - TransformOutput, -}; use rspack_regex::RspackRegex; +use rspack_plugin_javascript::ast::{self, SourceMapConfig}; +use rspack_plugin_javascript::TransformOutput; use rspack_util::source_map::SourceMapKind; -use serde::Deserialize; use swc_config::{config_types::MergingOption, merge::Merge}; use swc_core::{ - base::config::{Config, InputSourceMap, Options, OutputCharset, TransformConfig}, - ecma::parser::{Syntax, TsConfig}, + base::config::{Config, InputSourceMap, Options, OutputCharset, TransformConfig, SourceMapsConfig}, + ecma::parser::{Syntax, TsSyntax}, }; +use swc_core::ecma::visit::VisitWith; mod transform; - -use swc_compiler::{IntoJsAst, SwcCompiler}; use transform::*; #[derive(Debug, Default, Deserialize)] @@ -45,13 +41,12 @@ pub struct CompilationOptions { transform_features: TransformFeatureOptions, compile_rules: CompileRules, } + pub struct CompilationLoader { identifier: Identifier, loader_options: CompilationOptions, } -pub const COMPILATION_LOADER_IDENTIFIER: &str = "builtin:compilation-loader"; - impl From for CompilationOptions { fn from(value: LoaderOptions) -> Self { let transform_features = value.transform_features; @@ -80,58 +75,58 @@ impl CompilationLoader { self.identifier = identifier; self } -} -lazy_static! { - static ref GLOBAL_FILE_ACCESS: Mutex> = Mutex::new(HashMap::new()); - static ref GLOBAL_ROUTES_CONFIG: Mutex>> = Mutex::new(None); -} - -#[async_trait::async_trait] -impl Loader for CompilationLoader { - async fn run(&self, loader_context: &mut LoaderContext<'_, LoaderRunnerContext>) -> Result<()> { - let resource_path = loader_context.resource_path.to_path_buf(); + fn loader_impl(&self, loader_context: &mut LoaderContext) -> Result<()> { + let resource_path = loader_context + .resource_path() + .map(|p| p.to_path_buf()) + .unwrap_or_default(); + let Some(content) = std::mem::take(&mut loader_context.content) else { + return Ok(()); + }; if self.loader_options.compile_rules.exclude.is_some() { let exclude = self.loader_options.compile_rules.exclude.as_ref().unwrap(); for pattern in exclude { let pattern = RspackRegex::new(pattern).unwrap(); - if pattern.test(&resource_path.to_string_lossy()) { + if pattern.test(&resource_path.as_str()) { + loader_context.content = Some(content); return Ok(()); } } } - let content = std::mem::take(&mut loader_context.content).expect("content should be available"); + let resource_str = resource_path.as_str().to_string(); let swc_options = { let mut swc_options = self.loader_options.swc_options.clone(); if swc_options.config.jsc.transform.as_ref().is_some() { let mut transform = TransformConfig::default(); - transform.react.development = Some(Mode::is_development(&loader_context.context.options.mode)); + transform.react.development = + Some(Mode::is_development(&loader_context.context.options.mode)); swc_options .config .jsc .transform .merge(MergingOption::from(Some(transform))); } + if let Some(pre_source_map) = loader_context.source_map.clone() { + if let Ok(source_map) = pre_source_map.to_json() { + swc_options.config.input_source_map = Some(InputSourceMap::Str(source_map)) + } + } + swc_options.filename = resource_path.as_str().to_string(); + swc_options.source_file_name = Some(resource_path.as_str().to_string()); let file_extension = resource_path.extension().unwrap(); let ts_extensions = vec!["tsx", "ts", "mts"]; if ts_extensions.iter().any(|ext| ext == &file_extension) { - swc_options.config.jsc.syntax = Some(Syntax::Typescript(TsConfig { + swc_options.config.jsc.syntax = Some(Syntax::Typescript(TsSyntax { tsx: true, decorators: true, ..Default::default() })); } - - if let Some(pre_source_map) = std::mem::take(&mut loader_context.source_map) { - if let Ok(source_map) = pre_source_map.to_json() { - swc_options.config.input_source_map = Some(InputSourceMap::Str(source_map)) - } - } - if swc_options.config.jsc.target.is_some() && swc_options.config.env.is_some() { loader_context.emit_diagnostic(Diagnostic::warn( COMPILATION_LOADER_IDENTIFIER.to_string(), @@ -140,88 +135,101 @@ impl Loader for CompilationLoader { } swc_options }; - let source_map_kind = &loader_context.context.module_source_map_kind; - let source = content.try_into_string()?; - let compiler = SwcCompiler::new(resource_path.clone(), source.clone(), swc_options) - .map_err(AnyhowError::from)?; - let transform_options = &self.loader_options.transform_features; + let source_map_kind: SourceMapKind = match swc_options.config.source_maps { + Some(SourceMapsConfig::Bool(false)) => SourceMapKind::empty(), + _ => loader_context.context.module_source_map_kind, + }; + + let source = content.try_into_string()?; + let c = SwcCompiler::new( + resource_path.clone().into_std_path_buf(), + source.clone(), + swc_options, + ) + .map_err(AnyhowError::from)?; + + let mut routes_config: Option> = None; let compiler_context: &str = loader_context.context.options.context.as_ref(); - let mut file_access = GLOBAL_FILE_ACCESS.lock().unwrap(); - let mut routes_config = GLOBAL_ROUTES_CONFIG.lock().unwrap(); - let file_accessed = file_access.contains_key(&resource_path.to_string_lossy().to_string()); - - if routes_config.is_none() || file_accessed { - // Load routes config for transform. - let routes_config_path: std::path::PathBuf = - Path::new(compiler_context).join(".ice/route-manifest.json"); - let routes_content = load_routes_config(&routes_config_path); - if routes_content.is_ok() { - *routes_config = Some(routes_content.map_err(AnyhowError::from)?); - } - if file_accessed { - // If file accessed, then we need to clear the map for the current compilation. - file_access.clear(); - } + let routes_config_path: std::path::PathBuf = + Path::new(compiler_context).join(".ice/route-manifest.json"); + let routes_content = load_routes_config(&routes_config_path); + if routes_content.is_ok() { + routes_config = Some(routes_content.map_err(AnyhowError::from)?); } - file_access.insert(resource_path.to_string_lossy().to_string(), true); - let built = compiler + let transform_options = &self.loader_options.transform_features; + let built = c .parse(None, |_| { - transform(&resource_path, routes_config.as_ref(), transform_options) + transform(&resource_path.as_str(), routes_config.as_ref(), transform_options) }) .map_err(AnyhowError::from)?; - let codegen_options = ast::CodegenOptions { + let input_source_map = c + .input_source_map(&built.input_source_map) + .map_err(|e| error!(e.to_string()))?; + let mut codegen_options = ast::CodegenOptions { target: Some(built.target), minify: Some(built.minify), + input_source_map: input_source_map.as_ref(), ascii_only: built .output .charset .as_ref() .map(|v| matches!(v, OutputCharset::Ascii)), source_map_config: SourceMapConfig { - enable: !matches!(source_map_kind, SourceMapKind::None), - inline_sources_content: true, - emit_columns: matches!(source_map_kind, SourceMapKind::SourceMap), + enable: source_map_kind.source_map(), + inline_sources_content: source_map_kind.source_map(), + emit_columns: !source_map_kind.cheap(), names: Default::default(), }, inline_script: Some(false), keep_comments: Some(true), }; - let program = compiler.transform(built).map_err(AnyhowError::from)?; - let ast = compiler.into_js_ast(program); - - // If swc-loader is the latest loader available, - // then loader produces AST, which could be used as an optimization. - if loader_context.loader_index() == 0 - && (loader_context - .current_loader() - .composed_index_by_identifier(&self.identifier) - .map(|idx| idx == 0) - .unwrap_or(true)) - && !loader_context - .additional_data - .contains::<&LoadersShouldAlwaysGiveContent>() - { - loader_context - .additional_data - .insert(RspackAst::JavaScript(ast)); - loader_context.additional_data.insert(codegen_options); - loader_context.content = Some("".to_owned().into()) - } else { - let TransformOutput { code, map } = ast::stringify(&ast, codegen_options)?; - loader_context.content = Some(code.into()); - loader_context.source_map = map - .map(|m| SourceMap::from_json(&m)) - .transpose() - .map_err(|e| error!(e.to_string()))?; + + let program = tokio::task::block_in_place(|| c.transform(built).map_err(AnyhowError::from))?; + if source_map_kind.enabled() { + let mut v = IdentCollector { + names: Default::default(), + }; + program.visit_with(&mut v); + codegen_options.source_map_config.names = v.names; } + let ast = c.into_js_ast(program); + let TransformOutput { code, map } = ast::stringify(&ast, codegen_options)?; + loader_context.content = Some(code.into()); + + let map = map + .map(|m| SourceMap::from_json(&m)) + .transpose() + .map_err(|e| error!(e.to_string()))?; + loader_context.source_map = map; Ok(()) } } +pub const COMPILATION_LOADER_IDENTIFIER: &str = "builtin:compilation-loader"; + +#[async_trait::async_trait] +impl Loader for CompilationLoader { + async fn run(&self, loader_context: &mut LoaderContext) -> Result<()> { + #[allow(unused_mut)] + let mut inner = || self.loader_impl(loader_context); + #[cfg(debug_assertions)] + { + // Adjust stack to avoid stack overflow. + stacker::maybe_grow( + 2 * 1024 * 1024, /* 2mb */ + 4 * 1024 * 1024, /* 4mb */ + inner, + ) + } + #[cfg(not(debug_assertions))] + inner() + } +} + impl Identifiable for CompilationLoader { fn identifier(&self) -> Identifier { self.identifier diff --git a/crates/loader_compilation/src/transform.rs b/crates/loader_compilation/src/transform.rs index 3a4fb3b..0316382 100644 --- a/crates/loader_compilation/src/transform.rs +++ b/crates/loader_compilation/src/transform.rs @@ -3,6 +3,11 @@ use anyhow::{Context, Error}; use either::Either; use serde::Deserialize; use swc_core::common::chain; +use swc_core::atoms::Atom; +use swc_core::common::collections::AHashMap; +use swc_core::common::BytePos; +use swc_core::ecma::ast::Ident; +use swc_core::ecma::visit::{noop_visit_type, Visit}; use swc_core::ecma::{transforms::base::pass::noop, visit::Fold}; use swc_env_replacement::env_replacement; use swc_keep_export::keep_export; @@ -13,6 +18,7 @@ use swc_change_package_import::{change_package_import, Config as ImportConfig, S macro_rules! either { ($config:expr, $f:expr) => { if let Some(config) = &$config { + #[allow(clippy::redundant_closure_call)] Either::Left($f(config)) } else { Either::Right(noop()) @@ -60,11 +66,10 @@ pub(crate) fn load_routes_config(path: &Path) -> Result, Error> { parse_routes_config(content) } -fn match_route_entry(resource_path: &Path, routes: Option<&Vec>) -> bool { - let resource_path_str = resource_path.to_str().unwrap(); +fn match_route_entry(resource_path: &str, routes: Option<&Vec>) -> bool { if let Some(routes) = routes { for route in routes { - if resource_path_str.ends_with(&route.to_string()) { + if resource_path.ends_with(&route.to_string()) { return true; } } @@ -72,11 +77,10 @@ fn match_route_entry(resource_path: &Path, routes: Option<&Vec>) -> bool false } -fn match_app_entry(resource_path: &Path) -> bool { - let resource_path_str = resource_path.to_str().unwrap(); +fn match_app_entry(resource_path: &str) -> bool { // File path ends with src/app.(ts|tsx|js|jsx) let regex_for_app = regex::Regex::new(r"src/app\.(ts|tsx|js|jsx)$").unwrap(); - regex_for_app.is_match(resource_path_str) + regex_for_app.is_match(resource_path) } #[derive(Debug, Default, Deserialize)] @@ -89,7 +93,7 @@ pub struct TransformFeatureOptions { } pub(crate) fn transform<'a>( - resource_path: &'a Path, + resource_path: &'a str, routes_config: Option<&Vec>, feature_options: &TransformFeatureOptions, ) -> impl Fold + 'a { @@ -133,3 +137,15 @@ pub(crate) fn transform<'a>( ), ) } + +pub struct IdentCollector { + pub names: AHashMap, +} + +impl Visit for IdentCollector { + noop_visit_type!(); + + fn visit_ident(&mut self, ident: &Ident) { + self.names.insert(ident.span.lo, ident.sym.clone()); + } +} diff --git a/crates/node_binding/Cargo.toml b/crates/node_binding/Cargo.toml index 21ba605..4c1f50d 100644 --- a/crates/node_binding/Cargo.toml +++ b/crates/node_binding/Cargo.toml @@ -6,17 +6,29 @@ version = "0.0.0" [lib] crate-type = ["cdylib"] +[features] +default = [] +plugin = ["binding_options/plugin"] + [dependencies] -rspack_binding_macros = { path = "../.rspack_crates/rspack_binding_macros" } -rspack_binding_options = { path = "../.rspack_crates/rspack_binding_options" } -binding_options = { path = "../binding_options" } -rspack_binding_values = { path = "../.rspack_crates/rspack_binding_values" } -rspack_core = { path = "../.rspack_crates/rspack_core" } -rspack_error = { path = "../.rspack_crates/rspack_error" } -rspack_fs_node = { path = "../.rspack_crates/rspack_fs_node" } -rspack_hook = { path = "../.rspack_crates/rspack_hook" } -rspack_napi_shared = { path = "../.rspack_crates/rspack_napi_shared" } -rspack_tracing = { path = "../.rspack_crates/rspack_tracing" } +binding_options = { version = "0.1.0", path = "../binding_options" } +rspack_allocator = { version = "0.1.0", path = "../.rspack_crates/rspack_allocator" } +# rspack_binding_options = { version = "0.1.0", path = "../.rspack_crates/rspack_binding_options" } +rspack_binding_values = { version = "0.1.0", path = "../.rspack_crates/rspack_binding_values" } +rspack_collections = { version = "0.1.0", path = "../.rspack_crates/rspack_collections" } +rspack_core = { version = "0.1.0", path = "../.rspack_crates/rspack_core" } +rspack_error = { version = "0.1.0", path = "../.rspack_crates/rspack_error" } +rspack_fs_node = { version = "0.1.0", path = "../.rspack_crates/rspack_fs_node" } +rspack_hash = { version = "0.1.0", path = "../.rspack_crates/rspack_hash" } +rspack_hook = { version = "0.1.0", path = "../.rspack_crates/rspack_hook" } +rspack_napi = { version = "0.1.0", path = "../.rspack_crates/rspack_napi" } +rspack_paths = { version = "0.1.0", path = "../.rspack_crates/rspack_paths" } +rspack_plugin_html = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_html" } +rspack_plugin_javascript = { version = "0.1.0", path = "../.rspack_crates/rspack_plugin_javascript" } +plugin_manifest = { version = "0.1.0", path = "../plugin_manifest" } + +rspack_tracing = { version = "0.1.0", path = "../.rspack_crates/rspack_tracing" } +tokio = { workspace = true, features = ["rt", "rt-multi-thread"] } async-trait = { workspace = true } once_cell = { workspace = true } @@ -27,14 +39,6 @@ napi-derive = { workspace = true } color-backtrace = "0.6" -[target.'cfg(not(target_os = "linux"))'.dependencies] -mimalloc-rust = { workspace = true } - -[target.'cfg(all(target_os = "linux", target_env = "gnu", any(target_arch = "x86_64", target_arch = "aarch64")))'.dependencies] -tikv-jemallocator = { workspace = true } [build-dependencies] napi-build = { workspace = true } - -[dev-dependencies] -testing_macros = { workspace = true } diff --git a/crates/node_binding/index.d.ts b/crates/node_binding/index.d.ts index 519dd1f..b431210 100644 --- a/crates/node_binding/index.d.ts +++ b/crates/node_binding/index.d.ts @@ -16,11 +16,11 @@ export interface NodeFS { mkdirp: (...args: any[]) => any } export interface ThreadsafeNodeFS { - writeFile: (...args: any[]) => any - removeFile: (...args: any[]) => any - mkdir: (...args: any[]) => any - mkdirp: (...args: any[]) => any - removeDirAll: (...args: any[]) => any + writeFile: (name: string, content: Buffer) => Promise | void + removeFile: (name: string) => Promise | void + mkdir: (name: string) => Promise | void + mkdirp: (name: string) => Promise | string | void + removeDirAll: (name: string) => Promise | string | void } export interface JsAssetInfoRelated { sourceMap?: string @@ -30,16 +30,15 @@ export interface JsAssetInfo { immutable: boolean /** whether the asset is minimized */ minimized: boolean - /** - * the value(s) of the full hash used for this asset - * the value(s) of the chunk hash used for this asset - */ - chunkHash: Array + /** the value(s) of the full hash used for this asset */ + fullhash: Array + /** the value(s) of the chunk hash used for this asset */ + chunkhash: Array /** * the value(s) of the module hash used for this asset * the value(s) of the content hash used for this asset */ - contentHash: Array + contenthash: Array sourceFilename?: string /** * size in bytes, only set after asset has been emitted @@ -52,6 +51,17 @@ export interface JsAssetInfo { javascriptModule?: boolean /** related object to other assets, keyed by type of relation (only points from parent to child) */ related: JsAssetInfoRelated + /** unused css local ident for the css chunk */ + cssUnusedIdents?: Array + /** + * Webpack: AssetInfo = KnownAssetInfo & Record + * But Napi.rs does not support Intersectiont types. This is a hack to store the additional fields + * in the rust struct and have the Js side to reshape and align with webpack + * Related: packages/rspack/src/Compilation.ts + */ + extras: Record + /** whether this asset is over the size limit */ + isOverSizeLimit?: boolean } export interface JsAsset { name: string @@ -76,7 +86,7 @@ export interface JsChunk { hash?: string contentHash: Record renderedHash?: string - chunkReasons: Array + chunkReason?: string auxiliaryFiles: Array } export function __chunk_inner_is_only_initial(jsChunkUkey: number, compilation: JsCompilation): boolean @@ -95,22 +105,36 @@ export function __chunk_graph_inner_get_chunk_entry_dependent_chunks_iterable(js export function __chunk_graph_inner_get_chunk_modules_iterable_by_source_type(jsChunkUkey: number, sourceType: string, compilation: JsCompilation): Array export interface JsChunkGroup { __inner_parents: Array + __inner_ukey: number chunks: Array index?: number name?: string + isInitial: boolean + origins: Array +} +export interface JsChunkGroupOrigin { + module?: ModuleDTO + request?: string } export function __chunk_group_inner_get_chunk_group(ukey: number, compilation: JsCompilation): JsChunkGroup +export function __entrypoint_inner_get_runtime_chunk(ukey: number, compilation: JsCompilation): JsChunk export interface JsCodegenerationResults { map: Record> } export interface JsCodegenerationResult { sources: Record } +export interface JsEntryData { + dependencies: Array + includeDependencies: Array + options: JsEntryOptions +} export interface JsExecuteModuleResult { fileDependencies: Array contextDependencies: Array buildDependencies: Array missingDependencies: Array + cacheable: boolean assets: Array id: number } @@ -118,56 +142,64 @@ export interface JsBuildTimeExecutionOption { publicPath?: string baseUri?: string } -export interface JsHooks { - processAssetsStageAdditional: (...args: any[]) => any - processAssetsStagePreProcess: (...args: any[]) => any - processAssetsStageDerived: (...args: any[]) => any - processAssetsStageAdditions: (...args: any[]) => any - processAssetsStageNone: (...args: any[]) => any - processAssetsStageOptimize: (...args: any[]) => any - processAssetsStageOptimizeCount: (...args: any[]) => any - processAssetsStageOptimizeCompatibility: (...args: any[]) => any - processAssetsStageOptimizeSize: (...args: any[]) => any - processAssetsStageDevTooling: (...args: any[]) => any - processAssetsStageOptimizeInline: (...args: any[]) => any - processAssetsStageSummarize: (...args: any[]) => any - processAssetsStageOptimizeHash: (...args: any[]) => any - processAssetsStageOptimizeTransfer: (...args: any[]) => any - processAssetsStageAnalyse: (...args: any[]) => any - processAssetsStageReport: (...args: any[]) => any - afterProcessAssets: (...args: any[]) => any - thisCompilation: (...args: any[]) => any - emit: (...args: any[]) => any - assetEmitted: (...args: any[]) => any - shouldEmit: (...args: any[]) => any - afterEmit: (...args: any[]) => any - make: (...args: any[]) => any - optimizeModules: (...args: any[]) => any - afterOptimizeModules: (...args: any[]) => any - optimizeTree: (...args: any[]) => any - optimizeChunkModules: (...args: any[]) => any - beforeCompile: (...args: any[]) => any - afterCompile: (...args: any[]) => any - finishModules: (...args: any[]) => any - finishMake: (...args: any[]) => any - buildModule: (...args: any[]) => any - beforeResolve: (...args: any[]) => any - afterResolve: (...args: any[]) => any - contextModuleFactoryBeforeResolve: (...args: any[]) => any - normalModuleFactoryCreateModule: (...args: any[]) => any - normalModuleFactoryResolveForScheme: (...args: any[]) => any - chunkAsset: (...args: any[]) => any - succeedModule: (...args: any[]) => any - stillValidModule: (...args: any[]) => any - executeModule: (...args: any[]) => any - runtimeModule: (...args: any[]) => any -} -export const enum JsHookType { - CompilerCompilation = 'CompilerCompilation' -} -export interface JsHook { - type: JsHookType - function: (...args: any[]) => any +export interface JsContextModuleFactoryBeforeResolveData { + context: string + request?: string +} +export interface JsContextModuleFactoryAfterResolveData { + resource: string + context: string + request: string + regExp?: RawRegex +} +export interface JsHtmlPluginTag { + tagName: string + attributes: Record + voidTag: boolean + innerHTML?: string + asset?: string +} +export interface JsHtmlPluginAssets { + publicPath: string + js: Array + css: Array + favicon?: string +} +export interface JsBeforeAssetTagGenerationData { + assets: JsHtmlPluginAssets + outputName: string +} +export interface JsHtmlPluginAssetTags { + scripts: Array + styles: Array + meta: Array +} +export interface JsAlterAssetTagsData { + assetTags: JsHtmlPluginAssetTags + outputName: string + publicPath: string +} +export interface JsAlterAssetTagGroupsData { + headTags: Array + bodyTags: Array + publicPath: string + outputName: string +} +export interface JsAfterTemplateExecutionData { + html: string + headTags: Array + bodyTags: Array + outputName: string +} +export interface JsBeforeEmitData { + html: string + outputName: string +} +export interface JsAfterEmitData { + outputName: string +} +export interface JsFactoryMeta { + sideEffectFree?: boolean } export interface JsModule { context?: string @@ -175,11 +207,15 @@ export interface JsModule { resource?: string moduleIdentifier: string nameForCondition?: string + request?: string + userRequest?: string + rawRequest?: string + factoryMeta?: JsFactoryMeta + type: string + layer?: string } export interface JsExecuteModuleArg { entry: string - request: string - options: JsBuildTimeExecutionOption runtimeModules: Array codegenResults: JsCodegenerationResults id: number @@ -194,57 +230,205 @@ export interface JsRuntimeModuleArg { module: JsRuntimeModule chunk: JsChunk } -export interface JsResolveForSchemeInput { +export interface JsResolveForSchemeArgs { resourceData: JsResourceData scheme: string } -export interface JsResolveForSchemeResult { - resourceData: JsResourceData - stop: boolean +export interface JsBeforeResolveArgs { + request: string + context: string + issuer: string } -export interface BeforeResolveData { +export interface JsFactorizeArgs { request: string context: string + issuer: string } -export interface AfterResolveData { +export interface JsResolveArgs { request: string context: string + issuer: string +} +export interface JsCreateData { + request: string + userRequest: string + resource: string +} +export interface JsAfterResolveData { + request: string + context: string + issuer: string fileDependencies: Array contextDependencies: Array missingDependencies: Array - factoryMeta: FactoryMeta + createData?: JsCreateData } -export interface CreateModuleData { +export interface JsNormalModuleFactoryCreateModuleArgs { dependencyType: string - resolveDataRequest: string + rawRequest: string resourceResolveData: JsResourceData context: string + matchResource?: string } -export interface FactoryMeta { - sideEffectFree?: boolean +export interface JsEntryPluginOptions { + context: string + entry: string + options: JsEntryOptions } -export interface JsResourceData { - /** Resource with absolute path, query and fragment */ - resource: string - /** Absolute resource path only */ +export interface JsEntryOptions { + name?: string + runtime?: false | string + chunkLoading?: string + asyncChunks?: boolean + publicPath?: "auto" | JsFilename + baseUri?: string + filename?: JsFilename + library?: JsLibraryOptions + dependOn?: Array + layer?: string +} +export interface JsLibraryCustomUmdObject { + amd?: string + commonjs?: string + root?: Array +} +export interface JsLibraryName { + type: "string" | "array" | "umdObject" + stringPayload?: string + arrayPayload?: Array + umdObjectPayload?: JsLibraryCustomUmdObject +} +export interface JsLibraryAuxiliaryComment { + root?: string + commonjs?: string + commonjs2?: string + amd?: string +} +export interface JsLibraryOptions { + name?: JsLibraryName + export?: Array + libraryType: string + umdNamedDefine?: boolean + auxiliaryComment?: JsLibraryAuxiliaryComment + amdContainer?: string +} +export interface RawAliasOptionItem { path: string - /** Resource query with `?` prefix */ - query?: string - /** Resource fragment with `#` prefix */ - fragment?: string + redirect: Array +} +export interface RawResolveTsconfigOptions { + configFile: string + referencesType: "auto" | "manual" | "disabled" + references?: Array +} +export interface RawResolveOptions { + preferRelative?: boolean + preferAbsolute?: boolean + extensions?: Array + mainFiles?: Array + mainFields?: Array + conditionNames?: Array + alias?: Array + fallback?: Array + symlinks?: boolean + tsconfig?: RawResolveTsconfigOptions + modules?: Array + byDependency?: Record + fullySpecified?: boolean + exportsFields?: Array + descriptionFiles?: Array + enforceExtension?: boolean + importsFields?: Array + extensionAlias?: Record> + aliasFields?: Array + restrictions?: Array + roots?: Array } -export interface PathData { +export interface RawResolveOptionsWithDependencyType { + preferRelative?: boolean + preferAbsolute?: boolean + extensions?: Array + mainFiles?: Array + mainFields?: Array + conditionNames?: Array + alias?: Array + fallback?: Array + symlinks?: boolean + tsconfig?: RawResolveTsconfigOptions + modules?: Array + byDependency?: Record + fullySpecified?: boolean + exportsFields?: Array + descriptionFiles?: Array + enforceExtension?: boolean + importsFields?: Array + extensionAlias?: Record> + aliasFields?: Array + restrictions?: Array + roots?: Array + dependencyCategory?: string + resolveToContext?: boolean +} +export interface JsPathData { filename?: string hash?: string contentHash?: string runtime?: string url?: string id?: string + chunk?: JsChunkPathData +} +export interface JsChunkPathData { + id?: string + name?: string + hash?: string + contentHash?: string | Record } export interface PathWithInfo { path: string info: JsAssetInfo } +export interface RawRegex { + source: string + flags: string +} +export interface JsResourceData { + /** Resource with absolute path, query and fragment */ + resource: string + /** Absolute resource path only */ + path?: string + /** Resource query with `?` prefix */ + query?: string + /** Resource fragment with `#` prefix */ + fragment?: string +} +export interface JsDiagnostic { + severity: JsRspackSeverity + error: JsRspackError +} +export const enum JsRspackSeverity { + Error = 'Error', + Warn = 'Warn' +} +export interface JsRspackError { + name: string + message: string + moduleIdentifier?: string + loc?: string + file?: string + stack?: string + hideStack?: boolean +} +export interface JsAdditionalTreeRuntimeRequirementsArg { + chunk: JsChunk + runtimeRequirements: JsRuntimeGlobals +} +export interface JsRuntimeGlobals { + value: Array +} +export interface JsAdditionalTreeRuntimeRequirementsResult { + runtimeRequirements: JsRuntimeGlobals +} export interface JsCompatSource { /** Whether the underlying data structure is a `RawSource` */ isRaw: boolean @@ -253,19 +437,42 @@ export interface JsCompatSource { source: Buffer map?: Buffer } +export interface JsModuleDescriptor { + identifier: string + name: string + id?: string +} export interface JsStatsError { + moduleDescriptor?: JsModuleDescriptor message: string - formatted: string - moduleIdentifier?: string - moduleName?: string - moduleId?: string + chunkName?: string + chunkEntry?: boolean + chunkInitial?: boolean + loc?: string + file?: string + chunkId?: string + details?: string + stack?: string + moduleTrace: Array } export interface JsStatsWarning { + moduleDescriptor?: JsModuleDescriptor message: string - formatted: string - moduleIdentifier?: string - moduleName?: string - moduleId?: string + chunkName?: string + chunkEntry?: boolean + chunkInitial?: boolean + file?: string + chunkId?: string + details?: string + stack?: string + moduleTrace: Array +} +export interface JsStatsModuleTrace { + origin: JsStatsModuleTraceModule + module: JsStatsModuleTraceModule +} +export interface JsStatsModuleTraceModule { + moduleDescriptor: JsModuleDescriptor } export interface JsStatsLogging { name: string @@ -276,39 +483,72 @@ export interface JsStatsLogging { export interface JsStatsAsset { type: string name: string - size: number - chunks: Array - chunkNames: Array info: JsStatsAssetInfo + size: number emitted: boolean + chunkNames: Array + chunkIdHints: Array + chunks: Array + auxiliaryChunkNames: Array + auxiliaryChunkIdHints: Array + auxiliaryChunks: Array } export interface JsStatsAssetInfo { + minimized: boolean development: boolean hotModuleReplacement: boolean sourceFilename?: string + immutable: boolean + javascriptModule?: boolean + chunkhash: Array + contenthash: Array + fullhash: Array + related: Array + isOverSizeLimit?: boolean } -export interface JsStatsModule { +export interface JsStatsAssetInfoRelated { + name: string + value: Array +} +export interface JsStatsModuleCommonAttributes { type: string moduleType: string - identifier: string - name: string - id?: string - chunks: Array + layer?: string size: number - issuer?: string - issuerName?: string - issuerId?: string - issuerPath: Array + sizes: Array + built: boolean + codeGenerated: boolean + buildTimeExecuted: boolean + cached: boolean + moduleDescriptor?: JsModuleDescriptor nameForCondition?: string - reasons?: Array + preOrderIndex?: number + postOrderIndex?: number + cacheable?: boolean + optional?: boolean + orphan?: boolean + failed?: boolean + errors?: number + warnings?: number + profile?: JsStatsModuleProfile + chunks?: Array assets?: Array + reasons?: Array + providedExports?: Array + optimizationBailout?: Array + depth?: number source?: string | Buffer - profile?: JsStatsModuleProfile - orphan: boolean +} +export interface JsStatsModule { + commonAttributes: JsStatsModuleCommonAttributes + dependent?: boolean + issuerDescriptor?: JsModuleDescriptor + issuerPath?: Array + usedExports?: string | Array + modules?: Array } export interface JsStatsModuleProfile { factory: JsStatsMillisecond - integration: JsStatsMillisecond building: JsStatsMillisecond } export interface JsStatsMillisecond { @@ -316,30 +556,45 @@ export interface JsStatsMillisecond { subsecMillis: number } export interface JsStatsModuleIssuer { - identifier: string - name: string - id?: string + moduleDescriptor: JsModuleDescriptor } export interface JsStatsModuleReason { - moduleIdentifier?: string - moduleName?: string - moduleId?: string + moduleDescriptor?: JsModuleDescriptor + resolvedModuleDescriptor?: JsModuleDescriptor + moduleChunks?: number type?: string userRequest?: string } +export interface JsOriginRecord { + moduleDescriptor?: JsModuleDescriptor + loc: string + request: string +} +export interface JsStatsSize { + sourceType: string + size: number +} export interface JsStatsChunk { type: string files: Array auxiliaryFiles: Array id?: string + idHints: Array + hash?: string entry: boolean initial: boolean names: Array size: number - modules?: Array parents?: Array children?: Array siblings?: Array + childrenByOrder: Record> + runtime: Array + reason?: string + rendered: boolean + sizes: Array + origins: Array + modules?: Array } export interface JsStatsChunkGroupAsset { name: string @@ -347,18 +602,69 @@ export interface JsStatsChunkGroupAsset { } export interface JsStatsChunkGroup { name: string + chunks: Array assets: Array - chunks: Array assetsSize: number + auxiliaryAssets?: Array + auxiliaryAssetsSize?: number + isOverSizeLimit?: boolean + children?: JsStatsChunkGroupChildren + childAssets?: JsStatsChildGroupChildAssets +} +export interface JsStatsChildGroupChildAssets { + preload?: Array + prefetch?: Array +} +export interface JsStatsChunkGroupChildren { + preload?: Array + prefetch?: Array +} +export interface JsStatsOptimizationBailout { + inner: string } export interface JsStatsAssetsByChunkName { name: string files: Array } +export interface JsStatsOptions { + assets: boolean + cachedModules: boolean + chunks: boolean + chunkGroupAuxiliary: boolean + chunkGroupChildren: boolean + chunkGroups: boolean + chunkModules: boolean + chunkRelations: boolean + depth: boolean + entrypoints: boolean | string + errors: boolean + hash: boolean + ids: boolean + modules: boolean + moduleAssets: boolean + nestedModules: boolean + optimizationBailout: boolean + providedExports: boolean + reasons: boolean + source: boolean + usedExports: boolean + warnings: boolean +} export interface JsStatsGetAssets { assets: Array assetsByChunkName: Array } +export interface JsStatsCompilation { + assets?: Array + assetsByChunkName?: Array + chunks?: Array + entrypoints?: Array + errors: Array + hash?: string + modules?: Array + namedChunkGroups?: Array + warnings: Array +} export interface RawBannerContentFnCtx { hash: string chunk: JsChunk @@ -369,17 +675,23 @@ export interface RawBannerPluginOptions { entryOnly?: boolean footer?: boolean raw?: boolean + stage?: number test?: string | RegExp | (string | RegExp)[] include?: string | RegExp | (string | RegExp)[] exclude?: string | RegExp | (string | RegExp)[] } export interface RawBundlerInfoPluginOptions { version: string + bundler: string force: boolean | string[] } +export interface RawToOptions { + context: string + absoluteFilename: string +} export interface RawCopyPattern { from: string - to?: string + to?: string | ((pathData: { context: string; absoluteFilename?: string }) => string | Promise) context?: string toType?: string noErrorOnMissing: boolean @@ -387,6 +699,7 @@ export interface RawCopyPattern { priority: number globOptions: RawCopyGlobOptions info?: RawInfo + transform?: (input: Buffer, absoluteFilename: string) => string | Buffer | Promise | Promise } export interface RawInfo { immutable?: boolean @@ -409,27 +722,106 @@ export interface RawCopyGlobOptions { export interface RawCopyRspackPluginOptions { patterns: Array } +export interface RawCssExtractPluginOption { + filename: JsFilename + chunkFilename: JsFilename + ignoreOrder: boolean + insert?: string + attributes: Record + linkType?: string + runtime: boolean + pathinfo: boolean +} export interface RawHtmlRspackPluginOptions { /** emitted file name in output path */ filename?: string /** template html file */ template?: string + templateFn?: (data: string) => Promise templateContent?: string - templateParameters?: Record + templateParameters?: boolean | Record | ((params: string) => Promise) /** "head", "body" or "false" */ inject: "head" | "body" | "false" /** path or `auto` */ publicPath?: string - /** `blocking`, `defer`, or `module` */ - scriptLoading: "blocking" | "defer" | "module" + /** `blocking`, `defer`, `module` or `systemjs-module` */ + scriptLoading: "blocking" | "defer" | "module" | "systemjs-module" /** entry_chunk_name (only entry chunks are supported) */ chunks?: Array - excludedChunks?: Array + excludeChunks?: Array sri?: "sha256" | "sha384" | "sha512" minify?: boolean title?: string favicon?: string meta?: Record> + hash?: boolean + base?: RawHtmlRspackPluginBaseOptions +} +export interface RawHtmlRspackPluginBaseOptions { + href?: string + target?: "_self" | "_blank" | "_parent" | "_top" +} +export interface RawIgnorePluginOptions { + resourceRegExp?: RegExp + contextRegExp?: RegExp + checkResource?: (resource: string, context: string) => boolean +} +export interface RawModuleInfo { + active: boolean + client: string + data: string +} +export interface RawLazyCompilationOption { + module: (err: Error | null, arg: RawModuleArg) => any + test?: RawLazyCompilationTest + entries: boolean + imports: boolean + cacheable: boolean +} +export interface RawModuleArg { + module: string + path: string +} +export interface RawLightningCssMinimizerRspackPluginOptions { + test?: string | RegExp | (string | RegExp)[] + include?: string | RegExp | (string | RegExp)[] + exclude?: string | RegExp | (string | RegExp)[] + removeUnusedLocalIdents: boolean + minimizerOptions: RawLightningCssMinimizerOptions +} +export interface RawLightningCssMinimizerOptions { + errorRecovery: boolean + targets?: Array + include?: number + exclude?: number + draft?: RawDraft + nonStandard?: RawNonStandard + pseudoClasses?: RawLightningCssPseudoClasses + unusedSymbols: Array +} +export interface RawLightningCssBrowsers { + android?: number + chrome?: number + edge?: number + firefox?: number + ie?: number + ios_saf?: number + opera?: number + safari?: number + samsung?: number +} +export interface RawDraft { + customMedia: boolean +} +export interface RawNonStandard { + deepSelectorCombinator: boolean +} +export interface RawLightningCssPseudoClasses { + hover?: string + active?: string + focus?: string + focusVisible?: string + focusWithin?: string } export interface RawLimitChunkCountPluginOptions { chunkOverhead?: number @@ -439,8 +831,8 @@ export interface RawLimitChunkCountPluginOptions { export interface RawContainerPluginOptions { name: string shareScope: string - library: RawLibraryOptions - runtime?: string + library: JsLibraryOptions + runtime?: false | string filename?: string exposes: Array enhanced: boolean @@ -467,6 +859,9 @@ export interface RawProvideOptions { shareScope: string version?: string | false | undefined eager: boolean + singleton?: boolean + requiredVersion?: string | false | undefined + strictVersion?: boolean } export interface RawConsumeSharedPluginOptions { consumes: Array @@ -487,77 +882,55 @@ export interface RawConsumeOptions { export interface RawProgressPluginOptions { prefix: string profile: boolean + template: string + tick?: string | Array + progressChars: string +} +export interface RawRuntimeChunkOptions { + name: string | ((entrypoint: { name: string }) => string) +} +export interface RawRuntimeChunkNameFnCtx { + name: string +} +export interface RawSizeLimitsPluginOptions { + assetFilter?: (assetFilename: string) => boolean + hints?: "error" | "warning" + maxAssetSize?: number + maxEntrypointSize?: number } export interface RawExtractComments { banner?: string | boolean condition?: string } export interface RawSwcJsMinimizerRspackPluginOptions { - extractComments?: RawExtractComments - compress: boolean | string - mangle: boolean | string - format: string - module?: boolean test?: string | RegExp | (string | RegExp)[] include?: string | RegExp | (string | RegExp)[] exclude?: string | RegExp | (string | RegExp)[] + extractComments?: RawExtractComments + minimizerOptions: RawSwcJsMinimizerOptions } -export interface RawStyleConfig { - styleLibraryDirectory?: string - custom?: string - css?: string - bool?: boolean -} -export interface RawPluginImportConfig { - libraryName: string - libraryDirectory?: string - customName?: string - customStyleName?: string - style?: RawStyleConfig - camelToDashComponentName?: boolean - transformToDefaultImport?: boolean - ignoreEsComponent?: Array - ignoreStyleComponent?: Array -} -export interface RawReactOptions { - runtime?: "automatic" | "classic" - importSource?: string - pragma?: string - pragmaFrag?: string - throwIfNamespace?: boolean - development?: boolean - useBuiltins?: boolean - useSpread?: boolean - refresh?: boolean -} -export interface RawRelayConfig { - artifactDirectory?: string - language: 'javascript' | 'typescript' | 'flow' -} -export interface RawCssPluginConfig { - modules: RawCssModulesConfig -} -export interface RawCssModulesConfig { - localsConvention: "asIs" | "camelCase" | "camelCaseOnly" | "dashes" | "dashesOnly" - localIdentName: string - exportsOnly: boolean -} -export interface RawBuiltins { - css?: RawCssPluginConfig - treeShaking: string +export interface RawSwcJsMinimizerOptions { + compress: any + mangle: any + format: any + module?: boolean + minify?: boolean } export const enum BuiltinPluginName { DefinePlugin = 'DefinePlugin', ProvidePlugin = 'ProvidePlugin', BannerPlugin = 'BannerPlugin', + IgnorePlugin = 'IgnorePlugin', ProgressPlugin = 'ProgressPlugin', EntryPlugin = 'EntryPlugin', + DynamicEntryPlugin = 'DynamicEntryPlugin', ExternalsPlugin = 'ExternalsPlugin', NodeTargetPlugin = 'NodeTargetPlugin', ElectronTargetPlugin = 'ElectronTargetPlugin', EnableChunkLoadingPlugin = 'EnableChunkLoadingPlugin', EnableLibraryPlugin = 'EnableLibraryPlugin', EnableWasmLoadingPlugin = 'EnableWasmLoadingPlugin', + FetchCompileAsyncWasmPlugin = 'FetchCompileAsyncWasmPlugin', ChunkPrefetchPreloadPlugin = 'ChunkPrefetchPreloadPlugin', CommonJsChunkFormatPlugin = 'CommonJsChunkFormatPlugin', ArrayPushCallbackChunkFormatPlugin = 'ArrayPushCallbackChunkFormatPlugin', @@ -573,8 +946,11 @@ export const enum BuiltinPluginName { ContainerReferencePlugin = 'ContainerReferencePlugin', ProvideSharedPlugin = 'ProvideSharedPlugin', ConsumeSharedPlugin = 'ConsumeSharedPlugin', + ModuleFederationRuntimePlugin = 'ModuleFederationRuntimePlugin', NamedModuleIdsPlugin = 'NamedModuleIdsPlugin', + NaturalModuleIdsPlugin = 'NaturalModuleIdsPlugin', DeterministicModuleIdsPlugin = 'DeterministicModuleIdsPlugin', + NaturalChunkIdsPlugin = 'NaturalChunkIdsPlugin', NamedChunkIdsPlugin = 'NamedChunkIdsPlugin', DeterministicChunkIdsPlugin = 'DeterministicChunkIdsPlugin', RealContentHashPlugin = 'RealContentHashPlugin', @@ -597,12 +973,20 @@ export const enum BuiltinPluginName { FlagDependencyUsagePlugin = 'FlagDependencyUsagePlugin', MangleExportsPlugin = 'MangleExportsPlugin', ModuleConcatenationPlugin = 'ModuleConcatenationPlugin', + CssModulesPlugin = 'CssModulesPlugin', + APIPlugin = 'APIPlugin', + RuntimeChunkPlugin = 'RuntimeChunkPlugin', + SizeLimitsPlugin = 'SizeLimitsPlugin', + NoEmitOnErrorsPlugin = 'NoEmitOnErrorsPlugin', HttpExternalsRspackPlugin = 'HttpExternalsRspackPlugin', CopyRspackPlugin = 'CopyRspackPlugin', HtmlRspackPlugin = 'HtmlRspackPlugin', SwcJsMinimizerRspackPlugin = 'SwcJsMinimizerRspackPlugin', - SwcCssMinimizerRspackPlugin = 'SwcCssMinimizerRspackPlugin', - BundlerInfoPlugin = 'BundlerInfoPlugin' + LightningCssMinimizerRspackPlugin = 'LightningCssMinimizerRspackPlugin', + BundlerInfoRspackPlugin = 'BundlerInfoRspackPlugin', + CssExtractRspackPlugin = 'CssExtractRspackPlugin', + JsLoaderRspackPlugin = 'JsLoaderRspackPlugin', + LazyCompilationPlugin = 'LazyCompilationPlugin' } export interface BuiltinPlugin { name: BuiltinPluginName @@ -620,6 +1004,11 @@ export interface RawCacheOptions { name: string version: string } +export interface RawPathData { + filename?: string + contentHash?: string + url?: string +} export interface RawModuleFilenameTemplateFnCtx { identifier: string shortIdentifier: string @@ -652,26 +1041,19 @@ export interface RawEvalDevToolModulePluginOptions { moduleFilenameTemplate?: string | ((info: RawModuleFilenameTemplateFnCtx) => string) sourceUrlComment?: string } -export interface RawEntryPluginOptions { - context: string - entry: string - options: RawEntryOptions +export interface RawEntryDynamicResult { + import: Array + options: JsEntryOptions } -export interface RawEntryOptions { - name?: string - runtime?: string - chunkLoading?: string - asyncChunks?: boolean - publicPath?: string - baseUri?: string - filename?: string - library?: RawLibraryOptions +export interface RawDynamicEntryPluginOptions { + context: string + entry: () => Promise } export interface RawRspackFuture { - newTreeshaking: boolean + newIncremental: boolean } export interface RawExperiments { - newSplitChunks: boolean + layers: boolean topLevelAwait: boolean rspackFuture: RawRspackFuture } @@ -687,10 +1069,14 @@ export interface RawExternalItemFnResult { externalType?: string result?: string | boolean | string[] | Record } +export interface ContextInfo { + issuer: string +} export interface RawExternalItemFnCtx { request: string context: string dependencyType: string + contextInfo: ContextInfo } export interface RawExternalsPresets { node: boolean @@ -700,48 +1086,6 @@ export interface RawExternalsPresets { electronPreload: boolean electronRenderer: boolean } -export interface JsLoaderContext { - /** Content maybe empty in pitching stage */ - content?: Buffer - additionalData?: Buffer - sourceMap?: Buffer - resource: string - resourcePath: string - resourceQuery?: string - resourceFragment?: string - cacheable: boolean - fileDependencies: Array - contextDependencies: Array - missingDependencies: Array - buildDependencies: Array - assetFilenames: Array - currentLoader: string - isPitching: boolean - /** - * Loader index from JS. - * If loaders are dispatched by JS loader runner, - * then, this field is correspondence with loader index in JS side. - * It is useful when loader dispatched on JS side has an builtin loader, for example: builtin:swc-loader, - * Then this field will be used as an hack to test whether it should return an AST or string. - */ - loaderIndexFromJs?: number - /** - * Internal additional data, contains more than `String` - * @internal - */ - additionalDataExternal: ExternalObject<'AdditionalData'> - /** - * Internal loader context - * @internal - */ - contextExternal: ExternalObject<'LoaderRunnerContext'> - /** - * Internal loader diagnostic - * @internal - */ - diagnosticsExternal: ExternalObject<'Diagnostic[]'> - _moduleIdentifier: string -} /** * `loader` is for both JS and Rust loaders. * `options` is @@ -755,22 +1099,20 @@ export interface RawModuleRuleUse { loader: string options?: string } -export interface RawModuleRuleUses { - type: "array" | "function" - arrayUse?: Array - funcUse?: (...args: any[]) => any -} -export interface RawRegexMatcher { - source: string - flags: string -} export interface RawRuleSetCondition { - type: "string" | "regexp" | "logical" | "array" | "function" - stringMatcher?: string - regexpMatcher?: RawRegexMatcher - logicalMatcher?: Array - arrayMatcher?: Array - funcMatcher?: (value: string) => boolean + type: RawRuleSetConditionType + string?: string + regexp?: RawRegex + logical?: Array + array?: Array + func?: (value: string) => boolean +} +export const enum RawRuleSetConditionType { + string = 'string', + regexp = 'regexp', + logical = 'logical', + array = 'array', + func = 'func' } export interface RawRuleSetLogicalConditions { and?: Array @@ -795,13 +1137,16 @@ export interface RawModuleRule { resourceQuery?: RawRuleSetCondition resourceFragment?: RawRuleSetCondition descriptionData?: Record + with?: Record sideEffects?: boolean - use?: RawModuleRuleUses + use?: RawModuleRuleUse[] | ((arg: RawFuncUseCtx) => RawModuleRuleUse[]) type?: string + layer?: string parser?: RawParserOptions generator?: RawGeneratorOptions resolve?: RawResolveOptions issuer?: RawRuleSetCondition + issuerLayer?: RawRuleSetCondition dependency?: RawRuleSetCondition scheme?: RawRuleSetCondition mimetype?: RawRuleSetCondition @@ -811,15 +1156,28 @@ export interface RawModuleRule { enforce?: 'pre' | 'post' } export interface RawParserOptions { - type: "asset" | "javascript" | "unknown" + type: "asset" | "css" | "css/auto" | "css/module" | "javascript" | "javascript/auto" | "javascript/dynamic" | "javascript/esm" asset?: RawAssetParserOptions + css?: RawCssParserOptions + cssAuto?: RawCssAutoParserOptions + cssModule?: RawCssModuleParserOptions javascript?: RawJavascriptParserOptions } export interface RawJavascriptParserOptions { dynamicImportMode: string dynamicImportPreload: string dynamicImportPrefetch: string + dynamicImportFetchPriority?: string url: string + exprContextCritical: boolean + wrappedContextCritical: boolean + exportsPresence?: string + importExportsPresence?: string + reexportExportsPresence?: string + strictExportPresence: boolean + worker: Array + overrideStrict?: string + importMeta: boolean } export interface RawAssetParserOptions { dataUrlCondition?: RawAssetParserDataUrl @@ -831,36 +1189,67 @@ export interface RawAssetParserDataUrl { export interface RawAssetParserDataUrlOptions { maxSize?: number } +export interface RawCssParserOptions { + namedExports?: boolean +} +export interface RawCssAutoParserOptions { + namedExports?: boolean +} +export interface RawCssModuleParserOptions { + namedExports?: boolean +} export interface RawGeneratorOptions { - type: "asset" | "asset/inline" | "asset/resource" | "unknown" + type: "asset" | "asset/inline" | "asset/resource" | "css" | "css/auto" | "css/module" asset?: RawAssetGeneratorOptions assetInline?: RawAssetInlineGeneratorOptions assetResource?: RawAssetResourceGeneratorOptions + css?: RawCssGeneratorOptions + cssAuto?: RawCssAutoGeneratorOptions + cssModule?: RawCssModuleGeneratorOptions } export interface RawAssetGeneratorOptions { - filename?: string - publicPath?: string - dataUrl?: RawAssetGeneratorDataUrl + emit?: boolean + filename?: JsFilename + publicPath?: "auto" | JsFilename + dataUrl?: RawAssetGeneratorDataUrlOptions | ((arg: RawAssetGeneratorDataUrlFnArgs) => string) } export interface RawAssetInlineGeneratorOptions { - dataUrl?: RawAssetGeneratorDataUrl + dataUrl?: RawAssetGeneratorDataUrlOptions | ((arg: RawAssetGeneratorDataUrlFnArgs) => string) } export interface RawAssetResourceGeneratorOptions { - filename?: string - publicPath?: string + emit?: boolean + filename?: JsFilename + publicPath?: "auto" | JsFilename } -export interface RawAssetGeneratorDataUrl { - type: "options" - options?: RawAssetGeneratorDataUrlOptions +export interface RawAssetGeneratorDataUrlFnArgs { + filename: string + content: string } export interface RawAssetGeneratorDataUrlOptions { encoding?: "base64" | "false" | undefined mimetype?: string } +export interface RawCssGeneratorOptions { + exportsOnly?: boolean + esModule?: boolean +} +export interface RawCssAutoGeneratorOptions { + exportsConvention?: "as-is" | "camel-case" | "camel-case-only" | "dashes" | "dashes-only" + exportsOnly?: boolean + localIdentName?: string + esModule?: boolean +} +export interface RawCssModuleGeneratorOptions { + exportsConvention?: "as-is" | "camel-case" | "camel-case-only" | "dashes" | "dashes-only" + exportsOnly?: boolean + localIdentName?: string + esModule?: boolean +} export interface RawModuleOptions { rules: Array parser?: Record generator?: Record + noParse?: string | RegExp | ((request: string) => boolean) | (string | RegExp | ((request: string) => boolean))[] } export interface RawFuncUseCtx { resource?: string @@ -885,62 +1274,46 @@ export interface RawOptimizationOptions { export interface RawTrustedTypes { policyName?: string } -export interface RawLibraryName { - type: "string" | "array" | "umdObject" - stringPayload?: string - arrayPayload?: Array - umdObjectPayload?: RawLibraryCustomUmdObject -} -export interface RawLibraryCustomUmdObject { - amd?: string - commonjs?: string - root?: Array -} -export interface RawLibraryAuxiliaryComment { - root?: string - commonjs?: string - commonjs2?: string - amd?: string -} -export interface RawLibraryOptions { - name?: RawLibraryName - export?: Array - libraryType: string - umdNamedDefine?: boolean - auxiliaryComment?: RawLibraryAuxiliaryComment - amdContainer?: string -} export interface RawCrossOriginLoading { type: "bool" | "string" stringPayload?: string boolPayload?: boolean } +export interface RawEnvironment { + const?: boolean + arrowFunction?: boolean +} export interface RawOutputOptions { path: string + pathinfo: boolean | "verbose" clean: boolean - publicPath: string - assetModuleFilename: string + publicPath: "auto" | JsFilename + assetModuleFilename: JsFilename wasmLoading: string enabledWasmLoadingTypes: Array webassemblyModuleFilename: string - filename: string - chunkFilename: string + filename: JsFilename + chunkFilename: JsFilename crossOriginLoading: RawCrossOriginLoading - cssFilename: string - cssChunkFilename: string + cssFilename: JsFilename + cssChunkFilename: JsFilename + cssHeadDataCompression: boolean hotUpdateMainFilename: string hotUpdateChunkFilename: string hotUpdateGlobal: string uniqueName: string chunkLoadingGlobal: string - library?: RawLibraryOptions + library?: JsLibraryOptions strictModuleErrorHandling: boolean enabledLibraryTypes?: Array globalObject: string importFunctionName: string + importMetaName: string iife: boolean module: boolean chunkLoading: string + chunkLoadTimeout: number + charset: boolean enabledChunkLoadingTypes?: Array trustedTypes?: RawTrustedTypes sourceMapFilename: string @@ -953,45 +1326,21 @@ export interface RawOutputOptions { workerWasmLoading: string workerPublicPath: string scriptType: "module" | "text/javascript" | "false" -} -export interface RawResolveTsconfigOptions { - configFile: string - referencesType: "auto" | "manual" | "disabled" - references?: Array -} -export interface RawResolveOptions { - preferRelative?: boolean - preferAbsolute?: boolean - extensions?: Array - mainFiles?: Array - mainFields?: Array - conditionNames?: Array - alias?: Record> - fallback?: Record> - symlinks?: boolean - tsconfig?: RawResolveTsconfigOptions - modules?: Array - byDependency?: Record - fullySpecified?: boolean - exportsFields?: Array - extensionAlias?: Record> - aliasFields?: Array - restrictions?: Array - roots?: Array -} -export interface RawSnapshotStrategy { - hash: boolean - timestamp: boolean + environment: RawEnvironment } export interface RawSnapshotOptions { - resolve: RawSnapshotStrategy - module: RawSnapshotStrategy + } -export interface RawCacheGroupTestCtx { - module: JsModule +export interface JsCacheGroupTestCtx { + module: ModuleDTO } export interface RawChunkOptionNameCtx { module: JsModule + chunks: Array + cacheGroupKey: string +} +export interface RawSplitChunkSizes { + sizes: Record } export interface RawSplitChunksOptions { fallbackCacheGroup?: RawFallbackCacheGroupOptions @@ -999,17 +1348,19 @@ export interface RawSplitChunksOptions { cacheGroups?: Array /** What kind of chunks should be selected. */ chunks?: RegExp | 'async' | 'initial' | 'all' | Function + usedExports?: boolean automaticNameDelimiter?: string maxAsyncRequests?: number maxInitialRequests?: number + defaultSizeTypes: Array minChunks?: number hidePathInfo?: boolean - minSize?: number + minSize?: number | RawSplitChunkSizes enforceSizeThreshold?: number - minRemainingSize?: number - maxSize?: number - maxAsyncSize?: number - maxInitialSize?: number + minRemainingSize?: number | RawSplitChunkSizes + maxSize?: number | RawSplitChunkSizes + maxAsyncSize?: number | RawSplitChunkSizes + maxInitialSize?: number | RawSplitChunkSizes } export interface RawCacheGroupOptions { key: string @@ -1020,22 +1371,26 @@ export interface RawCacheGroupOptions { /** What kind of chunks should be selected. */ chunks?: RegExp | 'async' | 'initial' | 'all' type?: RegExp | string + layer?: RegExp | string automaticNameDelimiter?: string minChunks?: number - minSize?: number - maxSize?: number - maxAsyncSize?: number - maxInitialSize?: number + minSize?: number | RawSplitChunkSizes + maxSize?: number | RawSplitChunkSizes + maxAsyncSize?: number | RawSplitChunkSizes + maxInitialSize?: number | RawSplitChunkSizes + maxAsyncRequests?: number + maxInitialRequests?: number name?: string | false | Function reuseExistingChunk?: boolean enforce?: boolean + usedExports?: boolean } export interface RawFallbackCacheGroupOptions { chunks?: RegExp | 'async' | 'initial' | 'all' - minSize?: number - maxSize?: number - maxAsyncSize?: number - maxInitialSize?: number + minSize?: number | RawSplitChunkSizes + maxSize?: number | RawSplitChunkSizes + maxAsyncSize?: number | RawSplitChunkSizes + maxInitialSize?: number | RawSplitChunkSizes automaticNameDelimiter?: string } export interface RawStatsOptions { @@ -1058,47 +1413,126 @@ export interface RawOptions { node?: RawNodeOption profile: boolean bail: boolean - builtins: RawBuiltins + __references: Record } -export interface RawStrategyOptions { - name: string - topLevelFrameworks: Array +export interface JsLoaderItem { + request: string + type: string + data: any + normalExecuted: boolean + pitchExecuted: boolean } -export interface RawFeatures { - splitChunksStrategy?: RawStrategyOptions - assetsManifest?: boolean +export const enum JsLoaderState { + Pitching = 'Pitching', + Normal = 'Normal' } -export interface RspackRawOptimizationOptions { - removeAvailableModules: boolean - sideEffects: string - usedExports: string - providedExports: boolean - innerGraph: boolean - mangleExports: string - concatenateModules: boolean +export interface JsLoaderContext { + resourceData: Readonly + /** Will be deprecated. Use module.module_identifier instead */ + _moduleIdentifier: Readonly + _module: JsModule + hot: Readonly + /** Content maybe empty in pitching stage */ + content: null | Buffer + additionalData?: any + sourceMap?: Buffer + cacheable: boolean + fileDependencies: Array + contextDependencies: Array + missingDependencies: Array + buildDependencies: Array + loaderItems: Array + loaderIndex: number + loaderState: Readonly } -export interface RsPackRawOptions { - mode?: undefined | 'production' | 'development' | 'none' - target: Array - context: string - output: RawOutputOptions - resolve: RawResolveOptions - resolveLoader: RawResolveOptions - module: RawModuleOptions - devtool: string - optimization: RspackRawOptimizationOptions - stats: RawStatsOptions - snapshot: RawSnapshotOptions - cache: RawCacheOptions - experiments: RawExperiments - node?: RawNodeOption - profile: boolean - bail: boolean - builtins: RawBuiltins - features: RawFeatures +export interface JsTap { + function: (...args: any[]) => any + stage: number +} +export const enum RegisterJsTapKind { + CompilerThisCompilation = 0, + CompilerCompilation = 1, + CompilerMake = 2, + CompilerFinishMake = 3, + CompilerShouldEmit = 4, + CompilerEmit = 5, + CompilerAfterEmit = 6, + CompilerAssetEmitted = 7, + CompilationBuildModule = 8, + CompilationStillValidModule = 9, + CompilationSucceedModule = 10, + CompilationExecuteModule = 11, + CompilationFinishModules = 12, + CompilationOptimizeModules = 13, + CompilationAfterOptimizeModules = 14, + CompilationOptimizeTree = 15, + CompilationOptimizeChunkModules = 16, + CompilationAdditionalTreeRuntimeRequirements = 17, + CompilationRuntimeModule = 18, + CompilationChunkHash = 19, + CompilationChunkAsset = 20, + CompilationProcessAssets = 21, + CompilationAfterProcessAssets = 22, + CompilationSeal = 23, + CompilationAfterSeal = 24, + NormalModuleFactoryBeforeResolve = 25, + NormalModuleFactoryFactorize = 26, + NormalModuleFactoryResolve = 27, + NormalModuleFactoryAfterResolve = 28, + NormalModuleFactoryCreateModule = 29, + NormalModuleFactoryResolveForScheme = 30, + ContextModuleFactoryBeforeResolve = 31, + ContextModuleFactoryAfterResolve = 32, + JavascriptModulesChunkHash = 33, + HtmlPluginBeforeAssetTagGeneration = 34, + HtmlPluginAlterAssetTags = 35, + HtmlPluginAlterAssetTagGroups = 36, + HtmlPluginAfterTemplateExecution = 37, + HtmlPluginBeforeEmit = 38, + HtmlPluginAfterEmit = 39 +} +export interface RegisterJsTaps { + registerCompilerThisCompilationTaps: (stages: Array) => Array<{ function: ((arg: JsCompilation) => void); stage: number; }> + registerCompilerCompilationTaps: (stages: Array) => Array<{ function: ((arg: JsCompilation) => void); stage: number; }> + registerCompilerMakeTaps: (stages: Array) => Array<{ function: ((arg: JsCompilation) => Promise); stage: number; }> + registerCompilerFinishMakeTaps: (stages: Array) => Array<{ function: ((arg: JsCompilation) => void); stage: number; }> + registerCompilerShouldEmitTaps: (stages: Array) => Array<{ function: ((arg: JsCompilation) => boolean | undefined); stage: number; }> + registerCompilerEmitTaps: (stages: Array) => Array<{ function: (() => Promise); stage: number; }> + registerCompilerAfterEmitTaps: (stages: Array) => Array<{ function: (() => Promise); stage: number; }> + registerCompilerAssetEmittedTaps: (stages: Array) => Array<{ function: ((arg: JsAssetEmittedArgs) => Promise); stage: number; }> + registerCompilationBuildModuleTaps: (stages: Array) => Array<{ function: ((arg: JsModule) => void); stage: number; }> + registerCompilationStillValidModuleTaps: (stages: Array) => Array<{ function: ((arg: JsModule) => void); stage: number; }> + registerCompilationSucceedModuleTaps: (stages: Array) => Array<{ function: ((arg: JsModule) => void); stage: number; }> + registerCompilationExecuteModuleTaps: (stages: Array) => Array<{ function: ((arg: JsExecuteModuleArg) => void); stage: number; }> + registerCompilationAdditionalTreeRuntimeRequirements: (stages: Array) => Array<{ function: ((arg: JsAdditionalTreeRuntimeRequirementsArg) => JsAdditionalTreeRuntimeRequirementsResult | undefined); stage: number; }> + registerCompilationRuntimeModuleTaps: (stages: Array) => Array<{ function: ((arg: JsRuntimeModuleArg) => JsRuntimeModule | undefined); stage: number; }> + registerCompilationFinishModulesTaps: (stages: Array) => Array<{ function: ((arg: JsCompilation) => Promise); stage: number; }> + registerCompilationOptimizeModulesTaps: (stages: Array) => Array<{ function: (() => boolean | undefined); stage: number; }> + registerCompilationAfterOptimizeModulesTaps: (stages: Array) => Array<{ function: (() => void); stage: number; }> + registerCompilationOptimizeTreeTaps: (stages: Array) => Array<{ function: (() => Promise); stage: number; }> + registerCompilationOptimizeChunkModulesTaps: (stages: Array) => Array<{ function: (() => Promise); stage: number; }> + registerCompilationChunkHashTaps: (stages: Array) => Array<{ function: ((arg: JsChunk) => Buffer); stage: number; }> + registerCompilationChunkAssetTaps: (stages: Array) => Array<{ function: ((arg: JsChunkAssetArgs) => void); stage: number; }> + registerCompilationProcessAssetsTaps: (stages: Array) => Array<{ function: ((arg: JsCompilation) => Promise); stage: number; }> + registerCompilationAfterProcessAssetsTaps: (stages: Array) => Array<{ function: ((arg: JsCompilation) => void); stage: number; }> + registerCompilationSealTaps: (stages: Array) => Array<{ function: (() => void); stage: number; }> + registerCompilationAfterSealTaps: (stages: Array) => Array<{ function: (() => Promise); stage: number; }> + registerNormalModuleFactoryBeforeResolveTaps: (stages: Array) => Array<{ function: ((arg: JsBeforeResolveArgs) => Promise<[boolean | undefined, JsBeforeResolveArgs]>); stage: number; }> + registerNormalModuleFactoryFactorizeTaps: (stages: Array) => Array<{ function: ((arg: JsFactorizeArgs) => Promise); stage: number; }> + registerNormalModuleFactoryResolveTaps: (stages: Array) => Array<{ function: ((arg: JsResolveArgs) => Promise); stage: number; }> + registerNormalModuleFactoryResolveForSchemeTaps: (stages: Array) => Array<{ function: ((arg: JsResolveForSchemeArgs) => Promise<[boolean | undefined, JsResolveForSchemeArgs]>); stage: number; }> + registerNormalModuleFactoryAfterResolveTaps: (stages: Array) => Array<{ function: ((arg: JsAfterResolveData) => Promise<[boolean | undefined, JsCreateData | undefined]>); stage: number; }> + registerNormalModuleFactoryCreateModuleTaps: (stages: Array) => Array<{ function: ((arg: JsNormalModuleFactoryCreateModuleArgs) => Promise); stage: number; }> + registerContextModuleFactoryBeforeResolveTaps: (stages: Array) => Array<{ function: ((arg: false | JsContextModuleFactoryBeforeResolveData) => Promise); stage: number; }> + registerContextModuleFactoryAfterResolveTaps: (stages: Array) => Array<{ function: ((arg: false | JsContextModuleFactoryAfterResolveData) => Promise); stage: number; }> + registerJavascriptModulesChunkHashTaps: (stages: Array) => Array<{ function: ((arg: JsChunk) => Buffer); stage: number; }> + registerHtmlPluginBeforeAssetTagGenerationTaps: (stages: Array) => Array<{ function: ((arg: JsBeforeAssetTagGenerationData) => JsBeforeAssetTagGenerationData); stage: number; }> + registerHtmlPluginAlterAssetTagsTaps: (stages: Array) => Array<{ function: ((arg: JsAlterAssetTagsData) => JsAlterAssetTagsData); stage: number; }> + registerHtmlPluginAlterAssetTagGroupsTaps: (stages: Array) => Array<{ function: ((arg: JsAlterAssetTagGroupsData) => JsAlterAssetTagGroupsData); stage: number; }> + registerHtmlPluginAfterTemplateExecutionTaps: (stages: Array) => Array<{ function: ((arg: JsAfterTemplateExecutionData) => JsAfterTemplateExecutionData); stage: number; }> + registerHtmlPluginBeforeEmitTaps: (stages: Array) => Array<{ function: ((arg: JsBeforeEmitData) => JsBeforeEmitData); stage: number; }> + registerHtmlPluginAfterEmitTaps: (stages: Array) => Array<{ function: ((arg: JsAfterEmitData) => JsAfterEmitData); stage: number; }> } -/** Builtin loader runner */ -export function runBuiltinLoader(builtin: string, options: string | undefined | null, loaderContext: JsLoaderContext): Promise /** * Some code is modified based on * https://github.com/swc-project/swc/blob/d1d0607158ab40463d1b123fed52cc526eba8385/bindings/binding_core_node/src/util.rs#L29-L58 @@ -1108,89 +1542,144 @@ export function runBuiltinLoader(builtin: string, options: string | undefined | */ export function registerGlobalTrace(filter: string, layer: "chrome" | "logger", output: string): void export function cleanupGlobalTrace(): void +export type DependenciesDTO = DependenciesDto +export class DependenciesDto { + get fileDependencies(): Array + get addedFileDependencies(): Array + get removedFileDependencies(): Array + get contextDependencies(): Array + get addedContextDependencies(): Array + get removedContextDependencies(): Array + get missingDependencies(): Array + get addedMissingDependencies(): Array + get removedMissingDependencies(): Array + get buildDependencies(): Array + get addedBuildDependencies(): Array + get removedBuildDependencies(): Array +} +export type EntryOptionsDTO = EntryOptionsDto +export class EntryOptionsDto { + get name(): string | undefined + set name(name: string | undefined) + get runtime(): false | string | undefined + set runtime(chunkLoading: boolean | string | undefined) + get chunkLoading(): string | undefined + set chunkLoading(chunkLoading: string | undefined) + get asyncChunks(): boolean | undefined + set asyncChunks(asyncChunks: boolean | undefined) + get baseUri(): string | undefined + set baseUri(baseUri: string | undefined) + get library(): JsLibraryOptions | undefined + set library(library: JsLibraryOptions | undefined) + get dependOn(): Array | undefined + set dependOn(dependOn: Array | undefined) + get layer(): string | undefined + set layer(layer: string | undefined) +} +export type EntryDataDTO = EntryDataDto +export class EntryDataDto { + get dependencies(): Array + get includeDependencies(): Array + get options(): EntryOptionsDto +} +export class JsEntries { + clear(): void + get size(): number + has(key: string): boolean + set(key: string, value: JsEntryData | EntryDataDto): void + delete(key: string): boolean + get(key: string): EntryDataDto | undefined + keys(): Array + values(): Array +} export class JsCompilation { updateAsset(filename: string, newSourceOrFunction: JsCompatSource | ((source: JsCompatSource) => JsCompatSource), assetInfoUpdateOrFunction?: JsAssetInfo | ((assetInfo: JsAssetInfo) => JsAssetInfo)): void getAssets(): Readonly[] getAsset(name: string): JsAsset | null getAssetSource(name: string): JsCompatSource | null - getModules(): Array + get modules(): Array + getOptimizationBailout(): Array getChunks(): Array + getNamedChunkKeys(): Array getNamedChunk(name: string): JsChunk | null - /** - * Only available for those none Js and Css source, - * return true if set module source successfully, false if failed. - */ - setNoneAstModuleSource(moduleIdentifier: string, source: JsCompatSource): boolean + getNamedChunkGroupKeys(): Array + getNamedChunkGroup(name: string): JsChunkGroup | null setAssetSource(name: string, source: JsCompatSource): void deleteAssetSource(name: string): void getAssetFilenames(): Array hasAsset(name: string): boolean + emitAssetFromLoader(filename: string, source: JsCompatSource, assetInfo: JsAssetInfo, module: string): void emitAsset(filename: string, source: JsCompatSource, assetInfo: JsAssetInfo): void deleteAsset(filename: string): void + renameAsset(filename: string, newName: string): void get entrypoints(): Record + get chunkGroups(): Array get hash(): string | null - getFileDependencies(): Array - getContextDependencies(): Array - getMissingDependencies(): Array - getBuildDependencies(): Array - pushDiagnostic(severity: "error" | "warning", title: string, message: string): void + dependencies(): DependenciesDto + pushDiagnostic(diagnostic: JsDiagnostic): void + spliceDiagnostic(start: number, end: number, replaceWith: Array): void pushNativeDiagnostics(diagnostics: ExternalObject<'Diagnostic[]'>): void + getErrors(): Array + getWarnings(): Array getStats(): JsStats - getAssetPath(filename: string, data: PathData): string - getAssetPathWithInfo(filename: string, data: PathData): PathWithInfo - getPath(filename: string, data: PathData): string - getPathWithInfo(filename: string, data: PathData): PathWithInfo + getAssetPath(filename: LocalJsFilename, data: JsPathData): string + getAssetPathWithInfo(filename: LocalJsFilename, data: JsPathData): PathWithInfo + getPath(filename: LocalJsFilename, data: JsPathData): string + getPathWithInfo(filename: LocalJsFilename, data: JsPathData): PathWithInfo addFileDependencies(deps: Array): void addContextDependencies(deps: Array): void addMissingDependencies(deps: Array): void addBuildDependencies(deps: Array): void rebuildModule(moduleIdentifiers: Array, f: (...args: any[]) => any): void - importModule(request: string, publicPath: string | undefined | null, baseUri: string | undefined | null, originalModule: string | undefined | null, originalModuleContext: string | undefined | null, callback: (...args: any[]) => any): void + importModule(request: string, layer: string | undefined | null, publicPath: JsFilename | undefined | null, baseUri: string | undefined | null, originalModule: string | undefined | null, originalModuleContext: string | undefined | null, callback: (...args: any[]) => any): void + get entries(): JsEntries +} +export type DependencyDTO = DependencyDto +export class DependencyDto { + get type(): string + get category(): string + get request(): string | undefined +} +export type DependenciesBlockDTO = DependenciesBlockDto +export class DependenciesBlockDto { + get dependencies(): Array + get blocks(): Array +} +export type ModuleDTO = ModuleDto +export class ModuleDto { + get context(): string | undefined + get originalSource(): JsCompatSource | undefined + get resource(): string | undefined + get moduleIdentifier(): string + get nameForCondition(): string | undefined + get request(): string | undefined + get userRequest(): string | undefined + get rawRequest(): string | undefined + get factoryMeta(): JsFactoryMeta | undefined + get type(): string + get layer(): string | undefined + get blocks(): Array + size(ty?: string | undefined | null): number +} +export class JsResolver { + resolveSync(path: string, request: string): string | false + withOptions(raw?: RawResolveOptionsWithDependencyType | undefined | null): this } export class JsStats { - getAssets(): JsStatsGetAssets - getModules(reasons: boolean, moduleAssets: boolean, nestedModules: boolean, source: boolean): Array - getChunks(chunkModules: boolean, chunksRelations: boolean, reasons: boolean, moduleAssets: boolean, nestedModules: boolean, source: boolean): Array - getEntrypoints(): Array - getNamedChunkGroups(): Array - getErrors(): Array - getWarnings(): Array + toJson(jsOptions: JsStatsOptions): JsStatsCompilation + hasWarnings(): boolean + hasErrors(): boolean getLogging(acceptedTypes: number): Array - getHash(): string | null +} +export class JsResolverFactory { + constructor() + get(type: string, options?: RawResolveOptionsWithDependencyType): JsResolver } export class Rspack { - constructor(options: RSPackRawOptions, builtinPlugins: Array, jsHooks: JsHooks, compilerHooks: Array, outputFilesystem: ThreadsafeNodeFS, jsLoaderRunner: (...args: any[]) => any) - unsafe_set_disabled_hooks(hooks: Array): void - /** - * Build with the given option passed to the constructor - * - * Warning: - * Calling this method recursively might cause a deadlock. - */ - unsafe_build(callback: (err: null | Error) => void): void - /** - * Rebuild with the given option passed to the constructor - * - * Warning: - * Calling this method recursively will cause a deadlock. - */ - unsafe_rebuild(changed_files: string[], removed_files: string[], callback: (err: null | Error) => void): void - /** - * Get the last compilation - * - * Warning: - * - * Calling this method under the build or rebuild method might cause a deadlock. - * - * **Note** that this method is not safe if you cache the _JsCompilation_ on the Node side, as it will be invalidated by the next build and accessing a dangling ptr is a UB. - */ - unsafe_last_compilation(f: (arg0: JsCompilation) => void): void - /** - * Destroy the compiler - * - * Warning: - * - * Anything related to this compiler will be invalidated after this method is called. - */ - unsafe_drop(): void + constructor(options: RawOptions, builtinPlugins: Array, registerJsTaps: RegisterJsTaps, outputFilesystem: ThreadsafeNodeFS, resolverFactoryReference: JsResolverFactory) + setNonSkippableRegisters(kinds: Array): void + /** Build with the given option passed to the constructor */ + build(callback: (err: null | Error) => void): void + /** Rebuild with the given option passed to the constructor */ + rebuild(changed_files: string[], removed_files: string[], callback: (err: null | Error) => void): void } diff --git a/crates/node_binding/index.js b/crates/node_binding/index.js index 913f384..c88ead6 100644 --- a/crates/node_binding/index.js +++ b/crates/node_binding/index.js @@ -252,7 +252,7 @@ if (!nativeBinding) { throw new Error(`Failed to load native binding`) } -const { __chunk_inner_is_only_initial, __chunk_inner_can_be_initial, __chunk_inner_has_runtime, __chunk_inner_get_all_async_chunks, __chunk_inner_get_all_initial_chunks, __chunk_inner_get_all_referenced_chunks, __chunk_graph_inner_get_chunk_modules, __chunk_graph_inner_get_chunk_entry_modules, __chunk_graph_inner_get_chunk_entry_dependent_chunks_iterable, __chunk_graph_inner_get_chunk_modules_iterable_by_source_type, __chunk_group_inner_get_chunk_group, JsCompilation, JsHookType, JsStats, BuiltinPluginName, runBuiltinLoader, Rspack, registerGlobalTrace, cleanupGlobalTrace } = nativeBinding +const { __chunk_inner_is_only_initial, __chunk_inner_can_be_initial, __chunk_inner_has_runtime, __chunk_inner_get_all_async_chunks, __chunk_inner_get_all_initial_chunks, __chunk_inner_get_all_referenced_chunks, __chunk_graph_inner_get_chunk_modules, __chunk_graph_inner_get_chunk_entry_modules, __chunk_graph_inner_get_chunk_entry_dependent_chunks_iterable, __chunk_graph_inner_get_chunk_modules_iterable_by_source_type, __chunk_group_inner_get_chunk_group, __entrypoint_inner_get_runtime_chunk, DependenciesDto, EntryOptionsDto, EntryDataDto, JsEntries, JsCompilation, DependencyDto, DependenciesBlockDto, ModuleDto, JsResolver, JsRspackSeverity, JsStats, BuiltinPluginName, RawRuleSetConditionType, JsLoaderState, RegisterJsTapKind, JsResolverFactory, Rspack, registerGlobalTrace, cleanupGlobalTrace } = nativeBinding module.exports.__chunk_inner_is_only_initial = __chunk_inner_is_only_initial module.exports.__chunk_inner_can_be_initial = __chunk_inner_can_be_initial @@ -265,11 +265,23 @@ module.exports.__chunk_graph_inner_get_chunk_entry_modules = __chunk_graph_inner module.exports.__chunk_graph_inner_get_chunk_entry_dependent_chunks_iterable = __chunk_graph_inner_get_chunk_entry_dependent_chunks_iterable module.exports.__chunk_graph_inner_get_chunk_modules_iterable_by_source_type = __chunk_graph_inner_get_chunk_modules_iterable_by_source_type module.exports.__chunk_group_inner_get_chunk_group = __chunk_group_inner_get_chunk_group +module.exports.__entrypoint_inner_get_runtime_chunk = __entrypoint_inner_get_runtime_chunk +module.exports.DependenciesDto = DependenciesDto +module.exports.EntryOptionsDto = EntryOptionsDto +module.exports.EntryDataDto = EntryDataDto +module.exports.JsEntries = JsEntries module.exports.JsCompilation = JsCompilation -module.exports.JsHookType = JsHookType +module.exports.DependencyDto = DependencyDto +module.exports.DependenciesBlockDto = DependenciesBlockDto +module.exports.ModuleDto = ModuleDto +module.exports.JsResolver = JsResolver +module.exports.JsRspackSeverity = JsRspackSeverity module.exports.JsStats = JsStats module.exports.BuiltinPluginName = BuiltinPluginName -module.exports.runBuiltinLoader = runBuiltinLoader +module.exports.RawRuleSetConditionType = RawRuleSetConditionType +module.exports.JsLoaderState = JsLoaderState +module.exports.RegisterJsTapKind = RegisterJsTapKind +module.exports.JsResolverFactory = JsResolverFactory module.exports.Rspack = Rspack module.exports.registerGlobalTrace = registerGlobalTrace module.exports.cleanupGlobalTrace = cleanupGlobalTrace diff --git a/crates/node_binding/src/compiler.rs b/crates/node_binding/src/compiler.rs new file mode 100644 index 0000000..2f7a8f7 --- /dev/null +++ b/crates/node_binding/src/compiler.rs @@ -0,0 +1,64 @@ +use std::{ + marker::PhantomPinned, + ops::{Deref, DerefMut}, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }, +}; + +use rspack_fs_node::AsyncNodeWritableFileSystem; + +type CompilerInner = rspack_core::Compiler; + +/// `Compiler` struct that is `!Unpin`. +pub(crate) struct Compiler(CompilerInner, PhantomPinned); + +impl From for Compiler { + fn from(value: CompilerInner) -> Self { + Self(value, PhantomPinned) + } +} + +impl Deref for Compiler { + type Target = CompilerInner; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for Compiler { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +pub(crate) struct CompilerState(Arc); + +impl CompilerState { + pub(crate) fn init() -> Self { + Self(Arc::new(AtomicBool::new(false))) + } +} + +impl CompilerState { + pub(crate) fn running(&self) -> bool { + self.0.load(Ordering::Relaxed) + } + + pub(crate) fn enter(&self) -> CompilerStateGuard { + self.0.store(true, Ordering::Relaxed); + CompilerStateGuard(self.0.clone()) + } +} + +pub(crate) struct CompilerStateGuard(Arc); + +unsafe impl Send for CompilerStateGuard {} + +impl Drop for CompilerStateGuard { + fn drop(&mut self) { + self.0.store(false, Ordering::Relaxed); + } +} diff --git a/crates/node_binding/src/hook.rs b/crates/node_binding/src/hook.rs deleted file mode 100644 index 5b12971..0000000 --- a/crates/node_binding/src/hook.rs +++ /dev/null @@ -1,82 +0,0 @@ -use std::sync::RwLock; - -/// rust support hooks -#[derive(PartialEq)] -pub enum Hook { - FinishMake, - BuildModule, - ThisCompilation, - AfterProcessAssets, - Emit, - AssetEmitted, - ShouldEmit, - AfterEmit, - OptimizeChunkModules, - BeforeCompile, - AfterCompile, - FinishModules, - OptimizeModules, - AfterOptimizeModules, - OptimizeTree, - /// webpack `compilation.hooks.chunkAsset` - ChunkAsset, - ContextModuleFactoryBeforeResolve, - ContextModuleFactoryAfterResolve, - NormalModuleFactoryResolveForScheme, - NormalModuleFactoryCreateModule, - AfterResolve, - BeforeResolve, - SucceedModule, - StillValidModule, - ExecuteModule, - RuntimeModule, -} - -impl From for Hook { - fn from(s: String) -> Self { - match s.as_str() { - "finishMake" => Hook::FinishMake, - "buildModule" => Hook::BuildModule, - "thisCompilation" => Hook::ThisCompilation, - "afterProcessAssets" => Hook::AfterProcessAssets, - "emit" => Hook::Emit, - "assetEmitted" => Hook::AssetEmitted, - "shouldEmit" => Hook::ShouldEmit, - "afterEmit" => Hook::AfterEmit, - "optimizeChunkModules" => Hook::OptimizeChunkModules, - "beforeCompile" => Hook::BeforeCompile, - "afterCompile" => Hook::AfterCompile, - "finishModules" => Hook::FinishModules, - "optimizeModules" => Hook::OptimizeModules, - "afterOptimizeModules" => Hook::AfterOptimizeModules, - "optimizeTree" => Hook::OptimizeTree, - "chunkAsset" => Hook::ChunkAsset, - "contextModuleFactoryBeforeResolve" => Hook::ContextModuleFactoryBeforeResolve, - "contextModuleFactoryAfterResolve" => Hook::ContextModuleFactoryAfterResolve, - "normalModuleFactoryCreateModule" => Hook::NormalModuleFactoryCreateModule, - "normalModuleFactoryResolveForScheme" => Hook::NormalModuleFactoryResolveForScheme, - "afterResolve" => Hook::AfterResolve, - "beforeResolve" => Hook::BeforeResolve, - "succeedModule" => Hook::SucceedModule, - "stillValidModule" => Hook::StillValidModule, - "executeModule" => Hook::ExecuteModule, - "runtimeModule" => Hook::RuntimeModule, - hook_name => panic!("{hook_name} is an invalid hook name"), - } - } -} - -#[derive(Default)] -pub struct DisabledHooks(RwLock>); - -impl DisabledHooks { - pub fn set_disabled_hooks(&self, hooks: Vec) -> napi::Result<()> { - let mut disabled_hooks = self.0.write().expect("failed to write lock"); - *disabled_hooks = hooks.into_iter().map(Into::into).collect::>(); - Ok(()) - } - - pub fn is_hook_disabled(&self, hook: &Hook) -> bool { - self.0.read().expect("").contains(hook) - } -} diff --git a/crates/node_binding/src/lib.rs b/crates/node_binding/src/lib.rs index e0573b7..bd3f256 100644 --- a/crates/node_binding/src/lib.rs +++ b/crates/node_binding/src/lib.rs @@ -3,60 +3,35 @@ #![feature(try_blocks)] #[macro_use] extern crate napi_derive; +extern crate rspack_allocator; -use std::collections::HashSet; use std::pin::Pin; -use std::sync::atomic::{AtomicU32, Ordering}; use std::sync::Mutex; -use binding_options::RSPackRawOptions; +use compiler::{Compiler, CompilerState, CompilerStateGuard}; use napi::bindgen_prelude::*; -use once_cell::sync::Lazy; -use rspack_binding_options::BuiltinPlugin; -use rspack_binding_values::SingleThreadedHashMap; -use rspack_core::PluginExt; +use binding_options::BuiltinPlugin; +use rspack_core::{Compilation, PluginExt}; use rspack_error::Diagnostic; use rspack_fs_node::{AsyncNodeWritableFileSystem, ThreadsafeNodeFS}; -mod hook; -mod loader; +mod compiler; mod panic; mod plugins; +mod resolver_factory; -use hook::*; -// Napi macro registered this successfully -#[allow(unused)] -use loader::run_builtin_loader; use plugins::*; -use rspack_binding_options::*; +use resolver_factory::*; +use binding_options::*; use rspack_binding_values::*; -use rspack_napi_shared::set_napi_env; use rspack_tracing::chrome::FlushGuard; +use plugin_manifest::ManifestPlugin; -#[cfg(not(target_os = "linux"))] -#[global_allocator] -static GLOBAL: mimalloc_rust::GlobalMiMalloc = mimalloc_rust::GlobalMiMalloc; - -#[cfg(all( - target_os = "linux", - target_env = "gnu", - any(target_arch = "x86_64", target_arch = "aarch64") -))] -#[global_allocator] -static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc; - -static COMPILERS: Lazy< - SingleThreadedHashMap>>>, -> = Lazy::new(Default::default); - -static NEXT_COMPILER_ID: AtomicU32 = AtomicU32::new(0); - -type CompilerId = u32; - -#[napi(custom_finalize)] +#[napi] pub struct Rspack { - id: CompilerId, js_plugin: JsHooksAdapterPlugin, + compiler: Pin>, + state: CompilerState, } #[napi] @@ -64,175 +39,158 @@ impl Rspack { #[napi(constructor)] pub fn new( env: Env, - options: RSPackRawOptions, + options: RawOptions, builtin_plugins: Vec, - js_hooks: JsHooks, register_js_taps: RegisterJsTaps, output_filesystem: ThreadsafeNodeFS, - js_loader_runner: JsFunction, + mut resolver_factory_reference: Reference, ) -> Result { - Self::prepare_environment(&env); tracing::info!("raw_options: {:#?}", &options); - let disabled_hooks: DisabledHooks = Default::default(); let mut plugins = Vec::new(); - let js_plugin = - JsHooksAdapterPlugin::from_js_hooks(env, js_hooks, disabled_hooks, register_js_taps)?; + let js_plugin = JsHooksAdapterPlugin::from_js_hooks(env, register_js_taps)?; plugins.push(js_plugin.clone().boxed()); for bp in builtin_plugins { - bp.append_to(&mut plugins) + bp.append_to(env, &mut plugins) .map_err(|e| Error::from_reason(format!("{e}")))?; } - let js_loader_runner: JsLoaderRunner = JsLoaderRunner::try_from(js_loader_runner)?; - plugins.push(JsLoaderResolver { js_loader_runner }.boxed()); - - let compiler_options = options - .apply(&mut plugins) + let compiler_options: rspack_core::CompilerOptions = options + .try_into() .map_err(|e| Error::from_reason(format!("{e}")))?; tracing::info!("normalized_options: {:#?}", &compiler_options); + let resolver_factory = + (*resolver_factory_reference).get_resolver_factory(compiler_options.resolve.clone()); + let loader_resolver_factory = (*resolver_factory_reference) + .get_loader_resolver_factory(compiler_options.resolve_loader.clone()); + + // Add default plugins to the compiler. + plugins.push(ManifestPlugin::new().boxed()); + let rspack = rspack_core::Compiler::new( compiler_options, plugins, - AsyncNodeWritableFileSystem::new(env, output_filesystem) + AsyncNodeWritableFileSystem::new(output_filesystem) .map_err(|e| Error::from_reason(format!("Failed to create writable filesystem: {e}",)))?, + Some(resolver_factory), + Some(loader_resolver_factory), ); - let id = NEXT_COMPILER_ID.fetch_add(1, Ordering::SeqCst); - unsafe { COMPILERS.insert_if_vacant(id, Box::pin(rspack)) }?; - - Ok(Self { id, js_plugin }) + Ok(Self { + compiler: Box::pin(Compiler::from(rspack)), + state: CompilerState::init(), + js_plugin, + }) } - #[allow(clippy::unwrap_in_result, clippy::unwrap_used)] - #[napi( - js_name = "unsafe_set_disabled_hooks", - ts_args_type = "hooks: Array" - )] - pub fn set_disabled_hooks(&self, _env: Env, hooks: Vec) -> Result<()> { - self.js_plugin.set_disabled_hooks(hooks) + #[napi] + pub fn set_non_skippable_registers(&self, kinds: Vec) { + self.js_plugin.set_non_skippable_registers(kinds) } /// Build with the given option passed to the constructor - /// - /// Warning: - /// Calling this method recursively might cause a deadlock. - #[napi( - js_name = "unsafe_build", - ts_args_type = "callback: (err: null | Error) => void" - )] - pub fn build(&self, env: Env, f: JsFunction) -> Result<()> { - let handle_build = |compiler: &mut Pin>>| { - // Safety: compiler is stored in a global hashmap, so it's guaranteed to be alive. - let compiler: &'static mut Pin>> = - unsafe { std::mem::transmute::<&'_ mut _, &'static mut _>(compiler) }; - - callbackify(env, f, async move { - compiler.build().await.map_err(|e| { - Error::new( - napi::Status::GenericFailure, - print_error_diagnostic(e, compiler.options.stats.colors), - ) - })?; - tracing::info!("build ok"); - Ok(()) + #[napi(ts_args_type = "callback: (err: null | Error) => void")] + pub fn build(&mut self, env: Env, reference: Reference, f: JsFunction) -> Result<()> { + unsafe { + self.run(env, reference, |compiler, _guard| { + callbackify(env, f, async move { + compiler.build().await.map_err(|e| { + Error::new( + napi::Status::GenericFailure, + print_error_diagnostic(e, compiler.options.stats.colors), + ) + })?; + tracing::info!("build ok"); + drop(_guard); + Ok(()) + }) }) - }; - unsafe { COMPILERS.borrow_mut(&self.id, handle_build) } + } } /// Rebuild with the given option passed to the constructor - /// - /// Warning: - /// Calling this method recursively will cause a deadlock. #[napi( - js_name = "unsafe_rebuild", ts_args_type = "changed_files: string[], removed_files: string[], callback: (err: null | Error) => void" )] pub fn rebuild( - &self, + &mut self, env: Env, + reference: Reference, changed_files: Vec, removed_files: Vec, f: JsFunction, ) -> Result<()> { - let handle_rebuild = |compiler: &mut Pin>>| { - // Safety: compiler is stored in a global hashmap, so it's guaranteed to be alive. - // The reason why use Box here instead of Compiler itself is that: - // Compilers may expand and change its layout underneath, make Compiler layout change. - // Use Box to make sure the Compiler layout won't change - let compiler: &'static mut Pin>> = - unsafe { std::mem::transmute::<&'_ mut _, &'static mut _>(compiler) }; - - callbackify(env, f, async move { - compiler - .rebuild( - HashSet::from_iter(changed_files.into_iter()), - HashSet::from_iter(removed_files.into_iter()), - ) - .await - .map_err(|e| { - Error::new( - napi::Status::GenericFailure, - print_error_diagnostic(e, compiler.options.stats.colors), + use std::collections::HashSet; + + unsafe { + self.run(env, reference, |compiler, _guard| { + callbackify(env, f, async move { + compiler + .rebuild( + HashSet::from_iter(changed_files.into_iter()), + HashSet::from_iter(removed_files.into_iter()), ) - })?; - tracing::info!("rebuild ok"); - Ok(()) + .await + .map_err(|e| { + Error::new( + napi::Status::GenericFailure, + print_error_diagnostic(e, compiler.options.stats.colors), + ) + })?; + tracing::info!("rebuild ok"); + drop(_guard); + Ok(()) + }) }) - }; - - unsafe { COMPILERS.borrow_mut(&self.id, handle_rebuild) } - } - - /// Get the last compilation - /// - /// Warning: - /// - /// Calling this method under the build or rebuild method might cause a deadlock. - /// - /// **Note** that this method is not safe if you cache the _JsCompilation_ on the Node side, as it will be invalidated by the next build and accessing a dangling ptr is a UB. - #[napi(js_name = "unsafe_last_compilation")] - pub fn unsafe_last_compilation Result<()>>(&self, f: F) -> Result<()> { - let handle_last_compilation = |compiler: &mut Pin>>| { - // Safety: compiler is stored in a global hashmap, and compilation is only available in the callback of this function, so it is safe to cast to a static lifetime. See more in the warning part of this method. - // The reason why use Box here instead of Compiler itself is that: - // Compilers may expand and change its layout underneath, make Compiler layout change. - // Use Box to make sure the Compiler layout won't change - let compiler: &'static mut Pin>> = - unsafe { std::mem::transmute::<&'_ mut _, &'static mut _>(compiler) }; - f(JsCompilation::from_compilation(&mut compiler.compilation)) - }; - - unsafe { COMPILERS.borrow_mut(&self.id, handle_last_compilation) } + } } +} - /// Destroy the compiler - /// - /// Warning: +impl Rspack { + /// Run the given function with the compiler. /// - /// Anything related to this compiler will be invalidated after this method is called. - #[napi(js_name = "unsafe_drop")] - pub fn drop(&self) -> Result<()> { - unsafe { COMPILERS.remove(&self.id) }; - - Ok(()) + /// ## Safety + /// 1. The caller must ensure that the `Compiler` is not moved or dropped during the lifetime of the callback. + /// 2. `CompilerStateGuard` should and only be dropped so soon as each `Compiler` is free of use. + /// Accessing `Compiler` beyond the lifetime of `CompilerStateGuard` would lead to potential race condition. + unsafe fn run( + &mut self, + env: Env, + reference: Reference, + f: impl FnOnce(&'static mut Compiler, CompilerStateGuard) -> Result, + ) -> Result { + if self.state.running() { + return Err(concurrent_compiler_error()); + } + let _guard = self.state.enter(); + let mut compiler = reference.share_with(env, |s| { + // SAFETY: The mutable reference to `Compiler` is exclusive. It's guaranteed by the running state guard. + Ok(unsafe { s.compiler.as_mut().get_unchecked_mut() }) + })?; + + self.cleanup_last_compilation(&compiler.compilation); + + // SAFETY: + // 1. `Compiler` is pinned and stored on the heap. + // 2. `JsReference` (NAPI internal mechanism) keeps `Compiler` alive until its instance getting garbage collected. + f( + unsafe { std::mem::transmute::<&mut Compiler, &'static mut Compiler>(*compiler) }, + _guard, + ) } -} -impl ObjectFinalize for Rspack { - fn finalize(self, _env: Env) -> Result<()> { - // WARNING: Don't try to destroy the compiler from the finalize method. The background thread may still be working and it's a COMPLETELY unsafe way. - Ok(()) + fn cleanup_last_compilation(&self, compilation: &Compilation) { + JsCompilationWrapper::cleanup(compilation.id()); } } -impl Rspack { - fn prepare_environment(env: &Env) { - set_napi_env(env.raw()); - } +fn concurrent_compiler_error() -> Error { + Error::new( + napi::Status::GenericFailure, + "ConcurrentCompilationError: You ran rspack twice. Each instance only supports a single concurrent compilation at a time.", + ) } #[derive(Default)] diff --git a/crates/node_binding/src/loader.rs b/crates/node_binding/src/loader.rs deleted file mode 100644 index f610069..0000000 --- a/crates/node_binding/src/loader.rs +++ /dev/null @@ -1,13 +0,0 @@ -use napi::Result; -use rspack_binding_options::JsLoaderContext; - -/// Builtin loader runner -#[napi] -#[allow(unused)] -pub async fn run_builtin_loader( - builtin: String, - options: Option, - loader_context: JsLoaderContext, -) -> Result { - binding_options::run_builtin_loader(builtin, options.as_deref(), loader_context).await -} diff --git a/crates/node_binding/src/panic.rs b/crates/node_binding/src/panic.rs index f748060..64775ff 100644 --- a/crates/node_binding/src/panic.rs +++ b/crates/node_binding/src/panic.rs @@ -45,8 +45,6 @@ pub fn install_panic_handler() { true }); })) - .verbosity(color_backtrace::Verbosity::Medium) - .lib_verbosity(color_backtrace::Verbosity::Medium) .print_addresses(false) // .install(default_output_stream()); .into_panic_handler(default_output_stream()); diff --git a/crates/node_binding/src/plugins/interceptor.rs b/crates/node_binding/src/plugins/interceptor.rs index f0b166d..eca2912 100644 --- a/crates/node_binding/src/plugins/interceptor.rs +++ b/crates/node_binding/src/plugins/interceptor.rs @@ -1,18 +1,71 @@ -use std::sync::Arc; +use std::{ + borrow::Cow, + hash::Hash, + sync::{Arc, RwLock}, +}; use async_trait::async_trait; -use napi::{Env, JsFunction, NapiRaw}; -use rspack_binding_macros::{call_js_function_with_napi_objects, js_fn_into_threadsafe_fn}; -use rspack_binding_values::JsCompilation; +use napi::{ + bindgen_prelude::{Buffer, FromNapiValue, Promise, ToNapiValue}, + Env, JsFunction, NapiRaw, +}; +use rspack_binding_values::{ + CompatSource, JsAdditionalTreeRuntimeRequirementsArg, JsAdditionalTreeRuntimeRequirementsResult, + JsAfterEmitData, JsAfterResolveData, JsAfterResolveOutput, JsAfterTemplateExecutionData, + JsAlterAssetTagGroupsData, JsAlterAssetTagsData, JsAssetEmittedArgs, + JsBeforeAssetTagGenerationData, JsBeforeEmitData, JsBeforeResolveArgs, JsBeforeResolveOutput, + JsChunk, JsChunkAssetArgs, JsCompilationWrapper, JsContextModuleFactoryAfterResolveData, + JsContextModuleFactoryAfterResolveResult, JsContextModuleFactoryBeforeResolveData, + JsContextModuleFactoryBeforeResolveResult, JsCreateData, JsExecuteModuleArg, JsFactorizeArgs, + JsFactorizeOutput, JsModule, JsNormalModuleFactoryCreateModuleArgs, JsResolveArgs, + JsResolveForSchemeArgs, JsResolveForSchemeOutput, JsResolveOutput, JsRuntimeGlobals, + JsRuntimeModule, JsRuntimeModuleArg, ToJsCompatSource, ToJsModule, +}; +use rspack_collections::IdentifierSet; use rspack_core::{ - Compilation, CompilationParams, CompilationProcessAssetsHook, CompilerCompilationHook, - CompilerMakeHook, MakeParam, + parse_resource, rspack_sources::SourceExt, AfterResolveData, AfterResolveResult, + AssetEmittedInfo, BeforeResolveData, BeforeResolveResult, BoxModule, Chunk, ChunkUkey, + CodeGenerationResults, Compilation, CompilationAdditionalTreeRuntimeRequirements, + CompilationAdditionalTreeRuntimeRequirementsHook, CompilationAfterOptimizeModules, + CompilationAfterOptimizeModulesHook, CompilationAfterProcessAssets, + CompilationAfterProcessAssetsHook, CompilationAfterSeal, CompilationAfterSealHook, + CompilationBuildModule, CompilationBuildModuleHook, CompilationChunkAsset, + CompilationChunkAssetHook, CompilationChunkHash, CompilationChunkHashHook, + CompilationExecuteModule, CompilationExecuteModuleHook, CompilationFinishModules, + CompilationFinishModulesHook, CompilationOptimizeChunkModules, + CompilationOptimizeChunkModulesHook, CompilationOptimizeModules, CompilationOptimizeModulesHook, + CompilationOptimizeTree, CompilationOptimizeTreeHook, CompilationParams, + CompilationProcessAssets, CompilationProcessAssetsHook, CompilationRuntimeModule, + CompilationRuntimeModuleHook, CompilationSeal, CompilationSealHook, CompilationStillValidModule, + CompilationStillValidModuleHook, CompilationSucceedModule, CompilationSucceedModuleHook, + CompilerAfterEmit, CompilerAfterEmitHook, CompilerAssetEmitted, CompilerAssetEmittedHook, + CompilerCompilation, CompilerCompilationHook, CompilerEmit, CompilerEmitHook, CompilerFinishMake, + CompilerFinishMakeHook, CompilerMake, CompilerMakeHook, CompilerShouldEmit, + CompilerShouldEmitHook, CompilerThisCompilation, CompilerThisCompilationHook, + ContextModuleFactoryAfterResolve, ContextModuleFactoryAfterResolveHook, + ContextModuleFactoryBeforeResolve, ContextModuleFactoryBeforeResolveHook, ExecuteModuleId, + ModuleFactoryCreateData, ModuleIdentifier, NormalModuleCreateData, + NormalModuleFactoryAfterResolve, NormalModuleFactoryAfterResolveHook, + NormalModuleFactoryBeforeResolve, NormalModuleFactoryBeforeResolveHook, + NormalModuleFactoryCreateModule, NormalModuleFactoryCreateModuleHook, + NormalModuleFactoryFactorize, NormalModuleFactoryFactorizeHook, NormalModuleFactoryResolve, + NormalModuleFactoryResolveForScheme, NormalModuleFactoryResolveForSchemeHook, + NormalModuleFactoryResolveHook, NormalModuleFactoryResolveResult, ResourceData, RuntimeGlobals, + Scheme, }; -use rspack_hook::{AsyncSeries, AsyncSeries2, Hook, Interceptor}; -use rspack_napi_shared::{ - threadsafe_function::{ThreadsafeFunction, ThreadsafeFunctionCallMode}, - NapiResultExt, +use rspack_hash::RspackHash; +use rspack_hook::{Hook, Interceptor}; +use rspack_napi::threadsafe_function::ThreadsafeFunction; +use rspack_paths::Utf8PathBuf; +use rspack_plugin_html::{ + AfterEmitData, AfterTemplateExecutionData, AlterAssetTagGroupsData, AlterAssetTagsData, + BeforeAssetTagGenerationData, BeforeEmitData, HtmlPluginAfterEmit, HtmlPluginAfterEmitHook, + HtmlPluginAfterTemplateExecution, HtmlPluginAfterTemplateExecutionHook, + HtmlPluginAlterAssetTagGroups, HtmlPluginAlterAssetTagGroupsHook, HtmlPluginAlterAssetTags, + HtmlPluginAlterAssetTagsHook, HtmlPluginBeforeAssetTagGeneration, + HtmlPluginBeforeAssetTagGenerationHook, HtmlPluginBeforeEmit, HtmlPluginBeforeEmitHook, }; +use rspack_plugin_javascript::{JavascriptModulesChunkHash, JavascriptModulesChunkHashHook}; #[napi(object)] pub struct JsTap { @@ -25,120 +78,913 @@ pub struct ThreadsafeJsTap { pub stage: i32, } -impl< - T: napi::bindgen_prelude::ToNapiValue, - R: 'static + Send + napi::bindgen_prelude::FromNapiValue, - > ThreadsafeJsTap -{ +impl Clone for ThreadsafeJsTap { + fn clone(&self) -> Self { + Self { + function: self.function.clone(), + stage: self.stage, + } + } +} + +impl ThreadsafeJsTap { pub fn from_js_tap(js_tap: JsTap, env: Env) -> napi::Result { + let function = + unsafe { ThreadsafeFunction::from_napi_value(env.raw(), js_tap.function.raw()) }?; Ok(Self { - function: js_fn_into_threadsafe_fn!(js_tap.function, env), + function, stage: js_tap.stage, }) } } -fn register_taps_fn_into_threadsafe_fn< - S: napi::bindgen_prelude::ToNapiValue, - T: napi::bindgen_prelude::ToNapiValue, - R: 'static + Send + napi::bindgen_prelude::FromNapiValue, ->( - js_cb: JsFunction, - env: Env, -) -> napi::Result>>> { - let cb = unsafe { js_cb.raw() }; - let mut tsfn = ThreadsafeFunction::create(env.raw(), cb, 0, |ctx| { - let (ctx, resolver) = ctx.split_into_parts(); - - let env = ctx.env; - let cb = ctx.callback; - let result = unsafe { call_js_function_with_napi_objects!(env, cb, ctx.value) }; - - resolver.resolve_non_promise(result, |env, result: Vec| { - result - .into_iter() - .map(|t| ThreadsafeJsTap::from_js_tap(t, *env)) - .collect::>>() - }) - })?; +impl FromNapiValue for ThreadsafeJsTap { + unsafe fn from_napi_value( + env: napi::sys::napi_env, + napi_val: napi::sys::napi_value, + ) -> napi::Result { + let t = JsTap::from_napi_value(env, napi_val)?; + ThreadsafeJsTap::from_js_tap(t, Env::from_raw(env)) + } +} + +type RegisterFunctionOutput = Vec>; +type RegisterFunction = ThreadsafeFunction, RegisterFunctionOutput>; - // See the comment in `threadsafe_function.rs` - tsfn.unref(&env)?; - Ok(tsfn) +struct RegisterJsTapsInner { + register: RegisterFunction, + cache: RegisterJsTapsCache, + non_skippable_registers: Option, } -#[napi(object)] -pub struct RegisterJsTaps { - pub register_compiler_compilation_taps: JsFunction, - pub register_compiler_make_taps: JsFunction, - pub register_compilation_process_assets_taps: JsFunction, +impl Clone for RegisterJsTapsInner { + fn clone(&self) -> Self { + Self { + register: self.register.clone(), + cache: self.cache.clone(), + non_skippable_registers: self.non_skippable_registers.clone(), + } + } } -#[derive(Clone)] -pub struct ThreadsafeRegisterJsTaps(Arc); - -struct ThreadsafeRegisterJsTapsInner { - register_compiler_compilation_taps: - ThreadsafeFunction, Vec>>, - register_compiler_make_taps: - ThreadsafeFunction, Vec>>, - register_compilation_process_assets_taps: - ThreadsafeFunction, Vec>>, -} - -impl ThreadsafeRegisterJsTaps { - pub fn from_js_taps(register_js_taps: RegisterJsTaps, env: Env) -> napi::Result { - Ok(Self(Arc::new(ThreadsafeRegisterJsTapsInner { - register_compiler_compilation_taps: register_taps_fn_into_threadsafe_fn( - register_js_taps.register_compiler_compilation_taps, - env, - )?, - register_compiler_make_taps: register_taps_fn_into_threadsafe_fn( - register_js_taps.register_compiler_make_taps, - env, - )?, - register_compilation_process_assets_taps: register_taps_fn_into_threadsafe_fn( - register_js_taps.register_compilation_process_assets_taps, - env, - )?, - }))) +enum RegisterJsTapsCache { + NoCache, + Cache(Arc>>), + SyncCache(Arc>>), +} + +impl Clone for RegisterJsTapsCache { + fn clone(&self) -> Self { + match self { + Self::NoCache => Self::NoCache, + Self::Cache(c) => Self::Cache(c.clone()), + Self::SyncCache(c) => Self::SyncCache(c.clone()), + } } } -#[derive(Clone)] -struct CompilerCompilationTap { - function: ThreadsafeFunction, - stage: i32, +impl RegisterJsTapsCache { + pub fn new(cache: bool, sync: bool) -> Self { + if cache { + if sync { + Self::SyncCache(Default::default()) + } else { + Self::Cache(Default::default()) + } + } else { + Self::NoCache + } + } } -impl CompilerCompilationTap { - pub fn new(tap: ThreadsafeJsTap) -> Self { +impl RegisterJsTapsInner { + pub fn new( + register: RegisterFunction, + non_skippable_registers: Option, + cache: bool, + sync: bool, + ) -> Self { Self { - function: tap.function, - stage: tap.stage, + register, + cache: RegisterJsTapsCache::new(cache, sync), + non_skippable_registers, + } + } + + pub async fn call_register( + &self, + hook: &impl Hook, + ) -> rspack_error::Result>> { + if let RegisterJsTapsCache::Cache(cache) = &self.cache { + let js_taps = cache + .get_or_try_init(|| self.call_register_impl(hook)) + .await?; + Ok(Cow::Borrowed(js_taps)) + } else { + let js_taps = self.call_register_impl(hook).await?; + Ok(Cow::Owned(js_taps)) + } + } + + async fn call_register_impl( + &self, + hook: &impl Hook, + ) -> rspack_error::Result> { + let mut used_stages = Vec::from_iter(hook.used_stages()); + used_stages.sort(); + self.register.call_with_sync(used_stages).await + } + + pub fn call_register_blocking( + &self, + hook: &impl Hook, + ) -> rspack_error::Result>> { + if let RegisterJsTapsCache::SyncCache(cache) = &self.cache { + let js_taps = cache.get_or_try_init(|| self.call_register_blocking_impl(hook))?; + Ok(Cow::Borrowed(js_taps)) + } else { + let js_taps = self.call_register_blocking_impl(hook)?; + Ok(Cow::Owned(js_taps)) } } + + fn call_register_blocking_impl( + &self, + hook: &impl Hook, + ) -> rspack_error::Result> { + let mut used_stages = Vec::from_iter(hook.used_stages()); + used_stages.sort(); + self.register.blocking_call_with_sync(used_stages) + } +} + +/// define js taps register +/// cache: add cache for register function, used for `before_resolve` or `build_module` +/// which run register function multiple times for every module, cache will ensure +/// it only run once. +/// sync: synchronously/blocking call the register function, most of the register shouldn't +/// be sync since calling a ThreadsafeFunction is async, for now it's only used by +/// execute_module, which strongly required sync call. +macro_rules! define_register { + ($name:ident, tap = $tap_name:ident<$arg:ty, $ret:ty> @ $tap_hook:ty, cache = $cache:literal, sync = $sync:tt, kind = $kind:expr, skip = $skip:tt,) => { + define_register!(@BASE $name, $tap_name<$arg, $ret>, $cache, $sync); + define_register!(@SKIP $name, $arg, $ret, $cache, $sync, $skip); + define_register!(@INTERCEPTOR $name, $tap_name, $tap_hook, $cache, $kind, $sync); + }; + (@BASE $name:ident, $tap_name:ident<$arg:ty, $ret:ty>, $cache:literal, $sync:literal) => { + #[derive(Clone)] + pub struct $name { + inner: RegisterJsTapsInner<$arg, $ret>, + } + + #[derive(Clone)] + struct $tap_name { + function: ThreadsafeFunction<$arg, $ret>, + stage: i32, + } + + impl $tap_name { + pub fn new(tap: ThreadsafeJsTap<$arg, $ret>) -> Self { + Self { + function: tap.function, + stage: tap.stage, + } + } + } + }; + (@SKIP $name:ident, $arg:ty, $ret:ty, $cache:literal, $sync:literal, $skip:literal) => { + impl $name { + pub fn new(register: RegisterFunction<$arg, $ret>, non_skippable_registers: NonSkippableRegisters) -> Self { + Self { + inner: RegisterJsTapsInner::new(register, $skip.then_some(non_skippable_registers), $cache, $sync), + } + } + } + }; + (@INTERCEPTOR $name:ident, $tap_name:ident, $tap_hook:ty, $cache:literal, $kind:expr, false) => { + #[async_trait] + impl Interceptor<$tap_hook> for $name { + async fn call( + &self, + hook: &$tap_hook, + ) -> rspack_error::Result::Tap>> { + if let Some(non_skippable_registers) = &self.inner.non_skippable_registers && !non_skippable_registers.is_non_skippable(&$kind) { + return Ok(Vec::new()); + } + let js_taps = self.inner.call_register(hook).await?; + let js_taps = js_taps + .iter() + .map(|t| Box::new($tap_name::new(t.clone())) as <$tap_hook as Hook>::Tap) + .collect(); + Ok(js_taps) + } + } + }; + (@INTERCEPTOR $name:ident, $tap_name:ident, $tap_hook:ty, $cache:literal, $kind:expr, true) => { + impl Interceptor<$tap_hook> for $name { + fn call_blocking( + &self, + hook: &$tap_hook, + ) -> rspack_error::Result::Tap>> { + if let Some(non_skippable_registers) = &self.inner.non_skippable_registers && !non_skippable_registers.is_non_skippable(&$kind) { + return Ok(Vec::new()); + } + let js_taps = self.inner.call_register_blocking(hook)?; + let js_taps = js_taps + .iter() + .map(|t| Box::new($tap_name::new(t.clone())) as <$tap_hook as Hook>::Tap) + .collect(); + Ok(js_taps) + } + } + }; } +#[napi] +#[derive(Debug, PartialEq, Eq)] +pub enum RegisterJsTapKind { + CompilerThisCompilation, + CompilerCompilation, + CompilerMake, + CompilerFinishMake, + CompilerShouldEmit, + CompilerEmit, + CompilerAfterEmit, + CompilerAssetEmitted, + CompilationBuildModule, + CompilationStillValidModule, + CompilationSucceedModule, + CompilationExecuteModule, + CompilationFinishModules, + CompilationOptimizeModules, + CompilationAfterOptimizeModules, + CompilationOptimizeTree, + CompilationOptimizeChunkModules, + CompilationAdditionalTreeRuntimeRequirements, + CompilationRuntimeModule, + CompilationChunkHash, + CompilationChunkAsset, + CompilationProcessAssets, + CompilationAfterProcessAssets, + CompilationSeal, + CompilationAfterSeal, + NormalModuleFactoryBeforeResolve, + NormalModuleFactoryFactorize, + NormalModuleFactoryResolve, + NormalModuleFactoryAfterResolve, + NormalModuleFactoryCreateModule, + NormalModuleFactoryResolveForScheme, + ContextModuleFactoryBeforeResolve, + ContextModuleFactoryAfterResolve, + JavascriptModulesChunkHash, + HtmlPluginBeforeAssetTagGeneration, + HtmlPluginAlterAssetTags, + HtmlPluginAlterAssetTagGroups, + HtmlPluginAfterTemplateExecution, + HtmlPluginBeforeEmit, + HtmlPluginAfterEmit, +} + +#[derive(Default, Clone)] +pub struct NonSkippableRegisters(Arc>>); + +impl NonSkippableRegisters { + pub fn set_non_skippable_registers(&self, kinds: Vec) { + let mut ks = self.0.write().expect("failed to write lock"); + *ks = kinds; + } + + pub fn is_non_skippable(&self, kind: &RegisterJsTapKind) -> bool { + self.0.read().expect("should lock").contains(kind) + } +} + +#[derive(Clone)] +#[napi(object, object_to_js = false)] +pub struct RegisterJsTaps { + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: JsCompilation) => void); stage: number; }>" + )] + pub register_compiler_this_compilation_taps: RegisterFunction, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: JsCompilation) => void); stage: number; }>" + )] + pub register_compiler_compilation_taps: RegisterFunction, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: JsCompilation) => Promise); stage: number; }>" + )] + pub register_compiler_make_taps: RegisterFunction>, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: JsCompilation) => void); stage: number; }>" + )] + pub register_compiler_finish_make_taps: RegisterFunction>, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: JsCompilation) => boolean | undefined); stage: number; }>" + )] + pub register_compiler_should_emit_taps: RegisterFunction>, + #[napi( + ts_type = "(stages: Array) => Array<{ function: (() => Promise); stage: number; }>" + )] + pub register_compiler_emit_taps: RegisterFunction<(), Promise<()>>, + #[napi( + ts_type = "(stages: Array) => Array<{ function: (() => Promise); stage: number; }>" + )] + pub register_compiler_after_emit_taps: RegisterFunction<(), Promise<()>>, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: JsAssetEmittedArgs) => Promise); stage: number; }>" + )] + pub register_compiler_asset_emitted_taps: RegisterFunction>, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: JsModule) => void); stage: number; }>" + )] + pub register_compilation_build_module_taps: RegisterFunction, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: JsModule) => void); stage: number; }>" + )] + pub register_compilation_still_valid_module_taps: RegisterFunction, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: JsModule) => void); stage: number; }>" + )] + pub register_compilation_succeed_module_taps: RegisterFunction, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: JsExecuteModuleArg) => void); stage: number; }>" + )] + pub register_compilation_execute_module_taps: RegisterFunction, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: JsAdditionalTreeRuntimeRequirementsArg) => JsAdditionalTreeRuntimeRequirementsResult | undefined); stage: number; }>" + )] + pub register_compilation_additional_tree_runtime_requirements: RegisterFunction< + JsAdditionalTreeRuntimeRequirementsArg, + Option, + >, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: JsRuntimeModuleArg) => JsRuntimeModule | undefined); stage: number; }>" + )] + pub register_compilation_runtime_module_taps: + RegisterFunction>, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: JsCompilation) => Promise); stage: number; }>" + )] + pub register_compilation_finish_modules_taps: RegisterFunction>, + #[napi( + ts_type = "(stages: Array) => Array<{ function: (() => boolean | undefined); stage: number; }>" + )] + pub register_compilation_optimize_modules_taps: RegisterFunction<(), Option>, + #[napi(ts_type = "(stages: Array) => Array<{ function: (() => void); stage: number; }>")] + pub register_compilation_after_optimize_modules_taps: RegisterFunction<(), ()>, + #[napi( + ts_type = "(stages: Array) => Array<{ function: (() => Promise); stage: number; }>" + )] + pub register_compilation_optimize_tree_taps: RegisterFunction<(), Promise<()>>, + #[napi( + ts_type = "(stages: Array) => Array<{ function: (() => Promise); stage: number; }>" + )] + pub register_compilation_optimize_chunk_modules_taps: RegisterFunction<(), Promise>>, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: JsChunk) => Buffer); stage: number; }>" + )] + pub register_compilation_chunk_hash_taps: RegisterFunction, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: JsChunkAssetArgs) => void); stage: number; }>" + )] + pub register_compilation_chunk_asset_taps: RegisterFunction, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: JsCompilation) => Promise); stage: number; }>" + )] + pub register_compilation_process_assets_taps: RegisterFunction>, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: JsCompilation) => void); stage: number; }>" + )] + pub register_compilation_after_process_assets_taps: RegisterFunction, + #[napi(ts_type = "(stages: Array) => Array<{ function: (() => void); stage: number; }>")] + pub register_compilation_seal_taps: RegisterFunction<(), ()>, + #[napi( + ts_type = "(stages: Array) => Array<{ function: (() => Promise); stage: number; }>" + )] + pub register_compilation_after_seal_taps: RegisterFunction<(), Promise<()>>, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: JsBeforeResolveArgs) => Promise<[boolean | undefined, JsBeforeResolveArgs]>); stage: number; }>" + )] + pub register_normal_module_factory_before_resolve_taps: + RegisterFunction>, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: JsFactorizeArgs) => Promise); stage: number; }>" + )] + pub register_normal_module_factory_factorize_taps: + RegisterFunction>, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: JsResolveArgs) => Promise); stage: number; }>" + )] + pub register_normal_module_factory_resolve_taps: + RegisterFunction>, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: JsResolveForSchemeArgs) => Promise<[boolean | undefined, JsResolveForSchemeArgs]>); stage: number; }>" + )] + pub register_normal_module_factory_resolve_for_scheme_taps: + RegisterFunction>, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: JsAfterResolveData) => Promise<[boolean | undefined, JsCreateData | undefined]>); stage: number; }>" + )] + pub register_normal_module_factory_after_resolve_taps: + RegisterFunction>, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: JsNormalModuleFactoryCreateModuleArgs) => Promise); stage: number; }>" + )] + pub register_normal_module_factory_create_module_taps: + RegisterFunction>, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: false | JsContextModuleFactoryBeforeResolveData) => Promise); stage: number; }>" + )] + pub register_context_module_factory_before_resolve_taps: RegisterFunction< + JsContextModuleFactoryBeforeResolveResult, + Promise, + >, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: false | JsContextModuleFactoryAfterResolveData) => Promise); stage: number; }>" + )] + pub register_context_module_factory_after_resolve_taps: RegisterFunction< + JsContextModuleFactoryAfterResolveResult, + Promise, + >, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: JsChunk) => Buffer); stage: number; }>" + )] + pub register_javascript_modules_chunk_hash_taps: RegisterFunction, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: JsBeforeAssetTagGenerationData) => JsBeforeAssetTagGenerationData); stage: number; }>" + )] + pub register_html_plugin_before_asset_tag_generation_taps: + RegisterFunction>, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: JsAlterAssetTagsData) => JsAlterAssetTagsData); stage: number; }>" + )] + pub register_html_plugin_alter_asset_tags_taps: + RegisterFunction>, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: JsAlterAssetTagGroupsData) => JsAlterAssetTagGroupsData); stage: number; }>" + )] + pub register_html_plugin_alter_asset_tag_groups_taps: + RegisterFunction>, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: JsAfterTemplateExecutionData) => JsAfterTemplateExecutionData); stage: number; }>" + )] + pub register_html_plugin_after_template_execution_taps: + RegisterFunction>, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: JsBeforeEmitData) => JsBeforeEmitData); stage: number; }>" + )] + pub register_html_plugin_before_emit_taps: + RegisterFunction>, + #[napi( + ts_type = "(stages: Array) => Array<{ function: ((arg: JsAfterEmitData) => JsAfterEmitData); stage: number; }>" + )] + pub register_html_plugin_after_emit_taps: + RegisterFunction>, +} + +/* Compiler Hooks */ +define_register!( + RegisterCompilerThisCompilationTaps, + tap = CompilerThisCompilationTap @ CompilerThisCompilationHook, + cache = false, + sync = false, + kind = RegisterJsTapKind::CompilerThisCompilation, + skip = false, +); +define_register!( + RegisterCompilerCompilationTaps, + tap = CompilerCompilationTap @ CompilerCompilationHook, + cache = false, + sync = false, + kind = RegisterJsTapKind::CompilerCompilation, + skip = true, +); +define_register!( + RegisterCompilerMakeTaps, + tap = CompilerMakeTap> @ CompilerMakeHook, + cache = false, + sync = false, + kind = RegisterJsTapKind::CompilerMake, + skip = true, +); +define_register!( + RegisterCompilerFinishMakeTaps, + tap = CompilerFinishMakeTap> @ CompilerFinishMakeHook, + cache = false, + sync = false, + kind = RegisterJsTapKind::CompilerFinishMake, + skip = true, +); +define_register!( + RegisterCompilerShouldEmitTaps, + tap = CompilerShouldEmitTap> @ CompilerShouldEmitHook, + cache = false, + sync = false, + kind = RegisterJsTapKind::CompilerShouldEmit, + skip = true, +); +define_register!( + RegisterCompilerEmitTaps, + tap = CompilerEmitTap<(), Promise<()>> @ CompilerEmitHook, + cache = false, + sync = false, + kind = RegisterJsTapKind::CompilerEmit, + skip = true, +); +define_register!( + RegisterCompilerAfterEmitTaps, + tap = CompilerAfterEmitTap<(), Promise<()>> @ CompilerAfterEmitHook, + cache = false, + sync = false, + kind = RegisterJsTapKind::CompilerAfterEmit, + skip = true, +); +define_register!( + RegisterCompilerAssetEmittedTaps, + tap = CompilerAssetEmittedTap> @ CompilerAssetEmittedHook, + cache = true, + sync = false, + kind = RegisterJsTapKind::CompilerAssetEmitted, + skip = true, +); + +/* Compilation Hooks */ +define_register!( + RegisterCompilationBuildModuleTaps, + tap = CompilationBuildModuleTap @ CompilationBuildModuleHook, + cache = true, + sync = false, + kind = RegisterJsTapKind::CompilationBuildModule, + skip = true, +); +define_register!( + RegisterCompilationStillValidModuleTaps, + tap = CompilationStillValidModuleTap @ CompilationStillValidModuleHook, + cache = true, + sync = false, + kind = RegisterJsTapKind::CompilationStillValidModule, + skip = true, +); +define_register!( + RegisterCompilationSucceedModuleTaps, + tap = CompilationSucceedModuleTap @ CompilationSucceedModuleHook, + cache = true, + sync = false, + kind = RegisterJsTapKind::CompilationSucceedModule, + skip = true, +); +define_register!( + RegisterCompilationExecuteModuleTaps, + tap = CompilationExecuteModuleTap @ CompilationExecuteModuleHook, + cache = false, + sync = true, + kind = RegisterJsTapKind::CompilationExecuteModule, + skip = true, +); +define_register!( + RegisterCompilationFinishModulesTaps, + tap = CompilationFinishModulesTap> @ CompilationFinishModulesHook, + cache = false, + sync = false, + kind = RegisterJsTapKind::CompilationFinishModules, + skip = true, +); +define_register!( + RegisterCompilationOptimizeModulesTaps, + tap = CompilationOptimizeModulesTap<(), Option> @ CompilationOptimizeModulesHook, + cache = true, + sync = false, + kind = RegisterJsTapKind::CompilationOptimizeModules, + skip = true, +); +define_register!( + RegisterCompilationAfterOptimizeModulesTaps, + tap = CompilationAfterOptimizeModulesTap<(), ()> @ CompilationAfterOptimizeModulesHook, + cache = false, + sync = false, + kind = RegisterJsTapKind::CompilationAfterOptimizeModules, + skip = true, +); +define_register!( + RegisterCompilationOptimizeTreeTaps, + tap = CompilationOptimizeTreeTap<(), Promise<()>> @ CompilationOptimizeTreeHook, + cache = false, + sync = false, + kind = RegisterJsTapKind::CompilationOptimizeTree, + skip = true, +); +define_register!( + RegisterCompilationOptimizeChunkModulesTaps, + tap = CompilationOptimizeChunkModulesTap<(), Promise>> @ CompilationOptimizeChunkModulesHook, + cache = false, + sync = false, + kind = RegisterJsTapKind::CompilationOptimizeChunkModules, + skip = true, +); +define_register!( + RegisterCompilationAdditionalTreeRuntimeRequirementsTaps, + tap = CompilationAdditionalTreeRuntimeRequirementsTap> @ CompilationAdditionalTreeRuntimeRequirementsHook, + cache = true, + sync = false, + kind = RegisterJsTapKind::CompilationAdditionalTreeRuntimeRequirements, + skip = true, +); +define_register!( + RegisterCompilationRuntimeModuleTaps, + tap = CompilationRuntimeModuleTap> @ CompilationRuntimeModuleHook, + cache = true, + sync = false, + kind = RegisterJsTapKind::CompilationRuntimeModule, + skip = true, +); +define_register!( + RegisterCompilationChunkHashTaps, + tap = CompilationChunkHashTap @ CompilationChunkHashHook, + cache = true, + sync = false, + kind = RegisterJsTapKind::CompilationChunkHash, + skip = true, +); +define_register!( + RegisterCompilationChunkAssetTaps, + tap = CompilationChunkAssetTap @ CompilationChunkAssetHook, + cache = true, + sync = false, + kind = RegisterJsTapKind::CompilationChunkAsset, + skip = true, +); +define_register!( + RegisterCompilationProcessAssetsTaps, + tap = CompilationProcessAssetsTap> @ CompilationProcessAssetsHook, + cache = false, + sync = false, + kind = RegisterJsTapKind::CompilationProcessAssets, + skip = true, +); +define_register!( + RegisterCompilationAfterProcessAssetsTaps, + tap = CompilationAfterProcessAssetsTap @ CompilationAfterProcessAssetsHook, + cache = false, + sync = false, + kind = RegisterJsTapKind::CompilationAfterProcessAssets, + skip = true, +); +define_register!( + RegisterCompilationSealTaps, + tap = CompilationSealTap<(), ()> @ CompilationSealHook, + cache = false, + sync = false, + kind = RegisterJsTapKind::CompilationSeal, + skip = true, +); +define_register!( + RegisterCompilationAfterSealTaps, + tap = CompilationAfterSealTap<(), Promise<()>> @ CompilationAfterSealHook, + cache = false, + sync = false, + kind = RegisterJsTapKind::CompilationAfterSeal, + skip = true, +); + +/* NormalModuleFactory Hooks */ +define_register!( + RegisterNormalModuleFactoryBeforeResolveTaps, + tap = NormalModuleFactoryBeforeResolveTap> @ NormalModuleFactoryBeforeResolveHook, + cache = true, + sync = false, + kind = RegisterJsTapKind::NormalModuleFactoryBeforeResolve, + skip = true, +); +define_register!( + RegisterNormalModuleFactoryFactorizeTaps, + tap = NormalModuleFactoryFactorizeTap> @ NormalModuleFactoryFactorizeHook, + cache = true, + sync = false, + kind = RegisterJsTapKind::NormalModuleFactoryFactorize, + skip = true, +); +define_register!( + RegisterNormalModuleFactoryResolveTaps, + tap = NormalModuleFactoryResolveTap> @ NormalModuleFactoryResolveHook, + cache = true, + sync = false, + kind = RegisterJsTapKind::NormalModuleFactoryResolve, + skip = true, +); +define_register!( + RegisterNormalModuleFactoryResolveForSchemeTaps, + tap = NormalModuleFactoryResolveForSchemeTap> @ NormalModuleFactoryResolveForSchemeHook, + cache = true, + sync = false, + kind = RegisterJsTapKind::NormalModuleFactoryResolveForScheme, + skip = true, +); +define_register!( + RegisterNormalModuleFactoryAfterResolveTaps, + tap = NormalModuleFactoryAfterResolveTap> @ NormalModuleFactoryAfterResolveHook, + cache = true, + sync = false, + kind = RegisterJsTapKind::NormalModuleFactoryAfterResolve, + skip = true, +); +define_register!( + RegisterNormalModuleFactoryCreateModuleTaps, + tap = NormalModuleFactoryCreateModuleTap> @ NormalModuleFactoryCreateModuleHook, + cache = true, + sync = false, + kind = RegisterJsTapKind::NormalModuleFactoryCreateModule, + skip = true, +); + +/* ContextModuleFactory Hooks */ +define_register!( + RegisterContextModuleFactoryBeforeResolveTaps, + tap = ContextModuleFactoryBeforeResolveTap> @ ContextModuleFactoryBeforeResolveHook, + cache = true, + sync = false, + kind = RegisterJsTapKind::ContextModuleFactoryBeforeResolve, + skip = true, +); +define_register!( + RegisterContextModuleFactoryAfterResolveTaps, + tap = ContextModuleFactoryAfterResolveTap> @ ContextModuleFactoryAfterResolveHook, + cache = true, + sync = false, + kind = RegisterJsTapKind::ContextModuleFactoryAfterResolve, + skip = true, +); + +/* JavascriptModules Hooks */ +define_register!( + RegisterJavascriptModulesChunkHashTaps, + tap = JavascriptModulesChunkHashTap @ JavascriptModulesChunkHashHook, + cache = true, + sync = false, + kind = RegisterJsTapKind::JavascriptModulesChunkHash, + skip = true, +); + +/* HtmlPlugin Hooks */ +define_register!( + RegisterHtmlPluginBeforeAssetTagGenerationTaps, + tap = HtmlPluginBeforeAssetTagGenerationTap> @ HtmlPluginBeforeAssetTagGenerationHook, + cache = true, + sync = false, + kind = RegisterJsTapKind::HtmlPluginBeforeAssetTagGeneration, + skip = true, +); + +define_register!( + RegisterHtmlPluginAlterAssetTagsTaps, + tap = HtmlPluginAlterAssetTagsTap> @ HtmlPluginAlterAssetTagsHook, + cache = true, + sync = false, + kind = RegisterJsTapKind::HtmlPluginAlterAssetTags, + skip = true, +); + +define_register!( + RegisterHtmlPluginAlterAssetTagGroupsTaps, + tap = HtmlPluginAlterAssetTagGroupsTap> @ HtmlPluginAlterAssetTagGroupsHook, + cache = true, + sync = false, + kind = RegisterJsTapKind::HtmlPluginAlterAssetTagGroups, + skip = true, +); + +define_register!( + RegisterHtmlPluginAfterTemplateExecutionTaps, + tap = HtmlPluginAfterTemplateExecutionTap> @ HtmlPluginAfterTemplateExecutionHook, + cache = true, + sync = false, + kind = RegisterJsTapKind::HtmlPluginAfterTemplateExecution, + skip = true, +); + +define_register!( + RegisterHtmlPluginBeforeEmitTaps, + tap = HtmlPluginBeforeEmitTap> @ HtmlPluginBeforeEmitHook, + cache = true, + sync = false, + kind = RegisterJsTapKind::HtmlPluginBeforeEmit, + skip = true, +); + +define_register!( + RegisterHtmlPluginAfterEmitTaps, + tap = HtmlPluginAfterEmitTap> @ HtmlPluginAfterEmitHook, + cache = true, + sync = false, + kind = RegisterJsTapKind::HtmlPluginAfterEmit, + skip = true, +); + #[async_trait] -impl AsyncSeries2 for CompilerCompilationTap { +impl CompilerThisCompilation for CompilerThisCompilationTap { async fn run( &self, compilation: &mut Compilation, _: &mut CompilationParams, ) -> rspack_error::Result<()> { - let compilation = JsCompilation::from_compilation(unsafe { - std::mem::transmute::<&'_ mut rspack_core::Compilation, &'static mut rspack_core::Compilation>( - compilation, - ) - }); + let compilation = JsCompilationWrapper::new(compilation); + self.function.call_with_sync(compilation).await + } + fn stage(&self) -> i32 { + self.stage + } +} + +#[async_trait] +impl CompilerCompilation for CompilerCompilationTap { + async fn run( + &self, + compilation: &mut Compilation, + _: &mut CompilationParams, + ) -> rspack_error::Result<()> { + let compilation = JsCompilationWrapper::new(compilation); + self.function.call_with_sync(compilation).await + } + + fn stage(&self) -> i32 { + self.stage + } +} + +#[async_trait] +impl CompilerMake for CompilerMakeTap { + async fn run(&self, compilation: &mut Compilation) -> rspack_error::Result<()> { + let compilation = JsCompilationWrapper::new(compilation); + self.function.call_with_promise(compilation).await + } + + fn stage(&self) -> i32 { + self.stage + } +} + +#[async_trait] +impl CompilerFinishMake for CompilerFinishMakeTap { + async fn run(&self, compilation: &mut Compilation) -> rspack_error::Result<()> { + let compilation = JsCompilationWrapper::new(compilation); + self.function.call_with_promise(compilation).await + } + + fn stage(&self) -> i32 { + self.stage + } +} + +#[async_trait] +impl CompilerShouldEmit for CompilerShouldEmitTap { + async fn run(&self, compilation: &mut Compilation) -> rspack_error::Result> { + let compilation = JsCompilationWrapper::new(compilation); + self.function.call_with_sync(compilation).await + } + + fn stage(&self) -> i32 { + self.stage + } +} + +#[async_trait] +impl CompilerEmit for CompilerEmitTap { + async fn run(&self, _compilation: &mut Compilation) -> rspack_error::Result<()> { + self.function.call_with_promise(()).await + } + + fn stage(&self) -> i32 { + self.stage + } +} + +#[async_trait] +impl CompilerAfterEmit for CompilerAfterEmitTap { + async fn run(&self, _compilation: &mut Compilation) -> rspack_error::Result<()> { + self.function.call_with_promise(()).await + } + + fn stage(&self) -> i32 { + self.stage + } +} + +#[async_trait] +impl CompilerAssetEmitted for CompilerAssetEmittedTap { + async fn run( + &self, + _compilation: &Compilation, + filename: &str, + info: &AssetEmittedInfo, + ) -> rspack_error::Result<()> { self .function - .call(compilation, ThreadsafeFunctionCallMode::NonBlocking) - .into_rspack_result()? + .call_with_promise(JsAssetEmittedArgs { + filename: filename.to_string(), + output_path: info.output_path.as_str().to_owned(), + target_path: info.target_path.as_str().to_owned(), + }) .await - .unwrap_or_else(|err| panic!("Failed to call compiler.hooks.compilation: {err}")) } fn stage(&self) -> i32 { @@ -147,62 +993,224 @@ impl AsyncSeries2 for CompilerCompilationTap { } #[async_trait] -impl Interceptor for ThreadsafeRegisterJsTaps { - async fn call( - &self, - hook: &CompilerCompilationHook, - ) -> rspack_error::Result::Tap>> { - let mut used_stages = Vec::from_iter(hook.used_stages()); - used_stages.sort(); - let js_taps: Vec> = self - .0 - .register_compiler_compilation_taps - .call(used_stages, ThreadsafeFunctionCallMode::NonBlocking) - .into_rspack_result()? +impl CompilationBuildModule for CompilationBuildModuleTap { + async fn run(&self, module: &mut BoxModule) -> rspack_error::Result<()> { + self + .function + .call_with_sync(module.to_js_module().expect("Convert to js_module failed.")) .await - .unwrap_or_else(|err| panic!("Failed to register compiler.hooks.compilation: {err}"))?; - let js_taps = js_taps - .into_iter() - .map(|t| Box::new(CompilerCompilationTap::new(t)) as ::Tap) - .collect(); - Ok(js_taps) + } + + fn stage(&self) -> i32 { + self.stage } } -#[derive(Clone)] -struct CompilerMakeTap { - function: ThreadsafeFunction, - stage: i32, +#[async_trait] +impl CompilationStillValidModule for CompilationStillValidModuleTap { + async fn run(&self, module: &mut BoxModule) -> rspack_error::Result<()> { + self + .function + .call_with_sync(module.to_js_module().expect("Convert to js_module failed.")) + .await + } + + fn stage(&self) -> i32 { + self.stage + } } -impl CompilerMakeTap { - pub fn new(tap: ThreadsafeJsTap) -> Self { - Self { - function: tap.function, - stage: tap.stage, +#[async_trait] +impl CompilationSucceedModule for CompilationSucceedModuleTap { + async fn run(&self, module: &mut BoxModule) -> rspack_error::Result<()> { + self + .function + .call_with_sync(module.to_js_module().expect("Convert to js_module failed.")) + .await + } + + fn stage(&self) -> i32 { + self.stage + } +} + +#[async_trait] +impl CompilationExecuteModule for CompilationExecuteModuleTap { + fn run( + &self, + entry: &ModuleIdentifier, + runtime_modules: &IdentifierSet, + codegen_results: &CodeGenerationResults, + id: &ExecuteModuleId, + ) -> rspack_error::Result<()> { + self.function.blocking_call_with_sync(JsExecuteModuleArg { + entry: entry.to_string(), + runtime_modules: runtime_modules.iter().map(|id| id.to_string()).collect(), + codegen_results: codegen_results.clone().into(), + id: *id, + }) + } + + fn stage(&self) -> i32 { + self.stage + } +} + +#[async_trait] +impl CompilationFinishModules for CompilationFinishModulesTap { + async fn run(&self, compilation: &mut Compilation) -> rspack_error::Result<()> { + let compilation = JsCompilationWrapper::new(compilation); + self.function.call_with_promise(compilation).await + } + + fn stage(&self) -> i32 { + self.stage + } +} + +#[async_trait] +impl CompilationOptimizeModules for CompilationOptimizeModulesTap { + async fn run(&self, _compilation: &mut Compilation) -> rspack_error::Result> { + self.function.call_with_sync(()).await + } + + fn stage(&self) -> i32 { + self.stage + } +} + +#[async_trait] +impl CompilationAfterOptimizeModules for CompilationAfterOptimizeModulesTap { + async fn run(&self, _compilation: &mut Compilation) -> rspack_error::Result<()> { + self.function.call_with_sync(()).await + } + + fn stage(&self) -> i32 { + self.stage + } +} + +#[async_trait] +impl CompilationOptimizeTree for CompilationOptimizeTreeTap { + async fn run(&self, _compilation: &mut Compilation) -> rspack_error::Result<()> { + self.function.call_with_promise(()).await + } + + fn stage(&self) -> i32 { + self.stage + } +} + +#[async_trait] +impl CompilationOptimizeChunkModules for CompilationOptimizeChunkModulesTap { + async fn run(&self, _compilation: &mut Compilation) -> rspack_error::Result> { + self.function.call_with_promise(()).await + } + + fn stage(&self) -> i32 { + self.stage + } +} + +#[async_trait] +impl CompilationAdditionalTreeRuntimeRequirements + for CompilationAdditionalTreeRuntimeRequirementsTap +{ + async fn run( + &self, + compilation: &mut Compilation, + chunk_ukey: &ChunkUkey, + runtime_requirements: &mut RuntimeGlobals, + ) -> rspack_error::Result<()> { + let chunk = compilation.chunk_by_ukey.expect_get(chunk_ukey); + let arg = JsAdditionalTreeRuntimeRequirementsArg { + chunk: JsChunk::from(chunk), + runtime_requirements: JsRuntimeGlobals::from(*runtime_requirements), + }; + let result = self.function.call_with_sync(arg).await?; + if let Some(result) = result { + let _ = std::mem::replace(runtime_requirements, result.as_runtime_globals()); } + Ok(()) + } + + fn stage(&self) -> i32 { + self.stage } } #[async_trait] -impl AsyncSeries2> for CompilerMakeTap { +impl CompilationRuntimeModule for CompilationRuntimeModuleTap { async fn run( &self, compilation: &mut Compilation, - _: &mut Vec, + m: &ModuleIdentifier, + c: &ChunkUkey, ) -> rspack_error::Result<()> { - let compilation = JsCompilation::from_compilation(unsafe { - std::mem::transmute::<&'_ mut rspack_core::Compilation, &'static mut rspack_core::Compilation>( - compilation, - ) - }); + let Some(module) = compilation.runtime_modules.get(m) else { + return Ok(()); + }; + let chunk = compilation.chunk_by_ukey.expect_get(c); + let arg = JsRuntimeModuleArg { + module: JsRuntimeModule { + source: Some( + module + .generate(compilation)? + .to_js_compat_source() + .unwrap_or_else(|err| panic!("Failed to generate runtime module source: {err}")), + ), + module_identifier: module.identifier().to_string(), + constructor_name: module.get_constructor_name(), + name: module.name().to_string().replace("webpack/runtime/", ""), + }, + chunk: JsChunk::from(chunk), + }; + if let Some(module) = self.function.call_with_sync(arg).await? + && let Some(source) = module.source + { + let module = compilation + .runtime_modules + .get_mut(m) + .expect("should have module"); + module.set_custom_source(CompatSource::from(source).boxed()) + } + Ok(()) + } + + fn stage(&self) -> i32 { + self.stage + } +} +#[async_trait] +impl CompilationChunkHash for CompilationChunkHashTap { + async fn run( + &self, + compilation: &Compilation, + chunk_ukey: &ChunkUkey, + hasher: &mut RspackHash, + ) -> rspack_error::Result<()> { + let chunk = compilation.chunk_by_ukey.expect_get(chunk_ukey); + let result = self.function.call_with_sync(JsChunk::from(chunk)).await?; + result.hash(hasher); + Ok(()) + } + + fn stage(&self) -> i32 { + self.stage + } +} + +#[async_trait] +impl CompilationChunkAsset for CompilationChunkAssetTap { + async fn run(&self, chunk: &mut Chunk, file: &str) -> rspack_error::Result<()> { self .function - .call(compilation, ThreadsafeFunctionCallMode::NonBlocking) - .into_rspack_result()? + .call_with_sync(JsChunkAssetArgs { + chunk: JsChunk::from(chunk), + filename: file.to_string(), + }) .await - .unwrap_or_else(|err| panic!("Failed to call compiler.hooks.make: {err}")) } fn stage(&self) -> i32 { @@ -211,58 +1219,154 @@ impl AsyncSeries2> for CompilerMakeTap { } #[async_trait] -impl Interceptor for ThreadsafeRegisterJsTaps { - async fn call( - &self, - hook: &CompilerMakeHook, - ) -> rspack_error::Result::Tap>> { - let mut used_stages = Vec::from_iter(hook.used_stages()); - used_stages.sort(); - let js_taps: Vec> = self - .0 - .register_compiler_make_taps - .call(used_stages, ThreadsafeFunctionCallMode::NonBlocking) - .into_rspack_result()? - .await - .unwrap_or_else(|err| panic!("Failed to register compiler.hooks.make: {err}"))?; - let js_taps = js_taps - .into_iter() - .map(|t| Box::new(CompilerMakeTap::new(t)) as ::Tap) - .collect(); - Ok(js_taps) +impl CompilationProcessAssets for CompilationProcessAssetsTap { + async fn run(&self, compilation: &mut Compilation) -> rspack_error::Result<()> { + let compilation = JsCompilationWrapper::new(compilation); + self.function.call_with_promise(compilation).await + } + + fn stage(&self) -> i32 { + self.stage } } -#[derive(Clone)] -struct CompilationProcessAssetsTap { - function: ThreadsafeFunction, - stage: i32, +#[async_trait] +impl CompilationAfterProcessAssets for CompilationAfterProcessAssetsTap { + async fn run(&self, compilation: &mut Compilation) -> rspack_error::Result<()> { + let compilation = JsCompilationWrapper::new(compilation); + self.function.call_with_sync(compilation).await + } + + fn stage(&self) -> i32 { + self.stage + } } -impl CompilationProcessAssetsTap { - pub fn new(tap: ThreadsafeJsTap) -> Self { - Self { - function: tap.function, - stage: tap.stage, +#[async_trait] +impl CompilationSeal for CompilationSealTap { + async fn run(&self, _compilation: &mut Compilation) -> rspack_error::Result<()> { + self.function.call_with_sync(()).await + } + + fn stage(&self) -> i32 { + self.stage + } +} + +#[async_trait] +impl CompilationAfterSeal for CompilationAfterSealTap { + async fn run(&self, _compilation: &mut Compilation) -> rspack_error::Result<()> { + self.function.call_with_promise(()).await + } + + fn stage(&self) -> i32 { + self.stage + } +} + +#[async_trait] +impl NormalModuleFactoryBeforeResolve for NormalModuleFactoryBeforeResolveTap { + async fn run(&self, data: &mut ModuleFactoryCreateData) -> rspack_error::Result> { + let dependency = data + .dependency + .as_module_dependency_mut() + .expect("should be module dependency"); + match self + .function + .call_with_promise(JsBeforeResolveArgs { + request: dependency.request().to_string(), + context: data.context.to_string(), + issuer: data + .issuer + .as_ref() + .map(|issuer| issuer.to_string()) + .unwrap_or_default(), + }) + .await + { + Ok((ret, resolve_data)) => { + dependency.set_request(resolve_data.request); + data.context = resolve_data.context.into(); + Ok(ret) + } + Err(err) => Err(err), } } + + fn stage(&self) -> i32 { + self.stage + } } #[async_trait] -impl AsyncSeries for CompilationProcessAssetsTap { - async fn run(&self, compilation: &mut Compilation) -> rspack_error::Result<()> { - let compilation = JsCompilation::from_compilation(unsafe { - std::mem::transmute::<&'_ mut rspack_core::Compilation, &'static mut rspack_core::Compilation>( - compilation, - ) - }); +impl NormalModuleFactoryFactorize for NormalModuleFactoryFactorizeTap { + async fn run( + &self, + data: &mut ModuleFactoryCreateData, + ) -> rspack_error::Result> { + let dependency = data + .dependency + .as_module_dependency_mut() + .expect("should be module dependency"); + match self + .function + .call_with_promise(JsFactorizeArgs { + request: dependency.request().to_string(), + context: data.context.to_string(), + issuer: data + .issuer + .as_ref() + .map(|issuer| issuer.to_string()) + .unwrap_or_default(), + }) + .await + { + Ok(resolve_data) => { + dependency.set_request(resolve_data.request); + data.context = resolve_data.context.into(); + // only supports update resolve request for now + Ok(None) + } + Err(err) => Err(err), + } + } - self + fn stage(&self) -> i32 { + self.stage + } +} + +#[async_trait] +impl NormalModuleFactoryResolve for NormalModuleFactoryResolveTap { + async fn run( + &self, + data: &mut ModuleFactoryCreateData, + ) -> rspack_error::Result> { + let dependency = data + .dependency + .as_module_dependency_mut() + .expect("should be module dependency"); + match self .function - .call(compilation, ThreadsafeFunctionCallMode::NonBlocking) - .into_rspack_result()? + .call_with_promise(JsResolveArgs { + request: dependency.request().to_string(), + context: data.context.to_string(), + issuer: data + .issuer + .as_ref() + .map(|issuer| issuer.to_string()) + .unwrap_or_default(), + }) .await - .unwrap_or_else(|err| panic!("Failed to call compilation.hooks.processAssets: {err}")) + { + Ok(resolve_data) => { + dependency.set_request(resolve_data.request); + data.context = resolve_data.context.into(); + // only supports update resolve request for now + Ok(None) + } + Err(err) => Err(err), + } } fn stage(&self) -> i32 { @@ -271,26 +1375,314 @@ impl AsyncSeries for CompilationProcessAssetsTap { } #[async_trait] -impl Interceptor for ThreadsafeRegisterJsTaps { - async fn call( +impl NormalModuleFactoryResolveForScheme for NormalModuleFactoryResolveForSchemeTap { + async fn run( &self, - hook: &CompilationProcessAssetsHook, - ) -> rspack_error::Result::Tap>> { - let mut used_stages = Vec::from_iter(hook.used_stages()); - used_stages.sort(); - let js_taps: Vec> = self - .0 - .register_compilation_process_assets_taps - .call(used_stages, ThreadsafeFunctionCallMode::NonBlocking) - .into_rspack_result()? + _data: &mut ModuleFactoryCreateData, + resource_data: &mut ResourceData, + scheme: &Scheme, + ) -> rspack_error::Result> { + let (bail, new_resource_data) = self + .function + .call_with_promise(JsResolveForSchemeArgs { + resource_data: resource_data.clone().into(), + scheme: scheme.to_string(), + }) + .await?; + resource_data.set_resource(new_resource_data.resource); + resource_data.set_path_optional(new_resource_data.path.map(Utf8PathBuf::from)); + resource_data.set_query_optional(new_resource_data.query); + resource_data.set_fragment_optional(new_resource_data.fragment); + Ok(bail) + } + + fn stage(&self) -> i32 { + self.stage + } +} + +#[async_trait] +impl NormalModuleFactoryAfterResolve for NormalModuleFactoryAfterResolveTap { + async fn run( + &self, + data: &mut ModuleFactoryCreateData, + create_data: &mut NormalModuleCreateData, + ) -> rspack_error::Result> { + match self + .function + .call_with_promise(JsAfterResolveData { + request: create_data.raw_request.to_string(), + context: data.context.to_string(), + issuer: data + .issuer + .as_ref() + .map(|issuer| issuer.to_string()) + .unwrap_or_default(), + file_dependencies: data + .file_dependencies + .clone() + .into_iter() + .map(|item| item.to_string_lossy().to_string()) + .collect::>(), + context_dependencies: data + .context_dependencies + .clone() + .into_iter() + .map(|item| item.to_string_lossy().to_string()) + .collect::>(), + missing_dependencies: data + .missing_dependencies + .clone() + .into_iter() + .map(|item| item.to_string_lossy().to_string()) + .collect::>(), + create_data: Some(JsCreateData { + request: create_data.request.to_owned(), + user_request: create_data.user_request.to_owned(), + resource: create_data.resource_resolve_data.resource.to_owned(), + }), + }) .await - .unwrap_or_else(|err| panic!("Failed to register compilation.hooks.processAssets: {err}"))?; - let js_taps = js_taps - .into_iter() - .map(|t| { - Box::new(CompilationProcessAssetsTap::new(t)) as ::Tap + { + Ok((ret, resolve_data)) => { + if let Some(resolve_data) = resolve_data { + fn update_resource_data(old_resource_data: &mut ResourceData, new_resource: String) { + if old_resource_data.resource_path.is_some() + && let Some(parsed) = parse_resource(&new_resource) + { + old_resource_data.set_path(parsed.path); + old_resource_data.set_query_optional(parsed.query); + old_resource_data.set_fragment_optional(parsed.fragment); + } + old_resource_data.set_resource(new_resource); + } + + create_data.request = resolve_data.request; + create_data.user_request = resolve_data.user_request; + update_resource_data( + &mut create_data.resource_resolve_data, + resolve_data.resource, + ); + } + + Ok(ret) + } + Err(err) => Err(err), + } + } + + fn stage(&self) -> i32 { + self.stage + } +} + +#[async_trait] +impl NormalModuleFactoryCreateModule for NormalModuleFactoryCreateModuleTap { + async fn run( + &self, + data: &mut ModuleFactoryCreateData, + create_data: &mut NormalModuleCreateData, + ) -> rspack_error::Result> { + self + .function + .call_with_promise(JsNormalModuleFactoryCreateModuleArgs { + dependency_type: data.dependency.dependency_type().to_string(), + raw_request: create_data.raw_request.clone(), + resource_resolve_data: create_data.resource_resolve_data.clone().into(), + context: data.context.to_string(), + match_resource: create_data.match_resource.clone(), }) - .collect(); - Ok(js_taps) + .await?; + Ok(None) + } + + fn stage(&self) -> i32 { + self.stage + } +} + +#[async_trait] +impl ContextModuleFactoryBeforeResolve for ContextModuleFactoryBeforeResolveTap { + async fn run(&self, result: BeforeResolveResult) -> rspack_error::Result { + let js_result = match result { + BeforeResolveResult::Ignored => JsContextModuleFactoryBeforeResolveResult::A(false), + BeforeResolveResult::Data(d) => { + JsContextModuleFactoryBeforeResolveResult::B(JsContextModuleFactoryBeforeResolveData { + context: d.context, + request: d.request, + }) + } + }; + match self.function.call_with_promise(js_result).await { + Ok(js_result) => match js_result { + napi::bindgen_prelude::Either::A(_) => Ok(BeforeResolveResult::Ignored), + napi::bindgen_prelude::Either::B(d) => { + let data = BeforeResolveData { + context: d.context, + request: d.request, + }; + Ok(BeforeResolveResult::Data(Box::new(data))) + } + }, + Err(err) => Err(err), + } + } + + fn stage(&self) -> i32 { + self.stage + } +} + +#[async_trait] +impl ContextModuleFactoryAfterResolve for ContextModuleFactoryAfterResolveTap { + async fn run(&self, result: AfterResolveResult) -> rspack_error::Result { + let js_result = match result { + AfterResolveResult::Ignored => JsContextModuleFactoryAfterResolveResult::A(false), + AfterResolveResult::Data(d) => { + JsContextModuleFactoryAfterResolveResult::B(JsContextModuleFactoryAfterResolveData { + resource: d.resource.as_str().to_owned(), + context: d.context.to_owned(), + request: d.request.to_owned(), + reg_exp: d.reg_exp.clone().map(|r| r.into()), + }) + } + }; + match self.function.call_with_promise(js_result).await? { + napi::Either::A(_) => Ok(AfterResolveResult::Ignored), + napi::Either::B(d) => { + let data = AfterResolveData { + resource: d.resource.into(), + context: d.context, + request: d.request, + reg_exp: match d.reg_exp { + Some(r) => Some(r.try_into()?), + None => None, + }, + }; + Ok(AfterResolveResult::Data(Box::new(data))) + } + } + } + + fn stage(&self) -> i32 { + self.stage + } +} + +#[async_trait] +impl JavascriptModulesChunkHash for JavascriptModulesChunkHashTap { + async fn run( + &self, + compilation: &Compilation, + chunk_ukey: &ChunkUkey, + hasher: &mut RspackHash, + ) -> rspack_error::Result<()> { + let chunk = compilation.chunk_by_ukey.expect_get(chunk_ukey); + let result = self.function.call_with_sync(JsChunk::from(chunk)).await?; + result.hash(hasher); + Ok(()) + } + + fn stage(&self) -> i32 { + self.stage + } +} + +#[async_trait] +impl HtmlPluginBeforeAssetTagGeneration for HtmlPluginBeforeAssetTagGenerationTap { + async fn run( + &self, + data: BeforeAssetTagGenerationData, + ) -> rspack_error::Result { + let result = self + .function + .call_with_promise(JsBeforeAssetTagGenerationData::from(data)) + .await?; + Ok(result.into()) + } + + fn stage(&self) -> i32 { + self.stage + } +} + +#[async_trait] +impl HtmlPluginAlterAssetTags for HtmlPluginAlterAssetTagsTap { + async fn run(&self, data: AlterAssetTagsData) -> rspack_error::Result { + let result = self + .function + .call_with_promise(JsAlterAssetTagsData::from(data)) + .await?; + Ok(result.into()) + } + + fn stage(&self) -> i32 { + self.stage + } +} + +#[async_trait] +impl HtmlPluginAlterAssetTagGroups for HtmlPluginAlterAssetTagGroupsTap { + async fn run( + &self, + data: AlterAssetTagGroupsData, + ) -> rspack_error::Result { + let result = self + .function + .call_with_promise(JsAlterAssetTagGroupsData::from(data)) + .await?; + Ok(result.into()) + } + + fn stage(&self) -> i32 { + self.stage + } +} + +#[async_trait] +impl HtmlPluginAfterTemplateExecution for HtmlPluginAfterTemplateExecutionTap { + async fn run( + &self, + data: AfterTemplateExecutionData, + ) -> rspack_error::Result { + let result = self + .function + .call_with_promise(JsAfterTemplateExecutionData::from(data)) + .await?; + Ok(result.into()) + } + + fn stage(&self) -> i32 { + self.stage + } +} + +#[async_trait] +impl HtmlPluginBeforeEmit for HtmlPluginBeforeEmitTap { + async fn run(&self, data: BeforeEmitData) -> rspack_error::Result { + let result = self + .function + .call_with_promise(JsBeforeEmitData::from(data)) + .await?; + Ok(result.into()) + } + + fn stage(&self) -> i32 { + self.stage + } +} + +#[async_trait] +impl HtmlPluginAfterEmit for HtmlPluginAfterEmitTap { + async fn run(&self, data: AfterEmitData) -> rspack_error::Result { + let result = self + .function + .call_with_promise(JsAfterEmitData::from(data)) + .await?; + Ok(result.into()) + } + + fn stage(&self) -> i32 { + self.stage } } diff --git a/crates/node_binding/src/plugins/loader.rs b/crates/node_binding/src/plugins/loader.rs deleted file mode 100644 index b834dd1..0000000 --- a/crates/node_binding/src/plugins/loader.rs +++ /dev/null @@ -1,97 +0,0 @@ -use std::{fmt::Debug, path::Path, sync::Arc}; - -use binding_options::get_builtin_loader; -use rspack_binding_options::{JsLoaderAdapter, JsLoaderRunner}; -use rspack_core::{ - BoxLoader, CompilerOptions, NormalModule, Plugin, ResolveResult, Resolver, BUILTIN_LOADER_PREFIX, -}; -use rspack_error::{error, Result}; - -pub struct JsLoaderResolver { - pub js_loader_runner: JsLoaderRunner, -} - -impl Debug for JsLoaderResolver { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("JsLoaderResolver") - .field("js_loader_runner", &"..") - .finish() - } -} - -#[async_trait::async_trait] -impl Plugin for JsLoaderResolver { - async fn before_loaders(&self, module: &mut NormalModule) -> Result<()> { - let contains_inline = module.contains_inline_loader(); - let contains_js_loader = module - .loaders() - .iter() - .any(|l| !l.identifier().starts_with(BUILTIN_LOADER_PREFIX)); - - // If there's any JS loader, then we switch to the JS loader runner. - // Else, we run loader on the Rust side using the Rust loader runner. - // Note: If the loaders list contains inline loaders, - // fallback to JS loader runner for passing builtin options(reuse `Compiler.ruleSet`). - if contains_inline || contains_js_loader { - *module.loaders_mut_vec() = vec![Arc::new(JsLoaderAdapter { - runner: self.js_loader_runner.clone(), - identifier: module - .loaders() - .iter() - .map(|l| l.identifier().as_str()) - .collect::>() - .join("$") - .into(), - })]; - } - - Ok(()) - } - - async fn resolve_loader( - &self, - _compiler_options: &CompilerOptions, - context: &Path, - resolver: &Resolver, - loader_request: &str, - loader_options: Option<&str>, - ) -> Result> { - let mut rest = None; - let prev = if let Some(index) = loader_request.find('?') { - rest = Some(&loader_request[index..]); - Path::new(&loader_request[0..index]) - } else { - Path::new(loader_request) - }; - - if loader_request.starts_with(BUILTIN_LOADER_PREFIX) { - return Ok(Some(get_builtin_loader(loader_request, loader_options))); - } - - let resolve_result = resolver - .resolve(context, &prev.to_string_lossy()) - .map_err(|err| { - let loader_request = prev.display(); - let context = context.display(); - error!("Failed to resolve loader: {loader_request} in {context} {err:?}") - })?; - - match resolve_result { - ResolveResult::Resource(resource) => { - // TODO: Should move this logic to `resolver`, since `resolve.alias` may contain query or fragment too. @Boshen - let resource = resource.path.to_string_lossy().to_string() + rest.unwrap_or_default(); - Ok(Some(Arc::new(JsLoaderAdapter { - identifier: resource.into(), - runner: self.js_loader_runner.clone(), - }))) - } - ResolveResult::Ignored => { - let loader_request = prev.display(); - let context = context.to_string_lossy(); - Err(error!( - "Failed to resolve loader: loader_request={loader_request}, context={context}" - )) - } - } - } -} diff --git a/crates/node_binding/src/plugins/mod.rs b/crates/node_binding/src/plugins/mod.rs index 01d77c1..a1596a7 100644 --- a/crates/node_binding/src/plugins/mod.rs +++ b/crates/node_binding/src/plugins/mod.rs @@ -1,73 +1,70 @@ mod interceptor; -mod loader; use std::fmt; -use std::path::PathBuf; -use std::sync::Arc; use async_trait::async_trait; +pub use interceptor::RegisterJsTapKind; pub use interceptor::RegisterJsTaps; use napi::{Env, Result}; -use rspack_binding_macros::js_fn_into_threadsafe_fn; -use rspack_binding_values::{ - AfterResolveData, JsChunk, JsChunkAssetArgs, JsModule, JsRuntimeModule, JsRuntimeModuleArg, - ToJsCompatSource, -}; -use rspack_binding_values::{BeforeResolveData, JsAssetEmittedArgs, ToJsModule}; -use rspack_binding_values::{CreateModuleData, JsBuildTimeExecutionOption, JsExecuteModuleArg}; -use rspack_binding_values::{JsResolveForSchemeInput, JsResolveForSchemeResult}; -use rspack_core::rspack_sources::Source; -use rspack_core::{ - ApplyContext, BuildTimeExecutionOption, Chunk, ChunkAssetArgs, CompilerOptions, ModuleIdentifier, - NormalModuleAfterResolveArgs, PluginContext, RuntimeModule, -}; -use rspack_core::{NormalModuleBeforeResolveArgs, PluginNormalModuleFactoryAfterResolveOutput}; -use rspack_core::{ - NormalModuleCreateData, PluginNormalModuleFactoryBeforeResolveOutput, - PluginNormalModuleFactoryCreateModuleHookOutput, ResourceData, -}; -use rspack_core::{PluginNormalModuleFactoryResolveForSchemeOutput, PluginShouldEmitHookOutput}; -use rspack_napi_shared::threadsafe_function::{ThreadsafeFunction, ThreadsafeFunctionCallMode}; -use rspack_napi_shared::NapiResultExt; - -use self::interceptor::ThreadsafeRegisterJsTaps; -pub use self::loader::JsLoaderResolver; -use crate::{DisabledHooks, Hook, JsCompilation, JsHooks}; - -pub struct JsHooksAdapterInner { - pub disabled_hooks: DisabledHooks, - pub this_compilation_tsfn: ThreadsafeFunction, - pub after_process_assets_tsfn: ThreadsafeFunction<(), ()>, - pub emit_tsfn: ThreadsafeFunction<(), ()>, - pub asset_emitted_tsfn: ThreadsafeFunction, - pub should_emit_tsfn: ThreadsafeFunction>, - pub after_emit_tsfn: ThreadsafeFunction<(), ()>, - pub optimize_modules_tsfn: ThreadsafeFunction, - pub after_optimize_modules_tsfn: ThreadsafeFunction, - pub optimize_tree_tsfn: ThreadsafeFunction<(), ()>, - pub optimize_chunk_modules_tsfn: ThreadsafeFunction, - pub before_compile_tsfn: ThreadsafeFunction<(), ()>, - pub after_compile_tsfn: ThreadsafeFunction, - pub finish_modules_tsfn: ThreadsafeFunction, - pub finish_make_tsfn: ThreadsafeFunction, - pub build_module_tsfn: ThreadsafeFunction, // TODO - pub chunk_asset_tsfn: ThreadsafeFunction, - pub before_resolve: ThreadsafeFunction, BeforeResolveData)>, - pub after_resolve: ThreadsafeFunction>, - pub context_module_factory_before_resolve: ThreadsafeFunction>, - pub context_module_factory_after_resolve: ThreadsafeFunction>, - pub normal_module_factory_create_module: ThreadsafeFunction, - pub normal_module_factory_resolve_for_scheme: - ThreadsafeFunction, - pub succeed_module_tsfn: ThreadsafeFunction, - pub still_valid_module_tsfn: ThreadsafeFunction, - pub execute_module_tsfn: ThreadsafeFunction, - pub runtime_module_tsfn: ThreadsafeFunction>, -} - +use rspack_core::Compilation; +use rspack_core::CompilationParams; +use rspack_core::CompilerCompilation; +use rspack_core::{ApplyContext, CompilerOptions, PluginContext}; +use rspack_hook::plugin; +use rspack_hook::plugin_hook; +use rspack_hook::Hook as _; +use rspack_plugin_html::HtmlRspackPlugin; +use rspack_plugin_javascript::JsPlugin; + +use self::interceptor::*; + +#[plugin] #[derive(Clone)] pub struct JsHooksAdapterPlugin { - inner: Arc, - interceptor: Box, + non_skippable_registers: NonSkippableRegisters, + register_compiler_this_compilation_taps: RegisterCompilerThisCompilationTaps, + register_compiler_compilation_taps: RegisterCompilerCompilationTaps, + register_compiler_make_taps: RegisterCompilerMakeTaps, + register_compiler_finish_make_taps: RegisterCompilerFinishMakeTaps, + register_compiler_should_emit_taps: RegisterCompilerShouldEmitTaps, + register_compiler_emit_taps: RegisterCompilerEmitTaps, + register_compiler_after_emit_taps: RegisterCompilerAfterEmitTaps, + register_compiler_asset_emitted_taps: RegisterCompilerAssetEmittedTaps, + register_compilation_build_module_taps: RegisterCompilationBuildModuleTaps, + register_compilation_still_valid_module_taps: RegisterCompilationStillValidModuleTaps, + register_compilation_succeed_module_taps: RegisterCompilationSucceedModuleTaps, + register_compilation_execute_module_taps: RegisterCompilationExecuteModuleTaps, + register_compilation_finish_modules_taps: RegisterCompilationFinishModulesTaps, + register_compilation_optimize_modules_taps: RegisterCompilationOptimizeModulesTaps, + register_compilation_after_optimize_modules_taps: RegisterCompilationAfterOptimizeModulesTaps, + register_compilation_optimize_tree_taps: RegisterCompilationOptimizeTreeTaps, + register_compilation_optimize_chunk_modules_taps: RegisterCompilationOptimizeChunkModulesTaps, + register_compilation_additional_tree_runtime_requirements: + RegisterCompilationAdditionalTreeRuntimeRequirementsTaps, + register_compilation_runtime_module_taps: RegisterCompilationRuntimeModuleTaps, + register_compilation_chunk_hash_taps: RegisterCompilationChunkHashTaps, + register_compilation_chunk_asset_taps: RegisterCompilationChunkAssetTaps, + register_compilation_process_assets_taps: RegisterCompilationProcessAssetsTaps, + register_compilation_after_process_assets_taps: RegisterCompilationAfterProcessAssetsTaps, + register_compilation_seal_taps: RegisterCompilationSealTaps, + register_compilation_after_seal_taps: RegisterCompilationAfterSealTaps, + register_normal_module_factory_before_resolve_taps: RegisterNormalModuleFactoryBeforeResolveTaps, + register_normal_module_factory_factorize_taps: RegisterNormalModuleFactoryFactorizeTaps, + register_normal_module_factory_resolve_taps: RegisterNormalModuleFactoryResolveTaps, + register_normal_module_factory_resolve_for_scheme_taps: + RegisterNormalModuleFactoryResolveForSchemeTaps, + register_normal_module_factory_after_resolve_taps: RegisterNormalModuleFactoryAfterResolveTaps, + register_normal_module_factory_create_module_taps: RegisterNormalModuleFactoryCreateModuleTaps, + register_context_module_factory_before_resolve_taps: + RegisterContextModuleFactoryBeforeResolveTaps, + register_context_module_factory_after_resolve_taps: RegisterContextModuleFactoryAfterResolveTaps, + register_javascript_modules_chunk_hash_taps: RegisterJavascriptModulesChunkHashTaps, + register_html_plugin_before_asset_tag_generation_taps: + RegisterHtmlPluginBeforeAssetTagGenerationTaps, + register_html_plugin_alter_asset_tags_taps: RegisterHtmlPluginAlterAssetTagsTaps, + register_html_plugin_alter_asset_tag_groups_taps: RegisterHtmlPluginAlterAssetTagGroupsTaps, + register_html_plugin_after_template_execution_taps: RegisterHtmlPluginAfterTemplateExecutionTaps, + register_html_plugin_before_emit_taps: RegisterHtmlPluginBeforeEmitTaps, + register_html_plugin_after_emit_taps: RegisterHtmlPluginAfterEmitTaps, } impl fmt::Debug for JsHooksAdapterPlugin { @@ -76,15 +73,6 @@ impl fmt::Debug for JsHooksAdapterPlugin { } } -// TODO: remove deref -impl std::ops::Deref for JsHooksAdapterPlugin { - type Target = JsHooksAdapterInner; - - fn deref(&self) -> &Self::Target { - &self.inner - } -} - #[async_trait] impl rspack_core::Plugin for JsHooksAdapterPlugin { fn name(&self) -> &'static str { @@ -97,673 +85,462 @@ impl rspack_core::Plugin for JsHooksAdapterPlugin { ctx: PluginContext<&mut ApplyContext>, _options: &mut CompilerOptions, ) -> rspack_error::Result<()> { + ctx + .context + .compiler_hooks + .this_compilation + .intercept(self.register_compiler_this_compilation_taps.clone()); ctx .context .compiler_hooks .compilation - .intercept(self.interceptor.clone()); + .intercept(self.register_compiler_compilation_taps.clone()); ctx .context .compiler_hooks .make - .intercept(self.interceptor.clone()); + .intercept(self.register_compiler_make_taps.clone()); + ctx + .context + .compiler_hooks + .finish_make + .intercept(self.register_compiler_finish_make_taps.clone()); + ctx + .context + .compiler_hooks + .should_emit + .intercept(self.register_compiler_should_emit_taps.clone()); + ctx + .context + .compiler_hooks + .emit + .intercept(self.register_compiler_emit_taps.clone()); + ctx + .context + .compiler_hooks + .after_emit + .intercept(self.register_compiler_after_emit_taps.clone()); + ctx + .context + .compiler_hooks + .asset_emitted + .intercept(self.register_compiler_asset_emitted_taps.clone()); + ctx + .context + .compilation_hooks + .build_module + .intercept(self.register_compilation_build_module_taps.clone()); + ctx + .context + .compilation_hooks + .still_valid_module + .intercept(self.register_compilation_still_valid_module_taps.clone()); + ctx + .context + .compilation_hooks + .succeed_module + .intercept(self.register_compilation_succeed_module_taps.clone()); + ctx + .context + .compilation_hooks + .execute_module + .intercept(self.register_compilation_execute_module_taps.clone()); + ctx + .context + .compilation_hooks + .finish_modules + .intercept(self.register_compilation_finish_modules_taps.clone()); + ctx + .context + .compilation_hooks + .optimize_modules + .intercept(self.register_compilation_optimize_modules_taps.clone()); + ctx + .context + .compilation_hooks + .after_optimize_modules + .intercept( + self + .register_compilation_after_optimize_modules_taps + .clone(), + ); + ctx + .context + .compilation_hooks + .optimize_tree + .intercept(self.register_compilation_optimize_tree_taps.clone()); + ctx + .context + .compilation_hooks + .optimize_chunk_modules + .intercept( + self + .register_compilation_optimize_chunk_modules_taps + .clone(), + ); + ctx + .context + .compilation_hooks + .additional_tree_runtime_requirements + .intercept( + self + .register_compilation_additional_tree_runtime_requirements + .clone(), + ); + ctx + .context + .compilation_hooks + .runtime_module + .intercept(self.register_compilation_runtime_module_taps.clone()); + ctx + .context + .compilation_hooks + .chunk_hash + .intercept(self.register_compilation_chunk_hash_taps.clone()); + ctx + .context + .compilation_hooks + .chunk_asset + .intercept(self.register_compilation_chunk_asset_taps.clone()); ctx .context .compilation_hooks .process_assets - .intercept(self.interceptor.clone()); - Ok(()) - } - - async fn this_compilation( - &self, - args: rspack_core::ThisCompilationArgs<'_>, - _params: &rspack_core::CompilationParams, - ) -> rspack_core::PluginThisCompilationHookOutput { - if self.is_hook_disabled(&Hook::ThisCompilation) { - return Ok(()); - } - - let compilation = JsCompilation::from_compilation(unsafe { - std::mem::transmute::<&'_ mut rspack_core::Compilation, &'static mut rspack_core::Compilation>( - args.this_compilation, - ) - }); - - self - .this_compilation_tsfn - .call(compilation, ThreadsafeFunctionCallMode::NonBlocking) - .into_rspack_result()? - .await - .unwrap_or_else(|err| panic!("Failed to call this_compilation: {err}")) - } - - async fn chunk_asset(&self, args: &ChunkAssetArgs) -> rspack_error::Result<()> { - if self.is_hook_disabled(&Hook::ChunkAsset) { - return Ok(()); - } - - self - .chunk_asset_tsfn - .call( - JsChunkAssetArgs::from(args), - ThreadsafeFunctionCallMode::NonBlocking, - ) - .into_rspack_result()? - .await - .unwrap_or_else(|err| panic!("Failed to chunk asset: {err}")) - } + .intercept(self.register_compilation_process_assets_taps.clone()); + ctx + .context + .compilation_hooks + .after_process_assets + .intercept(self.register_compilation_after_process_assets_taps.clone()); + ctx + .context + .compilation_hooks + .seal + .intercept(self.register_compilation_seal_taps.clone()); + ctx + .context + .compilation_hooks + .after_seal + .intercept(self.register_compilation_after_seal_taps.clone()); - async fn before_resolve( - &self, - _ctx: rspack_core::PluginContext, - args: &mut NormalModuleBeforeResolveArgs, - ) -> PluginNormalModuleFactoryBeforeResolveOutput { - if self.is_hook_disabled(&Hook::BeforeResolve) { - return Ok(None); - } - match self + ctx + .context + .normal_module_factory_hooks .before_resolve - .call(args.clone().into(), ThreadsafeFunctionCallMode::NonBlocking) - .into_rspack_result()? - .await - .unwrap_or_else(|err| panic!("Failed to call this_compilation: {err}")) - { - Ok((ret, resolve_data)) => { - args.request = resolve_data.request; - args.context = resolve_data.context; - Ok(ret) - } - Err(err) => Err(err), - } - } - - async fn after_resolve( - &self, - _ctx: rspack_core::PluginContext, - args: &mut NormalModuleAfterResolveArgs<'_>, - ) -> PluginNormalModuleFactoryAfterResolveOutput { - if self.is_hook_disabled(&Hook::AfterResolve) { - return Ok(None); - } - self + .intercept( + self + .register_normal_module_factory_before_resolve_taps + .clone(), + ); + ctx + .context + .normal_module_factory_hooks + .factorize + .intercept(self.register_normal_module_factory_factorize_taps.clone()); + ctx + .context + .normal_module_factory_hooks + .resolve + .intercept(self.register_normal_module_factory_resolve_taps.clone()); + ctx + .context + .normal_module_factory_hooks + .resolve_for_scheme + .intercept( + self + .register_normal_module_factory_resolve_for_scheme_taps + .clone(), + ); + ctx + .context + .normal_module_factory_hooks .after_resolve - .call((&*args).into(), ThreadsafeFunctionCallMode::NonBlocking) - .into_rspack_result()? - .await - .unwrap_or_else(|err| panic!("Failed to call this_compilation: {err}")) - } - - async fn context_module_before_resolve( - &self, - _ctx: rspack_core::PluginContext, - args: &mut NormalModuleBeforeResolveArgs, - ) -> PluginNormalModuleFactoryBeforeResolveOutput { - if self.is_hook_disabled(&Hook::ContextModuleFactoryBeforeResolve) { - return Ok(None); - } - self - .context_module_factory_before_resolve - .call(args.clone().into(), ThreadsafeFunctionCallMode::NonBlocking) - .into_rspack_result()? - .await - .unwrap_or_else(|err| panic!("Failed to call this_compilation: {err}")) - } - - async fn context_module_after_resolve( - &self, - _ctx: rspack_core::PluginContext, - args: &mut NormalModuleAfterResolveArgs<'_>, - ) -> PluginNormalModuleFactoryBeforeResolveOutput { - if self.is_hook_disabled(&Hook::ContextModuleFactoryAfterResolve) { - return Ok(None); - } - self - .context_module_factory_after_resolve - .call((&*args).into(), ThreadsafeFunctionCallMode::NonBlocking) - .into_rspack_result()? - .await - .unwrap_or_else(|err| panic!("Failed to call this_compilation: {err}")) - } - - async fn normal_module_factory_create_module( - &self, - _ctx: rspack_core::PluginContext, - args: &mut NormalModuleCreateData<'_>, - ) -> PluginNormalModuleFactoryCreateModuleHookOutput { - if self.is_hook_disabled(&Hook::NormalModuleFactoryCreateModule) { - return Ok(None); - } - self - .normal_module_factory_create_module - .call(args.into(), ThreadsafeFunctionCallMode::NonBlocking) - .into_rspack_result()? - .await - .map(|_| None) - .map_err(|err| panic!("Failed to call this_compilation: {err}")) - } - - async fn normal_module_factory_resolve_for_scheme( - &self, - _ctx: rspack_core::PluginContext, - args: ResourceData, - ) -> PluginNormalModuleFactoryResolveForSchemeOutput { - if self.is_hook_disabled(&Hook::NormalModuleFactoryResolveForScheme) { - return Ok((args, false)); - } - let res = self - .normal_module_factory_resolve_for_scheme - .call(args.into(), ThreadsafeFunctionCallMode::NonBlocking) - .into_rspack_result()? - .await - .unwrap_or_else(|err| panic!("Failed to call this_compilation: {err}")); - res.map(|res| { - let JsResolveForSchemeResult { - resource_data, - stop, - } = res; - ( - ResourceData::new(resource_data.resource, PathBuf::from(resource_data.path)) - .query_optional(resource_data.query) - .fragment_optional(resource_data.fragment), - stop, - ) - }) - } - - async fn after_process_assets( - &self, - _ctx: rspack_core::PluginContext, - _args: rspack_core::ProcessAssetsArgs<'_>, - ) -> rspack_core::PluginProcessAssetsHookOutput { - if self.is_hook_disabled(&Hook::AfterProcessAssets) { - return Ok(()); - } - self - .after_process_assets_tsfn - .call((), ThreadsafeFunctionCallMode::NonBlocking) - .into_rspack_result()? - .await - .unwrap_or_else(|err| panic!("Failed to call process assets stage report: {err}")) - } - - async fn optimize_modules( - &self, - compilation: &mut rspack_core::Compilation, - ) -> rspack_error::Result<()> { - if self.is_hook_disabled(&Hook::OptimizeModules) { - return Ok(()); - } - let compilation = JsCompilation::from_compilation(unsafe { - std::mem::transmute::<&'_ mut rspack_core::Compilation, &'static mut rspack_core::Compilation>( - compilation, - ) - }); - self - .optimize_modules_tsfn - .call(compilation, ThreadsafeFunctionCallMode::Blocking) - .into_rspack_result()? - .await - .unwrap_or_else(|err| panic!("Failed to call optimize modules: {err}")) - } - - async fn after_optimize_modules( - &self, - compilation: &mut rspack_core::Compilation, - ) -> rspack_error::Result<()> { - if self.is_hook_disabled(&Hook::AfterOptimizeModules) { - return Ok(()); - } - let compilation = JsCompilation::from_compilation(unsafe { - std::mem::transmute::<&'_ mut rspack_core::Compilation, &'static mut rspack_core::Compilation>( - compilation, - ) - }); - self - .after_optimize_modules_tsfn - .call(compilation, ThreadsafeFunctionCallMode::Blocking) - .into_rspack_result()? - .await - .unwrap_or_else(|err| panic!("Failed to call optimize modules: {err}")) - } - - async fn optimize_tree( - &self, - _compilation: &mut rspack_core::Compilation, - ) -> rspack_error::Result<()> { - if self.is_hook_disabled(&Hook::OptimizeTree) { - return Ok(()); - } - self - .optimize_tree_tsfn - .call((), ThreadsafeFunctionCallMode::NonBlocking) - .into_rspack_result()? - .await - .unwrap_or_else(|err| panic!("Failed to call optimize tree: {err}")) - } - - async fn optimize_chunk_modules( - &self, - args: rspack_core::OptimizeChunksArgs<'_>, - ) -> rspack_error::Result<()> { - if self.is_hook_disabled(&Hook::OptimizeChunkModules) { - return Ok(()); - } - - let compilation = JsCompilation::from_compilation(unsafe { - std::mem::transmute::<&'_ mut rspack_core::Compilation, &'static mut rspack_core::Compilation>( - args.compilation, - ) - }); - - self - .optimize_chunk_modules_tsfn - .call(compilation, ThreadsafeFunctionCallMode::NonBlocking) - .into_rspack_result()? - .await - .unwrap_or_else(|err| panic!("Failed to compilation: {err}")) - } - - async fn before_compile( - &self, - _params: &rspack_core::CompilationParams, - ) -> rspack_error::Result<()> { - if self.is_hook_disabled(&Hook::BeforeCompile) { - return Ok(()); - } - - self - .before_compile_tsfn - .call({}, ThreadsafeFunctionCallMode::NonBlocking) - .into_rspack_result()? - .await - .unwrap_or_else(|err| panic!("Failed to call before compile: {err}")) - } - - async fn after_compile( - &self, - compilation: &mut rspack_core::Compilation, - ) -> rspack_error::Result<()> { - if self.is_hook_disabled(&Hook::AfterCompile) { - return Ok(()); - } - - let compilation = JsCompilation::from_compilation(unsafe { - std::mem::transmute::<&'_ mut rspack_core::Compilation, &'static mut rspack_core::Compilation>( - compilation, - ) - }); - - self - .after_compile_tsfn - .call(compilation, ThreadsafeFunctionCallMode::NonBlocking) - .into_rspack_result()? - .await - .unwrap_or_else(|err| panic!("Failed to call after compile: {err}")) - } - - async fn finish_make( - &self, - compilation: &mut rspack_core::Compilation, - ) -> rspack_error::Result<()> { - if self.is_hook_disabled(&Hook::FinishMake) { - return Ok(()); - } - - let compilation = JsCompilation::from_compilation(unsafe { - std::mem::transmute::<&'_ mut rspack_core::Compilation, &'static mut rspack_core::Compilation>( - compilation, - ) - }); - - self - .finish_make_tsfn - .call(compilation, ThreadsafeFunctionCallMode::NonBlocking) - .into_rspack_result()? - .await - .unwrap_or_else(|err| panic!("Failed to call finish make: {err}")) - } - - async fn build_module(&self, module: &mut dyn rspack_core::Module) -> rspack_error::Result<()> { - if self.is_hook_disabled(&Hook::BuildModule) { - return Ok(()); - } - - self - .build_module_tsfn - .call( - module.to_js_module().expect("Convert to js_module failed."), - ThreadsafeFunctionCallMode::NonBlocking, - ) - .into_rspack_result()? - .await - .unwrap_or_else(|err| panic!("Failed to call build module: {err}")) - } - - async fn finish_modules( - &self, - compilation: &mut rspack_core::Compilation, - ) -> rspack_error::Result<()> { - if self.is_hook_disabled(&Hook::FinishModules) { - return Ok(()); - } - - let compilation = JsCompilation::from_compilation(unsafe { - std::mem::transmute::<&'_ mut rspack_core::Compilation, &'static mut rspack_core::Compilation>( - compilation, - ) - }); - - self - .finish_modules_tsfn - .call(compilation, ThreadsafeFunctionCallMode::NonBlocking) - .into_rspack_result()? - .await - .unwrap_or_else(|err| panic!("Failed to finish modules: {err}")) - } - - async fn emit(&self, _: &mut rspack_core::Compilation) -> rspack_error::Result<()> { - if self.is_hook_disabled(&Hook::Emit) { - return Ok(()); - } - - self - .emit_tsfn - .call((), ThreadsafeFunctionCallMode::NonBlocking) - .into_rspack_result()? - .await - .unwrap_or_else(|err| panic!("Failed to call emit: {err}")) - } - - async fn asset_emitted(&self, args: &rspack_core::AssetEmittedArgs) -> rspack_error::Result<()> { - if self.is_hook_disabled(&Hook::AssetEmitted) { - return Ok(()); - } - - let args: JsAssetEmittedArgs = args.into(); - self - .asset_emitted_tsfn - .call(args, ThreadsafeFunctionCallMode::NonBlocking) - .into_rspack_result()? - .await - .unwrap_or_else(|err| panic!("Failed to call asset emitted: {err}")) - } - - async fn should_emit( - &self, - compilation: &mut rspack_core::Compilation, - ) -> PluginShouldEmitHookOutput { - if self.is_hook_disabled(&Hook::ShouldEmit) { - return Ok(None); - } - - let compilation = JsCompilation::from_compilation(unsafe { - std::mem::transmute::<&'_ mut rspack_core::Compilation, &'static mut rspack_core::Compilation>( - compilation, - ) - }); - - let res = self - .should_emit_tsfn - .call(compilation, ThreadsafeFunctionCallMode::NonBlocking) - .into_rspack_result()? - .await; - res.unwrap_or_else(|err| panic!("Failed to call should emit: {err}")) - } + .intercept( + self + .register_normal_module_factory_after_resolve_taps + .clone(), + ); + ctx + .context + .normal_module_factory_hooks + .create_module + .intercept( + self + .register_normal_module_factory_create_module_taps + .clone(), + ); + ctx + .context + .context_module_factory_hooks + .before_resolve + .intercept( + self + .register_context_module_factory_before_resolve_taps + .clone(), + ); + ctx + .context + .context_module_factory_hooks + .after_resolve + .intercept( + self + .register_context_module_factory_after_resolve_taps + .clone(), + ); - async fn after_emit(&self, _: &mut rspack_core::Compilation) -> rspack_error::Result<()> { - if self.is_hook_disabled(&Hook::AfterEmit) { - return Ok(()); - } + ctx + .context + .compiler_hooks + .compilation + .tap(js_hooks_adapter_compilation::new(self)); - self - .after_emit_tsfn - .call((), ThreadsafeFunctionCallMode::NonBlocking) - .into_rspack_result()? - .await - .unwrap_or_else(|err| panic!("Failed to call after emit: {err}")) - } + ctx + .context + .compiler_hooks + .compilation + .tap(html_hooks_adapter_compilation::new(self)); - async fn succeed_module(&self, args: &dyn rspack_core::Module) -> rspack_error::Result<()> { - if self.is_hook_disabled(&Hook::SucceedModule) { - return Ok(()); - } - let js_module = args - .to_js_module() - .expect("Failed to convert module to JsModule"); - self - .succeed_module_tsfn - .call(js_module, ThreadsafeFunctionCallMode::NonBlocking) - .into_rspack_result()? - .await - .unwrap_or_else(|err| panic!("Failed to call succeed_module hook: {err}")) + Ok(()) } +} - async fn still_valid_module(&self, args: &dyn rspack_core::Module) -> rspack_error::Result<()> { - if self.is_hook_disabled(&Hook::StillValidModule) { - return Ok(()); - } +#[plugin_hook(CompilerCompilation for JsHooksAdapterPlugin)] +async fn js_hooks_adapter_compilation( + &self, + compilation: &mut Compilation, + _params: &mut CompilationParams, +) -> rspack_error::Result<()> { + let mut hooks = JsPlugin::get_compilation_hooks_mut(compilation); + hooks + .chunk_hash + .intercept(self.register_javascript_modules_chunk_hash_taps.clone()); + + Ok(()) +} +#[plugin_hook(CompilerCompilation for JsHooksAdapterPlugin)] +async fn html_hooks_adapter_compilation( + &self, + compilation: &mut Compilation, + _params: &mut CompilationParams, +) -> rspack_error::Result<()> { + let mut hooks = HtmlRspackPlugin::get_compilation_hooks_mut(compilation); + hooks.before_asset_tag_generation.intercept( self - .still_valid_module_tsfn - .call( - args.to_js_module().expect("Convert to js_module failed."), - ThreadsafeFunctionCallMode::NonBlocking, - ) - .into_rspack_result()? - .await - .unwrap_or_else(|err| panic!("Failed to call still_valid_module hook: {err}")) - } - - fn execute_module( - &self, - entry: ModuleIdentifier, - request: &str, - options: &BuildTimeExecutionOption, - runtime_modules: Vec, - codegen_results: &rspack_core::CodeGenerationResults, - id: u32, - ) -> rspack_error::Result<()> { - if self.is_hook_disabled(&Hook::ExecuteModule) { - return Ok(()); - } - + .register_html_plugin_before_asset_tag_generation_taps + .clone(), + ); + hooks + .alter_asset_tags + .intercept(self.register_html_plugin_alter_asset_tags_taps.clone()); + hooks.alter_asset_tag_groups.intercept( self - .execute_module_tsfn - .call( - JsExecuteModuleArg { - entry: entry.to_string(), - request: request.into(), - options: JsBuildTimeExecutionOption { - public_path: options.public_path.clone(), - base_uri: options.base_uri.clone(), - }, - runtime_modules: runtime_modules - .into_iter() - .map(|id| id.to_string()) - .collect(), - codegen_results: codegen_results.clone().into(), - id, - }, - ThreadsafeFunctionCallMode::NonBlocking, - ) - .into_rspack_result()? - .blocking_recv() - .unwrap_or_else(|recv_err| panic!("{}", recv_err.to_string())) - } - - async fn runtime_module( - &self, - module: &mut dyn RuntimeModule, - source: Arc, - chunk: &Chunk, - ) -> rspack_error::Result> { - if self.is_hook_disabled(&Hook::RuntimeModule) { - return Ok(None); - } - + .register_html_plugin_alter_asset_tag_groups_taps + .clone(), + ); + hooks.after_template_execution.intercept( self - .runtime_module_tsfn - .call( - JsRuntimeModuleArg { - module: JsRuntimeModule { - source: Some( - source - .to_js_compat_source() - .unwrap_or_else(|err| panic!("Failed to generate runtime module source: {err}")), - ), - module_identifier: module.identifier().to_string(), - constructor_name: module.get_constructor_name(), - name: module - .identifier() - .to_string() - .replace("webpack/runtime/", ""), - }, - chunk: JsChunk::from(chunk), - }, - ThreadsafeFunctionCallMode::NonBlocking, - ) - .into_rspack_result()? - .await - .unwrap_or_else(|err| panic!("Failed to call runtime module hook: {err}")) - .map(|r| { - r.and_then(|s| s.source).map(|s| { - std::str::from_utf8(&s.source) - .unwrap_or_else(|err| panic!("Failed to covert buffer to utf-8 string: {err}")) - .to_string() - }) - }) - } + .register_html_plugin_after_template_execution_taps + .clone(), + ); + hooks + .before_emit + .intercept(self.register_html_plugin_before_emit_taps.clone()); + hooks + .after_emit + .intercept(self.register_html_plugin_after_emit_taps.clone()); + + Ok(()) } impl JsHooksAdapterPlugin { - pub fn from_js_hooks( - env: Env, - js_hooks: JsHooks, - disabled_hooks: DisabledHooks, - interceptor: RegisterJsTaps, - ) -> Result { - let JsHooks { - after_process_assets, - this_compilation, - should_emit, - emit, - asset_emitted, - after_emit, - optimize_modules, - after_optimize_modules, - optimize_tree, - optimize_chunk_modules, - before_resolve, - after_resolve, - context_module_factory_before_resolve, - context_module_factory_after_resolve, - normal_module_factory_create_module, - normal_module_factory_resolve_for_scheme, - before_compile, - after_compile, - finish_modules, - finish_make, - build_module, - chunk_asset, - succeed_module, - still_valid_module, - execute_module, - runtime_module, - } = js_hooks; - - let after_process_assets_tsfn: ThreadsafeFunction<(), ()> = - js_fn_into_threadsafe_fn!(after_process_assets, env); - let emit_tsfn: ThreadsafeFunction<(), ()> = js_fn_into_threadsafe_fn!(emit, env); - let should_emit_tsfn: ThreadsafeFunction> = - js_fn_into_threadsafe_fn!(should_emit, env); - let asset_emitted_tsfn: ThreadsafeFunction = - js_fn_into_threadsafe_fn!(asset_emitted, env); - let after_emit_tsfn: ThreadsafeFunction<(), ()> = js_fn_into_threadsafe_fn!(after_emit, env); - let this_compilation_tsfn: ThreadsafeFunction = - js_fn_into_threadsafe_fn!(this_compilation, env); - let optimize_modules_tsfn: ThreadsafeFunction = - js_fn_into_threadsafe_fn!(optimize_modules, env); - let after_optimize_modules_tsfn: ThreadsafeFunction = - js_fn_into_threadsafe_fn!(after_optimize_modules, env); - let optimize_tree_tsfn: ThreadsafeFunction<(), ()> = - js_fn_into_threadsafe_fn!(optimize_tree, env); - let optimize_chunk_modules_tsfn: ThreadsafeFunction = - js_fn_into_threadsafe_fn!(optimize_chunk_modules, env); - let before_compile_tsfn: ThreadsafeFunction<(), ()> = - js_fn_into_threadsafe_fn!(before_compile, env); - let after_compile_tsfn: ThreadsafeFunction = - js_fn_into_threadsafe_fn!(after_compile, env); - let finish_make_tsfn: ThreadsafeFunction = - js_fn_into_threadsafe_fn!(finish_make, env); - let build_module_tsfn: ThreadsafeFunction = - js_fn_into_threadsafe_fn!(build_module, env); - let finish_modules_tsfn: ThreadsafeFunction = - js_fn_into_threadsafe_fn!(finish_modules, env); - let context_module_factory_before_resolve: ThreadsafeFunction> = - js_fn_into_threadsafe_fn!(context_module_factory_before_resolve, env); - let context_module_factory_after_resolve: ThreadsafeFunction> = - js_fn_into_threadsafe_fn!(context_module_factory_after_resolve, env); - let before_resolve: ThreadsafeFunction, BeforeResolveData)> = - js_fn_into_threadsafe_fn!(before_resolve, env); - let after_resolve: ThreadsafeFunction> = - js_fn_into_threadsafe_fn!(after_resolve, env); - let normal_module_factory_create_module: ThreadsafeFunction = - js_fn_into_threadsafe_fn!(normal_module_factory_create_module, env); - let normal_module_factory_resolve_for_scheme: ThreadsafeFunction< - JsResolveForSchemeInput, - JsResolveForSchemeResult, - > = js_fn_into_threadsafe_fn!(normal_module_factory_resolve_for_scheme, env); - let chunk_asset_tsfn: ThreadsafeFunction = - js_fn_into_threadsafe_fn!(chunk_asset, env); - let succeed_module_tsfn: ThreadsafeFunction = - js_fn_into_threadsafe_fn!(succeed_module, env); - let still_valid_module_tsfn: ThreadsafeFunction = - js_fn_into_threadsafe_fn!(still_valid_module, env); - let execute_module_tsfn: ThreadsafeFunction = - js_fn_into_threadsafe_fn!(execute_module, env); - let runtime_module_tsfn: ThreadsafeFunction> = - js_fn_into_threadsafe_fn!(runtime_module, env); - + pub fn from_js_hooks(_env: Env, register_js_taps: RegisterJsTaps) -> Result { + let non_skippable_registers = NonSkippableRegisters::default(); Ok(JsHooksAdapterPlugin { - interceptor: Box::new(ThreadsafeRegisterJsTaps::from_js_taps(interceptor, env)?), - inner: Arc::new(JsHooksAdapterInner { - disabled_hooks, - after_process_assets_tsfn, - this_compilation_tsfn, - should_emit_tsfn, - emit_tsfn, - asset_emitted_tsfn, - after_emit_tsfn, - optimize_modules_tsfn, - after_optimize_modules_tsfn, - optimize_tree_tsfn, - optimize_chunk_modules_tsfn, - before_compile_tsfn, - after_compile_tsfn, - before_resolve, - context_module_factory_before_resolve, - context_module_factory_after_resolve, - normal_module_factory_create_module, - normal_module_factory_resolve_for_scheme, - finish_modules_tsfn, - finish_make_tsfn, - build_module_tsfn, - chunk_asset_tsfn, - after_resolve, - succeed_module_tsfn, - still_valid_module_tsfn, - execute_module_tsfn, - runtime_module_tsfn, - }), + inner: JsHooksAdapterPluginInner { + register_compiler_this_compilation_taps: RegisterCompilerThisCompilationTaps::new( + register_js_taps.register_compiler_this_compilation_taps, + non_skippable_registers.clone(), + ), + register_compiler_compilation_taps: RegisterCompilerCompilationTaps::new( + register_js_taps.register_compiler_compilation_taps, + non_skippable_registers.clone(), + ), + register_compiler_make_taps: RegisterCompilerMakeTaps::new( + register_js_taps.register_compiler_make_taps, + non_skippable_registers.clone(), + ), + register_compiler_finish_make_taps: RegisterCompilerFinishMakeTaps::new( + register_js_taps.register_compiler_finish_make_taps, + non_skippable_registers.clone(), + ), + register_compiler_should_emit_taps: RegisterCompilerShouldEmitTaps::new( + register_js_taps.register_compiler_should_emit_taps, + non_skippable_registers.clone(), + ), + register_compiler_emit_taps: RegisterCompilerEmitTaps::new( + register_js_taps.register_compiler_emit_taps, + non_skippable_registers.clone(), + ), + register_compiler_after_emit_taps: RegisterCompilerAfterEmitTaps::new( + register_js_taps.register_compiler_after_emit_taps, + non_skippable_registers.clone(), + ), + register_compiler_asset_emitted_taps: RegisterCompilerAssetEmittedTaps::new( + register_js_taps.register_compiler_asset_emitted_taps, + non_skippable_registers.clone(), + ), + register_compilation_build_module_taps: RegisterCompilationBuildModuleTaps::new( + register_js_taps.register_compilation_build_module_taps, + non_skippable_registers.clone(), + ), + register_compilation_still_valid_module_taps: RegisterCompilationStillValidModuleTaps::new( + register_js_taps.register_compilation_still_valid_module_taps, + non_skippable_registers.clone(), + ), + register_compilation_succeed_module_taps: RegisterCompilationSucceedModuleTaps::new( + register_js_taps.register_compilation_succeed_module_taps, + non_skippable_registers.clone(), + ), + register_compilation_execute_module_taps: RegisterCompilationExecuteModuleTaps::new( + register_js_taps.register_compilation_execute_module_taps, + non_skippable_registers.clone(), + ), + register_compilation_finish_modules_taps: RegisterCompilationFinishModulesTaps::new( + register_js_taps.register_compilation_finish_modules_taps, + non_skippable_registers.clone(), + ), + register_compilation_optimize_modules_taps: RegisterCompilationOptimizeModulesTaps::new( + register_js_taps.register_compilation_optimize_modules_taps, + non_skippable_registers.clone(), + ), + register_compilation_after_optimize_modules_taps: + RegisterCompilationAfterOptimizeModulesTaps::new( + register_js_taps.register_compilation_after_optimize_modules_taps, + non_skippable_registers.clone(), + ), + register_compilation_optimize_tree_taps: RegisterCompilationOptimizeTreeTaps::new( + register_js_taps.register_compilation_optimize_tree_taps, + non_skippable_registers.clone(), + ), + register_compilation_optimize_chunk_modules_taps: + RegisterCompilationOptimizeChunkModulesTaps::new( + register_js_taps.register_compilation_optimize_chunk_modules_taps, + non_skippable_registers.clone(), + ), + register_compilation_additional_tree_runtime_requirements: + RegisterCompilationAdditionalTreeRuntimeRequirementsTaps::new( + register_js_taps.register_compilation_additional_tree_runtime_requirements, + non_skippable_registers.clone(), + ), + register_compilation_runtime_module_taps: RegisterCompilationRuntimeModuleTaps::new( + register_js_taps.register_compilation_runtime_module_taps, + non_skippable_registers.clone(), + ), + register_compilation_chunk_hash_taps: RegisterCompilationChunkHashTaps::new( + register_js_taps.register_compilation_chunk_hash_taps, + non_skippable_registers.clone(), + ), + register_compilation_chunk_asset_taps: RegisterCompilationChunkAssetTaps::new( + register_js_taps.register_compilation_chunk_asset_taps, + non_skippable_registers.clone(), + ), + register_compilation_process_assets_taps: RegisterCompilationProcessAssetsTaps::new( + register_js_taps.register_compilation_process_assets_taps, + non_skippable_registers.clone(), + ), + register_compilation_after_process_assets_taps: + RegisterCompilationAfterProcessAssetsTaps::new( + register_js_taps.register_compilation_after_process_assets_taps, + non_skippable_registers.clone(), + ), + register_compilation_seal_taps: RegisterCompilationSealTaps::new( + register_js_taps.register_compilation_seal_taps, + non_skippable_registers.clone(), + ), + register_compilation_after_seal_taps: RegisterCompilationAfterSealTaps::new( + register_js_taps.register_compilation_after_seal_taps, + non_skippable_registers.clone(), + ), + register_normal_module_factory_before_resolve_taps: + RegisterNormalModuleFactoryBeforeResolveTaps::new( + register_js_taps.register_normal_module_factory_before_resolve_taps, + non_skippable_registers.clone(), + ), + register_normal_module_factory_factorize_taps: + RegisterNormalModuleFactoryFactorizeTaps::new( + register_js_taps.register_normal_module_factory_factorize_taps, + non_skippable_registers.clone(), + ), + register_normal_module_factory_resolve_taps: RegisterNormalModuleFactoryResolveTaps::new( + register_js_taps.register_normal_module_factory_resolve_taps, + non_skippable_registers.clone(), + ), + register_normal_module_factory_resolve_for_scheme_taps: + RegisterNormalModuleFactoryResolveForSchemeTaps::new( + register_js_taps.register_normal_module_factory_resolve_for_scheme_taps, + non_skippable_registers.clone(), + ), + register_normal_module_factory_after_resolve_taps: + RegisterNormalModuleFactoryAfterResolveTaps::new( + register_js_taps.register_normal_module_factory_after_resolve_taps, + non_skippable_registers.clone(), + ), + register_normal_module_factory_create_module_taps: + RegisterNormalModuleFactoryCreateModuleTaps::new( + register_js_taps.register_normal_module_factory_create_module_taps, + non_skippable_registers.clone(), + ), + register_context_module_factory_before_resolve_taps: + RegisterContextModuleFactoryBeforeResolveTaps::new( + register_js_taps.register_context_module_factory_before_resolve_taps, + non_skippable_registers.clone(), + ), + register_context_module_factory_after_resolve_taps: + RegisterContextModuleFactoryAfterResolveTaps::new( + register_js_taps.register_context_module_factory_after_resolve_taps, + non_skippable_registers.clone(), + ), + register_javascript_modules_chunk_hash_taps: RegisterJavascriptModulesChunkHashTaps::new( + register_js_taps.register_javascript_modules_chunk_hash_taps, + non_skippable_registers.clone(), + ), + register_html_plugin_before_asset_tag_generation_taps: + RegisterHtmlPluginBeforeAssetTagGenerationTaps::new( + register_js_taps.register_html_plugin_before_asset_tag_generation_taps, + non_skippable_registers.clone(), + ), + register_html_plugin_alter_asset_tags_taps: RegisterHtmlPluginAlterAssetTagsTaps::new( + register_js_taps.register_html_plugin_alter_asset_tags_taps, + non_skippable_registers.clone(), + ), + register_html_plugin_alter_asset_tag_groups_taps: + RegisterHtmlPluginAlterAssetTagGroupsTaps::new( + register_js_taps.register_html_plugin_alter_asset_tag_groups_taps, + non_skippable_registers.clone(), + ), + register_html_plugin_after_template_execution_taps: + RegisterHtmlPluginAfterTemplateExecutionTaps::new( + register_js_taps.register_html_plugin_after_template_execution_taps, + non_skippable_registers.clone(), + ), + register_html_plugin_before_emit_taps: RegisterHtmlPluginBeforeEmitTaps::new( + register_js_taps.register_html_plugin_before_emit_taps, + non_skippable_registers.clone(), + ), + register_html_plugin_after_emit_taps: RegisterHtmlPluginAfterEmitTaps::new( + register_js_taps.register_html_plugin_after_emit_taps, + non_skippable_registers.clone(), + ), + non_skippable_registers, + } + .into(), }) } - fn is_hook_disabled(&self, hook: &Hook) -> bool { - self.disabled_hooks.is_hook_disabled(hook) - } - - pub fn set_disabled_hooks(&self, hooks: Vec) -> Result<()> { - self.disabled_hooks.set_disabled_hooks(hooks) + pub fn set_non_skippable_registers(&self, kinds: Vec) { + self + .non_skippable_registers + .set_non_skippable_registers(kinds); } } diff --git a/crates/node_binding/src/resolver_factory.rs b/crates/node_binding/src/resolver_factory.rs new file mode 100644 index 0000000..c367e7b --- /dev/null +++ b/crates/node_binding/src/resolver_factory.rs @@ -0,0 +1,78 @@ +use std::sync::Arc; + +use napi_derive::napi; +use rspack_core::{Resolve, ResolverFactory}; + +use crate::{ + raw_resolve::{ + normalize_raw_resolve_options_with_dependency_type, RawResolveOptionsWithDependencyType, + }, + JsResolver, +}; + +#[napi] +pub struct JsResolverFactory { + pub(crate) resolver_factory: Option>, + pub(crate) loader_resolver_factory: Option>, +} + +#[napi] +impl JsResolverFactory { + #[napi(constructor)] + pub fn new() -> napi::Result { + Ok(Self { + resolver_factory: None, + loader_resolver_factory: None, + }) + } + + pub fn get_resolver_factory(&mut self, resolve_options: Resolve) -> Arc { + match &self.resolver_factory { + Some(resolver_factory) => resolver_factory.clone(), + None => { + let resolver_factory = Arc::new(ResolverFactory::new(resolve_options)); + self.resolver_factory = Some(resolver_factory.clone()); + resolver_factory + } + } + } + + pub fn get_loader_resolver_factory(&mut self, resolve_options: Resolve) -> Arc { + match &self.loader_resolver_factory { + Some(resolver_factory) => resolver_factory.clone(), + None => { + let resolver_factory = Arc::new(ResolverFactory::new(resolve_options)); + self.loader_resolver_factory = Some(resolver_factory.clone()); + resolver_factory + } + } + } + + #[napi(ts_args_type = "type: string, options?: RawResolveOptionsWithDependencyType")] + pub fn get( + &mut self, + r#type: String, + raw: Option, + ) -> napi::Result { + match r#type.as_str() { + "normal" => { + let options = normalize_raw_resolve_options_with_dependency_type(raw, false).map_err(|e| napi::Error::from_reason(format!("{e}")))?; + let resolver_factory = self.get_resolver_factory(*options.resolve_options.clone().unwrap_or_default()); + Ok(JsResolver::new(resolver_factory, options)) + } + "loader" => { + let options = normalize_raw_resolve_options_with_dependency_type(raw, false).map_err(|e| napi::Error::from_reason(format!("{e}")))?; + let resolver_factory = self.get_loader_resolver_factory(*options.resolve_options.clone().unwrap_or_default()); + Ok(JsResolver::new(resolver_factory, options)) + } + "context" => { + let options = normalize_raw_resolve_options_with_dependency_type(raw, true).map_err(|e| napi::Error::from_reason(format!("{e}")))?; + let resolver_factory = self.get_resolver_factory(*options.resolve_options.clone().unwrap_or_default()); + Ok(JsResolver::new(resolver_factory, options)) + } + _ => { + Err(napi::Error::from_reason(format!("Invalid resolver type '{}' specified. Rspack only supports 'normal', 'context', and 'loader' types.", r#type))) + } + } + } +} diff --git a/crates/plugin_manifest/Cargo.toml b/crates/plugin_manifest/Cargo.toml index 5479134..2f08035 100644 --- a/crates/plugin_manifest/Cargo.toml +++ b/crates/plugin_manifest/Cargo.toml @@ -13,7 +13,4 @@ serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } rspack_core = { path = "../.rspack_crates/rspack_core" } rspack_hook = { path = "../.rspack_crates/rspack_hook" } -rspack_error = { path = "../.rspack_crates/rspack_error" } - -[dev-dependencies] -rspack_testing = { path = "../.rspack_crates/rspack_testing" } \ No newline at end of file +rspack_error = { path = "../.rspack_crates/rspack_error" } \ No newline at end of file diff --git a/crates/plugin_manifest/src/plugin.rs b/crates/plugin_manifest/src/plugin.rs index 983edee..bce9ff6 100644 --- a/crates/plugin_manifest/src/plugin.rs +++ b/crates/plugin_manifest/src/plugin.rs @@ -4,11 +4,13 @@ use rspack_core::{ rspack_sources::{RawSource, SourceExt}, CompilationAsset, Plugin, PublicPath, Compilation, + CompilationProcessAssets, }; use rspack_error::Result; -use rspack_hook::AsyncSeries; +use rspack_hook::{plugin, plugin_hook}; use serde::{Deserialize, Serialize}; +#[plugin] #[derive(Debug)] pub struct ManifestPlugin; @@ -26,100 +28,89 @@ const AUTO_PUBLIC_PATH_PLACEHOLDER: &str = "__RSPACK_PLUGIN_CSS_AUTO_PUBLIC_PATH impl ManifestPlugin { pub fn new() -> Self { - Self {} + Self::new_inner() } } -struct MainfestPluginProcessAssetsHook; +#[plugin_hook(CompilationProcessAssets for ManifestPlugin, stage = Compilation::PROCESS_ASSETS_STAGE_ADDITIONS)] +async fn process_assets(&self, compilation: &mut Compilation) -> Result<()> { + let public_path = match &compilation.options.output.public_path { + PublicPath::Filename(p) => p.template(), + PublicPath::Auto => Some(AUTO_PUBLIC_PATH_PLACEHOLDER), + }; + let mut assets_mainfest = AssetsManifest { + pages: HashMap::new(), + entries: HashMap::new(), + assets: HashMap::new(), + public_path: public_path.unwrap_or_default().to_string(), + data_loader: None, + }; + let entry_points = &compilation.entrypoints; + let assets = &compilation.assets(); -#[async_trait::async_trait] -impl AsyncSeries for MainfestPluginProcessAssetsHook { - async fn run(&self, compilation: &mut Compilation) -> Result<()> { - let public_path = match &compilation.options.output.public_path { - PublicPath::String(p) => p, - PublicPath::Auto => AUTO_PUBLIC_PATH_PLACEHOLDER, - }; - let mut assets_mainfest = AssetsManifest { - pages: HashMap::new(), - entries: HashMap::new(), - assets: HashMap::new(), - public_path: public_path.to_string(), - data_loader: None, - }; - let entry_points = &compilation.entrypoints; - let assets = &compilation.assets(); - - assets.into_iter().for_each(|(_, asset)| { - let version = &asset.info.version; - let source_file = &asset.info.source_filename; - if let Some(name) = source_file { - assets_mainfest - .assets - .insert(name.to_string(), version.to_string()); - } - }); - - entry_points.iter().for_each(|(name, _entry)| { - let mut files: Vec = Vec::new(); - compilation - .entrypoint_by_name(name) - .chunks - .iter() - .for_each(|chunk| { - let chunk = compilation.chunk_by_ukey.expect_get(chunk); - chunk.files.iter().for_each(|file| { - if let Some(asset) = assets.get(file) { - if !asset.info.hot_module_replacement && !asset.info.development { - files.push(file.to_string()); - } - } else { + assets.into_iter().for_each(|(_, asset)| { + let version = &asset.info.version; + let source_file = &asset.info.source_filename; + if let Some(name) = source_file { + assets_mainfest + .assets + .insert(name.to_string(), version.to_string()); + } + }); + entry_points.iter().for_each(|(name, _entry)| { + let mut files: Vec = Vec::new(); + compilation + .entrypoint_by_name(name) + .chunks + .iter() + .for_each(|chunk| { + let chunk = compilation.chunk_by_ukey.expect_get(chunk); + chunk.files.iter().for_each(|file| { + if let Some(asset) = assets.get(file) { + if !asset.info.hot_module_replacement && !asset.info.development { files.push(file.to_string()); } - }); + } else { + files.push(file.to_string()); + } }); - assets_mainfest.entries.insert(name.to_string(), files); - }); - - // Check .ice/data-loader.ts is exists - let data_loader_file = - Path::new(&compilation.options.context.as_str()).join(".ice/data-loader.ts"); - if data_loader_file.exists() { - assets_mainfest.data_loader = Some("js/data-loader.js".to_string()); - } - - let page_chunk_name_regex = regex::Regex::new(r"^p_").unwrap(); - compilation.chunk_by_ukey.values().for_each(|c| { - if let Some(name) = &c.id { - if !c.has_entry_module(&compilation.chunk_graph) - && !c.can_be_initial(&compilation.chunk_group_by_ukey) - { - assets_mainfest.pages.insert( - page_chunk_name_regex.replace(name, "").to_string(), - Vec::from_iter( - c.files - .iter() - // Only collect js and css files. - .filter(|f| f.ends_with(".js") || f.ends_with(".css")) - .cloned(), - ), - ); - } - } - }); - let json_string = serde_json::to_string(&assets_mainfest).unwrap(); - compilation.emit_asset( - "assets-manifest.json".to_string(), - CompilationAsset::from(RawSource::from(json_string).boxed()), - ); - Ok(()) + }); + assets_mainfest.entries.insert(name.to_string(), files); + }); + // Check .ice/data-loader.ts is exists + let data_loader_file = + Path::new(&compilation.options.context.as_str()).join(".ice/data-loader.ts"); + if data_loader_file.exists() { + assets_mainfest.data_loader = Some("js/data-loader.js".to_string()); } - fn stage(&self) -> i32 { - Compilation::PROCESS_ASSETS_STAGE_ADDITIONS - } + let page_chunk_name_regex = regex::Regex::new(r"^p_").unwrap(); + compilation.chunk_by_ukey.values().for_each(|c| { + if let Some(name) = &c.id { + if !c.has_entry_module(&compilation.chunk_graph) + && !c.can_be_initial(&compilation.chunk_group_by_ukey) + { + assets_mainfest.pages.insert( + page_chunk_name_regex.replace(name, "").to_string(), + Vec::from_iter( + c.files + .iter() + // Only collect js and css files. + .filter(|f| f.ends_with(".js") || f.ends_with(".css")) + .cloned(), + ), + ); + } + } + }); + let json_string = serde_json::to_string(&assets_mainfest).unwrap(); + compilation.emit_asset( + "assets-manifest.json".to_string(), + CompilationAsset::from(RawSource::from(json_string).boxed()), + ); + Ok(()) } - impl Plugin for ManifestPlugin { fn name(&self) -> &'static str { "ManifestPlugin" @@ -134,7 +125,7 @@ impl Plugin for ManifestPlugin { .context .compilation_hooks .process_assets - .tap(Box::new(MainfestPluginProcessAssetsHook)); + .tap(process_assets::new(self)); Ok(()) } } diff --git a/crates/plugin_specilize_module_name/Cargo.toml b/crates/plugin_specilize_module_name/Cargo.toml index e7e9cd1..595bb69 100644 --- a/crates/plugin_specilize_module_name/Cargo.toml +++ b/crates/plugin_specilize_module_name/Cargo.toml @@ -10,6 +10,3 @@ async-trait = { workspace = true } tracing = { workspace = true } rspack_core = { path = "../.rspack_crates/rspack_core" } rspack_error = { path = "../.rspack_crates/rspack_error" } - -[dev-dependencies] -rspack_testing = { path = "../.rspack_crates/rspack_testing" } \ No newline at end of file diff --git a/crates/swc_compiler/Cargo.toml b/crates/swc_compiler/Cargo.toml index ac5e1a6..7b06a58 100644 --- a/crates/swc_compiler/Cargo.toml +++ b/crates/swc_compiler/Cargo.toml @@ -5,11 +5,14 @@ edition = "2021" [dependencies] anyhow = { workspace = true } +base64 = { version = "0.22" } dashmap = { workspace = true } +jsonc-parser = { version = "0.23.0", features = ["serde"] } rspack_ast = { path = "../.rspack_crates/rspack_ast" } -swc_config = { workspace = true } +swc_config = { workspace = true } swc_core = { workspace = true, features = [ "base", "ecma_ast", "common" -] } \ No newline at end of file +] } +url = "2.5.0" \ No newline at end of file diff --git a/crates/swc_compiler/src/compiler.rs b/crates/swc_compiler/src/compiler.rs index 3980224..20b55f2 100644 --- a/crates/swc_compiler/src/compiler.rs +++ b/crates/swc_compiler/src/compiler.rs @@ -6,14 +6,18 @@ * Copyright (c) */ use std::env; +use std::fs::File; use std::{path::PathBuf, sync::Arc}; -use anyhow::{Context, Error}; +use anyhow::{bail, Context, Error}; +use base64::prelude::*; use dashmap::DashMap; use rspack_ast::javascript::{Ast as JsAst, Context as JsAstContext, Program as JsProgram}; use swc_config::config_types::BoolOr; -use swc_core::base::config::{BuiltInput, Config, IsModule, JsMinifyCommentOption}; -use swc_core::base::SwcComments; +use swc_core::base::config::{ + BuiltInput, Config, InputSourceMap, IsModule, JsMinifyCommentOption, +}; +use swc_core::base::{sourcemap, SwcComments}; use swc_core::common::comments::{Comment, CommentKind, Comments}; use swc_core::common::errors::{Handler, HANDLER}; use swc_core::common::{ @@ -30,6 +34,7 @@ use swc_core::{ base::{config::Options, try_with_handler}, common::Globals, }; +use url::Url; fn minify_file_comments( comments: &SingleThreadedComments, @@ -119,7 +124,9 @@ impl SwcCompiler { res } +} +impl SwcCompiler { pub fn new(resource_path: PathBuf, source: String, mut options: Options) -> Result { let cm = Arc::new(SourceMap::new(FilePathMapping::empty())); let globals = Globals::default(); @@ -130,7 +137,7 @@ impl SwcCompiler { options.unresolved_mark = Some(unresolved_mark); }); - let fm = cm.new_source_file(FileName::Real(resource_path), source); + let fm = cm.new_source_file(Arc::new(FileName::Real(resource_path)), source); let comments = SingleThreadedComments::default(); let config = options.config.clone(); @@ -220,16 +227,153 @@ impl SwcCompiler { program } - pub fn comments(&self) -> &SingleThreadedComments { - &self.comments - } + pub fn input_source_map( + &self, + input_src_map: &InputSourceMap, + ) -> Result, Error> { + let fm = &self.fm; + let name = &self.fm.name; - pub fn options(&self) -> &Options { - &self.options - } + let read_inline_sourcemap = + |data_url: Option<&str>| -> Result, Error> { + match data_url { + Some(data_url) => { + let url = Url::parse(data_url) + .with_context(|| format!("failed to parse inline source map url\n{}", data_url))?; + + let idx = match url.path().find("base64,") { + Some(v) => v, + None => { + bail!("failed to parse inline source map: not base64: {:?}", url) + } + }; + + let content = url.path()[idx + "base64,".len()..].trim(); + + let res = BASE64_STANDARD + .decode(content.as_bytes()) + .context("failed to decode base64-encoded source map")?; + + Ok(Some(sourcemap::SourceMap::from_slice(&res).context( + "failed to read input source map from inlined base64 encoded \ + string", + )?)) + } + None => { + bail!("failed to parse inline source map: `sourceMappingURL` not found") + } + } + }; + + let read_file_sourcemap = + |data_url: Option<&str>| -> Result, Error> { + match name.as_ref() { + FileName::Real(filename) => { + let dir = match filename.parent() { + Some(v) => v, + None => { + bail!("unexpected: root directory is given as a input file") + } + }; + + let map_path = match data_url { + Some(data_url) => { + let mut map_path = dir.join(data_url); + if !map_path.exists() { + // Old behavior. This check would prevent + // regressions. + // Perhaps it shouldn't be supported. Sometimes + // developers don't want to expose their source + // code. + // Map files are for internal troubleshooting + // convenience. + map_path = PathBuf::from(format!("{}.map", filename.display())); + if !map_path.exists() { + bail!( + "failed to find input source map file {:?} in \ + {:?} file", + map_path.display(), + filename.display() + ) + } + } - pub fn cm(&self) -> &Arc { - &self.cm + Some(map_path) + } + None => { + // Old behavior. + let map_path = PathBuf::from(format!("{}.map", filename.display())); + if map_path.exists() { + Some(map_path) + } else { + None + } + } + }; + + match map_path { + Some(map_path) => { + let path = map_path.display().to_string(); + let file = File::open(&path); + + // Old behavior. + let file = file?; + + Ok(Some(sourcemap::SourceMap::from_reader(file).with_context( + || { + format!( + "failed to read input source map + from file at {}", + path + ) + }, + )?)) + } + None => Ok(None), + } + } + _ => Ok(None), + } + }; + + let read_sourcemap = || -> Option { + let s = "sourceMappingURL="; + let idx = fm.src.rfind(s); + + let data_url = idx.map(|idx| { + let data_idx = idx + s.len(); + if let Some(end) = fm.src[data_idx..].find('\n').map(|i| i + data_idx + 1) { + &fm.src[data_idx..end] + } else { + &fm.src[data_idx..] + } + }); + + match read_inline_sourcemap(data_url) { + Ok(r) => r, + Err(_err) => { + // Load original source map if possible + read_file_sourcemap(data_url).unwrap_or(None) + } + } + }; + + // Load original source map + match input_src_map { + InputSourceMap::Bool(false) => Ok(None), + InputSourceMap::Bool(true) => Ok(read_sourcemap()), + InputSourceMap::Str(ref s) => { + if s == "inline" { + Ok(read_sourcemap()) + } else { + // Load source map passed by user + Ok(Some( + sourcemap::SourceMap::from_slice(s.as_bytes()) + .context("failed to read input source map from user-provided sourcemap")?, + )) + } + } + } } } @@ -246,7 +390,7 @@ impl IntoJsAst for SwcCompiler { )) .with_context(JsAstContext { globals: self.globals, - helpers: self.helpers, + helpers: self.helpers.data(), source_map: self.cm, top_level_mark: self .options diff --git a/crates/swc_env_replacement/src/transform.rs b/crates/swc_env_replacement/src/transform.rs index d6b59bc..e5a5770 100644 --- a/crates/swc_env_replacement/src/transform.rs +++ b/crates/swc_env_replacement/src/transform.rs @@ -1,5 +1,5 @@ use swc_core::{ - common::DUMMY_SP, + common::{SyntaxContext, DUMMY_SP}, ecma::{ ast::*, visit::{Fold, FoldWith}, @@ -19,7 +19,7 @@ fn create_check_expr(meta_value: &str, renderer: &str) -> Expr { span: DUMMY_SP, kind: MetaPropKind::ImportMeta, })), - prop: Ident::new(meta_value.into(), DUMMY_SP).into(), + prop: MemberProp::Ident(Ident::new(meta_value.into(), DUMMY_SP, SyntaxContext::empty()).into()), })), right: Box::new(Expr::Lit(Lit::Str(Str { value: renderer.into(), @@ -75,7 +75,7 @@ fn build_regex_test_expression() -> Expr { // Create the typeof expression for `navigator` let typeof_navigator = Expr::Unary(UnaryExpr { op: UnaryOp::TypeOf, - arg: Box::new(Expr::Ident(Ident::new("navigator".into(), DUMMY_SP))), + arg: Box::new(Expr::Ident(Ident::new("navigator".into(), DUMMY_SP, SyntaxContext::empty()))), span: DUMMY_SP, }); @@ -84,14 +84,14 @@ fn build_regex_test_expression() -> Expr { test: Box::new(typeof_navigator), cons: Box::new(Expr::Bin(BinExpr { left: Box::new(Expr::Member(MemberExpr { - obj: Box::new(Expr::Ident(Ident::new("navigator".into(), DUMMY_SP))), - prop: MemberProp::Ident(Ident::new("userAgent".into(), DUMMY_SP)), + obj: Box::new(Expr::Ident(Ident::new("navigator".into(), DUMMY_SP, SyntaxContext::empty()))), + prop: MemberProp::Ident(Ident::new("userAgent".into(), DUMMY_SP, SyntaxContext::empty()).into()), span: DUMMY_SP, })), op: BinaryOp::LogicalOr, right: Box::new(Expr::Member(MemberExpr { - obj: Box::new(Expr::Ident(Ident::new("navigator".into(), DUMMY_SP))), - prop: MemberProp::Ident(Ident::new("swuserAgent".into(), DUMMY_SP)), + obj: Box::new(Expr::Ident(Ident::new("navigator".into(), DUMMY_SP, SyntaxContext::empty()))), + prop: MemberProp::Ident(Ident::new("swuserAgent".into(), DUMMY_SP, SyntaxContext::empty()).into()), span: DUMMY_SP, })), span: DUMMY_SP, @@ -108,7 +108,7 @@ fn build_regex_test_expression() -> Expr { let test_call = Expr::Call(CallExpr { callee: Callee::Expr(Box::new(Expr::Member(MemberExpr { obj: Box::new(regex_pattern), - prop: MemberProp::Ident(Ident::new("test".into(), DUMMY_SP)), + prop: MemberProp::Ident(Ident::new("test".into(), DUMMY_SP, SyntaxContext::empty()).into()), span: DUMMY_SP, }))), args: vec![ExprOrSpread { @@ -117,6 +117,7 @@ fn build_regex_test_expression() -> Expr { }], span: DUMMY_SP, type_args: None, + ctxt: Default::default(), }); test_call @@ -153,7 +154,7 @@ fn get_env_expr(specifier: &Ident) -> Expr { create_check_expr("renderer", "client"), create_check_expr("target", "web"), create_typeof_check( - Expr::Ident(Ident::new("pha".into(), DUMMY_SP)), + Expr::Ident(Ident::new("pha".into(), DUMMY_SP, SyntaxContext::empty())), "object", BinaryOp::EqEqEq, ), @@ -165,15 +166,15 @@ fn get_env_expr(specifier: &Ident) -> Expr { create_check_expr("renderer", "client"), build_regex_test_expression(), create_typeof_check( - Expr::Ident(Ident::new("WindVane".into(), DUMMY_SP)), + Expr::Ident(Ident::new("WindVane".into(), DUMMY_SP, SyntaxContext::empty())), "undefined", BinaryOp::NotEqEq, ), create_typeof_check( Expr::Member(MemberExpr { span: DUMMY_SP, - obj: Box::new(Expr::Ident(Ident::new("WindVane".into(), DUMMY_SP))), - prop: Ident::new("call".into(), DUMMY_SP).into(), + obj: Box::new(Expr::Ident(Ident::new("WindVane".into(), DUMMY_SP, SyntaxContext::empty()))), + prop: MemberProp::Ident(Ident::new("call".into(), DUMMY_SP, SyntaxContext::empty()).into()), }), "undefined", BinaryOp::NotEqEq, @@ -198,6 +199,7 @@ fn create_env_declare(specifier: &Ident, imported: &Ident) -> Stmt { span: DUMMY_SP, kind: VarDeclKind::Var, declare: false, + ctxt: Default::default(), decls: vec![VarDeclarator { span: DUMMY_SP, name: Pat::Ident(BindingIdent { @@ -212,6 +214,7 @@ fn create_env_declare(specifier: &Ident, imported: &Ident) -> Stmt { fn create_env_default_export(export_name: Ident) -> Stmt { Stmt::Decl(Decl::Var(Box::new(VarDecl { + ctxt: Default::default(), span: DUMMY_SP, kind: VarDeclKind::Const, declare: false, @@ -242,8 +245,8 @@ fn create_env_default_export(export_name: Ident) -> Stmt { .into_iter() .map(|target| { PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp { - key: PropName::Ident(Ident::new(target.into(), DUMMY_SP)), - value: Box::new(get_env_expr(&Ident::new(target.into(), DUMMY_SP))), + key: PropName::Ident(Ident::new(target.into(), DUMMY_SP, SyntaxContext::empty()).into()), + value: Box::new(get_env_expr(&Ident::new(target.into(), DUMMY_SP, SyntaxContext::empty()).into())), }))) }) .collect(), @@ -289,7 +292,7 @@ fn get_env_stmt(sources: &Vec, decls: Vec) -> Vec { ObjectPatProp::KeyValue(KeyValuePatProp { key, value, .. }) => { if let box Pat::Ident(BindingIdent { id, .. }) = &value { if let PropName::Ident(i) = key { - stmts.push(create_env_declare(i, &id)); + stmts.push(create_env_declare(&Ident::from(i.as_ref()), &id)); } } } diff --git a/crates/swc_optimize_barrel/src/lib.rs b/crates/swc_optimize_barrel/src/lib.rs index d7ba51e..dd952e7 100644 --- a/crates/swc_optimize_barrel/src/lib.rs +++ b/crates/swc_optimize_barrel/src/lib.rs @@ -217,6 +217,7 @@ impl Fold for OptimizeBarrel { span: DUMMY_SP, kind: VarDeclKind::Const, declare: false, + ctxt: Default::default(), decls: vec![VarDeclarator { span: DUMMY_SP, name: Pat::Ident(BindingIdent { @@ -255,6 +256,7 @@ impl Fold for OptimizeBarrel { span: DUMMY_SP, kind: VarDeclKind::Const, declare: false, + ctxt: Default::default(), decls: vec![VarDeclarator { span: DUMMY_SP, name: Pat::Ident(BindingIdent { diff --git a/crates/swc_remove_export/src/transform.rs b/crates/swc_remove_export/src/transform.rs index 847aad9..88d4201 100644 --- a/crates/swc_remove_export/src/transform.rs +++ b/crates/swc_remove_export/src/transform.rs @@ -300,6 +300,7 @@ impl RemoveExport { body: Some(BlockStmt { span: DUMMY_SP, stmts: vec![], + ctxt: Default::default(), }), span: DUMMY_SP, is_generator: false, @@ -307,6 +308,7 @@ impl RemoveExport { decorators: vec![], return_type: None, type_params: None, + ctxt: Default::default(), }), }; } diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 8a00cf7..00b7f43 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -2,4 +2,4 @@ profile = "default" # Use nightly for better access to the latest Rust features. # This date is aligned to stable release dates. -channel = "nightly-2023-12-28" # v1.75.0 +channel = "nightly-2024-06-07" # v1.80.0 \ No newline at end of file