esbuild-build.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. // scripts/esbuild_build.mjs (注意扩展名改成 .mjs 或启用 type: "module")
  2. import fs from "fs";
  3. import path from "path";
  4. import dotenv from 'dotenv';
  5. import esbuild from 'esbuild';
  6. import esbuildPluginPino from 'esbuild-plugin-pino';
  7. // 加载 .env 文件
  8. const define = {
  9. 'process.env.NODE_ENV': '"production"'
  10. }
  11. const env = dotenv.config({ path: path.resolve('.env') }).parsed;
  12. for (const key in env) {
  13. define[`process.env.${key}`] = JSON.stringify(env[key]);
  14. }
  15. const env_production = dotenv.config({ path: path.resolve('.env.production') }).parsed;
  16. for (const key in env_production) {
  17. define[`process.env.${key}`] = JSON.stringify(env_production[key]);
  18. }
  19. console.log({define})
  20. const SupportEsmPlugin = {
  21. name: 'SupportESM',
  22. setup(build) {
  23. build.onEnd(() => {
  24. const outdir = build.initialOptions.outdir;
  25. if (!outdir) return;
  26. const builtins = [
  27. '_http_agent',
  28. '_http_client',
  29. '_http_common',
  30. '_http_incoming',
  31. '_http_outgoing',
  32. '_http_server',
  33. '_stream_duplex',
  34. '_stream_passthrough',
  35. '_stream_readable',
  36. '_stream_transform',
  37. '_stream_wrap',
  38. '_stream_writable',
  39. '_tls_common',
  40. '_tls_wrap',
  41. 'assert',
  42. 'async_hooks',
  43. 'buffer',
  44. 'child_process',
  45. 'cluster',
  46. 'console',
  47. 'constants',
  48. 'crypto',
  49. 'dgram',
  50. 'diagnostics_channel',
  51. 'dns',
  52. 'domain',
  53. 'events',
  54. 'fs',
  55. 'http',
  56. 'http2',
  57. 'https',
  58. 'inspector',
  59. 'module',
  60. 'net',
  61. 'os',
  62. 'path',
  63. 'perf_hooks',
  64. 'process',
  65. 'punycode',
  66. 'querystring',
  67. 'readline',
  68. 'repl',
  69. 'stream',
  70. 'string_decoder',
  71. 'sys',
  72. 'timers',
  73. 'tls',
  74. 'trace_events',
  75. 'tty',
  76. 'url',
  77. 'util',
  78. 'v8',
  79. 'vm',
  80. 'wasi',
  81. 'worker_threads',
  82. 'zlib'
  83. ]
  84. const pattern = `\\b__require\\("(${builtins.join('|')})"\\)`;
  85. const rx = new RegExp(pattern, 'gm');
  86. const modules = new Map();
  87. const walk = (dir) => {
  88. for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
  89. const fullPath = path.join(dir, entry.name);
  90. console.log({fullPath})
  91. if (entry.isDirectory()) {
  92. walk(fullPath);
  93. } else if (/\.(js|ts|mjs|cjs)$/.test(entry.name)) {
  94. const data = fs.readFileSync(fullPath, 'utf8');
  95. const out = data.replace(rx, (_, mod) => {
  96. const id = `__import_${mod.toUpperCase()}`;
  97. modules.set(mod, id);
  98. return id;
  99. });
  100. fs.writeFileSync(fullPath, '');
  101. modules.forEach(function(val, key) {
  102. fs.appendFileSync(fullPath, `import ${val} from ${JSON.stringify(key)};\n`, 'utf8');
  103. })
  104. fs.appendFileSync(fullPath, out, 'utf8');
  105. }
  106. }
  107. };
  108. walk(outdir);
  109. });
  110. }
  111. }
  112. esbuild.build({
  113. entryPoints: ['src/index.ts'],
  114. bundle: true,
  115. platform: 'node',
  116. target: 'node22',
  117. format: 'esm', // ✅ 使用 ESM 输出格式
  118. outdir: "dist",
  119. outExtension: {
  120. '.js': '.mjs'
  121. },
  122. // outfile: 'dist/index.mjs',
  123. define,
  124. sourcemap: false,
  125. minify: false,
  126. external: ['node:*', 'tty', 'fs', 'path', 'net', 'crypto'], // 忽略 Node 内置模块
  127. plugins: [
  128. esbuildPluginPino({ transports: ["pino", "pino-pretty"] }),
  129. SupportEsmPlugin
  130. ],
  131. }).then(() => {
  132. console.log('✅ Build finished!');
  133. }).catch((err) => {
  134. console.error('❌ Build failed:', err);
  135. process.exit(1);
  136. });