您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

identifier.js 2.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. "use strict";
  2. const path = require("path");
  3. /**
  4. * @typedef {Object} MakeRelativePathsCache
  5. * @property {Map<string, Map<string, string>>=} relativePaths
  6. */
  7. /**
  8. *
  9. * @param {string} maybeAbsolutePath path to check
  10. * @returns {boolean} returns true if path is "Absolute Path"-like
  11. */
  12. const looksLikeAbsolutePath = maybeAbsolutePath => {
  13. if (/^\/.*\/$/.test(maybeAbsolutePath)) {
  14. // this 'path' is actually a regexp generated by dynamic requires.
  15. // Don't treat it as an absolute path.
  16. return false;
  17. }
  18. return /^(?:[a-z]:\\|\/)/i.test(maybeAbsolutePath);
  19. };
  20. /**
  21. *
  22. * @param {string} p path to normalize
  23. * @returns {string} normalized version of path
  24. */
  25. const normalizePathSeparator = p => p.replace(/\\/g, "/");
  26. /**
  27. *
  28. * @param {string} context context for relative path
  29. * @param {string} identifier identifier for path
  30. * @returns {string} a converted relative path
  31. */
  32. const _makePathsRelative = (context, identifier) => {
  33. return identifier
  34. .split(/([|! ])/)
  35. .map(str =>
  36. looksLikeAbsolutePath(str)
  37. ? normalizePathSeparator(path.relative(context, str))
  38. : str
  39. )
  40. .join("");
  41. };
  42. /**
  43. *
  44. * @param {string} context context used to create relative path
  45. * @param {string} identifier identifier used to create relative path
  46. * @param {MakeRelativePathsCache=} cache the cache object being set
  47. * @returns {string} the returned relative path
  48. */
  49. exports.makePathsRelative = (context, identifier, cache) => {
  50. if (!cache) return _makePathsRelative(context, identifier);
  51. const relativePaths =
  52. cache.relativePaths || (cache.relativePaths = new Map());
  53. let cachedResult;
  54. let contextCache = relativePaths.get(context);
  55. if (contextCache === undefined) {
  56. relativePaths.set(context, (contextCache = new Map()));
  57. } else {
  58. cachedResult = contextCache.get(identifier);
  59. }
  60. if (cachedResult !== undefined) {
  61. return cachedResult;
  62. } else {
  63. const relativePath = _makePathsRelative(context, identifier);
  64. contextCache.set(identifier, relativePath);
  65. return relativePath;
  66. }
  67. };
  68. /**
  69. * @param {string} context absolute context path
  70. * @param {string} request any request string may containing absolute paths, query string, etc.
  71. * @returns {string} a new request string avoiding absolute paths when possible
  72. */
  73. exports.contextify = (context, request) => {
  74. return request
  75. .split("!")
  76. .map(r => {
  77. const splitPath = r.split("?", 2);
  78. if (/^[a-zA-Z]:\\/.test(splitPath[0])) {
  79. splitPath[0] = path.win32.relative(context, splitPath[0]);
  80. if (!/^[a-zA-Z]:\\/.test(splitPath[0])) {
  81. splitPath[0] = splitPath[0].replace(/\\/g, "/");
  82. }
  83. }
  84. if (/^\//.test(splitPath[0])) {
  85. splitPath[0] = path.posix.relative(context, splitPath[0]);
  86. }
  87. if (!/^(\.\.\/|\/|[a-zA-Z]:\\)/.test(splitPath[0])) {
  88. splitPath[0] = "./" + splitPath[0];
  89. }
  90. return splitPath.join("?");
  91. })
  92. .join("!");
  93. };