mirror of
https://github.com/swc-project/swc.git
synced 2024-11-27 13:38:33 +03:00
fix(plugin): Fix caching of wasm modulee (#3616)
This commit is contained in:
parent
b69e4b2a93
commit
05aecf507e
@ -439,6 +439,9 @@ impl Options {
|
||||
filename: transform_filename,
|
||||
};
|
||||
|
||||
#[cfg(feature = "plugin")]
|
||||
swc_plugin_runner::cache::init_plugin_module_cache_once(&experimental.cache_root);
|
||||
|
||||
let pass = chain!(
|
||||
lint_to_fold(swc_ecma_lints::rules::all(LintParams {
|
||||
program: &program,
|
||||
|
@ -45,13 +45,9 @@ pub fn plugins(
|
||||
) -> impl Fold {
|
||||
#[cfg(feature = "plugin")]
|
||||
{
|
||||
let cache_root =
|
||||
swc_plugin_runner::resolve::resolve_plugin_cache_root(config.cache_root).ok();
|
||||
|
||||
RustPlugins {
|
||||
resolver,
|
||||
plugins: config.plugins,
|
||||
plugin_cache: cache_root,
|
||||
plugin_context,
|
||||
}
|
||||
}
|
||||
@ -65,10 +61,6 @@ pub fn plugins(
|
||||
struct RustPlugins {
|
||||
resolver: CachingResolver<NodeModulesResolver>,
|
||||
plugins: Option<Vec<PluginConfig>>,
|
||||
/// TODO: it is unclear how we'll support plugin itself in wasm target of
|
||||
/// swc, as well as cache.
|
||||
#[cfg(feature = "plugin")]
|
||||
plugin_cache: Option<swc_plugin_runner::resolve::PluginCache>,
|
||||
plugin_context: PluginContext,
|
||||
}
|
||||
|
||||
@ -112,7 +104,7 @@ impl RustPlugins {
|
||||
serialized = swc_plugin_runner::apply_js_plugin(
|
||||
&p.0,
|
||||
&path,
|
||||
&mut self.plugin_cache,
|
||||
&swc_plugin_runner::cache::PLUGIN_MODULE_CACHE,
|
||||
serialized,
|
||||
config_json,
|
||||
context_json,
|
||||
|
@ -16,7 +16,7 @@ parking_lot = "0.12.0"
|
||||
serde = {version = "1.0.126", features = ["derive"]}
|
||||
serde_json = "1.0.64"
|
||||
swc_atoms = {version = "0.2.7", path = '../swc_atoms'}
|
||||
swc_common = {version = "0.17.0", path = "../swc_common", features = ["plugin-rt"]}
|
||||
swc_common = {version = "0.17.0", path = "../swc_common", features = ["plugin-rt", "concurrent"]}
|
||||
swc_ecma_ast = {version = "0.65.0", path = "../swc_ecma_ast", features = ["rkyv-impl"]}
|
||||
swc_ecma_loader = { version = "0.28.0", path = "../swc_ecma_loader" }
|
||||
swc_ecma_parser = {version = "0.88.0", path = "../swc_ecma_parser"}
|
||||
|
153
crates/swc_plugin_runner/src/cache.rs
Normal file
153
crates/swc_plugin_runner/src/cache.rs
Normal file
@ -0,0 +1,153 @@
|
||||
use std::{
|
||||
env::current_dir,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use anyhow::{Context, Error};
|
||||
use parking_lot::Mutex;
|
||||
use swc_common::{
|
||||
collections::AHashMap,
|
||||
sync::{Lazy, OnceCell},
|
||||
};
|
||||
use wasmer::{Module, Store};
|
||||
use wasmer_cache::{Cache as WasmerCache, FileSystemCache, Hash};
|
||||
|
||||
/// Version for bytecode cache stored in local filesystem.
|
||||
///
|
||||
/// This MUST be updated when bump up wasmer.
|
||||
///
|
||||
/// Bytecode cache generated via wasmer is generally portable,
|
||||
/// however it is not gauranteed to be compatible across wasmer's
|
||||
/// internal changes.
|
||||
/// https://github.com/wasmerio/wasmer/issues/2781
|
||||
const MODULE_SERIALIZATION_VERSION: &str = "v1";
|
||||
|
||||
/// A shared instance to plugin's module bytecode cache.
|
||||
/// TODO: it is unclear how we'll support plugin itself in wasm target of
|
||||
/// swc, as well as cache.
|
||||
pub static PLUGIN_MODULE_CACHE: Lazy<PluginModuleCache> = Lazy::new(Default::default);
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct CacheInner {
|
||||
fs_cache: Option<FileSystemCache>,
|
||||
memory_cache: InMemoryCache,
|
||||
}
|
||||
|
||||
/// Lightweight in-memory cache to hold plugin module instances.
|
||||
/// Current it doesn't have any invalidation or expiration logics like lru,
|
||||
/// having a lot of plugins may create some memory pressure.
|
||||
#[derive(Default)]
|
||||
pub struct InMemoryCache {
|
||||
modules: AHashMap<PathBuf, Module>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct PluginModuleCache {
|
||||
inner: OnceCell<Mutex<CacheInner>>,
|
||||
/// To prevent concurrent access to `WasmerInstance::new`
|
||||
instantiation_lock: Mutex<()>,
|
||||
}
|
||||
|
||||
fn create_filesystem_cache(filesystem_cache_root: &Option<String>) -> Option<FileSystemCache> {
|
||||
let mut root_path = if let Some(root) = filesystem_cache_root {
|
||||
Some(PathBuf::from(root))
|
||||
} else if let Ok(cwd) = current_dir() {
|
||||
Some(cwd.join(".swc"))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if let Some(root_path) = &mut root_path {
|
||||
root_path.push("plugins");
|
||||
root_path.push(MODULE_SERIALIZATION_VERSION);
|
||||
|
||||
return FileSystemCache::new(&root_path).ok();
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
/// Create a new cache instance if not intialized. This can be called multiple
|
||||
/// time, but any subsequent call will be ignored.
|
||||
///
|
||||
/// This fn have a side effect to create path to cache if given path is not
|
||||
/// resolvable. If root is not specified, it'll generate default root for
|
||||
/// cache location.
|
||||
///
|
||||
/// If cache failed to initialize filesystem cache for given location
|
||||
/// it'll be serve in-memory cache only.
|
||||
pub fn init_plugin_module_cache_once(filesystem_cache_root: &Option<String>) {
|
||||
PLUGIN_MODULE_CACHE.inner.get_or_init(|| {
|
||||
Mutex::new(CacheInner {
|
||||
fs_cache: create_filesystem_cache(filesystem_cache_root),
|
||||
memory_cache: Default::default(),
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
impl PluginModuleCache {
|
||||
/// DO NOT USE unless absolutely necessary. This is mainly for testing
|
||||
/// purpose.
|
||||
pub fn new() -> Self {
|
||||
PluginModuleCache {
|
||||
inner: OnceCell::from(Mutex::new(Default::default())),
|
||||
instantiation_lock: Mutex::new(()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Load a compiled plugin Module from speficied path.
|
||||
/// Since plugin will be initialized per-file transform, this function tries
|
||||
/// to avoid reading filesystem per each initialization via naive
|
||||
/// in-memory map which stores raw bytecodes from file. Unlike compiled
|
||||
/// bytecode cache for the wasm, this is volatile.
|
||||
///
|
||||
/// ### Notes
|
||||
/// [This code](https://github.com/swc-project/swc/blob/fc4c6708f24cda39640fbbfe56123f2f6eeb2474/crates/swc/src/plugin.rs#L19-L44)
|
||||
/// includes previous incorrect attempt to workaround file read issues.
|
||||
/// In actual transform, `plugins` is also being called per each transform.
|
||||
pub fn load_module(&self, binary_path: &Path) -> Result<Module, Error> {
|
||||
let binary_path = binary_path.to_path_buf();
|
||||
let mut inner_cache = self.inner.get().expect("Cache should be available").lock();
|
||||
|
||||
// if constructed Module is available in-memory, directly return it.
|
||||
// Note we do not invalidate in-memory cache currently: if wasm binary is
|
||||
// replaced in-process lifecycle (i.e devserver) it won't be reflected.
|
||||
let in_memory_module = inner_cache.memory_cache.modules.get(&binary_path);
|
||||
if let Some(module) = in_memory_module {
|
||||
return Ok(module.clone());
|
||||
}
|
||||
|
||||
let module_bytes =
|
||||
std::fs::read(&binary_path).context("Cannot read plugin from specified path")?;
|
||||
let module_bytes_hash = Hash::generate(&module_bytes);
|
||||
|
||||
let wasmer_store = Store::default();
|
||||
|
||||
let load_cold_wasm_bytes = || {
|
||||
let _lock = self.instantiation_lock.lock();
|
||||
Module::new(&wasmer_store, module_bytes).context("Cannot compile plugin binary")
|
||||
};
|
||||
|
||||
// Try to load compiled bytes from filesystem cache if available.
|
||||
// Otherwise, cold compile instead.
|
||||
let module = if let Some(fs_cache) = &mut inner_cache.fs_cache {
|
||||
let load_result = unsafe { fs_cache.load(&wasmer_store, module_bytes_hash) };
|
||||
if let Ok(module) = load_result {
|
||||
module
|
||||
} else {
|
||||
let cold_bytes = load_cold_wasm_bytes()?;
|
||||
fs_cache.store(module_bytes_hash, &cold_bytes)?;
|
||||
cold_bytes
|
||||
}
|
||||
} else {
|
||||
load_cold_wasm_bytes()?
|
||||
};
|
||||
|
||||
inner_cache
|
||||
.memory_cache
|
||||
.modules
|
||||
.insert(binary_path, module.clone());
|
||||
|
||||
Ok(module)
|
||||
}
|
||||
}
|
@ -1,26 +1,19 @@
|
||||
use std::{
|
||||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
};
|
||||
use std::{path::Path, sync::Arc};
|
||||
|
||||
use anyhow::{anyhow, Context, Error};
|
||||
use cache::PluginModuleCache;
|
||||
use once_cell::sync::Lazy;
|
||||
use parking_lot::Mutex;
|
||||
use resolve::PluginCache;
|
||||
use swc_common::{
|
||||
collections::AHashMap,
|
||||
errors::{Diagnostic, HANDLER},
|
||||
hygiene::MutableMarkContext,
|
||||
plugin::{PluginError, Serialized},
|
||||
Mark, SyntaxContext,
|
||||
};
|
||||
use wasmer::{
|
||||
imports, Array, Exports, Function, Instance, LazyInit, Memory, Module, Store, WasmPtr,
|
||||
};
|
||||
use wasmer_cache::{Cache, Hash};
|
||||
use wasmer::{imports, Array, Exports, Function, Instance, LazyInit, Memory, WasmPtr};
|
||||
use wasmer_wasi::{is_wasi_module, WasiState};
|
||||
|
||||
pub mod resolve;
|
||||
pub mod cache;
|
||||
|
||||
fn copy_bytes_into_host(memory: &Memory, bytes_ptr: i32, bytes_ptr_len: i32) -> Vec<u8> {
|
||||
let ptr: WasmPtr<u8, Array> = WasmPtr::new(bytes_ptr as _);
|
||||
@ -202,94 +195,18 @@ struct HostEnvironment {
|
||||
transform_result: Arc<Mutex<Vec<u8>>>,
|
||||
}
|
||||
|
||||
/// Load plugin from specified path.
|
||||
/// If cache is provided, it'll try to load from cache first to avoid
|
||||
/// compilation.
|
||||
///
|
||||
/// Since plugin will be initialized per-file transform, this function tries to
|
||||
/// avoid reading filesystem per each initialization via naive in-memory map
|
||||
/// which stores raw bytecodes from file. Unlike compiled bytecode cache for the
|
||||
/// wasm, this is volatile.
|
||||
///
|
||||
/// ### Notes
|
||||
/// [This code](https://github.com/swc-project/swc/blob/fc4c6708f24cda39640fbbfe56123f2f6eeb2474/crates/swc/src/plugin.rs#L19-L44)
|
||||
/// includes previous incorrect attempt to workaround file read issues.
|
||||
/// In actual transform, `plugins` is also being called per each transform.
|
||||
fn load_plugin(
|
||||
plugin_path: &Path,
|
||||
cache: &mut Option<PluginCache>,
|
||||
cache: &Lazy<PluginModuleCache>,
|
||||
) -> Result<(Instance, Arc<Mutex<Vec<u8>>>), Error> {
|
||||
static BYTE_CACHE: Lazy<Mutex<AHashMap<PathBuf, Arc<Vec<u8>>>>> = Lazy::new(Default::default);
|
||||
|
||||
// TODO: This caching streategy does not consider few edge cases.
|
||||
// 1. If process is long-running (devServer) binary change in the middle of
|
||||
// process won't be reflected.
|
||||
// 2. If reading binary fails somehow it won't bail out but keep retry.
|
||||
let module_bytes_key = plugin_path.to_path_buf();
|
||||
let cached_bytes = BYTE_CACHE.lock().get(&module_bytes_key).cloned();
|
||||
let module_bytes = if let Some(cached_bytes) = cached_bytes {
|
||||
cached_bytes
|
||||
} else {
|
||||
let fresh_module_bytes = std::fs::read(plugin_path)
|
||||
.map(Arc::new)
|
||||
.context("Cannot read plugin from specified path")?;
|
||||
|
||||
BYTE_CACHE
|
||||
.lock()
|
||||
.insert(module_bytes_key, fresh_module_bytes.clone());
|
||||
|
||||
fresh_module_bytes
|
||||
};
|
||||
|
||||
// TODO: can we share store instances across each plugin binaries?
|
||||
let wasmer_store = Store::default();
|
||||
|
||||
let load_from_cache = |c: &mut PluginCache, hash: Hash| match c {
|
||||
PluginCache::File(filesystem_cache) => unsafe {
|
||||
filesystem_cache.load(&wasmer_store, hash)
|
||||
},
|
||||
};
|
||||
|
||||
let store_into_cache = |c: &mut PluginCache, hash: Hash, module: &Module| match c {
|
||||
PluginCache::File(filesystem_cache) => filesystem_cache.store(hash, module),
|
||||
};
|
||||
|
||||
let hash = Hash::generate(&module_bytes);
|
||||
|
||||
let load_cold_wasm_bytes =
|
||||
|| Module::new(&wasmer_store, module_bytes.as_ref()).context("Cannot compile plugin");
|
||||
|
||||
let module = if let Some(cache) = cache {
|
||||
let cached_module =
|
||||
load_from_cache(cache, hash).context("Failed to load plugin from cache");
|
||||
|
||||
match cached_module {
|
||||
Ok(module) => Ok(module),
|
||||
Err(err) => {
|
||||
let loaded_module = load_cold_wasm_bytes().map_err(|_| err);
|
||||
match &loaded_module {
|
||||
Ok(module) => {
|
||||
if let Err(err) = store_into_cache(cache, hash, module) {
|
||||
loaded_module
|
||||
.map_err(|_| err)
|
||||
.context("Failed to store compiled plugin into cache")
|
||||
} else {
|
||||
loaded_module
|
||||
}
|
||||
}
|
||||
Err(..) => loaded_module,
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
load_cold_wasm_bytes()
|
||||
};
|
||||
let module = cache.load_module(plugin_path);
|
||||
|
||||
return match module {
|
||||
Ok(module) => {
|
||||
let wasmer_store = module.store();
|
||||
let transform_result: Arc<Mutex<Vec<u8>>> = Arc::new(Mutex::new(vec![]));
|
||||
let set_transform_result_fn_decl = Function::new_native_with_env(
|
||||
&wasmer_store,
|
||||
wasmer_store,
|
||||
HostEnvironment {
|
||||
memory: LazyInit::default(),
|
||||
transform_result: transform_result.clone(),
|
||||
@ -298,7 +215,7 @@ fn load_plugin(
|
||||
);
|
||||
|
||||
let emit_diagnostics_fn_decl = Function::new_native_with_env(
|
||||
&wasmer_store,
|
||||
wasmer_store,
|
||||
HostEnvironment {
|
||||
memory: LazyInit::default(),
|
||||
transform_result: transform_result.clone(),
|
||||
@ -306,14 +223,13 @@ fn load_plugin(
|
||||
emit_diagnostics,
|
||||
);
|
||||
|
||||
let mark_fresh_fn_decl = Function::new_native(&wasmer_store, mark_fresh_proxy);
|
||||
let mark_parent_fn_decl = Function::new_native(&wasmer_store, mark_parent_proxy);
|
||||
let mark_is_builtin_fn_decl =
|
||||
Function::new_native(&wasmer_store, mark_is_builtin_proxy);
|
||||
let mark_fresh_fn_decl = Function::new_native(wasmer_store, mark_fresh_proxy);
|
||||
let mark_parent_fn_decl = Function::new_native(wasmer_store, mark_parent_proxy);
|
||||
let mark_is_builtin_fn_decl = Function::new_native(wasmer_store, mark_is_builtin_proxy);
|
||||
let mark_set_builtin_fn_decl =
|
||||
Function::new_native(&wasmer_store, mark_set_builtin_proxy);
|
||||
Function::new_native(wasmer_store, mark_set_builtin_proxy);
|
||||
let mark_is_descendant_of_fn_decl = Function::new_native_with_env(
|
||||
&wasmer_store,
|
||||
wasmer_store,
|
||||
HostEnvironment {
|
||||
memory: LazyInit::default(),
|
||||
transform_result: transform_result.clone(),
|
||||
@ -322,7 +238,7 @@ fn load_plugin(
|
||||
);
|
||||
|
||||
let mark_least_ancestor_fn_decl = Function::new_native_with_env(
|
||||
&wasmer_store,
|
||||
wasmer_store,
|
||||
HostEnvironment {
|
||||
memory: LazyInit::default(),
|
||||
transform_result: transform_result.clone(),
|
||||
@ -331,9 +247,9 @@ fn load_plugin(
|
||||
);
|
||||
|
||||
let syntax_context_apply_mark_fn_decl =
|
||||
Function::new_native(&wasmer_store, syntax_context_apply_mark_proxy);
|
||||
Function::new_native(wasmer_store, syntax_context_apply_mark_proxy);
|
||||
let syntax_context_remove_mark_fn_decl = Function::new_native_with_env(
|
||||
&wasmer_store,
|
||||
wasmer_store,
|
||||
HostEnvironment {
|
||||
memory: LazyInit::default(),
|
||||
transform_result: transform_result.clone(),
|
||||
@ -341,7 +257,7 @@ fn load_plugin(
|
||||
syntax_context_remove_mark_proxy,
|
||||
);
|
||||
let syntax_context_outer_fn_decl =
|
||||
Function::new_native(&wasmer_store, syntax_context_outer_proxy);
|
||||
Function::new_native(wasmer_store, syntax_context_outer_proxy);
|
||||
|
||||
// Plugin binary can be either wasm32-wasi or wasm32-unknown-unknown
|
||||
let import_object = if is_wasi_module(&module) {
|
||||
@ -431,7 +347,7 @@ struct PluginTransformTracker {
|
||||
}
|
||||
|
||||
impl PluginTransformTracker {
|
||||
fn new(path: &Path, cache: &mut Option<PluginCache>) -> Result<PluginTransformTracker, Error> {
|
||||
fn new(path: &Path, cache: &Lazy<PluginModuleCache>) -> Result<PluginTransformTracker, Error> {
|
||||
let (instance, transform_result) = load_plugin(path, cache)?;
|
||||
|
||||
let tracker = PluginTransformTracker {
|
||||
@ -534,7 +450,7 @@ impl Drop for PluginTransformTracker {
|
||||
pub fn apply_js_plugin(
|
||||
plugin_name: &str,
|
||||
path: &Path,
|
||||
cache: &mut Option<PluginCache>,
|
||||
cache: &Lazy<PluginModuleCache>,
|
||||
program: Serialized,
|
||||
config_json: Serialized,
|
||||
context_json: Serialized,
|
||||
|
@ -1,38 +0,0 @@
|
||||
use std::{env::current_dir, path::PathBuf};
|
||||
|
||||
use anyhow::{Context, Error};
|
||||
use wasmer_cache::FileSystemCache;
|
||||
|
||||
/// Type of cache to store compiled bytecodes of plugins.
|
||||
/// Currently only supports filesystem, but _may_ supports
|
||||
/// other type (in-memory, etcs) for the long-running processes like devserver.
|
||||
pub enum PluginCache {
|
||||
File(FileSystemCache),
|
||||
}
|
||||
|
||||
/// Build a path to cache location where plugin's bytecode cache will be stored.
|
||||
/// This fn does a side effect to create path to cache if given path is not
|
||||
/// resolvable. If root is not specified, it'll generate default root for cache
|
||||
/// location.
|
||||
///
|
||||
/// Note SWC's plugin should not fail to load when cache location is not
|
||||
/// available. It'll make each invocation to cold start.
|
||||
pub fn resolve_plugin_cache_root(root: Option<String>) -> Result<PluginCache, Error> {
|
||||
let root_path = match root {
|
||||
Some(root) => {
|
||||
let mut root = PathBuf::from(root);
|
||||
root.push("plugins");
|
||||
root
|
||||
}
|
||||
None => {
|
||||
let mut cwd = current_dir().context("failed to get current directory")?;
|
||||
cwd.push(".swc");
|
||||
cwd.push("plugins");
|
||||
cwd
|
||||
}
|
||||
};
|
||||
|
||||
FileSystemCache::new(root_path)
|
||||
.map(PluginCache::File)
|
||||
.context("Failed to create cache location for the plugins")
|
||||
}
|
@ -5,10 +5,11 @@ use std::{
|
||||
};
|
||||
|
||||
use anyhow::{anyhow, Error};
|
||||
use swc_common::{errors::HANDLER, plugin::Serialized, FileName};
|
||||
use swc_common::{errors::HANDLER, plugin::Serialized, sync::Lazy, FileName};
|
||||
use swc_ecma_ast::{CallExpr, Callee, EsVersion, Expr, Lit, MemberExpr, Program, Str};
|
||||
use swc_ecma_parser::{lexer::Lexer, EsConfig, Parser, StringInput, Syntax};
|
||||
use swc_ecma_visit::{Visit, VisitWith};
|
||||
use swc_plugin_runner::cache::PluginModuleCache;
|
||||
|
||||
/// Returns the path to the built plugin
|
||||
fn build_plugin(dir: &Path) -> Result<PathBuf, Error> {
|
||||
@ -85,10 +86,12 @@ fn internal() -> Result<(), Error> {
|
||||
let context = Serialized::serialize(&"{sourceFileName: 'single_plugin_test'}".to_string())
|
||||
.expect("Should serializable");
|
||||
|
||||
let cache: Lazy<PluginModuleCache> = Lazy::new(PluginModuleCache::new);
|
||||
|
||||
let program_bytes = swc_plugin_runner::apply_js_plugin(
|
||||
"internal-test",
|
||||
&path,
|
||||
&mut None,
|
||||
&cache,
|
||||
program,
|
||||
config,
|
||||
context,
|
||||
@ -131,11 +134,13 @@ fn internal() -> Result<(), Error> {
|
||||
Serialized::serialize(&"{sourceFileName: 'single_plugin_handler_test'}".to_string())
|
||||
.expect("Should serializable");
|
||||
|
||||
let cache: Lazy<PluginModuleCache> = Lazy::new(PluginModuleCache::new);
|
||||
|
||||
let _res = HANDLER.set(&handler, || {
|
||||
swc_plugin_runner::apply_js_plugin(
|
||||
"internal-test",
|
||||
&path,
|
||||
&mut None,
|
||||
&cache,
|
||||
program,
|
||||
config,
|
||||
context,
|
||||
@ -164,11 +169,12 @@ fn internal() -> Result<(), Error> {
|
||||
let program = parser.parse_program().unwrap();
|
||||
|
||||
let mut serialized_program = Serialized::serialize(&program).expect("Should serializable");
|
||||
let cache: Lazy<PluginModuleCache> = Lazy::new(PluginModuleCache::new);
|
||||
|
||||
serialized_program = swc_plugin_runner::apply_js_plugin(
|
||||
"internal-test",
|
||||
&path,
|
||||
&mut None,
|
||||
&cache,
|
||||
serialized_program,
|
||||
Serialized::serialize(&"{}".to_string()).expect("Should serializable"),
|
||||
Serialized::serialize(&"{sourceFileName: 'multiple_plugin_test'}".to_string())
|
||||
@ -180,7 +186,7 @@ fn internal() -> Result<(), Error> {
|
||||
serialized_program = swc_plugin_runner::apply_js_plugin(
|
||||
"internal-test",
|
||||
&path,
|
||||
&mut None,
|
||||
&cache,
|
||||
serialized_program,
|
||||
Serialized::serialize(&"{}".to_string()).expect("Should serializable"),
|
||||
Serialized::serialize(&"{sourceFileName: 'multiple_plugin_test2'}".to_string())
|
||||
|
13
tests/rust-plugins/swc_internal_plugin/Cargo.lock
generated
13
tests/rust-plugins/swc_internal_plugin/Cargo.lock
generated
@ -56,6 +56,13 @@ version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "better_scoped_tls"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"scoped-tls",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
@ -685,11 +692,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "swc_common"
|
||||
version = "0.17.5"
|
||||
version = "0.17.7"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"anyhow",
|
||||
"ast_node",
|
||||
"better_scoped_tls",
|
||||
"cfg-if 0.1.10",
|
||||
"debug_unreachable",
|
||||
"either",
|
||||
@ -699,7 +707,6 @@ dependencies = [
|
||||
"owning_ref",
|
||||
"rkyv",
|
||||
"rustc-hash",
|
||||
"scoped-tls",
|
||||
"serde",
|
||||
"siphasher",
|
||||
"string_cache",
|
||||
@ -766,7 +773,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "swc_plugin"
|
||||
version = "0.27.0"
|
||||
version = "0.27.1"
|
||||
dependencies = [
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
|
Loading…
Reference in New Issue
Block a user