Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into feat/upgrade_swc
Browse files Browse the repository at this point in the history
  • Loading branch information
stormslowly committed Sep 9, 2024
2 parents 8904f1f + 60f8c90 commit 022702b
Show file tree
Hide file tree
Showing 23 changed files with 157 additions and 36 deletions.
21 changes: 15 additions & 6 deletions .github/workflows/node-bind-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,34 @@ jobs:
rustup target add x86_64-apple-darwin
pnpm --filter @umijs/mako build --target x86_64-apple-darwin
strip -x ./packages/mako/*.node
- host: macos-latest
target: aarch64-apple-darwin
build: |
rustup target add aarch64-apple-darwin
pnpm --filter @umijs/mako build --target aarch64-apple-darwin
strip -x ./packages/mako/*.node
- host: ubuntu-latest
target: x86_64-unknown-linux-gnu
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian
build: |-
set -e &&
pnpm --filter @umijs/mako build --target x86_64-unknown-linux-gnu &&
strip ./packages/mako/*.node
- host: macos-latest
target: aarch64-apple-darwin
build: |
rustup target add aarch64-apple-darwin
pnpm --filter @umijs/mako build --target aarch64-apple-darwin
strip -x ./packages/mako/*.node
- host: ubuntu-latest
target: x86_64-unknown-linux-musl
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine
build: |
pnpm --filter @umijs/mako build --target x86_64-unknown-linux-musl
strip -x ./packages/mako/*.node
- host: ubuntu-latest
target: aarch64-unknown-linux-gnu
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian-aarch64
build: |-
set -e &&
export JEMALLOC_SYS_WITH_LG_PAGE=16 &&
export CC_aarch64_unknown_linux_gnu=/usr/aarch64-unknown-linux-gnu/bin/aarch64-unknown-linux-gnu-gcc &&
rustup target add aarch64-unknown-linux-gnu &&
pnpm --filter @umijs/mako build --target aarch64-unknown-linux-gnu
- host: ubuntu-latest
target: aarch64-unknown-linux-musl
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine
Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

`2024-09-05`

* perf: group chunks with post order dfs by [@xusd320](https://github.com/xusd320) in [#1554](https://github.com/umijs/mako/pull/1554)
* perf: group chunks with right first dfs by [@xusd320](https://github.com/xusd320) in [#1554](https://github.com/umijs/mako/pull/1554)
* refactor: unify base64 utils by [@xusd320](https://github.com/xusd320) in [#1557](https://github.com/umijs/mako/pull/1557)
* Revert "refactor: Unify the static server in bundler-mako and devServer" by [@stormslowly](https://github.com/stormslowly) in [#1556](https://github.com/umijs/mako/pull/1556)
* fix: define env by [@xusd320](https://github.com/xusd320) in [#1551](https://github.com/umijs/mako/pull/1551)
Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG_zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

`2024-09-05`

* 优化 group chunks 的性能,基于 post order dfs by [@xusd320](https://github.com/xusd320) in [#1554](https://github.com/umijs/mako/pull/1554)
* 优化 group chunks 的性能,基于 right first dfs by [@xusd320](https://github.com/xusd320) in [#1554](https://github.com/umijs/mako/pull/1554)
* 重构 base64 utils by [@xusd320](https://github.com/xusd320) in [#1557](https://github.com/umijs/mako/pull/1557)
* 回滚 "refactor: Unify the static server in bundler-mako and devServer" by [@stormslowly](https://github.com/stormslowly) in [#1556](https://github.com/umijs/mako/pull/1556)
* 修复 define env by [@xusd320](https://github.com/xusd320) in [#1551](https://github.com/umijs/mako/pull/1551)
Expand Down
79 changes: 65 additions & 14 deletions crates/mako/src/ast/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,21 +330,47 @@ type Search = String;
type Params = Vec<(String, String)>;
type Fragment = Option<String>;

fn has_hash_without_dot(input: &str) -> bool {
if let Some(pos) = input.find('#') {
let after_hash = &input[pos + 1..];
!after_hash.contains('.')
} else {
false
}
}

pub fn parse_path(path: &str) -> Result<(PathName, Search, Params, Fragment)> {
let base = "http://a.com/";
let base_url = Url::parse(base)?;
let full_url = base_url.join(path)?;
let path = full_url.path().to_string();
let fragment = full_url.fragment().map(|s| s.to_string());
let search = full_url.query().unwrap_or("").to_string();
let query_vec = full_url
.query_pairs()
.map(|(k, v)| (k.to_string(), v.to_string()))
.collect();
// dir or filename may contains space or other special characters
// so we need to decode it, e.g. "a%20b" -> "a b"
let path = percent_decode_str(&path).decode_utf8()?;
Ok((path.to_string(), search, query_vec, fragment))
#[cfg(target_os = "windows")]
let path = {
let prefix = "\\\\?\\";
let path = path.trim_start_matches(prefix);
path.replace('\\', "/")
};
#[cfg(not(target_os = "windows"))]
let path = path.to_string();
if path.contains('?') || has_hash_without_dot(path.as_str()) {
let (path, search) = if path.contains('?') {
path.split_once('?').unwrap_or((path.as_str(), ""))
} else {
path.split_once('#').unwrap_or((path.as_str(), ""))
};
let base = "http://a.com/";
let base_url = Url::parse(base)?;
let full_url = base_url.join(format!("?{}", search).as_str())?;
let fragment = full_url.fragment().map(|s| s.to_string());
let search = full_url.query().unwrap_or("").to_string();
let query_vec = full_url
.query_pairs()
.map(|(k, v)| (k.to_string(), v.to_string()))
.collect();
// dir or filename may contains space or other special characters
// so we need to decode it, e.g. "a%20b" -> "a b"
let path = percent_decode_str(path).decode_utf8()?;
Ok((path.to_string(), search.to_string(), query_vec, fragment))
} else {
let path = percent_decode_str(&path).decode_utf8()?;
Ok((path.to_string(), "".to_string(), vec![], None))
}
}

#[cfg(test)]
Expand All @@ -371,4 +397,29 @@ mod tests {
);
assert_eq!(f.path(), Some("/root/d.js".to_string()));
}

#[test]
fn test_parse_path_support_windows() {
let path = "C:\\a\\b\\c?foo";
let (path, search, params, fragment) = parse_path(path).unwrap();
assert_eq!(path, "C:\\a\\b\\c");
assert_eq!(search, "foo");
assert_eq!(params, vec![("foo".to_string(), "".to_string())]);
assert_eq!(fragment, None);
}

#[test]
fn test_parse_path_with_fragment() {
assert_eq!(parse_path("foo.ts#bar").unwrap().0, "foo.ts");
assert_eq!(parse_path("foo#bar.ts").unwrap().0, "foo#bar.ts");
}

#[test]
fn test_has_hash_without_dot() {
assert_eq!(has_hash_without_dot("foo.ts#world"), true);
assert_eq!(has_hash_without_dot("foo#bar.ts"), false);
assert_eq!(has_hash_without_dot("#no_dot"), true);
assert_eq!(has_hash_without_dot("no_hash"), false);
assert_eq!(has_hash_without_dot("#.dot_after_hash"), false);
}
}
4 changes: 3 additions & 1 deletion crates/mako/src/config/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ pub struct OutputConfig {
pub skip_write: bool,
#[serde(deserialize_with = "deserialize_cross_origin_loading")]
pub cross_origin_loading: Option<CrossOriginLoading>,
pub global_module_registry: bool,
}

#[derive(Deserialize, Serialize, Debug, Clone)]
Expand Down Expand Up @@ -722,7 +723,8 @@ const DEFAULT_CONFIG: &str = r#"
"preserveModules": false,
"preserveModulesRoot": "",
"skipWrite": false,
"crossOriginLoading": false
"crossOriginLoading": false,
"globalModuleRegistry": false,
},
"resolve": { "alias": [], "extensions": ["js", "jsx", "ts", "tsx"] },
"mode": "development",
Expand Down
1 change: 1 addition & 0 deletions crates/mako/src/generate/chunk_pot/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ pub(crate) fn runtime_code(context: &Arc<Context>) -> Result<String> {
.optimization
.as_ref()
.map_or(false, |o| o.concatenate_modules.unwrap_or(false)),
global_module_registry: context.config.output.global_module_registry,
};
let app_runtime = app_runtime.render_once()?;
let app_runtime = app_runtime.replace(
Expand Down
16 changes: 8 additions & 8 deletions crates/mako/src/generate/group_chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ impl Compiler {
}

/*
* Visit dependencies by post order DFS. The reason for this is that
* Visit dependencies by right first DFS. The reason for this is that
* the rightmost and deepest css dependence should have the highest priority.
* For example, the dependencies graph is:
*
Expand All @@ -499,19 +499,19 @@ impl Compiler {
* the final dependencies orders in chunk should be:
*
* ----------
* a.css
* c.css
* b.css
* index.css
* b.css
* c.css
* a.css
* ----------
* note that c.css, b.css, c.css before a.css will be deduplicated.
* note that c.css, b.css, c.css after a.css will be deduplicated.
*/
fn visit_modules<F, T>(mut queue: Vec<T>, visited: Option<HashSet<T>>, mut callback: F) -> Vec<T>
where
F: FnMut(&T) -> Vec<T>,
T: Hash + Eq + Clone,
{
let mut post_order_dfs_ret: Vec<T> = Vec::new();
let mut right_firtst_dfs_ret: Vec<T> = Vec::new();

let mut visited = visited.unwrap_or_default();

Expand All @@ -520,12 +520,12 @@ where
continue;
}

