Skip to content

Commit

Permalink
fix: css loading initial chunks (#4136)
Browse files Browse the repository at this point in the history
  • Loading branch information
underfin authored Sep 6, 2023
1 parent 0f61d3e commit ad727a9
Show file tree
Hide file tree
Showing 14 changed files with 96 additions and 47 deletions.
50 changes: 21 additions & 29 deletions crates/rspack_plugin_runtime/src/runtime_module/css_loading.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,35 +46,21 @@ impl RuntimeModule for CssLoadingRuntimeModule {
.contains(RuntimeGlobals::ENSURE_CHUNK_HANDLERS);

let initial_chunks = chunk.get_all_initial_chunks(&compilation.chunk_group_by_ukey);
let mut initial_chunk_ids_with_css = HashSet::default();
let mut initial_chunk_ids_without_css = HashSet::default();
for chunk_ukey in initial_chunks.iter() {
let chunk = compilation
.chunk_by_ukey
.get(chunk_ukey)
.expect("Chunk not found");
if chunk_has_css(chunk_ukey, compilation) {
initial_chunk_ids_with_css.insert(chunk.expect_id().to_string());
} else {
initial_chunk_ids_without_css.insert(chunk.expect_id().to_string());
}
}

// `initial_chunk_ids_without_css` is render to `installedChunks`
// `initial_chunk_ids_with_css` is render to `loadCssChunkData`, it will be add to `installedChunks`
// so here direct use `initial_chunk_ids`
let initial_chunk_ids = initial_chunks
.iter()
.map(|chunk_ukey| {
let chunk = compilation
.chunk_by_ukey
.get(chunk_ukey)
.expect("Chunk not found");
chunk.expect_id().to_string()
})
.collect::<HashSet<_>>();
// let mut initial_chunk_ids_with_css = HashSet::default();
// let mut initial_chunk_ids_without_css = HashSet::default();
// for chunk_ukey in initial_chunks.iter() {
// let chunk = compilation
// .chunk_by_ukey
// .get(chunk_ukey)
// .expect("Chunk not found");
// if chunk_has_css(chunk_ukey, compilation) {
// initial_chunk_ids_with_css.insert(chunk.expect_id().to_string());
// } else {
// initial_chunk_ids_without_css.insert(chunk.expect_id().to_string());
// }
// }

if !with_hmr && !with_loading && initial_chunk_ids.is_empty() {
if !with_hmr && !with_loading && initial_chunk_ids_with_css.is_empty() {
return RawSource::from("").boxed();
}

Expand All @@ -87,7 +73,7 @@ impl RuntimeModule for CssLoadingRuntimeModule {
// only render chunk without css. See packages/rspack/tests/runtimeCases/runtime/split-css-chunk test.
source.add(RawSource::from(format!(
"var installedChunks = {};\n",
&stringify_chunks(&initial_chunk_ids, 0)
&stringify_chunks(&initial_chunk_ids_without_css, 0)
)));

source.add(RawSource::from(
Expand All @@ -102,8 +88,14 @@ impl RuntimeModule for CssLoadingRuntimeModule {
compilation
.chunk_graph
.get_chunk_condition_map(&chunk_ukey, compilation, chunk_has_css);
let chunk_loading_global_expr = format!(
"{}['{}']",
&compilation.options.output.global_object,
&compilation.options.output.chunk_loading_global
);
source.add(RawSource::from(
include_str!("runtime/css_loading_with_loading.js")
.replace("$CHUNK_LOADING_GLOBAL_EXPR$", &chunk_loading_global_expr)
.replace("CSS_MATCHER", &render_condition_map(&condition_map)),
));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use rspack_core::{
use rspack_identifier::Identifier;
use rustc_hash::FxHashMap as HashMap;

use super::utils::{chunk_has_css, chunk_has_js};
use super::utils::chunk_has_css;
use crate::impl_runtime_module;

#[derive(Debug, Eq)]
Expand Down Expand Up @@ -79,17 +79,13 @@ impl RuntimeModule for GetChunkFilenameRuntimeModule {
for chunk_ukey in chunks.iter() {
if let Some(chunk) = compilation.chunk_by_ukey.get(chunk_ukey) {
let filename_template = match self.source_type {
SourceType::JavaScript => {
if chunk_has_js(chunk_ukey, compilation) {
Some(get_js_chunk_filename_template(
chunk,
&compilation.options.output,
&compilation.chunk_group_by_ukey,
))
} else {
None
}
}
// TODO webpack different
// css chunk will generate a js chunk, so here add it.
SourceType::JavaScript => Some(get_js_chunk_filename_template(
chunk,
&compilation.options.output,
&compilation.chunk_group_by_ukey,
)),
SourceType::Css => {
if chunk_has_css(chunk_ukey, compilation) {
Some(get_css_chunk_filename_template(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,18 @@ __webpack_require__.f.css = function (chunkId, promises) {
}
}
};
// TODO: diffrent with webpack
// webpack using `loadCssChunkData` and detect css variables to add install chunk.
// Because rspack the css chunk is always generate one js chunk, so here use js chunk to add install chunk.
var loadCssChunkCallback = function (parentChunkLoadingFunction, data) {
var chunkIds = data[0];
if (parentChunkLoadingFunction) parentChunkLoadingFunction(data);
for (var i = 0; i < chunkIds.length; i++) {
installedChunks[chunkIds[i]] = 0;
}
};
var chunkLoadingGlobal = $CHUNK_LOADING_GLOBAL_EXPR$ = $CHUNK_LOADING_GLOBAL_EXPR$ || [];
chunkLoadingGlobal.push = loadCssChunkCallback.bind(
null,
chunkLoadingGlobal.push.bind(chunkLoadingGlobal)
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#dynamic {
background: red;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import "./common.css";
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
it("should load css chunk", function (done) {
import("./share").then(module => {
expect(module.value).toBe(1);
// test is only for css loading
if (__webpack_require__.f.css) {
expect(document.getElementsByTagName("link").length).toBe(2);
}
done();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import "./common";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import "./share";
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import "./share.css";
import "./common.css";

export const value = 1;
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
module.exports = {
entry: {
main: './index1.js',
main2: './index2.js',
main3: './index3.js'
},
output: {
chunkFilename: '[id].[contenthash].js'
},
optimization: {
splitChunks: {
cacheGroups: {
common: {
chunks: 'all',
test: /common/,
enforce: true,
name: 'common'
},
share: {
chunks: 'all',
test: /share/,
enforce: true,
name: 'share'
}
}
},
runtimeChunk: 'single'
}
}
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
import "./common.css";

export const value = 1;
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
it("should load css chunk", function (done) {
import("./common").then(module => {
expect(module.value).toBe(1);
// test is only for css loading
if (__webpack_require__.f.css) {
expect(document.getElementsByTagName("link").length).toBe(1);
}
done();
});
});

import "./common.css";

// ./common.css is initial chunks and also be async chunks.
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
import "./common";

import("./other.css");

0 comments on commit ad727a9

Please sign in to comment.