esbuildService.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  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.transform = exports.stopService = exports.resolveJsxOptions = exports.vueJsxFilePath = exports.vueJsxPublicPath = exports.tjsxRE = void 0;
  7. const path_1 = __importDefault(require("path"));
  8. const chalk_1 = __importDefault(require("chalk"));
  9. const esbuild_1 = require("esbuild");
  10. const utils_1 = require("./utils");
  11. const debug = require('debug')('vite:esbuild');
  12. exports.tjsxRE = /\.(tsx?|jsx)$/;
  13. exports.vueJsxPublicPath = '/vite/jsx';
  14. exports.vueJsxFilePath = path_1.default.resolve(__dirname, '../client/vueJsxCompat.js');
  15. const JsxPresets = {
  16. vue: { jsxFactory: 'jsx', jsxFragment: 'Fragment' },
  17. preact: { jsxFactory: 'h', jsxFragment: 'Fragment' },
  18. react: {} // use esbuild default
  19. };
  20. function resolveJsxOptions(options = 'vue') {
  21. if (typeof options === 'string') {
  22. if (!(options in JsxPresets)) {
  23. console.error(`[vite] unknown jsx preset: '${options}'.`);
  24. }
  25. return JsxPresets[options] || {};
  26. }
  27. else if (options) {
  28. return {
  29. jsxFactory: options.factory,
  30. jsxFragment: options.fragment
  31. };
  32. }
  33. }
  34. exports.resolveJsxOptions = resolveJsxOptions;
  35. // lazy start the service
  36. let _servicePromise;
  37. const ensureService = async () => {
  38. if (!_servicePromise) {
  39. _servicePromise = esbuild_1.startService();
  40. }
  41. return _servicePromise;
  42. };
  43. exports.stopService = async () => {
  44. if (_servicePromise) {
  45. const service = await _servicePromise;
  46. service.stop();
  47. _servicePromise = undefined;
  48. }
  49. };
  50. // transform used in server plugins with a more friendly API
  51. exports.transform = async (src, request, options = {}, jsxOption) => {
  52. const service = await ensureService();
  53. const file = utils_1.cleanUrl(request);
  54. options = {
  55. loader: options.loader || path_1.default.extname(file).slice(1),
  56. sourcemap: true,
  57. // ensure source file name contains full query
  58. sourcefile: request,
  59. target: 'es2020',
  60. ...options
  61. };
  62. try {
  63. const result = await service.transform(src, options);
  64. if (result.warnings.length) {
  65. console.error(`[vite] warnings while transforming ${file} with esbuild:`);
  66. result.warnings.forEach((m) => printMessage(m, src));
  67. }
  68. let code = result.js;
  69. // if transpiling (j|t)sx file, inject the imports for the jsx helper and
  70. // Fragment.
  71. if (file.endsWith('x')) {
  72. if (!jsxOption || jsxOption === 'vue') {
  73. code +=
  74. `\nimport { jsx } from '${exports.vueJsxPublicPath}'` +
  75. `\nimport { Fragment } from 'vue'`;
  76. }
  77. if (jsxOption === 'preact') {
  78. code += `\nimport { h, Fragment } from 'preact'`;
  79. }
  80. }
  81. return {
  82. code,
  83. map: result.jsSourceMap
  84. };
  85. }
  86. catch (e) {
  87. console.error(chalk_1.default.red(`[vite] error while transforming ${file} with esbuild:`));
  88. if (e.errors) {
  89. e.errors.forEach((m) => printMessage(m, src));
  90. }
  91. else {
  92. console.error(e);
  93. }
  94. debug(`options used: `, options);
  95. return {
  96. code: '',
  97. map: undefined
  98. };
  99. }
  100. };
  101. function printMessage(m, code) {
  102. console.error(chalk_1.default.yellow(m.text));
  103. if (m.location) {
  104. const lines = code.split(/\r?\n/g);
  105. const line = Number(m.location.line);
  106. const column = Number(m.location.column);
  107. const offset = lines
  108. .slice(0, line - 1)
  109. .map((l) => l.length)
  110. .reduce((total, l) => total + l + 1, 0) + column;
  111. console.error(require('@vue/compiler-dom').generateCodeFrame(code, offset, offset + 1));
  112. }
  113. }
  114. //# sourceMappingURL=esbuildService.js.map