diff options
Diffstat (limited to 'scripts/frontend/create_jsconfig.js')
-rwxr-xr-x | scripts/frontend/create_jsconfig.js | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/scripts/frontend/create_jsconfig.js b/scripts/frontend/create_jsconfig.js new file mode 100755 index 00000000000..7e2d0eb02c4 --- /dev/null +++ b/scripts/frontend/create_jsconfig.js @@ -0,0 +1,106 @@ +#!/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'); + + const paths = {}; // aliases + const WEBPACK_ALIAS_EXCEPTIONS = ['jquery$', '@gitlab/svgs/dist/icons.svg']; + 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; + }); + + 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/', + ], + compilerOptions: { + baseUrl: '.', // Define the project root + checkJs: false, // Disable type checking on JavaScript files + disableSizeLimit: true, // Disable memory size limit for the language server + 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(); |