Welcome to mirror list, hosted at ThFree Co, Russian Federation.

create_jsconfig.js « frontend « scripts - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: be95c5cb2d382f6d784a253449630e5c51ec144c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#!/usr/bin/env node

/**
 * @file This file generates a
 * [jsconfig.json](https://code.visualstudio.com/docs/languages/jsconfig) file
 * using aliases from the webpack config. To use it run from project root:
 *
 * ```sh
 * node ./scripts/frontend/create_jsconfig.js
 * ```
 *
 * NOTE: since aliases are currently generated based on solely Webpack config,
 * aliases defined in Jest config might be missing.
 */

const fs = require('node:fs/promises');
const path = require('node:path');
const readline = require('node:readline/promises');
const { stdin, stdout } = require('node:process');
const chalk = require('chalk').default;
const prettier = require('prettier');

const PATH_PROJECT_ROOT = path.resolve(__dirname, '..', '..');
const PATH_JS_CONFIG = path.join(PATH_PROJECT_ROOT, 'jsconfig.json');

/**
 * Creates and writes a jsconfig.json file, based on Webpack aliases.
 */
async function createJsConfig() {
  // eslint-disable-next-line global-require
  const webpackConfig = require('../../config/webpack.config');

  // Aliases
  const paths = {
    // NOTE: Sentry is exposed via a wrapper, which has a limited API.
    '@sentry/browser': [
      path.relative(PATH_PROJECT_ROOT, 'app/assets/javascripts/sentry/sentry_browser_wrapper.js'),
    ],
  };
  const WEBPACK_ALIAS_EXCEPTIONS = [
    'jquery$',
    '@gitlab/svgs/dist/icons.svg',
    '@apollo/client$',
    '@sentry/browser$',
  ];
  Object.entries(webpackConfig.resolve.alias)
    .filter(([key]) => !WEBPACK_ALIAS_EXCEPTIONS.includes(key))
    .forEach(([key, value]) => {
      const alias = `${key}/*`;
      const target = [`${path.relative(PATH_PROJECT_ROOT, value)}/*`];
      paths[alias] = target;
    });

  // JS/TS config. See more: https://www.typescriptlang.org/tsconfig
  const jsConfig = {
    // As we're introducing jsconfig to the project, as a precaution we add both:
    // 'include' and 'exclude' options. This might be simplified in the future.
    exclude: ['node_modules', 'vendor'],

    // 'include' is currently manually defined. We might want to append manually
    // defined paths with paths from aliases
    include: [
      'app/assets/javascripts',
      'ee/app/assets/javascripts',
      'spec/frontend',
      'ee/spec/frontend',
      'tmp/tests/frontend/fixtures',
      'tmp/tests/frontend/fixtures-ee',
    ],

    // Explicitly enable automatic type acquisition
    // See more: https://www.typescriptlang.org/tsconfig#type-acquisition
    typeAcquisition: {
      enable: true,
    },

    compilerOptions: {
      baseUrl: '.', // Define the project root
      checkJs: false, // Disable type checking on JavaScript files
      disableSizeLimit: true, // Disable memory size limit for the language server
      skipLibCheck: true, // Skip type checking all .d.ts files
      resolveJsonModule: true, // Enable importing .json files
      paths, // Aliases
    },
  };

  // Stringify, format and update the config file
  const jsConfigString = prettier.format(JSON.stringify(jsConfig, null, 2), { parser: 'json' });
  await fs.writeFile(PATH_JS_CONFIG, jsConfigString);
}

function fileExists(filePath) {
  return fs.stat(filePath).then(
    () => true,
    () => false,
  );
}

async function main() {
  const jsconfigExists = await fileExists(PATH_JS_CONFIG);

  if (jsconfigExists) {
    console.log(`${chalk.yellow('WARNING:')} jsconfig.json file already exists.`);
    console.log('');
    const rl = readline.createInterface({ input: stdin, output: stdout });
    const response = await rl.question('Would you like to overwrite it? (y/n) ');
    rl.close();
    console.log('');

    const shouldOverwrite = response.match(/^y(es)?$/i);

    if (!shouldOverwrite) {
      console.log('Overwrite cancelled.');
      return;
    }
  }

  try {
    await createJsConfig();
    console.log(chalk.green('jsconfig.json file created.'));
  } catch (error) {
    console.log(`${chalk.red('ERROR:')} failed to create jsconfig.json. See the error below:`);
    console.error(error);
  }
}

main();