diff --git a/CHANGELOG.md b/CHANGELOG.md index 05d8058e3..2f06450e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,23 @@ +## 0.8.7 + +`2024-08-30` + +* refactor: 🎨 assign tpl's span to literal string by [@stormslowly](https://github.com/umijs/mako/pull/1529) +* perf: reapply pr 1509 and sourcemap missing when chain_map is empty by [@xusd320](https://github.com/umijs/mako/pull/1542) +* chore: ✨ strip span when parsing define's expression by [@stormslowly](https://github.com/umijs/mako/pull/1540) +* feat: support to control crossorigin for async chunk scripts and links by [@PeachScript](https://github.com/umijs/mako/)pull/1539 +* refactory: in str-impl chunk generate, remove cm when merge_code_and_sourcemap by [@stormslowly](https://github.com/umijs/mako/pull/1541) +* fix: entry support sub paths by [@sorrycc](https://github.com/umijs/mako/pull/1547) +* fix: filename too long when use pnpm by [@Jinbao1001](https://github.com/umijs/mako/pull/1421) +* refactor: Unify the static server in bundler-mako and devServer by [@whyer11](https://github.com/umijs/mako/pull/1468) +* feat: #1491 add duplicate package checker plugin by [@jeasonnow](https://github.com/umijs/mako/pull/1496) +* fix: #1478 support react class-component hot-update by [@jeasonnow](https://github.com/umijs/mako/pull/1489) +* fix(plugin:emotion): panic when target to chrome 40 by [@stormslowly](https://github.com/umijs/mako/pull/1527) + + +**Full Changelog**: https://github.com/umijs/mako/compare/v0.8.4...v0.8.7 + + ## 0.8.4 `2024-08-23` diff --git a/CHANGELOG_zh-CN.md b/CHANGELOG_zh-CN.md index 6899053a1..1025fbca9 100644 --- a/CHANGELOG_zh-CN.md +++ b/CHANGELOG_zh-CN.md @@ -1,3 +1,21 @@ +## 0.8.7 + +`2024-08-30` + +* 特性: 支持控制异步块脚本和链接的 crossorigin 属性 by [@PeachScript](https://github.com/umijs/mako/)pull/1539 +* 特性: 添加重复包检查插件 by [@jeasonnow](https://github.com/umijs/mako/pull/1496) +* 重构: 在 str-impl 块生成中,当 merge_code_and_sourcemap 时删除 cm by [@stormslowly](https://github.com/umijs/mako/pull/1541) +* 重构: 统一 bundler-mako 和 devServer 中的静态服务器 by [@whyer11](https://github.com/umijs/mako/pull/1468) +* 修复: 修复入口支持子路径的问题 by [@sorrycc](https://github.com/umijs/mako/pull/1547) +* 修复: 修复使用 pnpm 时文件名过长的问题 by [@Jinbao1001](https://github.com/umijs/mako/pull/1421) +* 修复: 支持 React 类组件热更新 by [@jeasonnow](https://github.com/umijs/mako/pull/1489) +* 修复(plugin:emotion): 修复将目标设置为 Chrome 40 时 emotion 插件崩溃的问题 by [@stormslowly](https://github.com/umijs/mako/pull/1527) +* 改进: 🎨 将 tpl 的 span 分配给文字字符串 by [@stormslowly](https://github.com/umijs/mako/pull/1529) +* 优化: 重新应用 PR 1509,修复 chain_map 为空时 sourcemap 丢失的问题 by [@xusd320](https://github.com/umijs/mako/pull/1542) +* 杂项: 解析 define 表达式时去除 span by [@stormslowly](https://github.com/umijs/mako/pull/1540) + + + ## 0.8.4 `2024-08-23` diff --git a/Cargo.lock b/Cargo.lock index 0051befa0..ec94c4c2a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -790,7 +790,7 @@ checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" dependencies = [ "camino", "cargo-platform", - "semver 1.0.17", + "semver 1.0.23", "serde", "serde_json", "thiserror", @@ -2672,6 +2672,7 @@ dependencies = [ "rayon", "regex", "sailfish", + "semver 1.0.23", "serde", "serde-xml-rs", "serde_json", @@ -2994,7 +2995,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "semver 1.0.17", + "semver 1.0.23", "syn 1.0.109", ] @@ -3707,7 +3708,7 @@ dependencies = [ "dashmap 5.5.3", "from_variant", "once_cell", - "semver 1.0.17", + "semver 1.0.23", "serde", "st-map", "tracing", @@ -4194,9 +4195,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.17" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" dependencies = [ "serde", ] @@ -5435,7 +5436,7 @@ dependencies = [ "once_cell", "preset_env_base", "rustc-hash", - "semver 1.0.17", + "semver 1.0.23", "serde", "serde_json", "st-map", @@ -6832,9 +6833,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", diff --git a/crates/mako/Cargo.toml b/crates/mako/Cargo.toml index 17cd0b0ee..20f71cf20 100644 --- a/crates/mako/Cargo.toml +++ b/crates/mako/Cargo.toml @@ -102,6 +102,7 @@ puffin_egui = { version = "0.22.0", optional = true } rayon = "1.7.0" regex = "1.9.3" sailfish = "0.8.3" +semver = "1.0.23" serde-xml-rs = "0.6.0" serde_yaml = "0.9.22" svgr-rs = "0.1.3" diff --git a/crates/mako/src/ast/js_ast.rs b/crates/mako/src/ast/js_ast.rs index 4254805a7..303fd78aa 100644 --- a/crates/mako/src/ast/js_ast.rs +++ b/crates/mako/src/ast/js_ast.rs @@ -2,8 +2,6 @@ use std::fmt; use std::sync::Arc; use anyhow::{anyhow, Result}; -use swc_core::base::try_with_handler; -use swc_core::common::errors::HANDLER; use swc_core::common::util::take::Take; use swc_core::common::{FileName, Mark, Spanned, GLOBALS}; use swc_core::ecma::ast::{EsVersion, Module}; @@ -12,7 +10,7 @@ use swc_core::ecma::codegen::{Config as JsCodegenConfig, Emitter}; use swc_core::ecma::parser::error::SyntaxError; use swc_core::ecma::parser::lexer::Lexer; use swc_core::ecma::parser::{EsConfig, Parser, StringInput, Syntax, TsConfig}; -use swc_core::ecma::transforms::base::helpers::{inject_helpers, Helpers, HELPERS}; +use swc_core::ecma::transforms::base::helpers::inject_helpers; use swc_core::ecma::utils::contains_top_level_await; use swc_core::ecma::visit; use swc_core::ecma::visit::{VisitMutWith, VisitWith}; @@ -23,7 +21,6 @@ use crate::ast::{error, utils}; use crate::compiler::Context; use crate::config::{DevtoolConfig, Mode, OutputMode}; use crate::module::Dependency; -use crate::plugin::PluginTransformJsParam; use crate::utils::base64_encode; use crate::visitors::dep_analyzer::DepAnalyzer; @@ -134,74 +131,46 @@ impl JsAst { &mut self, mut_visitors: &mut Vec>, folders: &mut Vec>, - file: &File, should_inject_helpers: bool, - context: Arc, + _context: Arc, ) -> Result<()> { - let cm = context.meta.script.cm.clone(); - GLOBALS.set(&context.meta.script.globals, || { - try_with_handler(cm, Default::default(), |handler| { - HELPERS.set(&Helpers::new(true), || { - HANDLER.set(handler, || { - let ast = &mut self.ast; - - // visitors - for visitor in mut_visitors { - ast.visit_mut_with(visitor.as_mut()); - } + let ast = &mut self.ast; - // folders - let body = ast.body.take(); - let mut module = Module { - span: ast.span, - shebang: ast.shebang.clone(), - body, - }; - for folder in folders { - module = folder.as_mut().fold_module(module); - } - ast.body = module.body; + // visitors + for visitor in mut_visitors { + ast.visit_mut_with(visitor.as_mut()); + } - // transform with plugin - context.plugin_driver.transform_js( - &PluginTransformJsParam { - handler, - path: file.path.to_str().unwrap(), - top_level_mark: self.top_level_mark, - unresolved_mark: self.unresolved_mark, - }, - ast, - &context, - )?; + // folders + let mut module = ast.take(); + for folder in folders { + module = folder.as_mut().fold_module(module); + } + *ast = module; - // FIXME: remove this, it's special logic - // inject helpers - // why need to handle cjs specially? - // because the ast is currently a module, not a program - // if not handled specially, the injected helpers will all be in esm format - // which is not as expected in the cjs scenario - // ref: https://github.com/umijs/mako/pull/831 - if should_inject_helpers { - if utils::is_esm(ast) { - ast.visit_mut_with(&mut inject_helpers(self.unresolved_mark)); - } else { - let body = ast.body.take(); - let mut script_ast = swc_core::ecma::ast::Script { - span: ast.span, - shebang: ast.shebang.clone(), - body: body.into_iter().map(|i| i.stmt().unwrap()).collect(), - }; - script_ast - .visit_mut_with(&mut inject_helpers(self.unresolved_mark)); - ast.body = script_ast.body.into_iter().map(|i| i.into()).collect(); - } - } + // FIXME: remove this, it's special logic + // inject helpers + // why need to handle cjs specially? + // because the ast is currently a module, not a program + // if not handled specially, the injected helpers will all be in esm format + // which is not as expected in the cjs scenario + // ref: https://github.com/umijs/mako/pull/831 + if should_inject_helpers { + if utils::is_esm(ast) { + ast.visit_mut_with(&mut inject_helpers(self.unresolved_mark)); + } else { + let body = ast.body.take(); + let mut script_ast = swc_core::ecma::ast::Script { + span: ast.span, + shebang: ast.shebang.clone(), + body: body.into_iter().map(|i| i.stmt().unwrap()).collect(), + }; + script_ast.visit_mut_with(&mut inject_helpers(self.unresolved_mark)); + ast.body = script_ast.body.into_iter().map(|i| i.into()).collect(); + } + } - Ok(()) - }) - }) - }) - }) + Ok(()) } pub fn analyze_deps(&self, context: Arc) -> Vec { diff --git a/crates/mako/src/build/transform.rs b/crates/mako/src/build/transform.rs index b823fe360..3e9d741b9 100644 --- a/crates/mako/src/build/transform.rs +++ b/crates/mako/src/build/transform.rs @@ -1,6 +1,7 @@ use std::sync::Arc; use anyhow::Result; +use swc_core::common::errors::HANDLER; use swc_core::common::GLOBALS; use swc_core::css::ast::{AtRule, AtRulePrelude, ImportHref, Rule, Str, Stylesheet, UrlValue}; use swc_core::css::compat::compiler::{self, Compiler}; @@ -8,12 +9,14 @@ use swc_core::css::{compat as swc_css_compat, prefixer, visit as swc_css_visit}; use swc_core::ecma::preset_env::{self as swc_preset_env}; use swc_core::ecma::transforms::base::feature::FeatureFlag; use swc_core::ecma::transforms::base::fixer::paren_remover; +use swc_core::ecma::transforms::base::helpers::{Helpers, HELPERS}; use swc_core::ecma::transforms::base::{resolver, Assumptions}; use swc_core::ecma::transforms::compat::reserved_words; use swc_core::ecma::transforms::optimization::simplifier; use swc_core::ecma::transforms::optimization::simplify::{dce, Config as SimpilifyConfig}; use swc_core::ecma::transforms::proposal::decorators; use swc_core::ecma::visit::{Fold, VisitMut}; +use swc_error_reporters::handler::try_with_handler; use crate::ast::css_ast::CssAst; use crate::ast::file::File; @@ -23,6 +26,7 @@ use crate::compiler::Context; use crate::config::Mode; use crate::features; use crate::module::ModuleAst; +use crate::plugin::PluginTransformJsParam; use crate::plugins::context_module::ContextModuleVisitor; use crate::visitors::css_assets::CSSAssets; use crate::visitors::css_flexbugs::CSSFlexbugs; @@ -51,163 +55,205 @@ impl Transform { crate::mako_profile_function!(); match ast { ModuleAst::Script(ast) => { + let cm = context.meta.script.cm.clone(); GLOBALS.set(&context.meta.script.globals, || { - let unresolved_mark = ast.unresolved_mark; - let top_level_mark = ast.top_level_mark; - let cm: Arc = context.meta.script.cm.clone(); - let origin_comments = context.meta.script.origin_comments.read().unwrap(); - let is_ts = file.extname == "ts"; - let is_tsx = file.extname == "tsx"; - let is_jsx = file.is_content_jsx() - || file.extname == "jsx" - || file.extname == "js" - || file.extname == "ts" - || file.extname == "tsx"; + try_with_handler(cm, Default::default(), |handler| { + HELPERS.set(&Helpers::new(true), || { + HANDLER.set(handler, || { + let unresolved_mark = ast.unresolved_mark; + let top_level_mark = ast.top_level_mark; + let cm: Arc = + context.meta.script.cm.clone(); + let origin_comments = + context.meta.script.origin_comments.read().unwrap(); + let is_ts = file.extname == "ts"; + let is_tsx = file.extname == "tsx"; + let is_jsx = file.is_content_jsx() + || file.extname == "jsx" + || file.extname == "js" + || file.extname == "ts" + || file.extname == "tsx"; - // visitors - let mut visitors: Vec> = vec![ - Box::new(resolver(unresolved_mark, top_level_mark, is_ts || is_tsx)), - // fix helper inject position - // should be removed after upgrade to latest swc - // ref: https://github.com/umijs/mako/issues/1193 - Box::new(FixHelperInjectPosition::new()), - Box::new(FixSymbolConflict::new(top_level_mark)), - Box::new(NewUrlAssets { - context: context.clone(), - path: file.path.clone(), - unresolved_mark, - }), - Box::new(WorkerModule::new(unresolved_mark)), - ]; - if is_tsx { - visitors.push(Box::new(tsx_strip( - cm.clone(), - context.clone(), - top_level_mark, - ))) - } - // strip should be ts only - // since when use this in js, it will remove all unused imports - // which is not expected as what webpack does - if is_ts { - visitors.push(Box::new(ts_strip(top_level_mark))) - } - // named default export - if context.args.watch && !file.is_under_node_modules && is_jsx { - visitors.push(Box::new(DefaultExportNamer::new())); - } - // react & react-refresh - let is_dev = matches!(context.config.mode, Mode::Development); - let is_browser = - matches!(context.config.platform, crate::config::Platform::Browser); - let use_refresh = is_dev - && context.args.watch - && context.config.hmr.is_some() - && !file.is_under_node_modules - && is_browser; - if is_jsx { - visitors.push(react( - cm, - context.clone(), - use_refresh, - &top_level_mark, - &unresolved_mark, - )); - } - { - let mut define = context.config.define.clone(); - let mode = context.config.mode.to_string(); - define - .entry("process.env.NODE_ENV".to_string()) - .or_insert_with(|| format!("\"{}\"", mode).into()); - let env_map = build_env_map(define, &context)?; - visitors.push(Box::new(EnvReplacer::new(env_map, unresolved_mark))); - visitors.push(Box::new(ImportMetaEnvReplacer::new(mode))); - } - visitors.push(Box::new(TryResolve { - path: file.path.to_string_lossy().to_string(), - context: context.clone(), - unresolved_mark, - })); - visitors.push(Box::new(PublicPathAssignment { unresolved_mark })); - // TODO: refact provide - visitors.push(Box::new(Provide::new( - context.config.providers.clone(), - unresolved_mark, - top_level_mark, - ))); - visitors.push(Box::new(VirtualCSSModules { - auto_css_modules: context.config.auto_css_modules, - unresolved_mark, - })); - // TODO: move ContextModuleVisitor out of plugin - visitors.push(Box::new(ContextModuleVisitor { unresolved_mark })); - visitors.push(Box::new(ImportTemplateToStringLiteral {})); - // DynamicImportToRequire must be after ContextModuleVisitor - // since ContextModuleVisitor will add extra dynamic imports - if context.config.dynamic_import_to_require { - visitors.push(Box::new(DynamicImportToRequire::new(unresolved_mark))); - } - if matches!(context.config.platform, crate::config::Platform::Node) { - visitors.push(Box::new(features::node::MockFilenameAndDirname { - unresolved_mark, - current_path: file.path.clone(), - context: context.clone(), - })); - } + // visitors + let mut visitors: Vec> = vec![ + Box::new(resolver( + unresolved_mark, + top_level_mark, + is_ts || is_tsx, + )), + // fix helper inject position + // should be removed after upgrade to latest swc + // ref: https://github.com/umijs/mako/issues/1193 + Box::new(FixHelperInjectPosition::new()), + Box::new(FixSymbolConflict::new(top_level_mark)), + Box::new(NewUrlAssets { + context: context.clone(), + path: file.path.clone(), + unresolved_mark, + }), + Box::new(WorkerModule::new(unresolved_mark)), + ]; + if is_tsx { + visitors.push(Box::new(tsx_strip( + cm.clone(), + context.clone(), + top_level_mark, + ))) + } + // strip should be ts only + // since when use this in js, it will remove all unused imports + // which is not expected as what webpack does + if is_ts { + visitors.push(Box::new(ts_strip(top_level_mark))) + } + // named default export + if context.args.watch && !file.is_under_node_modules && is_jsx { + visitors.push(Box::new(DefaultExportNamer::new())); + } + // react & react-refresh + let is_dev = matches!(context.config.mode, Mode::Development); + let is_browser = matches!( + context.config.platform, + crate::config::Platform::Browser + ); + let use_refresh = is_dev + && context.args.watch + && context.config.hmr.is_some() + && !file.is_under_node_modules + && is_browser; + if is_jsx { + visitors.push(react( + cm.clone(), + context.clone(), + use_refresh, + &top_level_mark, + &unresolved_mark, + )); + } + { + let mut define = context.config.define.clone(); + let mode = context.config.mode.to_string(); + define + .entry("process.env.NODE_ENV".to_string()) + .or_insert_with(|| format!("\"{}\"", mode).into()); + let env_map = build_env_map(define, &context)?; + visitors + .push(Box::new(EnvReplacer::new(env_map, unresolved_mark))); + visitors.push(Box::new(ImportMetaEnvReplacer::new(mode))); + } + visitors.push(Box::new(TryResolve { + path: file.path.to_string_lossy().to_string(), + context: context.clone(), + unresolved_mark, + })); + visitors.push(Box::new(PublicPathAssignment { unresolved_mark })); + // TODO: refact provide + visitors.push(Box::new(Provide::new( + context.config.providers.clone(), + unresolved_mark, + top_level_mark, + ))); + visitors.push(Box::new(VirtualCSSModules { + auto_css_modules: context.config.auto_css_modules, + unresolved_mark, + })); + // TODO: move ContextModuleVisitor out of plugin + visitors.push(Box::new(ContextModuleVisitor { unresolved_mark })); + visitors.push(Box::new(ImportTemplateToStringLiteral {})); + // DynamicImportToRequire must be after ContextModuleVisitor + // since ContextModuleVisitor will add extra dynamic imports + if context.config.dynamic_import_to_require { + visitors.push(Box::new(DynamicImportToRequire::new( + unresolved_mark, + ))); + } + if matches!(context.config.platform, crate::config::Platform::Node) + { + visitors.push(Box::new( + features::node::MockFilenameAndDirname { + unresolved_mark, + current_path: file.path.clone(), + context: context.clone(), + }, + )); + } - // folders - let mut folders: Vec> = vec![]; - // decorators should go before preset_env, when compile down to es5, - // classes become functions, then the decorators on the functions - // will be removed silently. - folders.push(Box::new(decorators(decorators::Config { - legacy: true, - emit_metadata: context.config.emit_decorator_metadata, - ..Default::default() - }))); - let comments = origin_comments.get_swc_comments().clone(); - let assumptions = context.assumptions_for(file); + // folders + let mut folders: Vec> = vec![]; + // decorators should go before preset_env, when compile down to es5, + // classes become functions, then the decorators on the functions + // will be removed silently. + folders.push(Box::new(decorators(decorators::Config { + legacy: true, + emit_metadata: context.config.emit_decorator_metadata, + ..Default::default() + }))); + let comments = origin_comments.get_swc_comments().clone(); + let assumptions = context.assumptions_for(file); - folders.push(Box::new(swc_preset_env::preset_env( - unresolved_mark, - Some(comments), - swc_preset_env::Config { - mode: Some(swc_preset_env::Mode::Entry), - targets: Some(swc_preset_env_targets_from_map( - context.config.targets.clone(), - )), - ..Default::default() - }, - assumptions, - &mut FeatureFlag::default(), - ))); - folders.push(Box::new(reserved_words::reserved_words())); - folders.push(Box::new(paren_remover(Default::default()))); - // simplify, but keep top level dead code - // e.g. import x from 'foo'; but x is not used - // this must be kept for tree shaking to work - folders.push(Box::new(simplifier( - unresolved_mark, - SimpilifyConfig { - dce: dce::Config { - top_level: false, - ..Default::default() - }, - ..Default::default() - }, - ))); - // NOTICE: remove optimize_package_imports temporarily - // folders.push(Box::new(Optional { - // enabled: should_optimize(file.path.to_str().unwrap(), context.clone()), - // visitor: optimize_package_imports( - // file.path.to_string_lossy().to_string(), - // context.clone(), - // ), - // })); + // NOTICE: remove optimize_package_imports temporarily + // folders.push(Box::new(Optional { + // enabled: should_optimize(file.path.to_str().unwrap(), context.clone()), + // visitor: optimize_package_imports( + // file.path.to_string_lossy().to_string(), + // context.clone(), + // ), + // })); + + ast.transform(&mut visitors, &mut folders, false, context.clone())?; - ast.transform(&mut visitors, &mut folders, file, true, context.clone())?; + // transform with plugin + context.plugin_driver.transform_js( + &PluginTransformJsParam { + handler, + path: file.path.to_str().unwrap(), + top_level_mark, + unresolved_mark, + }, + &mut ast.ast, + &context, + )?; + // preset_env should go last + let mut preset_folders: Vec> = vec![ + Box::new(swc_preset_env::preset_env( + unresolved_mark, + Some(comments), + swc_preset_env::Config { + mode: Some(swc_preset_env::Mode::Entry), + targets: Some(swc_preset_env_targets_from_map( + context.config.targets.clone(), + )), + ..Default::default() + }, + assumptions, + &mut FeatureFlag::default(), + )), + Box::new(reserved_words::reserved_words()), + Box::new(paren_remover(Default::default())), + // simplify, but keep top level dead code + // e.g. import x from 'foo'; but x is not used + // this must be kept for tree shaking to work + Box::new(simplifier( + unresolved_mark, + SimpilifyConfig { + dce: dce::Config { + top_level: false, + ..Default::default() + }, + ..Default::default() + }, + )), + ]; + ast.transform( + &mut vec![], + &mut preset_folders, + true, + context.clone(), + ) + }) + }) + })?; Ok(()) }) } diff --git a/crates/mako/src/compiler.rs b/crates/mako/src/compiler.rs index f26c535c7..8d909c747 100644 --- a/crates/mako/src/compiler.rs +++ b/crates/mako/src/compiler.rs @@ -255,6 +255,15 @@ impl Compiler { ))); } + if let Some(duplicate_package_checker) = &config.check_duplicate_package { + plugins.push(Arc::new( + plugins::duplicate_package_checker::DuplicatePackageCheckerPlugin::new() + .show_help(duplicate_package_checker.show_help) + .emit_error(duplicate_package_checker.emit_error) + .verbose(duplicate_package_checker.verbose), + )); + } + if config.experimental.require_context { plugins.push(Arc::new(plugins::require_context::RequireContextPlugin {})) } diff --git a/crates/mako/src/config/config.rs b/crates/mako/src/config/config.rs index dbbba3fcc..443f3f37c 100644 --- a/crates/mako/src/config/config.rs +++ b/crates/mako/src/config/config.rs @@ -93,6 +93,10 @@ create_deserialize_fn!(deserialize_manifest, ManifestConfig); create_deserialize_fn!(deserialize_code_splitting, CodeSplitting); create_deserialize_fn!(deserialize_px2rem, Px2RemConfig); create_deserialize_fn!(deserialize_progress, ProgressConfig); +create_deserialize_fn!( + deserialize_check_duplicate_package, + DuplicatePackageCheckerConfig +); create_deserialize_fn!(deserialize_umd, String); create_deserialize_fn!(deserialize_devtool, DevtoolConfig); create_deserialize_fn!(deserialize_tree_shaking, TreeShakingStrategy); @@ -281,6 +285,16 @@ pub struct ProgressConfig { pub progress_chars: String, } +#[derive(Deserialize, Serialize, Clone, Debug)] +pub struct DuplicatePackageCheckerConfig { + #[serde(rename = "verbose", default)] + pub verbose: bool, + #[serde(rename = "emitError", default)] + pub emit_error: bool, + #[serde(rename = "showHelp", default)] + pub show_help: bool, +} + impl Default for Px2RemConfig { fn default() -> Self { Px2RemConfig { @@ -580,6 +594,12 @@ pub struct Config { pub watch: WatchConfig, pub use_define_for_class_fields: bool, pub emit_decorator_metadata: bool, + #[serde( + rename = "duplicatePackageChecker", + deserialize_with = "deserialize_check_duplicate_package", + default + )] + pub check_duplicate_package: Option, } #[derive(Deserialize, Serialize, Clone, Debug, Default)] @@ -745,6 +765,11 @@ const DEFAULT_CONFIG: &str = r#" "progress": { "progressChars": "▨▨" }, + "duplicatePackageChecker": { + "verbose": false, + "showHelp": false, + "emitError": false, + }, "emitAssets": true, "cssModulesExportOnlyLocales": false, "inlineCSS": false, diff --git a/crates/mako/src/dev.rs b/crates/mako/src/dev.rs index 813da4a6c..4d0e6c33a 100644 --- a/crates/mako/src/dev.rs +++ b/crates/mako/src/dev.rs @@ -121,6 +121,8 @@ impl DevServer { staticfile: hyper_staticfile::Static, txws: broadcast::Sender, ) -> Result> { + debug!("> {} {}", req.method().to_string(), req.uri().path()); + let mut path = req.uri().path().to_string(); let public_path = &context.config.public_path; if !public_path.is_empty() && public_path.starts_with('/') && public_path != "/" { @@ -171,14 +173,16 @@ impl DevServer { // staticfile has 302 problems when modify tooooo fast in 1 second // it will response 302 and we will get the old file // TODO: fix the 302 problem? - if let Some(res) = context.get_static_content(path_without_slash_start) { - debug!("serve with context.get_static_content: {}", path); + if !context.config.write_to_disk { + if let Some(res) = context.get_static_content(path_without_slash_start) { + debug!("serve with context.get_static_content: {}", path); - return Ok(hyper::Response::builder() - .status(hyper::StatusCode::OK) - .header(CONTENT_TYPE, content_type) - .body(hyper::Body::from(res)) - .unwrap()); + return Ok(hyper::Response::builder() + .status(hyper::StatusCode::OK) + .header(CONTENT_TYPE, content_type) + .body(hyper::Body::from(res)) + .unwrap()); + } } // for cached dep let abs_path = context @@ -196,7 +200,11 @@ impl DevServer { } // for hmr files - debug!("serve with staticfile server: {}", path); + debug!("< static file serve: {}", path); + let req = hyper::Request::builder() + .uri(path) + .body(hyper::Body::empty()) + .unwrap(); let res = staticfile.serve(req).await; res.map_err(anyhow::Error::from) } diff --git a/crates/mako/src/plugins.rs b/crates/mako/src/plugins.rs index c1ddc18ee..add2cc46e 100644 --- a/crates/mako/src/plugins.rs +++ b/crates/mako/src/plugins.rs @@ -3,6 +3,7 @@ pub mod bundless_compiler; pub mod context_module; pub mod copy; pub mod detect_circular_dependence; +pub mod duplicate_package_checker; pub mod emotion; pub mod graphviz; pub mod hmr_runtime; diff --git a/crates/mako/src/plugins/duplicate_package_checker.rs b/crates/mako/src/plugins/duplicate_package_checker.rs new file mode 100644 index 000000000..2b3ee1b80 --- /dev/null +++ b/crates/mako/src/plugins/duplicate_package_checker.rs @@ -0,0 +1,199 @@ +use std::collections::HashMap; +use std::path::{Path, PathBuf}; +use std::sync::{Arc, RwLock}; + +use semver::Version; + +use crate::compiler::Context; +use crate::module_graph::ModuleGraph; +use crate::plugin::Plugin; +use crate::resolve::ResolverResource; + +#[derive(Debug, Clone)] +struct PackageInfo { + name: String, + version: Version, + path: PathBuf, +} + +#[derive(Default)] +pub struct DuplicatePackageCheckerPlugin { + verbose: bool, + show_help: bool, + emit_error: bool, +} + +/// Cleans the path by replacing /node_modules/ or \node_modules\ with /~/ +fn clean_path(module_path: &Path) -> PathBuf { + let path_str = module_path.to_string_lossy(); + let cleaned_path = path_str + .replace("/node_modules/", "/~/") + .replace("\\node_modules\\", "/~/"); + PathBuf::from(cleaned_path) +} + +/// Makes the cleaned path relative to the given context +fn clean_path_relative_to_context(module_path: &Path, context: &Path) -> PathBuf { + let cleaned_path = clean_path(module_path); + let context_str = context.to_str().unwrap(); + let cleaned_path_str = cleaned_path.to_str().unwrap(); + + if cleaned_path_str.starts_with(context_str) { + let relative_path = cleaned_path_str.trim_start_matches(context_str); + PathBuf::from(format!(".{}", relative_path)) + } else { + cleaned_path + } +} + +impl DuplicatePackageCheckerPlugin { + pub fn new() -> Self { + Self::default() + } + + pub fn verbose(mut self, verbose: bool) -> Self { + self.verbose = verbose; + self + } + + pub fn show_help(mut self, show_help: bool) -> Self { + self.show_help = show_help; + self + } + + pub fn emit_error(mut self, emit_error: bool) -> Self { + self.emit_error = emit_error; + self + } + + fn find_duplicates(packages: Vec) -> HashMap> { + let mut package_map: HashMap> = HashMap::new(); + + for package in packages { + package_map + .entry(package.name.clone()) + .or_default() + .push(package); + } + + package_map + .into_iter() + .filter(|(_, versions)| versions.len() > 1) + .collect() + } + + fn check_duplicates( + &self, + module_graph: &RwLock, + ) -> HashMap> { + let mut packages = Vec::new(); + + module_graph + .read() + .unwrap() + .modules() + .iter() + .for_each(|module| { + if let Some(ResolverResource::Resolved(resource)) = module + .info + .as_ref() + .and_then(|info| info.resolved_resource.as_ref()) + { + let package_json = resource.0.package_json().unwrap(); + let raw_json = package_json.raw_json(); + if let Some(name) = package_json.name.clone() { + if let Some(version) = raw_json.as_object().unwrap().get("version") { + let package_info = PackageInfo { + name, + version: semver::Version::parse(version.as_str().unwrap()).unwrap(), + path: package_json.path.clone(), + }; + + packages.push(package_info); + } + } + } + }); + + Self::find_duplicates(packages) + } +} + +impl Plugin for DuplicatePackageCheckerPlugin { + fn name(&self) -> &str { + "DuplicatePackageCheckerPlugin" + } + + fn after_build( + &self, + context: &Arc, + _compiler: &crate::compiler::Compiler, + ) -> anyhow::Result<()> { + let duplicates = self.check_duplicates(&context.module_graph); + + if !duplicates.is_empty() && self.verbose { + let mut message = String::new(); + + for (name, instances) in duplicates { + message.push_str(&format!("\nMultiple versions of {} found:\n", name)); + for instance in instances { + let mut line = format!(" {} {}", instance.version, instance.name); + let path = instance.path.clone(); + line.push_str(&format!( + " from {}", + clean_path_relative_to_context(&path, &context.root).display() + )); + message.push_str(&line); + message.push('\n'); + } + } + + if self.show_help { + message.push_str("\nCheck how you can resolve duplicate packages: \nhttps://github.com/darrenscerri/duplicate-package-checker-webpack-plugin#resolving-duplicate-packages-in-your-bundle\n"); + } + + if !self.emit_error { + println!("{}", message); + } else { + eprintln!("{}", message); + } + } + + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use std::path::PathBuf; + + use crate::config::{Config, DuplicatePackageCheckerConfig}; + use crate::plugin::Plugin; + use crate::plugins::duplicate_package_checker::DuplicatePackageCheckerPlugin; + use crate::utils::test_helper::setup_compiler; + + #[test] + fn test_duplicate_package_checker() { + let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("test/build/duplicate-package"); + let mut config = Config::new(&root, None, None).unwrap(); + config.check_duplicate_package = Some(DuplicatePackageCheckerConfig { + verbose: true, + emit_error: false, + show_help: true, + }); + + let compiler = setup_compiler("test/build/duplicate-package", false); + let plugin = DuplicatePackageCheckerPlugin::new() + .verbose(true) + .show_help(true) + .emit_error(false); + + // 运行编译 + compiler.compile().unwrap(); + + // 执行插件的 after_build 方法 + let result = plugin.after_build(&compiler.context, &compiler); + + assert!(result.is_ok()); + } +} diff --git a/crates/mako/src/plugins/emotion.rs b/crates/mako/src/plugins/emotion.rs index 35ec012af..1b3334a97 100644 --- a/crates/mako/src/plugins/emotion.rs +++ b/crates/mako/src/plugins/emotion.rs @@ -3,6 +3,7 @@ use std::path::Path; use anyhow::Ok; use swc_core::common::comments::NoopComments; use swc_core::common::sync::Lrc; +use swc_core::common::util::take::Take; use swc_core::common::SourceMap; use swc_core::ecma::ast::Module; use swc_core::ecma::visit::{Fold, VisitMut, VisitMutWith}; @@ -77,8 +78,7 @@ impl VisitMut for Emotion { self.cm.clone(), NoopComments, ); - module.body = folder.fold_module(module.clone()).body; - module.visit_mut_children_with(self); + *module = folder.fold_module(module.take()); } } diff --git a/crates/mako/src/visitors/fix_helper_inject_position.rs b/crates/mako/src/visitors/fix_helper_inject_position.rs index 69f268bee..c93ba2b0d 100644 --- a/crates/mako/src/visitors/fix_helper_inject_position.rs +++ b/crates/mako/src/visitors/fix_helper_inject_position.rs @@ -92,12 +92,12 @@ mod tests { use swc_core::common::GLOBALS; use swc_core::ecma::preset_env::{self as swc_preset_env}; use swc_core::ecma::transforms::base::feature::FeatureFlag; + use swc_core::ecma::transforms::base::helpers::{Helpers, HELPERS}; use swc_core::ecma::transforms::base::Assumptions; use swc_core::ecma::transforms::proposal::decorators; use swc_core::ecma::visit::{Fold, VisitMut, VisitMutWith}; use super::FixHelperInjectPosition; - use crate::ast::file::File; use crate::ast::tests::TestUtils; use crate::build::targets::swc_preset_env_targets_from_map; @@ -157,42 +157,43 @@ export { foo }; let ast = test_utils.ast.js_mut(); let unresolved_mark = ast.unresolved_mark; GLOBALS.set(&test_utils.context.meta.script.globals, || { - let mut v = FixHelperInjectPosition { exports: vec![] }; - ast.ast.visit_mut_with(&mut v); + HELPERS.set(&Helpers::new(true), || { + let mut v = FixHelperInjectPosition { exports: vec![] }; + ast.ast.visit_mut_with(&mut v); - // preset_env - let mut folders: Vec> = vec![]; - folders.push(Box::new(decorators(decorators::Config { - legacy: true, - emit_metadata: false, - ..Default::default() - }))); - let origin_comments = test_utils - .context - .meta - .script - .origin_comments - .read() - .unwrap(); - let comments = origin_comments.get_swc_comments().clone(); - let mut targets = HashMap::new(); - targets.insert("chrome".to_string(), 50.0); - folders.push(Box::new(swc_preset_env::preset_env( - unresolved_mark, - Some(comments), - swc_preset_env::Config { - mode: Some(swc_preset_env::Mode::Entry), - targets: Some(swc_preset_env_targets_from_map(targets)), + // preset_env + let mut folders: Vec> = vec![]; + folders.push(Box::new(decorators(decorators::Config { + legacy: true, + emit_metadata: false, ..Default::default() - }, - Assumptions::default(), - &mut FeatureFlag::default(), - ))); - let mut visitors: Vec> = vec![]; - let context = test_utils.context.clone(); - let file = File::new("test.ts".to_string(), context.clone()); - ast.transform(&mut visitors, &mut folders, &file, false, context) - .unwrap(); + }))); + let origin_comments = test_utils + .context + .meta + .script + .origin_comments + .read() + .unwrap(); + let comments = origin_comments.get_swc_comments().clone(); + let mut targets = HashMap::new(); + targets.insert("chrome".to_string(), 50.0); + folders.push(Box::new(swc_preset_env::preset_env( + unresolved_mark, + Some(comments), + swc_preset_env::Config { + mode: Some(swc_preset_env::Mode::Entry), + targets: Some(swc_preset_env_targets_from_map(targets)), + ..Default::default() + }, + Assumptions::default(), + &mut FeatureFlag::default(), + ))); + let mut visitors: Vec> = vec![]; + let context = test_utils.context.clone(); + ast.transform(&mut visitors, &mut folders, false, context) + .unwrap(); + }); }); test_utils.js_ast_to_code() } diff --git a/crates/mako/src/visitors/react.rs b/crates/mako/src/visitors/react.rs index d907baca9..8acc5f13a 100644 --- a/crates/mako/src/visitors/react.rs +++ b/crates/mako/src/visitors/react.rs @@ -160,8 +160,21 @@ fn react_refresh_module_postfix(context: &Arc) -> Box { code: r#" if (prevRefreshReg) self.$RefreshReg$ = prevRefreshReg; if (prevRefreshSig) self.$RefreshSig$ = prevRefreshSig; +function registerClassComponent(filename, moduleExports) { + for (const key in moduleExports) { + try { + if (key === "__esModule") continue; + const exportValue = moduleExports[key]; + if (RefreshRuntime.isLikelyComponentType(exportValue) && exportValue.prototype && exportValue.prototype.isReactComponent) { + RefreshRuntime.register(exportValue, filename + " " + key); + } + } catch (e) { + // in case the moduleExports[key] is not accessible due depedence loop + } + } +} function $RefreshIsReactComponentLike$(moduleExports) { - if (RefreshRuntime.isLikelyComponentType(moduleExports.default || moduleExports)) { + if (RefreshRuntime.isLikelyComponentType(moduleExports || moduleExports.default)) { return true; } for (var key in moduleExports) { @@ -175,6 +188,7 @@ function $RefreshIsReactComponentLike$(moduleExports) { } return false; } +registerClassComponent(module.id, module.exports); if ($RefreshIsReactComponentLike$(module.exports)) { module.meta.hot.accept(); RefreshRuntime.performReactRefresh(); diff --git a/crates/mako/test/build/duplicate-package/index.ts b/crates/mako/test/build/duplicate-package/index.ts new file mode 100644 index 000000000..62e5cf6e4 --- /dev/null +++ b/crates/mako/test/build/duplicate-package/index.ts @@ -0,0 +1,3 @@ +require('a'); +require('b'); +require('c'); diff --git a/crates/mako/test/build/duplicate-package/mako.config.json b/crates/mako/test/build/duplicate-package/mako.config.json new file mode 100644 index 000000000..57a9fd8f4 --- /dev/null +++ b/crates/mako/test/build/duplicate-package/mako.config.json @@ -0,0 +1,6 @@ +{ + "duplicatePackageChecker": { + "verbose": true, + "showHelp": true + } +} diff --git a/crates/mako/test/build/duplicate-package/node_modules/a/index.js b/crates/mako/test/build/duplicate-package/node_modules/a/index.js new file mode 100644 index 000000000..8609d0755 --- /dev/null +++ b/crates/mako/test/build/duplicate-package/node_modules/a/index.js @@ -0,0 +1 @@ +console.log('a'); diff --git a/crates/mako/test/build/duplicate-package/node_modules/a/package.json b/crates/mako/test/build/duplicate-package/node_modules/a/package.json new file mode 100644 index 000000000..9113c2528 --- /dev/null +++ b/crates/mako/test/build/duplicate-package/node_modules/a/package.json @@ -0,0 +1,4 @@ +{ + "name": "a", + "version": "1.0.0" +} diff --git a/crates/mako/test/build/duplicate-package/node_modules/b/index.js b/crates/mako/test/build/duplicate-package/node_modules/b/index.js new file mode 100644 index 000000000..4c6f10750 --- /dev/null +++ b/crates/mako/test/build/duplicate-package/node_modules/b/index.js @@ -0,0 +1 @@ +require('a'); diff --git a/crates/mako/test/build/duplicate-package/node_modules/b/node_modules/a/index.js b/crates/mako/test/build/duplicate-package/node_modules/b/node_modules/a/index.js new file mode 100644 index 000000000..91efbb97c --- /dev/null +++ b/crates/mako/test/build/duplicate-package/node_modules/b/node_modules/a/index.js @@ -0,0 +1 @@ +console.log('newer a'); diff --git a/crates/mako/test/build/duplicate-package/node_modules/b/node_modules/a/package.json b/crates/mako/test/build/duplicate-package/node_modules/b/node_modules/a/package.json new file mode 100644 index 000000000..9ce57f318 --- /dev/null +++ b/crates/mako/test/build/duplicate-package/node_modules/b/node_modules/a/package.json @@ -0,0 +1,4 @@ +{ + "name": "a", + "version": "2.0.0" +} diff --git a/crates/mako/test/build/duplicate-package/node_modules/b/package.json b/crates/mako/test/build/duplicate-package/node_modules/b/package.json new file mode 100644 index 000000000..f9c7de4f4 --- /dev/null +++ b/crates/mako/test/build/duplicate-package/node_modules/b/package.json @@ -0,0 +1,7 @@ +{ + "name": "b", + "version": "1.0.0", + "dependencies": { + "a" : "~2.0.0" + } +} diff --git a/crates/mako/test/build/duplicate-package/node_modules/c/index.js b/crates/mako/test/build/duplicate-package/node_modules/c/index.js new file mode 100644 index 000000000..0089f3fd5 --- /dev/null +++ b/crates/mako/test/build/duplicate-package/node_modules/c/index.js @@ -0,0 +1 @@ +require('d'); diff --git a/crates/mako/test/build/duplicate-package/node_modules/c/node_modules/d/index.js b/crates/mako/test/build/duplicate-package/node_modules/c/node_modules/d/index.js new file mode 100644 index 000000000..5f6937c38 --- /dev/null +++ b/crates/mako/test/build/duplicate-package/node_modules/c/node_modules/d/index.js @@ -0,0 +1 @@ +require('b'); diff --git a/crates/mako/test/build/duplicate-package/node_modules/c/node_modules/d/node_modules/b/index.js b/crates/mako/test/build/duplicate-package/node_modules/c/node_modules/d/node_modules/b/index.js new file mode 100644 index 000000000..e69de29bb diff --git a/crates/mako/test/build/duplicate-package/node_modules/c/node_modules/d/node_modules/b/package.json b/crates/mako/test/build/duplicate-package/node_modules/c/node_modules/d/node_modules/b/package.json new file mode 100644 index 000000000..57549744f --- /dev/null +++ b/crates/mako/test/build/duplicate-package/node_modules/c/node_modules/d/node_modules/b/package.json @@ -0,0 +1,4 @@ +{ + "name": "b", + "version": "2.0.0" +} diff --git a/crates/mako/test/build/duplicate-package/node_modules/c/node_modules/d/package.json b/crates/mako/test/build/duplicate-package/node_modules/c/node_modules/d/package.json new file mode 100644 index 000000000..6264236f9 --- /dev/null +++ b/crates/mako/test/build/duplicate-package/node_modules/c/node_modules/d/package.json @@ -0,0 +1,7 @@ +{ + "name": "d", + "version": "1.0.0", + "dependencies": { + "b": "~1.0.0" + } +} diff --git a/crates/mako/test/build/duplicate-package/node_modules/c/package.json b/crates/mako/test/build/duplicate-package/node_modules/c/package.json new file mode 100644 index 000000000..a1449a1d6 --- /dev/null +++ b/crates/mako/test/build/duplicate-package/node_modules/c/package.json @@ -0,0 +1,7 @@ +{ + "name": "c", + "version": "1.0.0", + "dependencies": { + "d" : "~1.0.0" + } +} diff --git a/crates/mako/test/build/duplicate-package/package.json b/crates/mako/test/build/duplicate-package/package.json new file mode 100644 index 000000000..baffb4cb3 --- /dev/null +++ b/crates/mako/test/build/duplicate-package/package.json @@ -0,0 +1,8 @@ +{ + "name": "test", + "version": "1.0.0", + "dependencies": { + "a": "~1.0.0", + "b": "~1.0.0" + } +} diff --git a/docs/config.md b/docs/config.md index 72b521116..2a2cab624 100644 --- a/docs/config.md +++ b/docs/config.md @@ -161,6 +161,31 @@ Specify the devServer configuration. Specify the source map type. +### duplicatePackageChecker + +- Type: `{ verbose: boolean, showHelp: boolean, emitError: boolean } | false` +- Default: `false` + +Configuration for duplicate package checker. + +Child configuration items: + +- `verbose`: Whether to output detailed information. +- `showHelp`: Whether to show help information. +- `emitError`: Whether to emit an error when duplicate packages are found. + +Example: + +```json +{ + "duplicatePackageChecker": { + "verbose": true, + "showHelp": true, + "emitError": false + } +} +``` + ### dynamicImportToRequire - Type: `boolean` @@ -772,3 +797,4 @@ e.g. If you want to ignore the `foo` directory under root directory, you can set - Default: `true` Whether to write the build result to disk when mode is development. + diff --git a/docs/config.zh-CN.md b/docs/config.zh-CN.md index 5f7319d44..261dd42f1 100644 --- a/docs/config.zh-CN.md +++ b/docs/config.zh-CN.md @@ -161,6 +161,31 @@ 指定源映射类型。 +### duplicatePackageChecker + +- 类型:`{ verbose: boolean, showHelp: boolean, emitError: boolean } | false` +- 默认值:`false` + +重复包检查器的配置。 + +子配置项: + +- `verbose`:是否输出详细信息。 +- `showHelp`:是否显示帮助信息。 +- `emitError`:发现重复包时是否抛出错误。 + +示例: + +```json +{ + "duplicatePackageChecker": { + "verbose": true, + "showHelp": true, + "emitError": false + } +} +``` + ### dynamicImportToRequire - 类型:`boolean` diff --git a/e2e/fixtures/config.emotion/expect.js b/e2e/fixtures/config.emotion/expect.js index d02630e93..9bb489fc6 100644 --- a/e2e/fixtures/config.emotion/expect.js +++ b/e2e/fixtures/config.emotion/expect.js @@ -55,3 +55,7 @@ const test = async () => { } }; module.exports = test; + +if (!module.parent) { + test(); +} diff --git a/e2e/fixtures/config.emotion/mako.config.json b/e2e/fixtures/config.emotion/mako.config.json index 5b5937ae9..9e75be755 100644 --- a/e2e/fixtures/config.emotion/mako.config.json +++ b/e2e/fixtures/config.emotion/mako.config.json @@ -1,3 +1,7 @@ { - "emotion": true + "emotion": true, + "targets": { + "chrome": 40 + }, + "progress": false } diff --git a/e2e/fixtures/tree-shaking.failed.remove-unused-imports/expect.js b/e2e/fixtures/tree-shaking.failed.remove-unused-imports/expect.js index fed527680..9b6b5b7bd 100644 --- a/e2e/fixtures/tree-shaking.failed.remove-unused-imports/expect.js +++ b/e2e/fixtures/tree-shaking.failed.remove-unused-imports/expect.js @@ -6,5 +6,5 @@ import 'b' import 'c' import 'd' - * but actucally: a, b, c imports are removed + * but actually: a, b, c imports are removed */ diff --git a/packages/bundler-mako/index.js b/packages/bundler-mako/index.js index d7c8407e1..50084c6c7 100644 --- a/packages/bundler-mako/index.js +++ b/packages/bundler-mako/index.js @@ -111,27 +111,17 @@ exports.dev = async function (opts) { logLevel: 'silent', }); app.use('/__/hmr-ws', wsProxy); - - const outputPath = path.resolve(opts.cwd, opts.config.outputPath || 'dist'); - - function processReqURL(publicPath, reqURL) { - if (!publicPath.startsWith('/')) { - publicPath = '/' + publicPath; + app.use((req, res, next) => { + if (req.method !== 'GET' && req.method !== 'HEAD') { + return next(); } - return reqURL.startsWith(publicPath) - ? reqURL.slice(publicPath.length - 1) - : reqURL; - } - - if (opts.config.publicPath) { - app.use((req, _res, next) => { - req.url = processReqURL(opts.config.publicPath, req.url); + if (req.accepts().join('').includes('html')) { + return next(); + } + wsProxy(req, res, () => { next(); }); - } - - // serve dist files - app.use(express.static(outputPath)); + }); if (process.env.SSU === 'true') { // for ssu cache chunks diff --git a/packages/bundler-mako/package.json b/packages/bundler-mako/package.json index 088e75050..a4dd39486 100644 --- a/packages/bundler-mako/package.json +++ b/packages/bundler-mako/package.json @@ -1,9 +1,9 @@ { "name": "@umijs/bundler-mako", - "version": "0.8.6", + "version": "0.8.7", "dependencies": { "@umijs/bundler-utils": "^4.0.81", - "@umijs/mako": "0.8.6", + "@umijs/mako": "0.8.7", "chalk": "^4.1.2", "compression": "^1.7.4", "connect-history-api-fallback": "^2.0.0", diff --git a/packages/mako/binding.d.ts b/packages/mako/binding.d.ts index 479963cfd..a9989c8a2 100644 --- a/packages/mako/binding.d.ts +++ b/packages/mako/binding.d.ts @@ -3,10 +3,6 @@ /* auto-generated by NAPI-RS */ -export interface TransformOutput { - code: string; - map?: string; -} export interface JsHooks { name?: string; load?: ( diff --git a/packages/mako/npm/darwin-arm64/package.json b/packages/mako/npm/darwin-arm64/package.json index 251a4b36c..e46978fa2 100644 --- a/packages/mako/npm/darwin-arm64/package.json +++ b/packages/mako/npm/darwin-arm64/package.json @@ -1,6 +1,6 @@ { "name": "@umijs/mako-darwin-arm64", - "version": "0.8.6", + "version": "0.8.7", "os": [ "darwin" ], diff --git a/packages/mako/npm/darwin-x64/package.json b/packages/mako/npm/darwin-x64/package.json index 7e00517aa..35d2f4285 100644 --- a/packages/mako/npm/darwin-x64/package.json +++ b/packages/mako/npm/darwin-x64/package.json @@ -1,6 +1,6 @@ { "name": "@umijs/mako-darwin-x64", - "version": "0.8.6", + "version": "0.8.7", "os": [ "darwin" ], diff --git a/packages/mako/npm/linux-arm64-musl/package.json b/packages/mako/npm/linux-arm64-musl/package.json index 720fe9d9e..569d20314 100644 --- a/packages/mako/npm/linux-arm64-musl/package.json +++ b/packages/mako/npm/linux-arm64-musl/package.json @@ -1,6 +1,6 @@ { "name": "@umijs/mako-linux-arm64-musl", - "version": "0.8.6", + "version": "0.8.7", "os": [ "linux" ], diff --git a/packages/mako/npm/linux-x64-gnu/package.json b/packages/mako/npm/linux-x64-gnu/package.json index 2adc959ec..6a70b37b9 100644 --- a/packages/mako/npm/linux-x64-gnu/package.json +++ b/packages/mako/npm/linux-x64-gnu/package.json @@ -1,6 +1,6 @@ { "name": "@umijs/mako-linux-x64-gnu", - "version": "0.8.6", + "version": "0.8.7", "os": [ "linux" ], diff --git a/packages/mako/npm/linux-x64-musl/package.json b/packages/mako/npm/linux-x64-musl/package.json index 7b4506d67..b7a51c859 100644 --- a/packages/mako/npm/linux-x64-musl/package.json +++ b/packages/mako/npm/linux-x64-musl/package.json @@ -1,6 +1,6 @@ { "name": "@umijs/mako-linux-x64-musl", - "version": "0.8.6", + "version": "0.8.7", "os": [ "linux" ], diff --git a/packages/mako/package.json b/packages/mako/package.json index 6059007a1..6bcae356a 100644 --- a/packages/mako/package.json +++ b/packages/mako/package.json @@ -1,6 +1,6 @@ { "name": "@umijs/mako", - "version": "0.8.6", + "version": "0.8.7", "main": "dist/index.js", "types": "dist/index.d.ts", "bin": { @@ -74,11 +74,11 @@ "src:build": "father build" }, "optionalDependencies": { - "@umijs/mako-darwin-arm64": "0.8.6", - "@umijs/mako-linux-arm64-musl": "0.8.6", - "@umijs/mako-darwin-x64": "0.8.6", - "@umijs/mako-linux-x64-gnu": "0.8.6", - "@umijs/mako-linux-x64-musl": "0.8.6" + "@umijs/mako-darwin-arm64": "0.8.7", + "@umijs/mako-linux-arm64-musl": "0.8.7", + "@umijs/mako-darwin-x64": "0.8.7", + "@umijs/mako-linux-x64-gnu": "0.8.7", + "@umijs/mako-linux-x64-musl": "0.8.7" }, "repository": "git@github.com:umijs/mako.git" } \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5078188cd..d0dc017ed 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -415,7 +415,7 @@ importers: specifier: ^4.0.81 version: 4.1.6 '@umijs/mako': - specifier: 0.8.6 + specifier: 0.8.7 version: link:../mako chalk: specifier: ^4.1.2 @@ -513,20 +513,20 @@ importers: version: 21.1.1 optionalDependencies: '@umijs/mako-darwin-arm64': - specifier: 0.8.6 - version: 0.8.6 + specifier: 0.8.7 + version: 0.8.7 '@umijs/mako-darwin-x64': - specifier: 0.8.6 - version: 0.8.6 + specifier: 0.8.7 + version: 0.8.7 '@umijs/mako-linux-arm64-musl': - specifier: 0.8.6 - version: 0.8.6 + specifier: 0.8.7 + version: 0.8.7 '@umijs/mako-linux-x64-gnu': - specifier: 0.8.6 - version: 0.8.6 + specifier: 0.8.7 + version: 0.8.7 '@umijs/mako-linux-x64-musl': - specifier: 0.8.6 - version: 0.8.6 + specifier: 0.8.7 + version: 0.8.7 devDependencies: '@napi-rs/cli': specifier: ^2.18.0 @@ -848,7 +848,7 @@ packages: '@ant-design/pro-skeleton': 2.1.3(antd@5.18.0)(react-dom@18.2.0)(react@18.2.0) '@ant-design/pro-table': 3.6.11(antd@5.18.0)(prop-types@15.8.1)(rc-field-form@1.41.0)(react-dom@18.2.0)(react@18.2.0) '@ant-design/pro-utils': 2.10.0(antd@5.18.0)(react-dom@18.2.0)(react@18.2.0) - '@babel/runtime': 7.24.7 + '@babel/runtime': 7.22.11 antd: 5.18.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -6462,8 +6462,8 @@ packages: dev: true optional: true - /@umijs/mako-darwin-arm64@0.8.6: - resolution: {integrity: sha512-VF4gsz7jsUbAR+c2owLIoOAtpJ2hEuKJbADFMOy6oMUkT6tbAAxnwAa/niv+qswlmKG8dRFy8HNn+5O37iT3SA==} + /@umijs/mako-darwin-arm64@0.8.7: + resolution: {integrity: sha512-eLNcEIb/ar2ytdJjJVWzh3IKwEvO94H6IO9OaJ0D2akWckR0lMGodfXfpBrLKYKVm1q5klXGUG8D2NKEN5jBmA==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] @@ -6480,8 +6480,8 @@ packages: dev: true optional: true - /@umijs/mako-darwin-x64@0.8.6: - resolution: {integrity: sha512-FggV7ZvDjB8ddg5kwS87GNR7p/Y86tLygvoZpzS1MNzzWc7VNLNc4cmJCEG4C0uy/G66cLktXgOYFdcqvPPQzg==} + /@umijs/mako-darwin-x64@0.8.7: + resolution: {integrity: sha512-jyT3EkrfiwTLnRZLDrgedj40IMTQpIsV391RL1xuUzcF2P2avQkJEx2y+lG/H0BZMtoFhkK4xTCR4f4MdQWcnA==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] @@ -6489,8 +6489,8 @@ packages: dev: false optional: true - /@umijs/mako-linux-arm64-musl@0.8.6: - resolution: {integrity: sha512-Vuhf/z8T85vPI8I5jsIUcIxlSuw+Tj1oMt92SCt0Dzo+WtKpRjmkHFRY8i/A+UE+nG1OJqjJgwBNbcHk7T6fug==} + /@umijs/mako-linux-arm64-musl@0.8.7: + resolution: {integrity: sha512-Gv0u6B22bMRxMjoah80hWoq4G058cOJN69qRp1miCtp7vCrYLuNEKRVO05/X4GGDiYAEnQP/qUNnJb+XUG4w4Q==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -6507,8 +6507,8 @@ packages: dev: true optional: true - /@umijs/mako-linux-x64-gnu@0.8.6: - resolution: {integrity: sha512-ClQjTjX/qfpuKyrafefiuIIVjZg8m4gzQ6tUw8zEii/5FSxDH99wLpOetUBdzteFBVW+jTzicxndCSUb0Il0Aw==} + /@umijs/mako-linux-x64-gnu@0.8.7: + resolution: {integrity: sha512-GjMLMfiOeY7Vh1+iXqyamQhy6R+6O6j2+pHO2/OxKsmb0EJMEmcAtjsPwE8OaktULFoQJzgVJCkgmTz94TKd2Q==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -6525,8 +6525,8 @@ packages: dev: true optional: true - /@umijs/mako-linux-x64-musl@0.8.6: - resolution: {integrity: sha512-kUcMQLDi7yEaktoOUx6bfKKuQOh5k5iZWTF5160hKSzhMjFpaVXctyXnnUyGOL2530Il1EKxcbKiLlbJddxnog==} + /@umijs/mako-linux-x64-musl@0.8.7: + resolution: {integrity: sha512-RfaxScHbp2oW/4F6cSdAxmhCoL+yM4AmNv2Y0yf7bpxWXrR/x84vCvP4V7RFmxtIOeV89oG4wiHDBekLDmEJDA==} engines: {node: '>= 10'} cpu: [x64] os: [linux]