From e55756d626a367ac1fe5be381e8d17fa33770763 Mon Sep 17 00:00:00 2001 From: "huanyu.why" Date: Wed, 10 Jul 2024 20:00:47 +0800 Subject: [PATCH] fix: the development server was unable to correctly consume the "publicPath" configuration --- crates/mako/src/dev/mod.rs | 12 ++++++--- crates/mako/src/utils/mod.rs | 48 ++++++++++++++++++++++++++++++++++ packages/bundler-mako/index.js | 19 ++++++++++++++ 3 files changed, 76 insertions(+), 3 deletions(-) diff --git a/crates/mako/src/dev/mod.rs b/crates/mako/src/dev/mod.rs index f54233a9e..6544b0322 100644 --- a/crates/mako/src/dev/mod.rs +++ b/crates/mako/src/dev/mod.rs @@ -21,7 +21,7 @@ use {hyper, hyper_staticfile, hyper_tungstenite, open}; use crate::compiler::{Compiler, Context}; use crate::plugin::{PluginGenerateEndParams, PluginGenerateStats}; -use crate::utils::tokio_runtime; +use crate::utils::{process_req_url, tokio_runtime}; pub struct DevServer { root: PathBuf, @@ -124,7 +124,13 @@ impl DevServer { staticfile: hyper_staticfile::Static, txws: broadcast::Sender, ) -> Result> { - let path = req.uri().path(); + let mut path = req.uri().path().to_string(); + let public_path = &context.config.public_path; + // public_path should be ended with "/", so we can replace it with "/" + // and we don't handle the public_path which start with http protocol + if !public_path.is_empty() { + path = process_req_url(public_path, &path); + } let path_without_slash_start = path.trim_start_matches('/'); let not_found_response = || { hyper::Response::builder() @@ -132,7 +138,7 @@ impl DevServer { .body(hyper::Body::empty()) .unwrap() }; - match path { + match path.as_str() { "/__/hmr-ws" => { if hyper_tungstenite::is_upgrade_request(&req) { debug!("new websocket connection"); diff --git a/crates/mako/src/utils/mod.rs b/crates/mako/src/utils/mod.rs index 787a71a6a..a1199c18e 100644 --- a/crates/mako/src/utils/mod.rs +++ b/crates/mako/src/utils/mod.rs @@ -32,3 +32,51 @@ impl ParseRegex for Option { }) } } + +pub fn process_req_url(public_path: &str, req_url: &str) -> String { + let mut public_path = public_path.to_string(); + if !public_path.starts_with('/') { + public_path = format!("/{}", public_path); + } + if !public_path.ends_with('/') { + public_path.push('/'); + } + if req_url.starts_with(&public_path) { + return req_url[public_path.len() - 1..].to_string(); + } + req_url.to_string() +} + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn test_process_req_url() { + assert_eq!( + process_req_url("/public/", "/public/index.html"), + "/index.html" + ); + assert_eq!( + process_req_url("public/", "/public/index.html"), + "/index.html" + ); + assert_eq!( + process_req_url("/public/foo/", "/public/foo/index.html"), + "/index.html" + ); + assert_eq!( + process_req_url("public/foo/", "/public/foo/index.html"), + "/index.html" + ); + assert_eq!(process_req_url("/", "/index.html"), "/index.html"); + assert_eq!(process_req_url("/#/", "/#/index.html"), "/index.html"); + assert_eq!( + process_req_url("/公共路径/", "/公共路径/index.html"), + "/index.html" + ); + assert_eq!( + process_req_url("公共路径/", "/公共路径/index.html"), + "/index.html" + ); + } +} diff --git a/packages/bundler-mako/index.js b/packages/bundler-mako/index.js index 47588543f..a20814bad 100644 --- a/packages/bundler-mako/index.js +++ b/packages/bundler-mako/index.js @@ -111,6 +111,25 @@ exports.dev = async function (opts) { const outputPath = path.resolve(opts.cwd, opts.config.outputPath || 'dist'); + function processReqURL(publicPath, reqURL) { + if (!publicPath.startsWith('/')) { + publicPath = '/' + publicPath; + } + if (!publicPath.endsWith('/')) { + publicPath += '/'; + } + if (reqURL.startsWith(publicPath)) { + return reqURL.slice(publicPath.length - 1); + } else { + return reqURL; + } + } + if (opts.config.publicPath) { + app.use((req, res, next) => { + req.url = processReqURL(opts.config.publicPath, req.url); + next(); + }); + } // serve dist files app.use(express.static(outputPath));