publicPathPlaceholder.js 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. */
  4. "use strict";
  5. // Placeholders embedded into asset `url()` / HTML chunk URLs at code-generation
  6. // time, when the final public path can't be resolved yet, then substituted
  7. // later once the information is available:
  8. // - PUBLIC_PATH_AUTO — stands in for `output.publicPath: "auto"`; replaced
  9. // with the per-output-file undo path (relative `../` segments back to the
  10. // output root) during chunk/asset render.
  11. // - PUBLIC_PATH_FULL_HASH — stands in for `[fullhash]`/`[hash]` in a public
  12. // path before the compilation hash exists. Form: `<prefix><len>__`, where
  13. // `<len>` is the requested hash length (`0` means the full hash). Replaced
  14. // with the real hash (build-time, e.g. CSS `.css` files) or a runtime
  15. // `__webpack_require__.h()` expression (inlined CSS in JS).
  16. const PUBLIC_PATH_AUTO = "__WEBPACK_CSS_PUBLIC_PATH_AUTO__";
  17. const PUBLIC_PATH_FULL_HASH = "__WEBPACK_CSS_PUBLIC_PATH_FULL_HASH_";
  18. /**
  19. * Scan `content` for `PUBLIC_PATH_FULL_HASH` placeholders and invoke `onMatch`
  20. * once per well-formed occurrence. The placeholder spans the half-open range
  21. * `[start, end)` and encodes the requested hash length (`0` means the full
  22. * hash). Callers substitute the build-time hash or a runtime expression
  23. * depending on context.
  24. * @param {string} content text to scan
  25. * @param {(start: number, end: number, length: number) => void} onMatch placeholder callback
  26. * @returns {void}
  27. */
  28. const walkFullHashPlaceholders = (content, onMatch) => {
  29. const prefix = PUBLIC_PATH_FULL_HASH;
  30. const prefixLen = prefix.length;
  31. const len = content.length;
  32. let idx = content.indexOf(prefix);
  33. while (idx !== -1) {
  34. let digitEnd = idx + prefixLen;
  35. while (digitEnd < len) {
  36. const cc = content.charCodeAt(digitEnd);
  37. if (cc < 48 || cc > 57) break;
  38. digitEnd++;
  39. }
  40. // Well-formed placeholder: at least one digit followed by `__`.
  41. if (
  42. digitEnd > idx + prefixLen &&
  43. digitEnd + 1 < len &&
  44. content.charCodeAt(digitEnd) === 95 &&
  45. content.charCodeAt(digitEnd + 1) === 95
  46. ) {
  47. const length = Number.parseInt(
  48. content.slice(idx + prefixLen, digitEnd),
  49. 10
  50. );
  51. onMatch(idx, digitEnd + 2, length);
  52. idx = content.indexOf(prefix, digitEnd + 2);
  53. } else {
  54. idx = content.indexOf(prefix, idx + prefixLen);
  55. }
  56. }
  57. };
  58. module.exports.PUBLIC_PATH_AUTO = PUBLIC_PATH_AUTO;
  59. module.exports.PUBLIC_PATH_FULL_HASH = PUBLIC_PATH_FULL_HASH;
  60. module.exports.walkFullHashPlaceholders = walkFullHashPlaceholders;