Skip to content

Commit 0a643d6

Browse files
committed
fix: port webpack#19434
1 parent 5f6c5e5 commit 0a643d6

File tree

12 files changed

+301
-8
lines changed

12 files changed

+301
-8
lines changed

crates/rspack_plugin_runtime/src/module_chunk_loading.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rspack_core::{
22
ChunkLoading, ChunkLoadingType, ChunkUkey, Compilation, CompilationRuntimeRequirementInTree,
3-
Plugin, PluginContext, RuntimeGlobals, RuntimeModuleExt,
3+
Plugin, PluginContext, PublicPath, RuntimeGlobals, RuntimeModuleExt,
44
};
55
use rspack_error::Result;
66
use rspack_hook::{plugin, plugin_hook};
@@ -30,6 +30,11 @@ async fn runtime_requirements_in_tree(
3030
match runtime_requirement {
3131
RuntimeGlobals::ENSURE_CHUNK_HANDLERS if is_enabled_for_chunk => {
3232
has_chunk_loading = true;
33+
34+
if !matches!(compilation.options.output.public_path, PublicPath::Auto) {
35+
runtime_requirements_mut.insert(RuntimeGlobals::PUBLIC_PATH);
36+
}
37+
3338
runtime_requirements_mut.insert(RuntimeGlobals::GET_CHUNK_SCRIPT_FILENAME);
3439
}
3540
RuntimeGlobals::EXTERNAL_INSTALL_CHUNK if is_enabled_for_chunk => {
@@ -40,6 +45,11 @@ async fn runtime_requirements_in_tree(
4045
RuntimeGlobals::ON_CHUNKS_LOADED | RuntimeGlobals::BASE_URI if is_enabled_for_chunk => {
4146
has_chunk_loading = true;
4247
}
48+
RuntimeGlobals::PREFETCH_CHUNK_HANDLERS | RuntimeGlobals::PRELOAD_CHUNK_HANDLERS => {
49+
if is_enabled_for_chunk {
50+
runtime_requirements_mut.insert(RuntimeGlobals::PUBLIC_PATH);
51+
}
52+
}
4353
_ => {}
4454
}
4555
}

crates/rspack_plugin_runtime/src/runtime_module/module_chunk_loading.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use rspack_collections::{DatabaseItem, Identifier};
22
use rspack_core::{
33
compile_boolean_matcher, impl_runtime_module, BooleanMatcher, Chunk, ChunkUkey, Compilation,
4-
RuntimeGlobals, RuntimeModule, RuntimeModuleStage,
4+
PublicPath, RuntimeGlobals, RuntimeModule, RuntimeModuleStage,
55
};
66

77
use super::utils::{chunk_has_js, get_output_dir};
@@ -142,12 +142,17 @@ impl RuntimeModule for ModuleChunkLoadingRuntimeModule {
142142
let body = if matches!(has_js_matcher, BooleanMatcher::Condition(false)) {
143143
"installedChunks[chunkId] = 0;".to_string()
144144
} else {
145+
let output_dir = if matches!(compilation.options.output.public_path, PublicPath::Auto) {
146+
serde_json::to_string(&root_output_dir).expect("should able to serde_json::to_string")
147+
} else {
148+
RuntimeGlobals::PUBLIC_PATH.to_string()
149+
};
145150
compilation.runtime_template.render(
146151
&self.template(TemplateId::WithLoading),
147152
Some(serde_json::json!({
148153
"_js_matcher": &has_js_matcher.render("chunkId"),
149154
"_import_function_name":&compilation.options.output.import_function_name,
150-
"_output_dir": &root_output_dir,
155+
"_output_dir": &output_dir,
151156
"_match_fallback": if matches!(has_js_matcher, BooleanMatcher::Condition(true)) {
152157
""
153158
} else {

crates/rspack_plugin_runtime/src/runtime_module/runtime/module_chunk_loading_with_loading.ejs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ if (installedChunkData !== 0) { // 0 means "already installed".'
77
} else {
88
if (<%- _js_matcher %>) {
99
// setup Promise in chunk cache
10-
var promise = <%- _import_function_name %>("<%- _output_dir %>" + <%- GET_CHUNK_SCRIPT_FILENAME %>(chunkId)).then(installChunk, <%- basicFunction("e") %> {
10+
var promise = <%- _import_function_name %>(<%- _output_dir %> + <%- GET_CHUNK_SCRIPT_FILENAME %>(chunkId)).then(installChunk, <%- basicFunction("e") %> {
1111
if (installedChunks[chunkId] !== 0) installedChunks[chunkId] = undefined;
1212
throw e;
1313
});

packages/rspack-test-tools/tests/runtimeDiffCases/chunk-loading/module-chunk-loading#with-hmr/__snapshot__/bundle.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
"webpack/runtime/hasOwnProperty shorthand": "!function () {\n __webpack_require__.o = function (obj, prop) {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n };\n}();",
88
"webpack/runtime/make namespace object": "!function () {\n __webpack_require__.r = function (exports) {\n if (typeof Symbol !== \"undefined\" && Symbol.toStringTag) Object.defineProperty(exports, Symbol.toStringTag, {\n \"value\": \"Module\"\n });\n Object.defineProperty(exports, \"__esModule\", {\n \"value\": true\n });\n };\n}();",
99
"webpack/runtime/hot module replacement": "!function () {\n var currentModuleData = {};\n var installedModules = __webpack_require__.c;\n var currentChildModule;\n var currentParents = [];\n var registeredStatusHandlers = [];\n var currentStatus = \"idle\";\n var blockingPromises = 0;\n var blockingPromisesWaiting = [];\n var currentUpdateApplyHandlers;\n var queuedInvalidatedModules;\n __webpack_require__.hmrD = currentModuleData;\n __webpack_require__.i.push(function (options) {\n var module = options.module;\n var require = createRequire(options.require, options.id);\n module.hot = createModuleHotObject(options.id, module);\n module.parents = currentParents;\n module.children = [];\n currentParents = [];\n options.require = require;\n });\n __webpack_require__.hmrC = {};\n __webpack_require__.hmrI = {};\n function createRequire(require, moduleId) {\n var me = installedModules[moduleId];\n if (!me) return require;\n var fn = function (request) {\n if (me.hot.active) {\n if (installedModules[request]) {\n var parents = installedModules[request].parents;\n if (parents.indexOf(moduleId) === -1) parents.push(moduleId);\n } else {\n currentParents = [moduleId];\n currentChildModule = request;\n }\n if (me.children.indexOf(request) === -1) me.children.push(request);\n } else {\n console.warn(\"[HMR] unexpected require(\" + request + \") from disposed module \" + moduleId);\n currentParents = [];\n }\n return require(request);\n };\n var createPropertyDescriptor = function (name) {\n return {\n \"configurable\": true,\n \"enumerable\": true,\n \"get\": function () {\n return require[name];\n },\n \"set\": function (value) {\n require[name] = value;\n }\n };\n };\n for (var name in require) if (Object.prototype.hasOwnProperty.call(require, name) && name !== \"e\") Object.defineProperty(fn, name, createPropertyDescriptor(name));\n fn.e = function (chunkId, fetchPriority) {\n return trackBlockingPromise(require.e(chunkId, fetchPriority));\n };\n return fn;\n }\n function createModuleHotObject(moduleId, me) {\n var _main = currentChildModule !== moduleId;\n var hot = {\n \"_acceptedDependencies\": {},\n \"_acceptedErrorHandlers\": {},\n \"_declinedDependencies\": {},\n \"_disposeHandlers\": [],\n \"_main\": _main,\n \"_requireSelf\": function () {\n currentParents = me.parents.slice();\n currentChildModule = _main ? undefined : moduleId;\n __webpack_require__(moduleId);\n },\n \"_selfAccepted\": false,\n \"_selfDeclined\": false,\n \"_selfInvalidated\": false,\n \"accept\": function (dep, callback, errorHandler) {\n if (dep === undefined) hot._selfAccepted = true;else if (typeof dep === \"function\") hot._selfAccepted = dep;else if (typeof dep === \"object\" && dep !== null) for (var i = 0; i < dep.length; i++) {\n hot._acceptedDependencies[dep[i]] = callback || function () {};\n hot._acceptedErrorHandlers[dep[i]] = errorHandler;\n } else {\n hot._acceptedDependencies[dep] = callback || function () {};\n hot._acceptedErrorHandlers[dep] = errorHandler;\n }\n },\n \"active\": true,\n \"addDisposeHandler\": function (callback) {\n hot._disposeHandlers.push(callback);\n },\n \"addStatusHandler\": function (l) {\n registeredStatusHandlers.push(l);\n },\n \"apply\": hotApply,\n \"check\": hotCheck,\n \"data\": currentModuleData[moduleId],\n \"decline\": function (dep) {\n if (dep === undefined) hot._selfDeclined = true;else if (typeof dep === \"object\" && dep !== null) for (var i = 0; i < dep.length; i++) hot._declinedDependencies[dep[i]] = true;else hot._declinedDependencies[dep] = true;\n },\n \"dispose\": function (callback) {\n hot._disposeHandlers.push(callback);\n },\n \"invalidate\": function () {\n this._selfInvalidated = true;\n switch (currentStatus) {\n case \"idle\":\n currentUpdateApplyHandlers = [];\n Object.keys(__webpack_require__.hmrI).forEach(function (key) {\n __webpack_require__.hmrI[key](moduleId, currentUpdateApplyHandlers);\n });\n setStatus(\"ready\");\n break;\n case \"ready\":\n Object.keys(__webpack_require__.hmrI).forEach(function (key) {\n __webpack_require__.hmrI[key](moduleId, currentUpdateApplyHandlers);\n });\n break;\n case \"prepare\":\n case \"check\":\n case \"dispose\":\n case \"apply\":\n (queuedInvalidatedModules = queuedInvalidatedModules || []).push(moduleId);\n break;\n default:\n break;\n }\n },\n \"removeDisposeHandler\": function (callback) {\n var idx = hot._disposeHandlers.indexOf(callback);\n if (idx >= 0) hot._disposeHandlers.splice(idx, 1);\n },\n \"removeStatusHandler\": function (l) {\n var idx = registeredStatusHandlers.indexOf(l);\n if (idx >= 0) registeredStatusHandlers.splice(idx, 1);\n },\n \"status\": function (l) {\n if (!l) return currentStatus;\n registeredStatusHandlers.push(l);\n }\n };\n currentChildModule = undefined;\n return hot;\n }\n function setStatus(newStatus) {\n currentStatus = newStatus;\n var results = [];\n for (var i = 0; i < registeredStatusHandlers.length; i++) results[i] = registeredStatusHandlers[i].call(null, newStatus);\n return Promise.all(results).then(function () {});\n }\n function unblock() {\n if (--blockingPromises === 0) setStatus(\"ready\").then(function () {\n if (blockingPromises === 0) {\n var list = blockingPromisesWaiting;\n blockingPromisesWaiting = [];\n for (var i = 0; i < list.length; i++) list[i]();\n }\n });\n }\n function trackBlockingPromise(promise) {\n switch (currentStatus) {\n case \"ready\":\n setStatus(\"prepare\");\n case \"prepare\":\n blockingPromises++;\n promise.then(unblock, unblock);\n return promise;\n default:\n return promise;\n }\n }\n function waitForBlockingPromises(fn) {\n if (blockingPromises === 0) return fn();\n return new Promise(function (resolve) {\n blockingPromisesWaiting.push(function () {\n resolve(fn());\n });\n });\n }\n function hotCheck(applyOnUpdate) {\n if (currentStatus !== \"idle\") throw new Error(\"check() is only allowed in idle status\");\n return setStatus(\"check\").then(__webpack_require__.hmrM).then(function (update) {\n if (!update) return setStatus(applyInvalidatedModules() ? \"ready\" : \"idle\").then(function () {\n return null;\n });\n return setStatus(\"prepare\").then(function () {\n var updatedModules = [];\n currentUpdateApplyHandlers = [];\n return Promise.all(Object.keys(__webpack_require__.hmrC).reduce(function (promises, key) {\n __webpack_require__.hmrC[key](update.c, update.r, update.m, promises, currentUpdateApplyHandlers, updatedModules);\n return promises;\n }, [])).then(function () {\n return waitForBlockingPromises(function () {\n if (applyOnUpdate) return internalApply(applyOnUpdate);\n return setStatus(\"ready\").then(function () {\n return updatedModules;\n });\n });\n });\n });\n });\n }\n function hotApply(options) {\n if (currentStatus !== \"ready\") return Promise.resolve().then(function () {\n throw new Error(\"apply() is only allowed in ready status (state: \" + currentStatus + \")\");\n });\n return internalApply(options);\n }\n function internalApply(options) {\n options = options || {};\n applyInvalidatedModules();\n var results = currentUpdateApplyHandlers.map(function (handler) {\n return handler(options);\n });\n currentUpdateApplyHandlers = undefined;\n var errors = results.map(function (r) {\n return r.error;\n }).filter(Boolean);\n if (errors.length > 0) return setStatus(\"abort\").then(function () {\n throw errors[0];\n });\n var disposePromise = setStatus(\"dispose\");\n results.forEach(function (result) {\n if (result.dispose) result.dispose();\n });\n var applyPromise = setStatus(\"apply\");\n var error;\n var reportError = function (err) {\n if (!error) error = err;\n };\n var outdatedModules = [];\n results.forEach(function (result) {\n if (result.apply) {\n var modules = result.apply(reportError);\n if (modules) for (var i = 0; i < modules.length; i++) outdatedModules.push(modules[i]);\n }\n });\n return Promise.all([disposePromise, applyPromise]).then(function () {\n if (error) return setStatus(\"fail\").then(function () {\n throw error;\n });\n if (queuedInvalidatedModules) return internalApply(options).then(function (list) {\n outdatedModules.forEach(function (moduleId) {\n if (list.indexOf(moduleId) < 0) list.push(moduleId);\n });\n return list;\n });\n return setStatus(\"idle\").then(function () {\n return outdatedModules;\n });\n });\n }\n function applyInvalidatedModules() {\n if (queuedInvalidatedModules) {\n if (!currentUpdateApplyHandlers) currentUpdateApplyHandlers = [];\n Object.keys(__webpack_require__.hmrI).forEach(function (key) {\n queuedInvalidatedModules.forEach(function (moduleId) {\n __webpack_require__.hmrI[key](moduleId, currentUpdateApplyHandlers);\n });\n });\n queuedInvalidatedModules = undefined;\n return true;\n }\n }\n}();",
10+
"webpack/runtime/publicPath": "!function () {\n __webpack_require__.p = \"\";\n}();",
1011
"webpack/runtime/export webpack runtime": "export default __webpack_require__;",
11-
"webpack/runtime/import chunk loading": "!function () {\n var installedChunks = __webpack_require__.hmrS_module = __webpack_require__.hmrS_module || {\n \"bundle\": 0\n };\n var installChunk = function (data) {\n var __webpack_ids__ = data.__webpack_ids__;\n var __webpack_modules__ = data.__webpack_modules__;\n var __webpack_runtime__ = data.__webpack_runtime__;\n var moduleId,\n chunkId,\n i = 0;\n for (moduleId in __webpack_modules__) if (__webpack_require__.o(__webpack_modules__, moduleId)) __webpack_require__.m[moduleId] = __webpack_modules__[moduleId];\n if (__webpack_runtime__) __webpack_runtime__(__webpack_require__);\n for (; i < __webpack_ids__.length; i++) {\n chunkId = __webpack_ids__[i];\n if (__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) installedChunks[chunkId][0]();\n installedChunks[__webpack_ids__[i]] = 0;\n }\n };\n __webpack_require__.f.j = function (chunkId, promises) {\n var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;\n if (installedChunkData !== 0) if (installedChunkData) promises.push(installedChunkData[1]);else if (\"bundle\" != chunkId) {\n var promise = import(\"./\" + __webpack_require__.u(chunkId)).then(installChunk, function (e) {\n if (installedChunks[chunkId] !== 0) installedChunks[chunkId] = undefined;\n throw e;\n });\n var promise = Promise.race([promise, new Promise(function (resolve) {\n installedChunkData = installedChunks[chunkId] = [resolve];\n })]);\n promises.push(installedChunkData[1] = promise);\n } else installedChunks[chunkId] = 0;\n };\n __webpack_require__.C = installChunk;\n}();"
12+
"webpack/runtime/import chunk loading": "!function () {\n var installedChunks = __webpack_require__.hmrS_module = __webpack_require__.hmrS_module || {\n \"bundle\": 0\n };\n var installChunk = function (data) {\n var __webpack_ids__ = data.__webpack_ids__;\n var __webpack_modules__ = data.__webpack_modules__;\n var __webpack_runtime__ = data.__webpack_runtime__;\n var moduleId,\n chunkId,\n i = 0;\n for (moduleId in __webpack_modules__) if (__webpack_require__.o(__webpack_modules__, moduleId)) __webpack_require__.m[moduleId] = __webpack_modules__[moduleId];\n if (__webpack_runtime__) __webpack_runtime__(__webpack_require__);\n for (; i < __webpack_ids__.length; i++) {\n chunkId = __webpack_ids__[i];\n if (__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) installedChunks[chunkId][0]();\n installedChunks[__webpack_ids__[i]] = 0;\n }\n };\n __webpack_require__.f.j = function (chunkId, promises) {\n var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;\n if (installedChunkData !== 0) if (installedChunkData) promises.push(installedChunkData[1]);else if (\"bundle\" != chunkId) {\n var promise = import(__webpack_require__.p + \"./\" + __webpack_require__.u(chunkId)).then(installChunk, function (e) {\n if (installedChunks[chunkId] !== 0) installedChunks[chunkId] = undefined;\n throw e;\n });\n var promise = Promise.race([promise, new Promise(function (resolve) {\n installedChunkData = installedChunks[chunkId] = [resolve];\n })]);\n promises.push(installedChunkData[1] = promise);\n } else installedChunks[chunkId] = 0;\n };\n __webpack_require__.C = installChunk;\n}();"
1213
}
1314
}

0 commit comments

Comments
 (0)