MCPcopy
hub / github.com/webpack/webpack / _renderHmrShim

Method _renderHmrShim

lib/html/HtmlGenerator.js:498–576  ·  view source on GitHub ↗

* Emits the JS shim with HMR self-acceptance. When `extracting` is true the * HTML module is also the document the browser is viewing, so the shim * additionally patches `document.body` and `document.title` on every hot * update so the rendered page reflects the new HTML without a full * rel

(module, html, extracting, runtimeTemplate)

Source from the content-addressed store, hash-verified

496 * @returns {string} JS shim source
497 */
498 _renderHmrShim(module, html, extracting, runtimeTemplate) {
499 const declare = runtimeTemplate.renderConst();
500 const acceptBlock = extracting
501 ? [
502 "module.hot.accept();",
503 // Mask `<!-- … -->` comments — replace their characters
504 // with spaces, preserving length — before any tag regex
505 // runs. Masking (rather than deleting) keeps string offsets
506 // stable, so the body/title content can be sliced back out
507 // of the original HTML with comments intact, while a
508 // `<body>`/`</body>`/`<title>` inside a comment can no
509 // longer fool the tag regexes (the non-greedy `*?` would
510 // otherwise stop at the FIRST `</body>` it sees, even one
511 // inside a comment).
512 `${declare} __webpack_mask_comments__ = ${runtimeTemplate.returningFunction(
513 `h.replace(/<!--[\\s\\S]*?-->/g, ${runtimeTemplate.returningFunction(
514 'c.replace(/[^\\n]/g, " ")',
515 "c"
516 )})`,
517 "h"
518 )};`,
519 // Mask comments once per evaluation; reused for every
520 // tag-boundary search (head/body/title and the dispose-time
521 // head diff) so a large page isn't re-scanned per section.
522 `${declare} __webpack_masked_html__ = __webpack_mask_comments__(__webpack_html__);`,
523 // Slice the inner content of `<tag>…</tag>` out of the original
524 // HTML, using the pre-masked copy to locate the tag boundaries.
525 `${declare} __webpack_extract__ = ${runtimeTemplate.basicFunction(
526 "tag",
527 [
528 `${declare} open = new RegExp("<" + tag + "[^>]*>", "i").exec(__webpack_masked_html__);`,
529 "if (!open) return null;",
530 `${declare} start = open.index + open[0].length;`,
531 `${declare} close = new RegExp("</" + tag + ">", "i").exec(__webpack_masked_html__.slice(start));`,
532 "if (!close) return null;",
533 "return __webpack_html__.slice(start, start + close.index);"
534 ]
535 )};`,
536 `${declare} __webpack_extract_head__ = ${runtimeTemplate.basicFunction(
537 "",
538 [
539 // Mask only the small extracted head so a comment-only head
540 // edit doesn't force a full reload.
541 `${declare} head = __webpack_extract__("head");`,
542 'return head === null ? "" : __webpack_mask_comments__(head).replace(/<title[^>]*>[\\s\\S]*?<\\/title>/i, "").trim();'
543 ]
544 )};`,
545 "if (module.hot.data && typeof document !== 'undefined') {",
546 Template.indent([
547 `${declare} __webpack_new_head__ = __webpack_extract_head__();`,
548 "if (module.hot.data.__webpack_head__ !== undefined && __webpack_new_head__ !== module.hot.data.__webpack_head__ && typeof window !== 'undefined' && window.location && typeof window.location.reload === 'function') {",
549 Template.indent("window.location.reload();"),
550 "} else {",
551 Template.indent([
552 `${declare} __webpack_body__ = __webpack_extract__("body");`,
553 "if (__webpack_body__ !== null && document.body) document.body.innerHTML = __webpack_body__;",
554 `${declare} __webpack_title__ = __webpack_extract__("title");`,
555 "if (__webpack_title__ !== null) document.title = __webpack_title__;"

Callers 1

generateMethod · 0.95

Calls 5

renderConstMethod · 0.80
returningFunctionMethod · 0.80
basicFunctionMethod · 0.80
indentMethod · 0.80
asStringMethod · 0.45

Tested by

no test coverage detected