From b321383ef0c9ce4273249a1c01c561d085b49b79 Mon Sep 17 00:00:00 2001 From: mantou132 <709922234@qq.com> Date: Wed, 4 Dec 2024 20:52:22 +0800 Subject: [PATCH] Add clippy & fmt --- .rustfmt.toml | 8 ++++ .vscode/settings.json | 1 + Cargo.lock | 1 + README.md | 26 +++++----- README_zh.md | 22 +++++---- clippy.toml | 26 ++++++++++ crates/swc-plugin-gem/.gitignore | 2 +- crates/swc-plugin-gem/README.md | 2 +- crates/swc-plugin-gem/package.json | 7 ++- crates/swc-plugin-gem/src/lib.rs | 32 ++++++++----- crates/swc-plugin-gem/src/visitors/hmr.rs | 31 ++++++++++++ crates/swc-plugin-gem/src/visitors/import.rs | 26 +++++----- crates/swc-plugin-gem/src/visitors/mod.rs | 1 + crates/swc-plugin-gem/src/visitors/path.rs | 26 +++++----- crates/swc-plugin-gem/src/visitors/preload.rs | 2 +- crates/swc-plugin-gem/types.d.ts | 48 +++++++++++++++++++ crates/zed-plugin-gem/Cargo.toml | 1 + crates/zed-plugin-gem/build.rs | 26 ++++++++-- crates/zed-plugin-gem/src/lib.rs | 8 ++-- .../en/001-guide/002-advance/009-building.md | 2 +- .../zh/001-guide/002-advance/009-building.md | 2 +- packages/gem/src/helper/hmr.ts | 13 +++++ 22 files changed, 241 insertions(+), 72 deletions(-) create mode 100644 .rustfmt.toml create mode 100644 clippy.toml create mode 100644 crates/swc-plugin-gem/src/visitors/hmr.rs create mode 100644 crates/swc-plugin-gem/types.d.ts create mode 100644 packages/gem/src/helper/hmr.ts diff --git a/.rustfmt.toml b/.rustfmt.toml new file mode 100644 index 00000000..0844fe72 --- /dev/null +++ b/.rustfmt.toml @@ -0,0 +1,8 @@ +edition = "2018" +format_strings = true +group_imports = "StdExternalCrate" +hex_literal_case = "Lower" +imports_granularity = "Crate" +reorder_impl_items = true +use_field_init_shorthand = true +wrap_comments = true diff --git a/.vscode/settings.json b/.vscode/settings.json index 3e9ebac4..6c4b21cd 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -12,6 +12,7 @@ "editor.codeActionsOnSave": { "source.fixAll": "explicit" }, + "rust-analyzer.check.command": "clippy", "[xml]": { "editor.defaultFormatter": null }, diff --git a/Cargo.lock b/Cargo.lock index ee9cdcf0..4c8148d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -618,6 +618,7 @@ dependencies = [ "reqwest", "tar", "tempfile", + "tracing", "zed_extension_api", ] diff --git a/README.md b/README.md index dff25342..edcd17f8 100644 --- a/README.md +++ b/README.md @@ -25,17 +25,21 @@ Create custom elements, bind data, route switching, and quickly develop WebApps ## Project Packages -| Package | Description | -| ---------------------------------------------- | ---------------------------------------------------------------- | -| [packages/gem](packages/gem) | Gem core | -| [packages/gem-devtools](packages/gem-devtools) | Browser debugging tool for Gem | -| [packages/gem-analyzer](packages/gem-analyzer) | Gem element analyzer, which can automatically generate documents | -| [packages/gem-book](packages/gem-book) | Documentation site builder created using Gem | -| [packages/duoyun-ui](packages/duoyun-ui) | UI library created using Gem | -| [packages/gem-port](packages/gem-port) | Export Gem elements as React/Vue/Svelte components | -| [packages/gem-examples](packages/gem-examples) | Gem and DuoyunUI examples | - -[Rodmap](https://mm.tt/app/map/3412316197?t=TGs84FRcwQ). +| Package | Description | +| ----------------------------------------------- | ---------------------------------------------------------------- | +| [gem](packages/gem) | Gem core | +| [gem-devtools](packages/gem-devtools) | Browser debugging tool for Gem | +| [gem-analyzer](packages/gem-analyzer) | Gem element analyzer, which can automatically generate documents | +| [gem-book](packages/gem-book) | Documentation site builder created using Gem | +| [duoyun-ui](packages/duoyun-ui) | UI library created using Gem | +| [gem-port](packages/gem-port) | Export Gem elements as React/Vue/Svelte components | +| [gem-examples](packages/gem-examples) | Gem and DuoyunUI examples | +| [language-service](packages/language-service) | language service for Gem | +| [vscode-gem-plugin](packages/vscode-gem-plugin) | VSCode extension | +| [swc-plugin-gem](crates/swc-plugin-gem) | Building plugin for [SWC](https://swc.rs/) | +| [zed-plugin-gem](crates/swc-plugin-gem) | [Zed](https://zed.dev/) extension | + +[Roadmap](https://mm.tt/app/map/3412316197?t=TGs84FRcwQ). ## Contribution diff --git a/README_zh.md b/README_zh.md index 70a78992..50fbb558 100644 --- a/README_zh.md +++ b/README_zh.md @@ -31,15 +31,19 @@ ## 项目结构 -| 目录 | 描述 | -| ---------------------------------------------- | --------------------------------------- | -| [packages/gem](packages/gem) | Gem 核心 | -| [packages/gem-devtools](packages/gem-devtools) | Gem 的浏览器调试工具 | -| [packages/gem-analyzer](packages/gem-analyzer) | Gem 元素分析器,能自动生成文档 | -| [packages/gem-book](packages/gem-book) | 使用 Gem 创建的文档站生成器 | -| [packages/duoyun-ui](packages/duoyun-ui) | 使用 Gem 创建的 UI 库 | -| [packages/gem-port](packages/gem-port) | 将 Gem 元素导出为 React/Vue/Svelte 组件 | -| [packages/gem-examples](packages/gem-examples) | 一些 Gem 和 DuoyunUI 示例 | +| 目录 | 描述 | +| ----------------------------------------------- | --------------------------------------- | +| [gem](packages/gem) | Gem 核心 | +| [gem-devtools](packages/gem-devtools) | Gem 的浏览器调试工具 | +| [gem-analyzer](packages/gem-analyzer) | Gem 元素分析器,能自动生成文档 | +| [gem-book](packages/gem-book) | 使用 Gem 创建的文档站生成器 | +| [duoyun-ui](packages/duoyun-ui) | 使用 Gem 创建的 UI 库 | +| [gem-port](packages/gem-port) | 将 Gem 元素导出为 React/Vue/Svelte 组件 | +| [gem-examples](packages/gem-examples) | 一些 Gem 和 DuoyunUI 示例 | +| [language-service](packages/language-service) | Gem 的语言服务 | +| [vscode-gem-plugin](packages/vscode-gem-plugin) | VSCode 扩展 | +| [swc-plugin-gem](crates/swc-plugin-gem) | [SWC](https://swc.rs/) 构建插件 | +| [zed-plugin-gem](crates/swc-plugin-gem) | [Zed](https://zed.dev/) 扩展 | [路线图](https://mm.tt/app/map/3412316197?t=TGs84FRcwQ)。 diff --git a/clippy.toml b/clippy.toml new file mode 100644 index 00000000..4528e02b --- /dev/null +++ b/clippy.toml @@ -0,0 +1,26 @@ +cognitive-complexity-threshold = 50 +disallowed-names = [ + "bool", + "char", + "str", + "f32", + "f64", + "i8", + "i16", + "i32", + "i64", + "u8", + "u16", + "u32", + "u64", + "isize", + "usize", +] +ignore-interior-mutability = [ + "bytes::Bytes", + "swc_atoms::Atom", + "swc_atoms::JsWord", + "swc_ecma_ast::Id", +] +msrv = "1.70" +type-complexity-threshold = 25000 diff --git a/crates/swc-plugin-gem/.gitignore b/crates/swc-plugin-gem/.gitignore index 894144f5..0da10fb6 100644 --- a/crates/swc-plugin-gem/.gitignore +++ b/crates/swc-plugin-gem/.gitignore @@ -2,4 +2,4 @@ *.wasm .swcrc .swc -*.d.ts \ No newline at end of file +auto-import.d.ts \ No newline at end of file diff --git a/crates/swc-plugin-gem/README.md b/crates/swc-plugin-gem/README.md index 7e3c501a..b8aa0022 100644 --- a/crates/swc-plugin-gem/README.md +++ b/crates/swc-plugin-gem/README.md @@ -16,7 +16,7 @@ "experimental": { "plugins": [ [ - "swc_plugin_gem", + "swc-plugin-gem", { "autoImport": { "extends": "gem", diff --git a/crates/swc-plugin-gem/package.json b/crates/swc-plugin-gem/package.json index 53604a6e..344c384e 100644 --- a/crates/swc-plugin-gem/package.json +++ b/crates/swc-plugin-gem/package.json @@ -10,7 +10,12 @@ "main": "swc_plugin_gem.wasm", "files": [], "scripts": { - "prepublishOnly": "cross-env CARGO_TARGET_DIR=target cargo build-wasi --release && cp target/wasm32-wasip1/release/swc_plugin_gem.wasm .", + "build:dev": "cross-env CARGO_TARGET_DIR=target cargo build-wasi", + "cp:dev": "cp target/wasm32-wasip1/debug/swc_plugin_gem.wasm .", + "build": "npm run build:dev -- --release", + "cp": "cp target/wasm32-wasip1/release/swc_plugin_gem.wasm .", + "prepublishOnly": "pnpm run build && npm run cp", + "dev": "cargo watch -s \"npm run build:dev && npm run cp:dev\"", "test": "cross-env RUST_LOG=info cargo watch -x test" }, "preferUnplugged": true, diff --git a/crates/swc-plugin-gem/src/lib.rs b/crates/swc-plugin-gem/src/lib.rs index 68938ea5..b105f802 100644 --- a/crates/swc-plugin-gem/src/lib.rs +++ b/crates/swc-plugin-gem/src/lib.rs @@ -1,14 +1,21 @@ use serde::Deserialize; use swc_common::pass::Optional; -use swc_core::ecma::visit::VisitMutWith; -use swc_core::plugin::metadata::TransformPluginMetadataContextKind; -use swc_core::plugin::{plugin_transform, proxies::TransformPluginProgramMetadata}; +use swc_core::{ + ecma::visit::VisitMutWith, + plugin::{ + metadata::TransformPluginMetadataContextKind, plugin_transform, + proxies::TransformPluginProgramMetadata, + }, +}; use swc_ecma_ast::Program; -pub use visitors::import::{import_transform, AutoImport}; -pub use visitors::memo::memo_transform; -pub use visitors::minify::minify_transform; -pub use visitors::path::path_transform; -pub use visitors::preload::preload_transform; +pub use visitors::{ + hmr::hmr_transform, + import::{import_transform, AutoImport}, + memo::memo_transform, + minify::minify_transform, + path::path_transform, + preload::preload_transform, +}; mod visitors; @@ -23,7 +30,7 @@ struct PluginConfig { pub resolve_path: bool, ///depend on URL loader, top await pub preload: bool, - /// un-implement + /// Under development, need add `@mantou/gem/helper/hmr` to entry pub hmr: bool, /// un-implement pub lazy_view: bool, @@ -47,10 +54,9 @@ pub fn process_transform(mut program: Program, data: TransformPluginProgramMetad }, Optional { enabled: match config.auto_import { - AutoImport::Gem(enabeld) => enabeld, + AutoImport::Gem(enabled) => enabled, AutoImport::Custom(_) => true, }, - // 执行在每个文件 visitor: import_transform(config.auto_import, config.auto_import_dts), }, Optional { @@ -65,6 +71,10 @@ pub fn process_transform(mut program: Program, data: TransformPluginProgramMetad enabled: config.preload, visitor: preload_transform(), }, + Optional { + enabled: config.hmr, + visitor: hmr_transform(), + }, )); program diff --git a/crates/swc-plugin-gem/src/visitors/hmr.rs b/crates/swc-plugin-gem/src/visitors/hmr.rs new file mode 100644 index 00000000..8f52ae87 --- /dev/null +++ b/crates/swc-plugin-gem/src/visitors/hmr.rs @@ -0,0 +1,31 @@ +//! https://rspack.dev/api/runtime-api/hmr +//! 为 HMR 添加一些特殊的转换 + +use swc_core::{ + ecma::visit::{noop_visit_mut_type, VisitMut, VisitMutWith}, + quote, +}; +use swc_ecma_ast::ModuleItem; + +#[derive(Default)] +struct TransformVisitor {} + +impl VisitMut for TransformVisitor { + noop_visit_mut_type!(); + + fn visit_mut_module_items(&mut self, node: &mut Vec) { + node.visit_mut_children_with(self); + + node.push(quote!( + " + if (module.hot) { + module.hot.accept(); + } + " as ModuleItem, + )); + } +} + +pub fn hmr_transform() -> impl VisitMut { + TransformVisitor::default() +} diff --git a/crates/swc-plugin-gem/src/visitors/import.rs b/crates/swc-plugin-gem/src/visitors/import.rs index 6979a1b1..0862485e 100644 --- a/crates/swc-plugin-gem/src/visitors/import.rs +++ b/crates/swc-plugin-gem/src/visitors/import.rs @@ -1,9 +1,10 @@ +use std::{collections::HashMap, env, fs}; + use indexmap::{IndexMap, IndexSet}; use node_resolve::Resolver; use once_cell::sync::{Lazy, OnceCell}; use regex::Regex; use serde::Deserialize; -use std::{collections::HashMap, env, fs}; use swc_common::{SyntaxContext, DUMMY_SP}; use swc_core::{ atoms::Atom, @@ -15,13 +16,13 @@ use swc_ecma_ast::{ VarDeclarator, }; -static CREATED_DTS: OnceCell = OnceCell::new(); - -static GLOBAL_CONFIG: OnceCell = OnceCell::new(); - static CUSTOM_ELEMENT_REGEX: Lazy = Lazy::new(|| Regex::new(r"(?s)<(?\w+(-\w+)+)(\s|>)").unwrap()); +// FIXME: 每个文件作为 loader 重新执行整个程序,这个全局缓存并没有生效 +static CREATED_DTS: OnceCell = OnceCell::new(); +static GLOBAL_CONFIG: OnceCell = OnceCell::new(); + #[derive(Deserialize, Debug, Clone, PartialEq)] #[serde(untagged)] enum MemberOrMemberAs { @@ -53,7 +54,7 @@ impl TransformVisitor { self.defined_members.insert(ident.to_id()); } - fn visit_mut_class(&mut self, node: &Box) { + fn visit_mut_class(&mut self, node: &Class) { if let Some(expr) = &node.super_class { if let Some(ident) = expr.as_ident() { self.inset_used_member(ident); @@ -146,7 +147,7 @@ impl VisitMut for TransformVisitor { node.visit_mut_children_with(self); if let Some(ident) = &node.name.as_ident() { - self.inset_defined_member(&ident); + self.inset_defined_member(ident); } } @@ -163,9 +164,7 @@ impl VisitMut for TransformVisitor { if !self.defined_members.contains(id) { let pkg = GLOBAL_CONFIG.get().unwrap().member_map.get(id.0.as_str()); if let Some(pkg) = pkg { - let set = available_import - .entry(pkg.into()) - .or_insert(Default::default()); + let set = available_import.entry(pkg.into()).or_default(); set.insert(&id.0, (&id.0, &id.1)); } } @@ -175,7 +174,7 @@ impl VisitMut for TransformVisitor { let mut specifiers: Vec = vec![]; for (member, (_member_as, ctx)) in set { specifiers.push(ImportSpecifier::Named(ImportNamedSpecifier { - local: Ident::new(member.clone(), DUMMY_SP, ctx.clone()), + local: Ident::new(member.clone(), DUMMY_SP, *ctx), span: DUMMY_SP, imported: None, is_type_only: false, @@ -183,7 +182,8 @@ impl VisitMut for TransformVisitor { } out.push(ImportDecl { specifiers, - // 也许可以支持替换:'@mantou/gem/{:pascal:}' + ColorPicker -> '@mantou/gem/ColorPicker' + // 也许可以支持替换:'@mantou/gem/{:pascal:}' + ColorPicker -> + // '@mantou/gem/ColorPicker' src: Box::new(Str::from(pkg)), span: DUMMY_SP, type_only: false, @@ -261,7 +261,7 @@ fn merge_content( return merge_content(get_config_content(AutoImport::Gem(true)), root); } else { let resolver = Resolver::new() - .with_extensions(&["json"]) + .with_extensions(["json"]) .with_basedir(env::current_dir().expect("get current dir error")); if let Ok(full_path) = resolver.resolve(&extends) { if let Ok(json_str) = fs::read_to_string(full_path) { diff --git a/crates/swc-plugin-gem/src/visitors/mod.rs b/crates/swc-plugin-gem/src/visitors/mod.rs index 28fea677..0107ec75 100644 --- a/crates/swc-plugin-gem/src/visitors/mod.rs +++ b/crates/swc-plugin-gem/src/visitors/mod.rs @@ -1,3 +1,4 @@ +pub mod hmr; pub mod import; pub mod memo; pub mod minify; diff --git a/crates/swc-plugin-gem/src/visitors/path.rs b/crates/swc-plugin-gem/src/visitors/path.rs index b2b42d5b..fe9fcca5 100644 --- a/crates/swc-plugin-gem/src/visitors/path.rs +++ b/crates/swc-plugin-gem/src/visitors/path.rs @@ -1,4 +1,4 @@ -use std::{env, path::PathBuf}; +use std::{env, path::Path}; use node_resolve::Resolver; use pathdiff::diff_paths; @@ -6,8 +6,8 @@ use swc_core::ecma::visit::{noop_visit_mut_type, VisitMut}; use swc_ecma_ast::{CallExpr, Callee, ExprOrSpread, ImportDecl, Lit, Str}; use typed_path::{Utf8Path, Utf8UnixEncoding, Utf8WindowsEncoding}; -fn converting_to_unix_path(path_buf: &PathBuf) -> String { - let windows_path = Utf8Path::::new(path_buf.to_str().unwrap()); +fn converting_to_unix_path(path: &Path) -> String { + let windows_path = Utf8Path::::new(path.to_str().unwrap()); windows_path.with_encoding::().to_string() } @@ -20,14 +20,15 @@ impl TransformVisitor { fn resolve_path(&self, origin: &str) -> Str { if let Some(filename) = &self.filename { let cwd = env::current_dir().expect("get current dir error"); - let dir = cwd.join(filename).parent().unwrap().to_path_buf(); + let full_filename = cwd.join(filename); + let dir = full_filename.parent().unwrap(); let resolver = Resolver::new() - .with_extensions(&["ts", "js", ".mjs"]) - .with_basedir(dir.clone()); - if let Ok(full_path) = resolver.resolve(origin) { + .with_extensions(["ts", "js", ".mjs"]) + .with_basedir(dir.to_path_buf()); + if let Ok(ref full_path) = resolver.resolve(origin) { if let Some(relative_path) = diff_paths( - &converting_to_unix_path(&full_path), - &converting_to_unix_path(&dir), + converting_to_unix_path(full_path), + converting_to_unix_path(dir), ) { if let Some(relative_path) = relative_path.to_str() { let relative_path = relative_path.replace(".ts", ".js"); @@ -54,7 +55,7 @@ impl VisitMut for TransformVisitor { // 只处理 string 的动态导入 fn visit_mut_call_expr(&mut self, node: &mut CallExpr) { if let Callee::Import(_) = node.callee { - if let Some(Some(Lit::Str(source))) = node.args.get(0).map(|e| e.expr.as_lit()) { + if let Some(Some(Lit::Str(source))) = node.args.first().map(|e| e.expr.as_lit()) { node.args = vec![ExprOrSpread { spread: None, expr: self.resolve_path(source.value.as_str()).into(), @@ -65,8 +66,5 @@ impl VisitMut for TransformVisitor { } pub fn path_transform(filename: Option) -> impl VisitMut { - TransformVisitor { - filename, - ..Default::default() - } + TransformVisitor { filename } } diff --git a/crates/swc-plugin-gem/src/visitors/preload.rs b/crates/swc-plugin-gem/src/visitors/preload.rs index c3795e7e..da39b43b 100644 --- a/crates/swc-plugin-gem/src/visitors/preload.rs +++ b/crates/swc-plugin-gem/src/visitors/preload.rs @@ -7,7 +7,7 @@ use swc_core::{ use swc_ecma_ast::{Ident, ImportDecl, ModuleItem, Str}; static IMG_REG: Lazy = - Lazy::new(|| Regex::new(r"(?i)\.(gif|jpe?g|tiff?|png|webp|bmp)$").unwrap()); + Lazy::new(|| Regex::new(r"(?i)\.(svg|gif|jpe?g|tiff?|a?png|webp|avif|bmp)$").unwrap()); enum AwaitItem { Img(Ident), diff --git a/crates/swc-plugin-gem/types.d.ts b/crates/swc-plugin-gem/types.d.ts new file mode 100644 index 00000000..8bfb7bf2 --- /dev/null +++ b/crates/swc-plugin-gem/types.d.ts @@ -0,0 +1,48 @@ +declare module '*.bmp?preload' { + const src: string; + export default src; +} +declare module '*.gif?preload' { + const src: string; + export default src; +} +declare module '*.jpg?preload' { + const src: string; + export default src; +} +declare module '*.jpeg?preload' { + const src: string; + export default src; +} +declare module '*.png?preload' { + const src: string; + export default src; +} +declare module '*.webp?preload' { + const src: string; + export default src; +} +declare module '*.svg?preload' { + const src: string; + export default src; +} +declare module '*.apng?preload' { + const src: string; + export default src; +} +declare module '*.avif?preload' { + const src: string; + export default src; +} +declare module '*.tif?preload' { + const src: string; + export default src; +} +declare module '*.tiff?preload' { + const src: string; + export default src; +} +declare module '*?preload' { + const data: ArrayBuffer; + export default data; +} diff --git a/crates/zed-plugin-gem/Cargo.toml b/crates/zed-plugin-gem/Cargo.toml index 6ac713dc..d83032d6 100644 --- a/crates/zed-plugin-gem/Cargo.toml +++ b/crates/zed-plugin-gem/Cargo.toml @@ -16,3 +16,4 @@ fs-more = "0.8.0" reqwest = { version = "0.12.9", features = ["blocking"] } flate2 = "1.0.35" tar = "0.4.43" +tracing = { workspace = true } diff --git a/crates/zed-plugin-gem/build.rs b/crates/zed-plugin-gem/build.rs index 89d7c601..15d789dc 100644 --- a/crates/zed-plugin-gem/build.rs +++ b/crates/zed-plugin-gem/build.rs @@ -1,11 +1,16 @@ +use std::{ + env, + fs::{self, File, OpenOptions}, + io::{self, Cursor, Write}, + time::Duration, +}; + use flate2::read::GzDecoder; use fs_more::directory::copy_directory; use reqwest::blocking::Client; -use std::fs::{self, File, OpenOptions}; -use std::io::{self, Cursor, Write}; -use std::time::Duration; use tar::Archive; use tempfile::tempdir; +use tracing::error; fn sync_typescript() -> anyhow::Result<()> { let dir = tempdir()?; @@ -38,9 +43,9 @@ fn sync_typescript() -> anyhow::Result<()> { Ok(()) } -fn main() -> anyhow::Result<()> { +fn set_languages() -> anyhow::Result<()> { if !fs::read_to_string("languages/typescript/injections.scm") - .unwrap_or(String::new()) + .unwrap_or_default() .contains("Gem") { sync_typescript()?; @@ -57,3 +62,14 @@ fn main() -> anyhow::Result<()> { Ok(()) } + +fn main() { + let profile = env::var("PROFILE").unwrap_or_else(|_| "debug".to_string()); + if set_languages().is_err() { + if profile == "release" { + panic!("set languages error"); + } else { + error!("set languages error"); + } + } +} diff --git a/crates/zed-plugin-gem/src/lib.rs b/crates/zed-plugin-gem/src/lib.rs index d95eda52..1bd1a849 100644 --- a/crates/zed-plugin-gem/src/lib.rs +++ b/crates/zed-plugin-gem/src/lib.rs @@ -1,4 +1,5 @@ use std::{env, fs}; + use zed::settings::LspSettings; use zed_extension_api::{self as zed, LanguageServerId, Result}; @@ -12,7 +13,7 @@ struct GemExtension { impl GemExtension { fn server_exists(&self) -> bool { - fs::metadata(LS_BIN_PATH).map_or(false, |stat| stat.is_file()) + fs::metadata(LS_BIN_PATH).is_ok_and(|stat| stat.is_file()) } fn server_script_path(&mut self, language_server_id: &zed::LanguageServerId) -> Result { @@ -39,8 +40,9 @@ impl GemExtension { Ok(()) => { if !self.server_exists() { Err(format!( - "installed package '{NPM_PKG_NAME}' did not contain expected path '{LS_BIN_PATH}'", - ))?; + "installed package '{NPM_PKG_NAME}' did not contain expected path \ + '{LS_BIN_PATH}'", + ))?; } } Err(error) => { diff --git a/packages/gem/docs/en/001-guide/002-advance/009-building.md b/packages/gem/docs/en/001-guide/002-advance/009-building.md index 11fa99f5..f27c787c 100644 --- a/packages/gem/docs/en/001-guide/002-advance/009-building.md +++ b/packages/gem/docs/en/001-guide/002-advance/009-building.md @@ -16,4 +16,4 @@ pnpm install swc-plugin-gem Config: - + diff --git a/packages/gem/docs/zh/001-guide/002-advance/009-building.md b/packages/gem/docs/zh/001-guide/002-advance/009-building.md index fdfd217b..44f747e2 100644 --- a/packages/gem/docs/zh/001-guide/002-advance/009-building.md +++ b/packages/gem/docs/zh/001-guide/002-advance/009-building.md @@ -16,4 +16,4 @@ pnpm install swc-plugin-gem 配置: - + diff --git a/packages/gem/src/helper/hmr.ts b/packages/gem/src/helper/hmr.ts new file mode 100644 index 00000000..a7236e43 --- /dev/null +++ b/packages/gem/src/helper/hmr.ts @@ -0,0 +1,13 @@ +/* eslint-disable no-console */ + +const nativeDefineElement = window.customElements.define.bind(window.customElements); + +window.customElements.define = (...rest: Parameters) => { + const [name, con] = rest; + if (!customElements.get(name)) { + nativeDefineElement(...rest); + } else { + // update + console.log(name, con); + } +};