Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: supports publicPath: auto #1717

Merged
merged 1 commit into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion crates/mako/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,9 @@ impl Config {
.define
.insert("NODE_ENV".to_string(), serde_json::Value::String(mode));

if config.public_path != "runtime" && !config.public_path.ends_with('/') {
if ["runtime", "auto"].iter().all(|p| *p != config.public_path)
&& !config.public_path.ends_with('/')
{
return Err(anyhow!("public_path must end with '/' or be 'runtime'"));
}

Expand Down
48 changes: 37 additions & 11 deletions crates/mako/src/plugins/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,46 @@ impl Plugin for MakoRuntime {
impl MakoRuntime {
fn public_path(&self, context: &Arc<Context>) -> String {
let public_path = context.config.public_path.clone();
let public_path = if public_path == "runtime" {
"(typeof globalThis !== 'undefined' ? globalThis : self).publicPath || '/'".to_string()
} else {
format!("\"{}\"", public_path)
};

format!(
r#"
match public_path.as_str() {
"runtime" => {
r#"/* mako/runtime/publicPath */
!function () {{
requireModule.publicPath= (typeof globalThis !== 'undefined' ? globalThis : self).publicPath || '/';
}}();"#.to_string()
}
"auto" => {
r#"/* mako/runtime/publicPath */
!function() {{
var scriptUrl;
if (!self.document && self.importScripts) {
scriptUrl = self.location + "";
}
if (!scriptUrl && document) {
if (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT')
scriptUrl = document.currentScript.src;
if (!scriptUrl) {
var scripts = document.getElementsByTagName("script");
if(scripts.length) {
var i = scripts.length - 1;
while (i > -1 && (!scriptUrl || !/^http(s?):/.test(scriptUrl))) scriptUrl = scripts[i--].src;
}
}
}
if (!scriptUrl) throw new Error("Automatic publicPath is not supported in this browser");
scriptUrl = scriptUrl.replace(/#.*$/, "").replace(/\?.*$/, "").replace(/\/[^\/]+$/, "/");
requireModule.publicPath = scriptUrl;
}}();"#
}
.to_string(),
_ => format!(
r#"
/* mako/runtime/publicPath */
!function () {{
requireModule.publicPath= {};
requireModule.publicPath= "{}";
}}();"#,
public_path
)
public_path
),
}
}

fn helper_runtime(&self, context: &Arc<Context>) -> Result<String> {
Expand Down
6 changes: 5 additions & 1 deletion docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,11 @@ Buffer;
- Type: `string`
- Default: `"/"`

publicPath configuration. Note: There is a special value `"runtime"`, which means that it will switch to runtime mode and use the runtime `window.publicPath` as publicPath.
publicPath configuration. Note: There is two special values

- `"runtime"`, which means that it will switch to runtime mode and use the runtime `window.publicPath` as publicPath.

- `"auto"`, which is just like `publicPath: "auto"` in webpack

If you want to set the `publicPath` in the runtime, use `__mako_public_path__`. (Notice: `__webpack_public_path__` is also supported)

Expand Down
4 changes: 3 additions & 1 deletion docs/config.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,9 @@ Buffer;
- 类型:`string`
- 默认值:`"/"`

publicPath 配置。注意:有一个特殊值 `"runtime"`,这意味着它将切换到运行时模式并使用运行时的 `window.publicPath` 作为 publicPath。
publicPath 配置。注意:有两个特殊值
* `"runtime"`,这意味着它将切换到运行时模式并使用运行时的 `window.publicPath` 作为 publicPath;
* `"auto"`,类似 webpack 的 `publicPath: "auto"`。

如果你想在运行时设置 `publicPath`,请使用 `__mako_public_path__`。(注:`__webpack_public_path__` 也是支持的)

Expand Down
11 changes: 11 additions & 0 deletions e2e/fixtures/config.public_path.auto/expect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const assert = require("assert");
const { parseBuildResult } = require("../../../scripts/test-utils");
const { files } = parseBuildResult(__dirname);

const content = files["index.js"];

assert.match(
content,
/scriptUrl = document.currentScript.src.*requireModule.publicPath = scriptUrl/s,
"requireModule.publicPath not correct"
);
3 changes: 3 additions & 0 deletions e2e/fixtures/config.public_path.auto/mako.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"publicPath": "auto"
}
1 change: 1 addition & 0 deletions e2e/fixtures/config.public_path.auto/src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log(1);
Loading