baseUri.js 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Alexander Akait @alexander-akait
  4. */
  5. "use strict";
  6. const RuntimeGlobals = require("../RuntimeGlobals");
  7. const SCHEME_REGEXP = /^[a-z][a-z\d+\-.]*:/i;
  8. /**
  9. * Whether `new URL(path, baseUri)` can resolve against it. Parsing is not the question:
  10. * an opaque scheme like `data:` or `mailto:` is a valid url and still no base for
  11. * anything, so the resolution itself is what gets asked.
  12. * @param {string} baseUri an entry's base uri
  13. * @returns {boolean} true when a relative path resolves against it
  14. */
  15. const isAbsoluteBaseUri = (baseUri) => {
  16. try {
  17. // eslint-disable-next-line no-new
  18. new URL("./", baseUri);
  19. return true;
  20. } catch (_error) {
  21. return false;
  22. }
  23. };
  24. /**
  25. * Whether a base names a place relative to the chunk, so a literal can spell it. A
  26. * scheme makes it a base of its own, and a protocol-relative one takes its scheme from
  27. * wherever the chunk was loaded — neither is something a literal can state.
  28. * @param {string} baseUri an entry's base uri
  29. * @returns {boolean} true when it can be baked beside the chunk
  30. */
  31. const isChunkRelativeBaseUri = (baseUri) =>
  32. !SCHEME_REGEXP.test(baseUri) && !baseUri.startsWith("//");
  33. /**
  34. * Assignment of `__webpack_require__.b` for a chunk. An entry `baseUri` replaces the
  35. * base an asset url resolves against, but only an absolute one is a base by itself —
  36. * a relative one is read against the base this target would use without it, so it
  37. * lands beside the chunk rather than throwing wherever the runtime reads it.
  38. * @param {string | undefined} baseUri the entry's base uri, if it set one
  39. * @param {string} fallback expression for the base this target uses without one
  40. * @returns {string} the assignment, ending with `;`
  41. */
  42. const renderBaseUri = (baseUri, fallback) => {
  43. // An empty one names no base of its own, so it leaves the target's alone.
  44. if (!baseUri) return `${RuntimeGlobals.baseURI} = ${fallback};`;
  45. // A scheme already makes it a base of its own. Whether anything resolves against an
  46. // opaque one is the user's to answer, as it was before.
  47. if (SCHEME_REGEXP.test(baseUri)) {
  48. return `${RuntimeGlobals.baseURI} = ${JSON.stringify(baseUri)};`;
  49. }
  50. return `${RuntimeGlobals.baseURI} = new URL(${JSON.stringify(
  51. baseUri
  52. )}, ${fallback}).href;`;
  53. };
  54. module.exports.isAbsoluteBaseUri = isAbsoluteBaseUri;
  55. module.exports.isChunkRelativeBaseUri = isChunkRelativeBaseUri;
  56. module.exports.renderBaseUri = renderBaseUri;