UNPKG

@roots/bud-extensions

Version:

bud.js core module

151 lines (150 loc) 6.29 kB
import { __decorate } from "tslib"; import { isAbsolute, join } from 'node:path'; import { Extension } from '@roots/bud-framework/extension'; import { bind, disabled, expose, label, options, } from '@roots/bud-framework/extension/decorators'; import isString from '@roots/bud-support/isString'; /** * The BudTsConfigValues class configures the bud.js application using settings * defined in a tsconfig.json file. This includes several options such as compilerOptions, * include, exclude, and a special bud key. The compilerOptions property provides configuration for the * TypeScript compiler, while include and exclude specify which files are to be included * in or excluded from the process. The bud property allows for enabling the use of compilerOptions. */ let BudTsConfigValues = class BudTsConfigValues extends Extension { get derivedBaseDir() { return (this.getCompilerOptions()?.rootDir ?? this.getCompilerOptions()?.baseUrl); } /** * The `configAfter` method adjusts the bud.js application * configuration by setting up paths and determining file inclusion and exclusion * based on the tsconfig.json settings. * * {@link Extension.configAfter} */ async configAfter(bud) { if (!this.isEnabled()) return; // If a base directory has been defined in the tsconfig.json (either as rootDir or baseUrl), // it is set as the @src path in the bud.js application. if (this.derivedBaseDir) { this.logger.log(`setting @src dir as specified in jsconfig/tsconfig: ${this.derivedBaseDir}`); bud.setPath({ '@src': this.derivedBaseDir }); } // If an output directory has been defined in the tsconfig.json, it is set as the @dist path in the bud.js application. if (this.compilerOptions?.outDir) { this.logger.log(`setting @dist dir as specified in jsconfig/tsconfig: ${this.compilerOptions.outDir}`); bud.setPath({ '@dist': this.compilerOptions.outDir }); } // If paths have been defined in the tsconfig.json, these paths are normalized (i.e., made absolute) // and then set as paths w/ aliases in the bud.js application. if (this.compilerOptions?.paths) { const normalPaths = this.normalizePaths(this.compilerOptions.paths); if (normalPaths) bud .setPath(normalPaths) // @ts-ignore .alias(Object.entries(normalPaths).reduce((a, [k, v]) => ({ ...a, [k]: this.makeAbsolute(v), }), {})); } // If specific directories have been defined to be included in the tsconfig.json, // those directories are added to the Bud.js application's compilation paths. if (this.include) { const directories = (await Promise.all(this.include.map(async (path) => { const type = await bud.fs.exists(path); // If the path exists, is a directory (not a file), // and it doesn't match the config path pattern, then it's added to the directories array. // The config directory is often ignored in this context because it typically contains // configuration files for various tools and libraries used in your project. These // files are not part of the actual source code that needs to be compiled or transformed, // but are instead used to control the behavior of these processes. return type === `dir` && !path.match(/^\.?\/?config/) ? path : undefined; }))).filter(isString); directories && // Include these directories in Bud.js' compilePaths // @ts-ignore bud.compilePaths(directories.map(dir => bud.path(dir))); } } /** * Make absolute path * * @param path string * @returns string */ makeAbsolute(path) { return isAbsolute(path) ? path : this.app.path(path); } /** * Resolve {@link CompilerOptions.paths} against {@link BudTsConfigValues.derivedBaseDir} * * @remarks * Operates on the first item in the array of paths * * @param paths * @returns */ normalizePaths(paths) { if (!paths) return; const normalPaths = Object.entries(paths) .filter(([k, v]) => Array.isArray(v)) .map(([k, v]) => [k, v[0]]) .filter(Boolean) .map(tuple => tuple.map((str) => str.replace(`/*`, ``))) .reduce((acc, [key, value]) => ({ ...acc, [key]: this.derivedBaseDir ? join(this.derivedBaseDir, value) : value, }), {}); this.logger.log(`normalized paths`, normalPaths); return normalPaths; } /** * {@link Extension.register} */ async register(bud) { const fetchConfigModule = bud.context.files[`tsconfig`]?.module ?? bud.context.files[`jsconfig`]?.module; if (!fetchConfigModule) return; const tsConfig = await fetchConfigModule(); if (!tsConfig) return; if (tsConfig.compilerOptions) this.setCompilerOptions(tsConfig.compilerOptions); tsConfig.include && this.setInclude(tsConfig.include); tsConfig.exclude && this.setExclude(tsConfig.exclude); tsConfig.bud && this.setBud(tsConfig.bud); tsConfig.bud?.useCompilerOptions && this.enable(); } }; __decorate([ bind ], BudTsConfigValues.prototype, "configAfter", null); __decorate([ bind ], BudTsConfigValues.prototype, "makeAbsolute", null); __decorate([ bind ], BudTsConfigValues.prototype, "normalizePaths", null); __decorate([ bind ], BudTsConfigValues.prototype, "register", null); BudTsConfigValues = __decorate([ label(`@roots/bud-extensions/tsconfig-values`), expose(`tsconfig`), options({ bud: undefined, compilerOptions: undefined, exclude: undefined, include: undefined, }), disabled ], BudTsConfigValues); export default BudTsConfigValues;