serverPluginModuleResolve.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  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.moduleResolvePlugin = exports.moduleRE = exports.moduleFileToIdMap = exports.moduleIdToFileMap = void 0;
  7. const path_1 = __importDefault(require("path"));
  8. const chalk_1 = __importDefault(require("chalk"));
  9. const fs_extra_1 = __importDefault(require("fs-extra"));
  10. const utils_1 = require("../utils");
  11. const url_1 = require("url");
  12. const resolver_1 = require("../resolver");
  13. const debug = require('debug')('vite:resolve');
  14. exports.moduleIdToFileMap = new Map();
  15. exports.moduleFileToIdMap = new Map();
  16. exports.moduleRE = /^\/@modules\//;
  17. const getDebugPath = (root, p) => {
  18. const relative = path_1.default.relative(root, p);
  19. return relative.startsWith('..') ? p : relative;
  20. };
  21. // plugin for resolving /@modules/:id requests.
  22. exports.moduleResolvePlugin = ({ root, app, resolver }) => {
  23. const vueResolved = utils_1.resolveVue(root);
  24. app.use(async (ctx, next) => {
  25. if (!exports.moduleRE.test(ctx.path)) {
  26. return next();
  27. }
  28. // path maybe contain encode chars
  29. const id = decodeURIComponent(ctx.path.replace(exports.moduleRE, ''));
  30. ctx.type = 'js';
  31. const serve = async (id, file, type) => {
  32. exports.moduleIdToFileMap.set(id, file);
  33. exports.moduleFileToIdMap.set(file, ctx.path);
  34. debug(`(${type}) ${id} -> ${getDebugPath(root, file)}`);
  35. await ctx.read(file);
  36. return next();
  37. };
  38. // special handling for vue runtime in case it's not installed
  39. if (!vueResolved.isLocal && id in vueResolved) {
  40. return serve(id, vueResolved[id], 'non-local vue');
  41. }
  42. // already resolved and cached
  43. const cachedPath = exports.moduleIdToFileMap.get(id);
  44. if (cachedPath) {
  45. return serve(id, cachedPath, 'cached');
  46. }
  47. // resolve from vite optimized modules
  48. const optimized = resolver_1.resolveOptimizedModule(root, id);
  49. if (optimized) {
  50. return serve(id, optimized, 'optimized');
  51. }
  52. const referer = ctx.get('referer');
  53. let importer;
  54. // this is a map file request from browser dev tool
  55. const isMapFile = ctx.path.endsWith('.map');
  56. if (referer) {
  57. importer = new url_1.URL(referer).pathname;
  58. }
  59. else if (isMapFile) {
  60. // for some reason Chrome doesn't provide referer for source map requests.
  61. // do our best to reverse-infer the importer.
  62. importer = ctx.path.replace(/\.map$/, '');
  63. }
  64. const importerFilePath = importer ? resolver.requestToFile(importer) : root;
  65. // #829 node package has sub-package(has package.json), should check it before `resolveNodeModuleFile`
  66. const nodeModuleInfo = resolver_1.resolveNodeModule(root, id, resolver);
  67. if (nodeModuleInfo) {
  68. return serve(id, nodeModuleInfo.entryFilePath, 'node_modules');
  69. }
  70. const nodeModuleFilePath = resolver_1.resolveNodeModuleFile(importerFilePath, id);
  71. if (nodeModuleFilePath) {
  72. return serve(id, nodeModuleFilePath, 'node_modules');
  73. }
  74. if (isMapFile && importer) {
  75. // the resolveNodeModuleFile doesn't work with linked pkg
  76. // our last try: infer from the dir of importer
  77. const inferMapPath = path_1.default.join(path_1.default.dirname(importerFilePath), path_1.default.basename(ctx.path));
  78. if (fs_extra_1.default.existsSync(inferMapPath)) {
  79. return serve(id, inferMapPath, 'map file in linked pkg');
  80. }
  81. }
  82. console.error(chalk_1.default.red(`[vite] Failed to resolve module import "${id}". ` +
  83. `(imported by ${importer || 'unknown'})`));
  84. ctx.status = 404;
  85. });
  86. };
  87. //# sourceMappingURL=serverPluginModuleResolve.js.map