buildPluginAsset.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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.createBuildAssetPlugin = exports.registerAssets = exports.resolveAsset = exports.injectAssetRe = void 0;
  7. const path_1 = __importDefault(require("path"));
  8. const fs_extra_1 = __importDefault(require("fs-extra"));
  9. const utils_1 = require("../utils");
  10. const slash_1 = __importDefault(require("slash"));
  11. const mime_types_1 = __importDefault(require("mime-types"));
  12. const debug = require('debug')('vite:build:asset');
  13. const assetResolveCache = new Map();
  14. const publicDirRE = /^public(\/|\\)/;
  15. exports.injectAssetRe = /import.meta.ROLLUP_FILE_URL_(\w+)/;
  16. exports.resolveAsset = async (id, root, publicBase, assetsDir, inlineLimit) => {
  17. id = utils_1.cleanUrl(id);
  18. const cached = assetResolveCache.get(id);
  19. if (cached) {
  20. return cached;
  21. }
  22. let resolved;
  23. const relativePath = path_1.default.relative(root, id);
  24. if (!fs_extra_1.default.existsSync(id)) {
  25. // try resolving from public dir
  26. const publicDirPath = path_1.default.join(root, 'public', relativePath);
  27. if (fs_extra_1.default.existsSync(publicDirPath)) {
  28. // file is resolved from public dir, it will be copied verbatim so no
  29. // need to read content here.
  30. resolved = {
  31. url: publicBase + slash_1.default(relativePath)
  32. };
  33. }
  34. }
  35. if (!resolved) {
  36. if (publicDirRE.test(relativePath)) {
  37. resolved = {
  38. url: publicBase + slash_1.default(relativePath.replace(publicDirRE, ''))
  39. };
  40. }
  41. }
  42. if (!resolved) {
  43. let url;
  44. let content = await fs_extra_1.default.readFile(id);
  45. if (!id.endsWith(`.svg`) && content.length < Number(inlineLimit)) {
  46. url = `data:${mime_types_1.default.lookup(id)};base64,${content.toString('base64')}`;
  47. content = undefined;
  48. }
  49. resolved = {
  50. content,
  51. fileName: path_1.default.basename(id),
  52. url
  53. };
  54. }
  55. assetResolveCache.set(id, resolved);
  56. return resolved;
  57. };
  58. exports.registerAssets = (assets, bundle) => {
  59. for (const [fileName, source] of assets) {
  60. bundle[fileName] = {
  61. name: fileName,
  62. isAsset: true,
  63. type: 'asset',
  64. fileName,
  65. source
  66. };
  67. }
  68. };
  69. exports.createBuildAssetPlugin = (root, resolver, publicBase, assetsDir, inlineLimit) => {
  70. const handleToIdMap = new Map();
  71. return {
  72. name: 'vite:asset',
  73. async load(id) {
  74. if (resolver.isAssetRequest(id)) {
  75. let { fileName, content, url } = await exports.resolveAsset(id, root, publicBase, assetsDir, inlineLimit);
  76. if (!url && fileName && content) {
  77. const fileHandle = this.emitFile({
  78. name: fileName,
  79. type: 'asset',
  80. source: content
  81. });
  82. url = 'import.meta.ROLLUP_FILE_URL_' + fileHandle;
  83. handleToIdMap.set(fileHandle, id);
  84. }
  85. else if (url && url.startsWith(`data:`)) {
  86. debug(`${id} -> base64 inlined`);
  87. }
  88. return `export default ${JSON.stringify(url)}`;
  89. }
  90. },
  91. async renderChunk(code) {
  92. let match;
  93. while ((match = exports.injectAssetRe.exec(code))) {
  94. const fileHandle = match[1];
  95. const outputFilepath = publicBase + slash_1.default(path_1.default.join(assetsDir, this.getFileName(fileHandle)));
  96. code = code.replace(match[0], outputFilepath);
  97. const originalId = handleToIdMap.get(fileHandle);
  98. if (originalId) {
  99. debug(`${originalId} -> ${outputFilepath}`);
  100. }
  101. }
  102. return { code, map: null };
  103. }
  104. };
  105. };
  106. //# sourceMappingURL=buildPluginAsset.js.map