Add ability to write tsconfig.json project references
This commit is contained in:
parent
c0a256ad83
commit
a4688f5432
@ -24,6 +24,29 @@ export function findNodeModules(dir: string = process.cwd()): string[] {
|
|||||||
return paths
|
return paths
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function findPackageRoot(dir: string): string {
|
||||||
|
let currentDir = dir
|
||||||
|
let lastDir = dir
|
||||||
|
do {
|
||||||
|
let s: fs.Stats
|
||||||
|
try {
|
||||||
|
s = fs.statSync(path.join(currentDir, 'package.json'))
|
||||||
|
} catch (err) {
|
||||||
|
lastDir = currentDir
|
||||||
|
currentDir = path.resolve(currentDir, '..')
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (!s.isFile()) {
|
||||||
|
lastDir = currentDir
|
||||||
|
currentDir = path.resolve(currentDir, '..')
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return currentDir
|
||||||
|
} while (lastDir !== currentDir)
|
||||||
|
|
||||||
|
throw new Error(`No package.json for directory "${dir}"`)
|
||||||
|
}
|
||||||
|
|
||||||
export function getPathVariable(
|
export function getPathVariable(
|
||||||
pathsToAdd: string[] = findNodeModules(),
|
pathsToAdd: string[] = findNodeModules(),
|
||||||
currentPath = process.env.PATH,
|
currentPath = process.env.PATH,
|
||||||
|
|||||||
@ -3,7 +3,8 @@ import {argparse, arg} from '@rondo.dev/argparse'
|
|||||||
import {info, error} from '../log'
|
import {info, error} from '../log'
|
||||||
import { getFolders } from '../getFolders'
|
import { getFolders } from '../getFolders'
|
||||||
import {readFileSync, writeFileSync} from 'fs'
|
import {readFileSync, writeFileSync} from 'fs'
|
||||||
import {join} from 'path'
|
import {join, resolve, relative} from 'path'
|
||||||
|
import { findPackageRoot } from '../modules'
|
||||||
|
|
||||||
interface Package {
|
interface Package {
|
||||||
name: string
|
name: string
|
||||||
@ -13,14 +14,27 @@ interface Package {
|
|||||||
devDependencies?: Record<string, string>
|
devDependencies?: Record<string, string>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface TSConfig {
|
||||||
|
references?: Array<{path: string}>
|
||||||
|
}
|
||||||
|
|
||||||
interface Dependencies {
|
interface Dependencies {
|
||||||
dependencies: string[]
|
dependencies: string[]
|
||||||
devDependencies: string[]
|
devDependencies: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function readJSON<T>(filename: string): T {
|
||||||
|
return JSON.parse(readFileSync(filename, 'utf8'))
|
||||||
|
}
|
||||||
|
|
||||||
|
function writeJSON<T>(filename: string, object: T) {
|
||||||
|
info('Writing %s', filename)
|
||||||
|
writeFileSync(filename, JSON.stringify(object, null, ' '))
|
||||||
|
}
|
||||||
|
|
||||||
export function imports(...argv: string[]) {
|
export function imports(...argv: string[]) {
|
||||||
const args = argparse({
|
const args = argparse({
|
||||||
packages: arg('string', {default: 'packages/', positional: true}),
|
packagesDir: arg('string', {default: 'packages/', positional: true}),
|
||||||
root: arg('string', {default: './package.json'}),
|
root: arg('string', {default: './package.json'}),
|
||||||
dryRun: arg('boolean'),
|
dryRun: arg('boolean'),
|
||||||
testFileRegex: arg('string', {default: '\\.test\\.(t|j)sx?$'}),
|
testFileRegex: arg('string', {default: '\\.test\\.(t|j)sx?$'}),
|
||||||
@ -130,22 +144,21 @@ export function imports(...argv: string[]) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
result.dependencies.sort()
|
||||||
|
result.devDependencies.sort()
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
function readPackage(path: string): Package {
|
|
||||||
return JSON.parse(readFileSync(path, 'utf8'))
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
const rootPackage = readPackage(args.root)
|
const rootPackage = readJSON<Package>(args.root)
|
||||||
|
|
||||||
function resolveModule(name: string, version?: string) {
|
function resolveModule(name: string, version?: string) {
|
||||||
if (!version) {
|
if (!version) {
|
||||||
throw new Error(`Module "${name}" not found in root package.json`)
|
throw new Error(`Module "${name}" not found in root package.json`)
|
||||||
}
|
}
|
||||||
if (version.startsWith('file:')) {
|
if (version.startsWith('file:')) {
|
||||||
const pkg = readPackage(join(version.slice(5), 'package.json'))
|
const pkg = readJSON<Package>(join(version.slice(5), 'package.json'))
|
||||||
if (!pkg.version) {
|
if (!pkg.version) {
|
||||||
throw new Error(`Package.json of referenced module "${name}" ` +
|
throw new Error(`Package.json of referenced module "${name}" ` +
|
||||||
'does not have version field')
|
'does not have version field')
|
||||||
@ -177,12 +190,12 @@ export function imports(...argv: string[]) {
|
|||||||
}, {} as Record<string, string>)
|
}, {} as Record<string, string>)
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = getFolders(args.packages)
|
function organizePackageDependencies(
|
||||||
.map(pkgDir => {
|
imports: Dependencies,
|
||||||
error('Entering: %s', pkgDir)
|
packageFile: string,
|
||||||
const imports = collectImports(pkgDir, 'tsconfig.json')
|
) {
|
||||||
const packageFile = join(pkgDir, 'package.json')
|
// handle imports
|
||||||
const targetPackage = readPackage(packageFile)
|
const targetPackage = readJSON<Package>(packageFile)
|
||||||
const dependencies = resolveDependencies(imports.dependencies)
|
const dependencies = resolveDependencies(imports.dependencies)
|
||||||
if (targetPackage.peerDependencies) {
|
if (targetPackage.peerDependencies) {
|
||||||
const peerDependencyNames = new Set(
|
const peerDependencyNames = new Set(
|
||||||
@ -206,11 +219,53 @@ export function imports(...argv: string[]) {
|
|||||||
debug('dependencies: %o', targetPackage.dependencies)
|
debug('dependencies: %o', targetPackage.dependencies)
|
||||||
debug('devDependencies: %o', targetPackage.devDependencies)
|
debug('devDependencies: %o', targetPackage.devDependencies)
|
||||||
return {filename: packageFile, json: targetPackage}
|
return {filename: packageFile, json: targetPackage}
|
||||||
|
}
|
||||||
|
|
||||||
|
function organizeProjectReferences(
|
||||||
|
packagesDir: string,
|
||||||
|
imports: Dependencies,
|
||||||
|
projectDir: string,
|
||||||
|
tsConfigFileName: string,
|
||||||
|
) {
|
||||||
|
const absolutePackagesDir = resolve(process.cwd(), packagesDir)
|
||||||
|
const filename = join(projectDir, tsConfigFileName)
|
||||||
|
const tsConfig = readJSON<TSConfig>(filename)
|
||||||
|
const allDeps = [
|
||||||
|
...imports.dependencies,
|
||||||
|
...imports.devDependencies,
|
||||||
|
]
|
||||||
|
|
||||||
|
tsConfig.references = allDeps
|
||||||
|
.map(dep => require.resolve(dep))
|
||||||
|
.filter(absoluteDep => absoluteDep.startsWith(absolutePackagesDir))
|
||||||
|
.map(findPackageRoot)
|
||||||
|
.map(pkgRoot => relative(projectDir, pkgRoot))
|
||||||
|
.map(path => ({ path }))
|
||||||
|
|
||||||
|
debug('references: %o', tsConfig.references)
|
||||||
|
|
||||||
|
return {filename, json: tsConfig}
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = getFolders(args.packagesDir)
|
||||||
|
.map(pkgDir => {
|
||||||
|
error('Entering: %s', pkgDir)
|
||||||
|
const tsConfigFileName = 'tsconfig.json'
|
||||||
|
const imports = collectImports(pkgDir, tsConfigFileName)
|
||||||
|
const packageFile = join(pkgDir, 'package.json')
|
||||||
|
|
||||||
|
return [
|
||||||
|
organizePackageDependencies(imports, packageFile),
|
||||||
|
organizeProjectReferences(
|
||||||
|
args.packagesDir, imports, pkgDir, tsConfigFileName),
|
||||||
|
]
|
||||||
})
|
})
|
||||||
.forEach(pkg => {
|
.forEach(files => {
|
||||||
info('Writing %s', pkg.filename)
|
if (!args.dryRun) {
|
||||||
const value = JSON.stringify(pkg.json, null, ' ')
|
files.forEach(item => {
|
||||||
writeFileSync(pkg.filename, value)
|
writeJSON(item.filename, item.json)
|
||||||
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user