25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

168 lines
4.4 KiB

  1. //@ts-check
  2. /** @typedef {import('webpack').Configuration} WebpackConfig **/
  3. const { spawnSync } = require('child_process');
  4. var fs = require('fs');
  5. var glob = require('glob');
  6. const path = require('path');
  7. const { CleanWebpackPlugin: CleanPlugin } = require('clean-webpack-plugin');
  8. const esbuild = require('esbuild');
  9. const ForkTsCheckerPlugin = require('fork-ts-checker-webpack-plugin');
  10. const JSON5 = require('json5');
  11. const nodeExternals = require('webpack-node-externals');
  12. module.exports =
  13. /**
  14. * @param {{ esbuild?: boolean } | undefined } env
  15. * @param {{ mode: 'production' | 'development' | 'none' | undefined }} argv
  16. * @returns { WebpackConfig[] }
  17. */
  18. function (env, argv) {
  19. const mode = argv.mode || 'development';
  20. env = {
  21. esbuild: true,
  22. ...env,
  23. };
  24. return [getExtensionConfig('node', mode, env) /*, getExtensionConfig('webworker', mode, env)*/];
  25. };
  26. /**
  27. * @param { 'node' | 'webworker' } target
  28. * @param { 'production' | 'development' | 'none' } mode
  29. * @param {{ analyzeBundle?: boolean; analyzeDeps?: boolean; esbuild?: boolean } | undefined } env
  30. * @returns { WebpackConfig }
  31. */
  32. function getExtensionConfig(target, mode, env) {
  33. /**
  34. * @type WebpackConfig['plugins'] | any
  35. */
  36. const plugins = [
  37. new CleanPlugin({ cleanOnceBeforeBuildPatterns: ['out/**'] }),
  38. new ForkTsCheckerPlugin({
  39. async: false,
  40. // eslint: {
  41. // enabled: true,
  42. // files: 'src/**/*.ts',
  43. // options: {
  44. // // cache: true,
  45. // cacheLocation: path.join(
  46. // __dirname,
  47. // target === 'webworker' ? '.eslintcache.browser' : '.eslintcache',
  48. // ),
  49. // overrideConfigFile: path.join(
  50. // __dirname,
  51. // target === 'webworker' ? '.eslintrc.browser.json' : '.eslintrc.json',
  52. // ),
  53. // },
  54. // },
  55. formatter: 'basic',
  56. typescript: {
  57. configFile: path.join(
  58. __dirname,
  59. target === 'webworker' ? 'tsconfig.test.browser.json' : 'tsconfig.test.json',
  60. ),
  61. },
  62. }),
  63. ];
  64. return {
  65. name: `tests:${target}`,
  66. entry: {
  67. runTest: './src/test/runTest.ts',
  68. 'suite/index': './src/test/suite/index.ts',
  69. ...glob.sync('./src/test/suite/**/*.test.ts').reduce(function (obj, e) {
  70. obj['suite/' + path.parse(e).name] = e;
  71. return obj;
  72. }, {}),
  73. },
  74. mode: mode,
  75. target: target,
  76. devtool: 'source-map',
  77. output: {
  78. path:
  79. target === 'webworker'
  80. ? path.join(__dirname, 'out', 'test', 'browser')
  81. : path.join(__dirname, 'out', 'test'),
  82. filename: '[name].js',
  83. sourceMapFilename: '[name].js.map',
  84. libraryTarget: 'commonjs2',
  85. },
  86. externals: [{ vscode: 'commonjs vscode' }, nodeExternals()],
  87. module: {
  88. rules: [
  89. {
  90. exclude: /\.d\.ts$/,
  91. include: path.join(__dirname, 'src'),
  92. test: /\.tsx?$/,
  93. use: env.esbuild
  94. ? {
  95. loader: 'esbuild-loader',
  96. options: {
  97. implementation: esbuild,
  98. loader: 'ts',
  99. target: ['es2020', 'chrome91', 'node14.16'],
  100. tsconfigRaw: resolveTSConfig(
  101. path.join(
  102. __dirname,
  103. target === 'webworker'
  104. ? 'tsconfig.test.browser.json'
  105. : 'tsconfig.test.json',
  106. ),
  107. ),
  108. },
  109. }
  110. : {
  111. loader: 'ts-loader',
  112. options: {
  113. configFile: path.join(
  114. __dirname,
  115. target === 'webworker' ? 'tsconfig.test.browser.json' : 'tsconfig.test.json',
  116. ),
  117. experimentalWatchApi: true,
  118. transpileOnly: true,
  119. },
  120. },
  121. },
  122. ],
  123. },
  124. resolve: {
  125. alias: { '@env': path.resolve(__dirname, 'src', 'env', target === 'webworker' ? 'browser' : target) },
  126. fallback: target === 'webworker' ? { path: require.resolve('path-browserify') } : undefined,
  127. mainFields: target === 'webworker' ? ['browser', 'module', 'main'] : ['module', 'main'],
  128. extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'],
  129. },
  130. plugins: plugins,
  131. infrastructureLogging: {
  132. level: 'log', // enables logging required for problem matchers
  133. },
  134. stats: {
  135. preset: 'errors-warnings',
  136. assets: true,
  137. colors: true,
  138. env: true,
  139. errorsCount: true,
  140. warningsCount: true,
  141. timings: true,
  142. },
  143. };
  144. }
  145. /**
  146. * @param { string } configFile
  147. * @returns { string }
  148. */
  149. function resolveTSConfig(configFile) {
  150. const result = spawnSync('yarn', ['tsc', `-p ${configFile}`, '--showConfig'], {
  151. cwd: __dirname,
  152. encoding: 'utf8',
  153. shell: true,
  154. });
  155. const data = result.stdout;
  156. const start = data.indexOf('{');
  157. const end = data.lastIndexOf('}') + 1;
  158. const json = JSON5.parse(data.substring(start, end));
  159. return json;
  160. }