templateTransformAssetUrl.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. "use strict";
  2. var __importDefault = (this && this.__importDefault) || function (mod) {
  3. return (mod && mod.__esModule) ? mod : { "default": mod };
  4. };
  5. Object.defineProperty(exports, "__esModule", { value: true });
  6. exports.transformAssetUrl = exports.createAssetUrlTransformWithOptions = exports.normalizeOptions = exports.defaultAssetUrlOptions = void 0;
  7. const path_1 = __importDefault(require("path"));
  8. const compiler_core_1 = require("@vue/compiler-core");
  9. const templateUtils_1 = require("./templateUtils");
  10. const shared_1 = require("@vue/shared");
  11. exports.defaultAssetUrlOptions = {
  12. base: null,
  13. includeAbsolute: false,
  14. tags: {
  15. video: ['src', 'poster'],
  16. source: ['src'],
  17. img: ['src'],
  18. image: ['xlink:href', 'href'],
  19. use: ['xlink:href', 'href'],
  20. },
  21. };
  22. const normalizeOptions = (options) => {
  23. if (Object.keys(options).some((key) => (0, shared_1.isArray)(options[key]))) {
  24. // legacy option format which directly passes in tags config
  25. return {
  26. ...exports.defaultAssetUrlOptions,
  27. tags: options,
  28. };
  29. }
  30. return {
  31. ...exports.defaultAssetUrlOptions,
  32. ...options,
  33. };
  34. };
  35. exports.normalizeOptions = normalizeOptions;
  36. const createAssetUrlTransformWithOptions = (options) => {
  37. return (node, context) => exports.transformAssetUrl(node, context, options);
  38. };
  39. exports.createAssetUrlTransformWithOptions = createAssetUrlTransformWithOptions;
  40. /**
  41. * A `@vue/compiler-core` plugin that transforms relative asset urls into
  42. * either imports or absolute urls.
  43. *
  44. * ``` js
  45. * // Before
  46. * createVNode('img', { src: './logo.png' })
  47. *
  48. * // After
  49. * import _imports_0 from './logo.png'
  50. * createVNode('img', { src: _imports_0 })
  51. * ```
  52. */
  53. const transformAssetUrl = (node, context, options = exports.defaultAssetUrlOptions) => {
  54. if (node.type === 1 /* NodeTypes.ELEMENT */) {
  55. if (!node.props.length) {
  56. return;
  57. }
  58. const tags = options.tags || exports.defaultAssetUrlOptions.tags;
  59. const attrs = tags[node.tag];
  60. const wildCardAttrs = tags['*'];
  61. if (!attrs && !wildCardAttrs) {
  62. return;
  63. }
  64. // 策略:
  65. // h5 平台保留原始策略
  66. // 非 h5 平台
  67. // - 绝对路径 static 资源不做转换
  68. // - 相对路径 static 资源转换为绝对路径
  69. // - 非 static 资源转换为 import
  70. const assetAttrs = (attrs || []).concat(wildCardAttrs || []);
  71. node.props.forEach((attr, index) => {
  72. if (attr.type !== 6 /* NodeTypes.ATTRIBUTE */ ||
  73. !assetAttrs.includes(attr.name) ||
  74. !attr.value ||
  75. (0, templateUtils_1.isExternalUrl)(attr.value.content) ||
  76. (0, templateUtils_1.isDataUrl)(attr.value.content) ||
  77. attr.value.content[0] === '#') {
  78. return;
  79. }
  80. // fixed by xxxxxx 区分 static 资源
  81. const isStaticAsset = attr.value.content.indexOf('/static/') > -1;
  82. // 绝对路径的静态资源不作处理
  83. if (isStaticAsset && !(0, templateUtils_1.isRelativeUrl)(attr.value.content)) {
  84. return;
  85. }
  86. const url = (0, templateUtils_1.parseUrl)(attr.value.content);
  87. if (options.base && attr.value.content[0] === '.' && isStaticAsset) {
  88. // explicit base - directly rewrite relative urls into absolute url
  89. // to avoid generating extra imports
  90. // Allow for full hostnames provided in options.base
  91. const base = (0, templateUtils_1.parseUrl)(options.base);
  92. const protocol = base.protocol || '';
  93. const host = base.host ? protocol + '//' + base.host : '';
  94. const basePath = base.path || '/';
  95. // when packaged in the browser, path will be using the posix-
  96. // only version provided by rollup-plugin-node-builtins.
  97. attr.value.content =
  98. host +
  99. (path_1.default.posix || path_1.default).join(basePath, url.path + (url.hash || ''));
  100. return;
  101. }
  102. // otherwise, transform the url into an import.
  103. // this assumes a bundler will resolve the import into the correct
  104. // absolute url (e.g. webpack file-loader)
  105. const exp = getImportsExpressionExp(url.path, url.hash, attr.loc, context);
  106. node.props[index] = {
  107. type: 7 /* NodeTypes.DIRECTIVE */,
  108. name: 'bind',
  109. arg: (0, compiler_core_1.createSimpleExpression)(attr.name, true, attr.loc),
  110. exp,
  111. modifiers: [],
  112. loc: attr.loc,
  113. };
  114. });
  115. }
  116. };
  117. exports.transformAssetUrl = transformAssetUrl;
  118. function getImportsExpressionExp(path, hash, loc, context) {
  119. if (path) {
  120. let name;
  121. let exp;
  122. const existingIndex = context.imports.findIndex((i) => i.path === path);
  123. if (existingIndex > -1) {
  124. name = `_imports_${existingIndex}`;
  125. exp = context.imports[existingIndex].exp;
  126. }
  127. else {
  128. name = `_imports_${context.imports.length}`;
  129. exp = (0, compiler_core_1.createSimpleExpression)(name, false, loc, 2 /* ConstantTypes.CAN_HOIST */);
  130. context.imports.push({ exp, path });
  131. }
  132. if (!hash) {
  133. return exp;
  134. }
  135. const hashExp = `${name} + '${hash}'`;
  136. const existingHoistIndex = context.hoists.findIndex((h) => {
  137. return (h &&
  138. h.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ &&
  139. !h.isStatic &&
  140. h.content === hashExp);
  141. });
  142. if (existingHoistIndex > -1) {
  143. return (0, compiler_core_1.createSimpleExpression)(`_hoisted_${existingHoistIndex + 1}`, false, loc, 2 /* ConstantTypes.CAN_HOIST */);
  144. }
  145. return context.hoist((0, compiler_core_1.createSimpleExpression)(hashExp, false, loc, 2 /* ConstantTypes.CAN_HOIST */));
  146. }
  147. else {
  148. return (0, compiler_core_1.createSimpleExpression)(`''`, false, loc, 2 /* ConstantTypes.CAN_HOIST */);
  149. }
  150. }