post_order_dfs_ret.push(id.clone());
right_firtst_dfs_ret.push(id.clone());

visited.insert(id.clone());

queue.extend(callback(&id));
}

post_order_dfs_ret
right_firtst_dfs_ret
}
1 change: 1 addition & 0 deletions crates/mako/src/generate/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ pub struct AppRuntimeTemplate {
pub is_browser: bool,
pub concatenate_enabled: bool,
pub cross_origin_loading: Option<String>,
pub global_module_registry: bool,
}
6 changes: 6 additions & 0 deletions crates/mako/templates/app_runtime.stpl
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
function createRuntime(makoModules, entryModuleId, global) {
<% if global_module_registry { %>
var modulesRegistry = (
(typeof globalThis !== "undefined" ? globalThis : self).__mako_module_registry =
((typeof globalThis !== "undefined" ? globalThis : self).__mako_module_registry || {}));
<% } else { %>
var modulesRegistry = {};
<% } %>

function requireModule(moduleId) {
var cachedModule = modulesRegistry[moduleId];
Expand Down
1 change: 1 addition & 0 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@ Output related configuration.
- `preserveModules`, whether to preserve the module directory structure (Bundless Only)
- `preserveModulesRoot`, preserve the root directory of the module directory structure (Bundless Only)
- `crossOriginLoading`, control the `crossorigin` attribute of the `script` tag and `link` tag for load async chunks
- `globalModuleRegistry`, whether enable shared module registry across multi entries

### optimization

Expand Down
1 change: 1 addition & 0 deletions docs/config.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,7 @@ e.g.
- `preserveModules`,是否保留模块目录结构(仅适用于 Bundless)
- `preserveModulesRoot`,是否保留模块目录结构的根目录(仅限 Bundless)
- `crossOriginLoading`,控制异步 chunk 加载时 `script``link` 标签的 `crossorigin` 属性值
- `globalModuleRegistry`,是否允许在多 entry 之间共享模块注册中心

### optimization

Expand Down
4 changes: 4 additions & 0 deletions e2e/fixtures/config.global-module-registry/expect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const assert = require("assert");

require('./dist/common');
assert(require('./dist/A').common === require('./dist/B').common, 'global module registry should work');
25 changes: 25 additions & 0 deletions e2e/fixtures/config.global-module-registry/mako.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"entry": {
"A": "./src/entryA.ts",
"B": "./src/entryB.ts"
},
"minify": false,
"platform": "node",
"cjs": true,
"codeSplitting": {
"strategy": "advanced",
"options": {
"groups": [
{
"name": "common",
"allowChunks": "all",
"minSize": 1,
"minChunks": 2
}
]
}
},
"output": {
"globalModuleRegistry": true
}
}
3 changes: 3 additions & 0 deletions e2e/fixtures/config.global-module-registry/src/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const common = {
value: 1
}
2 changes: 2 additions & 0 deletions e2e/fixtures/config.global-module-registry/src/entryA.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { common } from "./common";

2 changes: 2 additions & 0 deletions e2e/fixtures/config.global-module-registry/src/entryB.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { common } from "./common";

This file was deleted.

3 changes: 2 additions & 1 deletion packages/mako/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"defaults": false,
"additional": [
"aarch64-apple-darwin",
"aarch64-unknown-linux-gnu",
"aarch64-unknown-linux-musl",
"x86_64-apple-darwin",
"x86_64-unknown-linux-gnu",
Expand Down Expand Up @@ -81,4 +82,4 @@
"@umijs/mako-linux-x64-musl": "0.8.8"
},
"repository": "git@github.com:umijs/mako.git"
}
}
12 changes: 12 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions scripts/test-e2e.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ for (const dir of onlyDir ? [onlyDir] : dirs) {
const testFn = dir.includes('failed') && !argv.only ? test.skip : test;
await testFn(dir, async () => {
const cwd = path.join(fixtures, dir);
const expectPath = `file://${path.join(fixtures, dir, 'expect.js')}`;
if (argv.umi) {
if (!fs.existsSync(path.join(cwd, 'node_modules'))) {
await $`cd ${cwd} && mkdir node_modules`;
Expand All @@ -40,11 +41,11 @@ for (const dir of onlyDir ? [onlyDir] : dirs) {
} else {
try {
// run mako build
await $`${path.join(root, 'scripts', 'mako.js')} ${cwd}`;
await $`node ${path.join(root, 'scripts', 'mako.js')} ${cwd}`;
} catch (e) {
const isErrorCase = dir.split('.').includes('error');
if (isErrorCase) {
const mod = await import(path.join(fixtures, dir, 'expect.js'));
const mod = await import(expectPath);
mod.default(e);
return;
} else {
Expand All @@ -53,7 +54,7 @@ for (const dir of onlyDir ? [onlyDir] : dirs) {
}
}
// run expect.js
const mod = await import(path.join(fixtures, dir, 'expect.js'));
const mod = await import(expectPath);
if (mod && typeof mod.default === 'function') {
await mod.default();
}
Expand Down

0 comments on commit 022702b

Please sign in to comment.