Skip to content
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
8 changes: 6 additions & 2 deletions crates/mako/src/generate/chunk_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,15 @@ impl ChunkGraph {

pub fn sync_dependencies_chunk(&self, chunk_id: &ChunkId) -> Vec<ChunkId> {
let idx = self.id_index_map.get(chunk_id).unwrap();
self.graph
let ret = self
.graph
.neighbors_directed(*idx, Direction::Outgoing)
.filter(|idx| matches!(self.graph[*idx].chunk_type, ChunkType::Sync))
.map(|idx| self.graph[idx].id.clone())
.collect::<Vec<ChunkId>>()
.collect::<Vec<ChunkId>>();
// The neighbors ordering is reversed, see https://github.com/petgraph/petgraph/issues/116,
// so need to collect by reversed order
ret.into_iter().rev().collect()
}

pub fn entry_dependencies_chunk(&self, chunk_id: &ChunkId) -> Vec<ChunkId> {
Expand Down
59 changes: 40 additions & 19 deletions crates/mako/src/generate/group_chunk.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::collections::{HashSet, VecDeque};
use std::collections::HashSet;
use std::hash::Hash;
use std::vec;

use tracing::debug;
Expand Down Expand Up @@ -388,16 +389,10 @@ impl Compiler {

let chunk_id = entry_module_id.generate(&self.context);
let mut chunk = Chunk::new(chunk_id.into(), chunk_type.clone());
let mut visited_modules: Vec<&ModuleId> = vec![entry_module_id];

let module_graph = self.context.module_graph.read().unwrap();

visit_modules(vec![entry_module_id.clone()], None, |head| {
let parent_index = visited_modules
.iter()
.position(|m| m.id == head.id)
.unwrap_or(0);
let mut normal_deps = vec![];
let mut chunk_deps = visit_modules(vec![entry_module_id.clone()], None, |head| {
let mut next_module_ids = vec![];

for (dep_module_id, dep) in module_graph.get_dependencies(head) {
Expand All @@ -417,22 +412,17 @@ impl Compiler {
) =>
{
next_module_ids.push(dep_module_id.clone());
// collect normal deps for current head
normal_deps.push(dep_module_id);
}
_ => {}
}
}

// insert normal deps before head, so that we can keep the dfs order
visited_modules.splice(parent_index..parent_index, normal_deps);

next_module_ids
});

// add modules to chunk as dfs order
for module_id in visited_modules {
chunk.add_module(module_id.clone());
while let Some(dep) = chunk_deps.pop() {
chunk.add_module(dep);
}

(chunk, dynamic_entries, worker_entries)
Expand Down Expand Up @@ -492,19 +482,50 @@ impl Compiler {
}
}

fn visit_modules<F>(ids: Vec<ModuleId>, visited: Option<HashSet<ModuleId>>, mut callback: F)
/*
* Visit dependencies by post order DFS. The reason for this is that
* the rightmost and deepest css dependence should have the highest priority.
* For example, the dependencies graph is:
*
* ----------
* index.css
* -> a.css
* -> b.css
* -> c.css
* -> c.css
* -> b.css
* -> c.css
* ----------
* the final dependencies orders in chunk should be:
*
* ----------
* a.css
* c.css
* b.css
* index.css
* ----------
* note that c.css, b.css, c.css before 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(&ModuleId) -> Vec<ModuleId>,
F: FnMut(&T) -> Vec<T>,
T: Hash + Eq + Clone,
{
let mut queue = VecDeque::from(ids);
let mut post_order_dfs_ret: Vec<T> = Vec::new();

let mut visited = visited.unwrap_or_default();

while let Some(id) = queue.pop_front() {
while let Some(id) = queue.pop() {
if visited.contains(&id) {
continue;
}

post_order_dfs_ret.push(id.clone());

visited.insert(id.clone());

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

post_order_dfs_ret
}
12 changes: 6 additions & 6 deletions crates/mako/src/generate/optimize_chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -469,12 +469,12 @@ impl Compiler {
}

// add edge to original chunks
for (from, to) in edges_map
edges_map
.iter()
.flat_map(|(from, tos)| tos.iter().map(move |to| (from, to)))
{
chunk_graph.add_edge(from, to);
}
.for_each(|(from, to)| {
chunk_graph.add_edge(from, to);
});
}

fn apply_hot_update_optimize_infos(&self, optimize_chunks_infos: &Vec<OptimizeChunksInfo>) {
Expand Down Expand Up @@ -506,9 +506,9 @@ impl Compiler {
}

// add edge to original chunks
for (from, to) in edges.iter() {
edges.iter().for_each(|(from, to)| {
chunk_graph.add_edge(from, to);
}
});
}
}

Expand Down
6 changes: 3 additions & 3 deletions e2e/fixtures/code-splitting.complex/expect.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ assert.match(
files["index.js"].replace(/\s/g, ""),
new RegExp(`Promise.all\\(\\[${
[
"vendors_0",
"common",
"vendors_1",
"common",
"vendors_0",
"src/should-be-split.ts",
].map((f) => `__mako_require__.ensure\\("${f}"\\)`).join(",")
}\\]\\)`),
Expand All @@ -46,7 +46,7 @@ assert.match(
new RegExp(`Promise.all\\(\\[${
[
"common",
"vendors_1",
"vendors_0",
"src/other-dynamic.ts",
].map((f) => `__mako_require__.ensure\\("${f}"\\)`).join(",")
}\\]\\)`),
Expand Down
30 changes: 30 additions & 0 deletions e2e/fixtures/css.css-merge-deep-level/expect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const assert = require("assert");
const { parseBuildResult, moduleReg } = require("../../../scripts/test-utils");
const { files } = parseBuildResult(__dirname);

const names = Object.keys(files).join(",");
const content = files["index.css"];

assert(
content.includes(`
.a {
color: red;
}
.b {
color: blue;
}
.c {
color: green;
}
.b1 {
color: blue;
}
.c1 {
color: green;
}
.a1 {
color: red;
}
`.trim()),
"css merge deep level should work"
);
1 change: 1 addition & 0 deletions e2e/fixtures/css.css-merge-deep-level/mako.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"minify": false}
6 changes: 6 additions & 0 deletions e2e/fixtures/css.css-merge-deep-level/src/a.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@import "c.css";
@import "a1.css";

.a {
color: red;
}
5 changes: 5 additions & 0 deletions e2e/fixtures/css.css-merge-deep-level/src/a1.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@import "c1.css";

.a1 {
color: red;
}
6 changes: 6 additions & 0 deletions e2e/fixtures/css.css-merge-deep-level/src/b.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@import "c.css";
@import "b1.css";

.b {
color: blue;
}
5 changes: 5 additions & 0 deletions e2e/fixtures/css.css-merge-deep-level/src/b1.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@import "c1.css";

.b1 {
color: blue;
}
4 changes: 4 additions & 0 deletions e2e/fixtures/css.css-merge-deep-level/src/c.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@import "c1.css";
.c {
color: green;
}
3 changes: 3 additions & 0 deletions e2e/fixtures/css.css-merge-deep-level/src/c1.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.c1 {
color: green;
}
6 changes: 6 additions & 0 deletions e2e/fixtures/css.css-merge-deep-level/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import './a.css';
import './c1.css';
import './b.css';
import './c.css';
import './b1.css';
import './a1.css';
21 changes: 21 additions & 0 deletions e2e/fixtures/css.css-merge-in-css-multi-imports/expect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const assert = require("assert");
const { parseBuildResult, moduleReg } = require("../../../scripts/test-utils");
const { files } = parseBuildResult(__dirname);

const names = Object.keys(files).join(",");
const content = files["index.css"];

assert(
content.includes(`
.a {
color: red;
}
.c {
color: green;
}
.b {
color: blue;
}
`.trim()),
"css merge in css multi imports should work"
);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"minify": false}
6 changes: 6 additions & 0 deletions e2e/fixtures/css.css-merge-in-css-multi-imports/src/a.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@import "b.css";
@import "c.css";

.a {
color: red;
}
3 changes: 3 additions & 0 deletions e2e/fixtures/css.css-merge-in-css-multi-imports/src/b.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@import 'c.css';

.b { color: blue }
1 change: 1 addition & 0 deletions e2e/fixtures/css.css-merge-in-css-multi-imports/src/c.css
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.c { color: green }
2 changes: 2 additions & 0 deletions e2e/fixtures/css.css-merge-in-css-multi-imports/src/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@import 'a.css';
@import 'b.css';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import './index.css';
23 changes: 23 additions & 0 deletions e2e/fixtures/css.css-merge-reverse-by-descent/expect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const assert = require("assert");
const { parseBuildResult, moduleReg } = require("../../../scripts/test-utils");
const { files } = parseBuildResult(__dirname);

const names = Object.keys(files).join(",");
const content = files["index.css"];

assert(
content.includes(`
.b {
color: blue;
}
.c {
color: green;
}
.a {
color: red;
}
.d {
color: black;
}`.trim()),
"css merge reverse by descent should work"
);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"minify": false}
3 changes: 3 additions & 0 deletions e2e/fixtures/css.css-merge-reverse-by-descent/src/a.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@import 'c.css';

.a { color: red }
3 changes: 3 additions & 0 deletions e2e/fixtures/css.css-merge-reverse-by-descent/src/b.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@import 'c.css';

.b { color: blue }
1 change: 1 addition & 0 deletions e2e/fixtures/css.css-merge-reverse-by-descent/src/c.css
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.c { color: green }
7 changes: 7 additions & 0 deletions e2e/fixtures/css.css-merge-reverse-by-descent/src/d.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@import "c.css";
@import "b.css";
@import "a.css";

.d {
color: black;
}
4 changes: 4 additions & 0 deletions e2e/fixtures/css.css-merge-reverse-by-descent/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import './a.css';
import './b.css';
import './c.css';
import './d.css';