You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

208 line
5.5 KiB

  1. import * as esbuild from 'esbuild';
  2. import { sassPlugin } from 'esbuild-sass-plugin';
  3. import * as fs from 'fs';
  4. import * as path from 'path';
  5. import { minify } from 'terser';
  6. import { URL } from 'url';
  7. const __dirname = new URL('.', import.meta.url).pathname.substring(1);
  8. const args = process.argv.slice(2);
  9. let index = args.indexOf('--mode');
  10. const mode = (index >= 0 ? args[index + 1] : undefined) || 'none';
  11. const watch = args.includes('--watch');
  12. const check = !args.includes('--no-check');
  13. /**
  14. * @param { 'node' | 'webworker' } target
  15. * @param { 'production' | 'development' | 'none' } mode
  16. */
  17. async function buildExtension(target, mode) {
  18. let plugins = [];
  19. // let TypeCheckerPlugin;
  20. // if (check) {
  21. // ({ EsbuildPlugin: TypeCheckerPlugin } = require('vite-esbuild-typescript-checker'));
  22. // plugins.push(
  23. // TypeCheckerPlugin({
  24. // checker: {
  25. // async: false,
  26. // eslint: {
  27. // enabled: true,
  28. // files: 'src/**/*.ts',
  29. // options: {
  30. // // cache: true,
  31. // cacheLocation: path.join(
  32. // __dirname,
  33. // target === 'webworker' ? '.eslintcache.browser' : '.eslintcache',
  34. // ),
  35. // overrideConfigFile: path.join(
  36. // __dirname,
  37. // target === 'webworker' ? '.eslintrc.browser.json' : '.eslintrc.json',
  38. // ),
  39. // },
  40. // },
  41. // formatter: 'basic',
  42. // typescript: {
  43. // configFile: target === 'webworker' ? 'tsconfig.browser.json' : 'tsconfig.json',
  44. // },
  45. // },
  46. // }),
  47. // );
  48. // }
  49. const alias = {
  50. '@env': path.resolve(__dirname, 'src', 'env', target === 'webworker' ? 'browser' : target),
  51. // Stupid dependency that is used by `http[s]-proxy-agent`
  52. debug: path.resolve(__dirname, 'patches', 'debug.js'),
  53. // This dependency is very large, and isn't needed for our use-case
  54. tr46: path.resolve(__dirname, 'patches', 'tr46.js'),
  55. // This dependency is unnecessary for our use-case
  56. 'whatwg-url': path.resolve(__dirname, 'patches', 'whatwg-url.js'),
  57. };
  58. if (target === 'webworker') {
  59. alias.path = 'path-browserify';
  60. alias.os = 'os-browserify/browser';
  61. }
  62. const out = target === 'webworker' ? 'dist/browser' : 'dist';
  63. const result = await esbuild.build({
  64. bundle: true,
  65. entryPoints: ['src/extension.ts'],
  66. entryNames: '[dir]/gitlens',
  67. alias: alias,
  68. drop: ['debugger'],
  69. external: ['vscode'],
  70. format: 'esm',
  71. keepNames: true,
  72. legalComments: 'none',
  73. logLevel: 'info',
  74. mainFields: target === 'webworker' ? ['browser', 'module', 'main'] : ['module', 'main'],
  75. metafile: true,
  76. minify: mode === 'production',
  77. outdir: out,
  78. platform: target === 'webworker' ? 'browser' : target,
  79. sourcemap: mode !== 'production',
  80. // splitting: target !== 'webworker',
  81. // chunkNames: 'feature-[name]-[hash]',
  82. target: ['es2022', 'chrome102', 'node16.14.2'],
  83. treeShaking: true,
  84. tsconfig: target === 'webworker' ? 'tsconfig.browser.json' : 'tsconfig.json',
  85. // watch: watch,
  86. plugins: plugins,
  87. });
  88. if (!fs.existsSync(path.join('dist', 'meta'))) {
  89. fs.mkdirSync(path.join('dist', 'meta'));
  90. }
  91. fs.writeFileSync(
  92. path.join('dist', 'meta', `gitlens${target === 'webworker' ? '.browser' : ''}.json`),
  93. JSON.stringify(result.metafile),
  94. );
  95. if (mode === 'production') {
  96. const file = path.join(out, 'gitlens.js');
  97. console.log(`Minifying ${file}...`);
  98. const code = fs.readFileSync(file, 'utf8');
  99. const result = await minify(code, {
  100. compress: {
  101. drop_debugger: true,
  102. ecma: 2020,
  103. module: true,
  104. },
  105. ecma: 2020,
  106. format: {
  107. comments: false,
  108. ecma: 2020,
  109. },
  110. // Keep the class names otherwise @log won't provide a useful name
  111. keep_classnames: true,
  112. module: true,
  113. });
  114. fs.writeFileSync(file, result.code);
  115. }
  116. }
  117. /**
  118. * @param { 'production' | 'development' | 'none' } mode
  119. */
  120. async function buildGraphWebview(mode) {
  121. let plugins = [sassPlugin()];
  122. const out = 'dist/webviews';
  123. const result = await esbuild.build({
  124. bundle: true,
  125. entryPoints: ['src/webviews/apps/plus/graph/graph.tsx'],
  126. entryNames: '[dir]/graph',
  127. alias: {
  128. '@env': path.resolve(__dirname, 'src', 'env', 'browser'),
  129. tslib: path.resolve(__dirname, 'node_modules/tslib/tslib.es6.js'),
  130. '@microsoft/fast-foundation': path.resolve(
  131. __dirname,
  132. 'node_modules/@microsoft/fast-foundation/dist/esm/index.js',
  133. ),
  134. '@microsoft/fast-react-wrapper': path.resolve(
  135. __dirname,
  136. 'node_modules/@microsoft/fast-react-wrapper/dist/esm/index.js',
  137. ),
  138. },
  139. drop: ['debugger'],
  140. external: ['vscode'],
  141. format: 'esm',
  142. legalComments: 'none',
  143. logLevel: 'info',
  144. mainFields: ['browser', 'module', 'main'],
  145. metafile: true,
  146. minify: mode === 'production' ? true : false,
  147. outdir: out,
  148. platform: 'browser',
  149. sourcemap: true,
  150. target: ['es2022', 'chrome102'],
  151. treeShaking: true,
  152. tsconfig: 'src/webviews/apps/tsconfig.json',
  153. // watch: watch,
  154. plugins: plugins,
  155. });
  156. fs.writeFileSync(path.join('dist', 'meta', 'graph.json'), JSON.stringify(result.metafile));
  157. if (mode === 'production') {
  158. const file = path.join(out, 'graph.js');
  159. console.log(`Minifying ${file}...`);
  160. const code = fs.readFileSync(file, 'utf8');
  161. const result = await minify(code, {
  162. compress: {
  163. drop_debugger: true,
  164. ecma: 2020,
  165. module: true,
  166. },
  167. ecma: 2020,
  168. format: {
  169. comments: false,
  170. ecma: 2020,
  171. },
  172. module: true,
  173. });
  174. fs.writeFileSync(file, result.code);
  175. }
  176. }
  177. try {
  178. await Promise.allSettled([
  179. buildExtension('node', mode),
  180. buildExtension('webworker', mode),
  181. buildGraphWebview(mode),
  182. ]);
  183. } catch (ex) {
  184. console.error(ex);
  185. process.exit(1);
  186. }