sourceMap.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.originalPositionFor = exports.generatedPositionFor = exports.resolveUtsPluginSourceMapFile = exports.resolveUTSPluginSourceMapFile = void 0;
  4. const fs_1 = require("fs");
  5. const path_1 = require("path");
  6. const source_map_1 = require("source-map");
  7. const EXTNAME = {
  8. kotlin: '.kt',
  9. swift: '.swift',
  10. };
  11. const PLATFORM_DIR = {
  12. kotlin: 'app-android',
  13. swift: 'app-ios',
  14. };
  15. function resolveUTSPluginSourceMapFile(target, filename, inputDir, outputDir) {
  16. inputDir = normalizePath(inputDir);
  17. outputDir = normalizePath(outputDir);
  18. filename = normalizePath(filename);
  19. const pluginDir = resolvePluginDir(inputDir, outputDir, filename);
  20. if (!pluginDir) {
  21. throw `plugin dir not found`;
  22. }
  23. const is_uni_modules = (0, path_1.basename)((0, path_1.dirname)(pluginDir)) === 'uni_modules';
  24. const sourceMapFile = (0, path_1.join)((0, path_1.join)(outputDir, '../.sourcemap/app'), (0, path_1.relative)(inputDir, pluginDir), is_uni_modules ? 'utssdk' : '', PLATFORM_DIR[target], `index${EXTNAME[target]}.map`);
  25. if (!(0, fs_1.existsSync)(sourceMapFile)) {
  26. throw `${sourceMapFile} not found`;
  27. }
  28. return sourceMapFile;
  29. }
  30. exports.resolveUTSPluginSourceMapFile = resolveUTSPluginSourceMapFile;
  31. // 兼容旧版本
  32. exports.resolveUtsPluginSourceMapFile = resolveUTSPluginSourceMapFile;
  33. function resolvePluginDir(inputDir, outputDir, filename) {
  34. // 目标文件是编译后 kt 或 swift
  35. if (filename.startsWith(outputDir)) {
  36. const relativePath = (0, path_1.relative)(outputDir, filename);
  37. const hasSrc = normalizePath(relativePath).includes('/src/');
  38. // uni_modules/test-uts
  39. if (relativePath.startsWith('uni_modules')) {
  40. return (0, path_1.join)(inputDir, (0, path_1.join)(relativePath, hasSrc ? '../../../..' : '../../..'));
  41. }
  42. // utssdk/test-uts
  43. return (0, path_1.join)(inputDir, (0, path_1.join)(relativePath, hasSrc ? '../../..' : '../..'));
  44. }
  45. else if (filename.startsWith(inputDir)) {
  46. let parent = (0, path_1.dirname)(filename);
  47. const utssdkDir = normalizePath((0, path_1.join)(inputDir, 'utssdk'));
  48. const uniModulesDir = normalizePath((0, path_1.join)(inputDir, 'uni_modules'));
  49. while (parent) {
  50. const dir = (0, path_1.dirname)(parent);
  51. if (parent === dir) {
  52. // windows 上边会剩下一个盘符
  53. return;
  54. }
  55. if (dir === utssdkDir || dir === uniModulesDir) {
  56. return parent;
  57. }
  58. parent = dir;
  59. }
  60. throw `${filename} is not a uts plugin file`;
  61. }
  62. else {
  63. throw `${filename} is not in ${inputDir} or ${outputDir}`;
  64. }
  65. }
  66. const consumers = {};
  67. /**
  68. * 解析源码文件,目前 uts 的 sourcemap 存储的都是相对目录
  69. * @param consumer
  70. * @param filename
  71. * @returns
  72. */
  73. function resolveSource(consumer, filename) {
  74. filename = normalizePath(filename);
  75. return (consumer.sources.find((source) => filename.endsWith(source)) || filename);
  76. }
  77. /**
  78. * 根据源码文件名、行号、列号,返回生成后文件、行号、列号(根据 uts 文件返回 kt|swift 文件)
  79. * @param originalPosition
  80. * @returns
  81. */
  82. function generatedPositionFor({ sourceMapFile, filename, line, column, outputDir, }) {
  83. return resolveSourceMapConsumer(sourceMapFile).then((consumer) => {
  84. const res = consumer.generatedPositionFor({
  85. source: resolveSource(consumer, filename),
  86. line,
  87. column,
  88. bias: column === 0 ? 2 /* BIAS.LEAST_UPPER_BOUND */ : 1 /* BIAS.GREATEST_LOWER_BOUND */,
  89. });
  90. let source = null;
  91. if (outputDir) {
  92. // 根据 sourceMapFile 和 outputDir,计算出生成后的文件路径
  93. source = (0, path_1.join)(outputDir, (0, path_1.relative)((0, path_1.join)(outputDir, '../.sourcemap/app'), sourceMapFile)).replace('.map', '');
  94. }
  95. return Object.assign(res, { source });
  96. });
  97. }
  98. exports.generatedPositionFor = generatedPositionFor;
  99. /**
  100. * 根据生成后的文件名、行号、列号,返回源码文件、行号、列号(根据 kt|swift 文件返回 uts 文件)
  101. * @param generatedPosition
  102. * @returns
  103. */
  104. function originalPositionFor(generatedPosition) {
  105. return resolveSourceMapConsumer(generatedPosition.sourceMapFile).then((consumer) => {
  106. const res = consumer.originalPositionFor({
  107. line: generatedPosition.line,
  108. column: generatedPosition.column,
  109. bias: generatedPosition.column === 0
  110. ? 2 /* BIAS.LEAST_UPPER_BOUND */
  111. : 1 /* BIAS.GREATEST_LOWER_BOUND */,
  112. });
  113. if (generatedPosition.withSourceContent &&
  114. res.source &&
  115. res.line &&
  116. res.column) {
  117. return Object.assign(res, {
  118. sourceContent: consumer.sourceContentFor(res.source, true),
  119. });
  120. }
  121. if (res.source && generatedPosition.inputDir) {
  122. res.source = (0, path_1.join)(generatedPosition.inputDir, res.source);
  123. }
  124. return res;
  125. });
  126. }
  127. exports.originalPositionFor = originalPositionFor;
  128. async function resolveSourceMapConsumer(sourceMapFile) {
  129. const stats = (0, fs_1.statSync)(sourceMapFile);
  130. if (!stats.isFile()) {
  131. throw `${sourceMapFile} is not a file`;
  132. }
  133. const cache = consumers[sourceMapFile];
  134. if (!cache || cache.time !== stats.mtimeMs) {
  135. consumers[sourceMapFile] = {
  136. time: stats.mtimeMs,
  137. consumer: await new source_map_1.SourceMapConsumer((0, fs_1.readFileSync)(sourceMapFile, 'utf8')),
  138. };
  139. }
  140. return consumers[sourceMapFile].consumer;
  141. }
  142. function normalizePath(path) {
  143. return path.replace(/\\/g, '/');
  144. }