Package Exports
- @flex-development/tsconfig-utils
- @flex-development/tsconfig-utils/package.json
Readme
tsconfig-utils
Utilities for working with tsconfig files
Contents
- What is this?
- When should I use this?
- Install
- Use
- API
COMPILER_OPTIONSLIBloadCompilerOptions(tsconfig[, options])loadLib(tsconfig[, options])loadPaths(tsconfig[, options])loadPlugins(tsconfig[, options])loadTsconfig(id[, options])normalizeCompilerOptions(option)normalizeImportsNotUsed(option)normalizeJsx(option)normalizeLib(option)normalizeModule(option)normalizeModuleDetection(option)normalizeModuleResolution(option)normalizeNewLine(option)normalizeTarget(option)resolvePaths(code, options)
- Types
- Related
- Contribute
What is this?
This package exports a set of utilities for working with TypeScript configuration files.
When should I use this?
This package can be used to load tsconfig files, resolve path aliases, and normalize user options for the TypeScript Compiler API.
Install
This package is ESM only.
yarn add @flex-development/tsconfig-utilsFrom Git:
yarn add @flex-development/tsconfig-utils@flex-development/tsconfig-utilsSee Git - Protocols | Yarn for details on requesting a specific branch, commit, or tag.
Use
Let's say a developer wants to run a TypeScript file using node. The developer has a tsconfig.json
with path alias configurations.
They implement loader.mjs (and for good measure, typings/node/loader.d.ts
too 😉):
/**
* @file Custom Loader Hooks
* @module loader
* @see https://nodejs.org/api/esm.html#loaders
*/
import * as mlly from '@flex-development/mlly'
import * as pathe from '@flex-development/pathe'
import * as tscu from '@flex-development/tsconfig-utils'
import * as tutils from '@flex-development/tutils'
import * as esbuild from 'esbuild'
import { fileURLToPath, pathToFileURL } from 'node:url'
// add support for extensionless files in "bin" scripts
// https://github.com/nodejs/modules/issues/488
mlly.EXTENSION_FORMAT_MAP.set('', mlly.Format.COMMONJS)
/**
* URL of tsconfig file.
*
* @type {import('node:url').URL}
* @const tsconfig
*/
const tsconfig = mlly.toURL('tsconfig.json')
/**
* TypeScript compiler options.
*
* @type {tscu.CompilerOptions}
* @const compilerOptions
*/
const compilerOptions = tscu.loadCompilerOptions(tsconfig)
/**
* Determines how the module at the given `url` should be interpreted,
* retrieved, and parsed.
*
* @see {@linkcode LoadHookContext}
* @see https://nodejs.org/api/esm.html#loadurl-context-nextload
*
* @async
*
* @param {string} url - Resolved module URL
* @param {LoadHookContext} context - Hook context
* @return {Promise<LoadHookResult>} Hook result
*/
export const load = async (url, context) => {
// get module format
context.format = context.format ?? (await mlly.getFormat(url))
// validate import assertions
mlly.validateAssertions(url, context.format, context.importAssertions)
/**
* File extension of {@linkcode url}.
*
* @type {pathe.Ext | tutils.EmptyString}
* @const ext
*/
const ext = pathe.extname(url)
/**
* Source code.
*
* @type {tutils.Optional<esm.Source<Uint8Array | string>>}
* @var source
*/
let source = await mlly.getSource(url, { format: context.format })
// transform typescript files
if (/^\.(?:cts|mts|tsx?)$/.test(ext) && !/\.d\.(?:cts|mts|ts)$/.test(url)) {
// resolve path aliases
source = await tscu.resolvePaths(source, {
conditions: context.conditions,
ext: '',
parent: url,
tsconfig
})
// resolve modules
source = await mlly.resolveModules(source, {
conditions: context.conditions,
parent: url
})
// transpile source code
const { code } = await esbuild.transform(source, {
format: ext === '.cts' ? 'cjs' : 'esm',
loader: ext.slice(/^\.[cm]/.test(ext) ? 2 : 1),
minify: false,
sourcefile: fileURLToPath(url),
sourcemap: 'inline',
target: `node${process.versions.node}`,
tsconfigRaw: { compilerOptions }
})
// set source code to transpiled source
source = code
}
return { format: context.format, shortCircuit: true, source }
}
/**
* Resolves the given module `specifier`.
*
* Adds supports for:
*
* - Path alias resolution
* - Extensionless file and directory index resolution
*
* @see {@linkcode ResolveHookContext}
* @see https://nodejs.org/api/esm.html#resolvespecifier-context-nextresolve
*
* @async
*
* @param {string} specifier - Module specifier
* @param {ResolveHookContext} context - Hook context
* @return {Promise<ResolveHookResult>} Hook result
* @throws {Error}
*/
export const resolve = async (specifier, context) => {
const { conditions, parentURL: parent } = context
// resolve path alias
specifier = await mlly.resolveAlias(specifier, {
aliases: tscu.loadPaths(tsconfig),
conditions,
cwd: pathToFileURL(compilerOptions.baseUrl),
parent
})
/**
* Resolved module URL.
*
* @type {import('node:url').URL}
* @const url
*/
const url = await mlly.resolveModule(specifier, {
conditions,
parent: parent?.startsWith('file:') ? parent : specifier
})
return {
format: await mlly.getFormat(url),
shortCircuit: true,
url: url.href
}
}The developer creates scratch.ts to test their custom loader hooks:
/**
* @file Scratch
* @module scratch
*/
import { resolvePaths } from '@flex-development/tsconfig-utils'
import { dedent } from 'ts-dedent'
const code = dedent`
import type { ResolveAliasOptions } from '#src/interfaces'
import * as internal from '#src/internal'
import loadCompilerOptions from '#src/utils/load-compiler-options'
import * as mlly from '@flex-development/mlly'
`
console.debug(await resolvePaths(code, { ext: '', parent: import.meta.url }))Running the file with node --loader=./loader.mjs ./scratch yields:
import type { ResolveAliasOptions } from './src/interfaces'
import * as internal from './src/internal'
import loadCompilerOptions from './src/utils/load-compiler-options'
import * as mlly from '@flex-development/mlly'Pleased with their work, they crack open a cold Red Bull 😊
API
This package exports the following identifiers:
COMPILER_OPTIONSLIBloadCompilerOptionsloadLibloadPathsloadPluginsloadTsconfignormalizeCompilerOptionsnormalizeImportsNotUsednormalizeJsxnormalizeLibnormalizeModulenormalizeModuleDetectionnormalizeModuleResolutionnormalizeNewLinenormalizeTargetresolvePaths
There is no default export.
COMPILER_OPTIONS
Set containing compiler option names.
Source
LIB
Map containing type definition library names that correspond to files in the **/node_modules/typescript/lib
directory.
All keys are lowercase.
Source
loadCompilerOptions(tsconfig[, options])
Loads compilerOptions from a tsconfig file.
Parameters
{mlly.ModuleId}tsconfig— Module id of tsconfig file{LoadTsconfigOptions?}[options]— Tsconfig loading options
Returns
{CompilerOptions} Compiler options object.
Source
loadLib(tsconfig[, options])
Loads type definition library names from a tsconfig file.
Parameters
{mlly.ModuleId}tsconfig— Module id of tsconfig file{LoadTsconfigOptions?}[options]— Tsconfig loading options
Returns
{Lib[]} Type definition library names array.
Source
loadPaths(tsconfig[, options])
Loads a path alias configuration from a tsconfig file.
Parameters
{mlly.ModuleId}tsconfig— Module id of tsconfig file{LoadTsconfigOptions?}[options]— Tsconfig loading options
Returns
{Paths} Path alias configuration object.
Source
loadPlugins(tsconfig[, options])
Loads language service plugin configurations from a tsconfig file.
Parameters
{mlly.ModuleId}tsconfig— Module id of tsconfig file{LoadTsconfigOptions?}[options]— Tsconfig loading options
Returns
{Plugin[]} Language service plugin configurations array.
Source
loadTsconfig(id[, options])
Reads and parses the tsconfig file at the given module id.
If the tsconfig file is found, comments and byte order marks (BOMs) will be removed before parsing. If successfully parsed, an object representation of the tsconfig file will be returned.
Extending configuration files is also supported. If not overwritten, the baseUrl, outDir, and
rootDir properties from the base tsconfig file will be made relative to the tsconfig file being loaded.
Parameters
{mlly.ModuleId}id— Module id of tsconfig file{LoadTsconfigOptions?}[options]— Load options
Returns
{Nullable<TSConfig>} User configuration object or null if tsconfig file is not found.
Source
normalizeCompilerOptions(compilerOptions)
Converts the given compilerOptions into programmatic compiler options.
TypeScript programs expect compiler option objects to use enum values where appropriate.
Parameters
{unknown}compilerOptions— User compiler options
Returns
{ts.CompilerOptions} Programmatic compiler options.
Source
normalizeImportsNotUsed(option)
Converts the given option into a programmatic importsNotUsedAsValues option.
TypeScript programs expect a ts.ImportsNotUsedAsValues value.
If the option is already programmatic, it will be returned unmodified. If it cannot be converted, undefined will be
returned instead.
Parameters
{unknown}option— Option to evaluate
Returns
{ts.ImportsNotUsedAsValues | undefined} ts.ImportsNotUsedAsValues value or undefined.
Source
normalizeJsx(option)
Converts the given option into a programmatic jsx option.
TypeScript programs expect a ts.JsxEmit value.
If the option is already programmatic, it will be returned unmodified. If it cannot be converted, undefined will be
returned instead.
Parameters
{unknown}option— Option to evaluate
Returns
{ts.JsxEmit | undefined} ts.JsxEmit value or undefined.
Source
normalizeLib(option)
Converts the given option into an array containing programmatic lib options.
TypeScript programs expect values in compilerOptions.lib to match filenames in **/node_modules/typescript/lib
exactly.
Parameters
{unknown}option— Option to evaluate
Returns
{LibFile[]} Lib filename array.
Source
normalizeModule(option)
Converts the given option into a programmatic module option.
TypeScript programs expect a ts.ModuleKind value.
If the option is already programmatic, it will be returned unmodified. If it cannot be converted, undefined will be
returned instead.
Parameters
{unknown}option— Option to evaluate
Returns
{ts.ModuleKind | undefined} ts.ModuleKind value or undefined.
Source
normalizeModuleDetection(option)
Converts the given option into a programmatic moduleDetection option.
TypeScript programs expect a ts.ModuleDetectionKind value.
If the option is already programmatic, it will be returned unmodified. If it cannot be converted, undefined will be
returned instead.
Parameters
{unknown}option— Option to evaluate
Returns
{ts.ModuleDetectionKind | undefined} ts.ModuleDetectionKind value or undefined.
Source
normalizeModuleResolution(option)
Converts the given option into a programmatic moduleResolution option.
TypeScript programs expect a ts.ModuleResolutionKind value.
If the option is already programmatic, it will be returned unmodified. If it cannot be converted, undefined will be
returned instead.
Parameters
{unknown}option— Option to evaluate
Returns
{ts.ModuleResolutionKind | undefined} ts.ModuleResolutionKind value or undefined.
Source
normalizeNewLine(option)
Converts the given option into a programmatic newLine option.
TypeScript programs expect a ts.NewLineKind value.
If the option is already programmatic, it will be returned unmodified. If it cannot be converted, undefined will be
returned instead.
Parameters
{unknown}option— Option to evaluate
Returns
{ts.NewLineKind | undefined} ts.NewLineKind value or undefined.
Source
normalizeTarget(option)
Converts the given option into a programmatic target option.
TypeScript programs expect a ts.ScriptTarget value.
If the option is already programmatic, it will be returned unmodified. If it cannot be converted, undefined will be
returned instead.
Parameters
{unknown}option— Option to evaluate
Returns
{ts.ScriptTarget | undefined} ts.ScriptTarget value or undefined.
Source
resolvePaths(code, options)
Resolves path aliases in export, import, and require statements in the given piece of source code.
Parameters
{string}code— Code to evaluate{ResolvePathsOptions}options— Path alias resolution options
Returns
{Promise<string>} code with path aliases resolved and/or unmodified.
Source
Types
This package is fully typed with TypeScript.
Interfaces
tsconfig-types
This package re-exports TypeScript definitions from tsconfig-types. This is primarily for the convenience of
TypeScript users who do not hoist packages, but may need to import definitions used in this package.
Related
mlly— ECMAScript module utilitiestsconfig-types— TypeScript definitions fortsconfig.json
Contribute
See CONTRIBUTING.md.