Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ npx update-ts-references --help
Usage: update-ts-references [options]

Options:
--configName The name of the config files which needs to be updated. Default: tsconfig.json
--configName The name of the config files which needs to be updated. Default: tsconfig.json
--rootConfigName The name of the root config file which needs to be updated. Default: tsconfig.json
--withoutRootConfig If you will not have a tsconfig in the root directory or don't want to update it. Default: false
--check Checks if updates would be necessary (without applying them)
Expand Down Expand Up @@ -70,7 +70,7 @@ The output for the created file looks like the following
```

## using --createPathMappings
will create path mappings under `compilerOptions` for a better IDE support. It assumes the source files are under `src`.
will create path mappings under `compilerOptions` for a better IDE support. The generated mappings respect the `rootDir` defined in the referenced `tsconfig.json` or `jsconfig.json` and only fall back to `src` when no `rootDir` is provided.

```json
{
Expand Down Expand Up @@ -106,6 +106,14 @@ Example configuration see [here](./test-scenarios/ts-options-yaml/update-ts-refe
### using multiple configurations for different usecases
Executing update-ts-references with different configurations via the parameter `--usecase`.

## about jsconfig.json support
When a dependency does not ship a `tsconfig.json` but provides a `jsconfig.json`, the reference automatically targets that file and the path mappings pick up its `rootDir` as well, if `--createPathMappings` is enabled. `jsconfig.json` files participate in package-level `references`, but they stay out of the root `tsconfig.json`.

### in combination with the --configName argument
Currently the name of the config file derives from the the configName which is `tsconfig.json` and would look for `jsconfig.json`.

Example: ` --configName tsconfig.test.json` would look for `jsconfig.test.json`

## FAQ
### Why is my pnpm workspace alias not working?

Expand Down
58 changes: 52 additions & 6 deletions src/update-ts-references.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const assert = require('assert').strict;

const PACKAGE_JSON = 'package.json';
const TSCONFIG_JSON = 'tsconfig.json'
const JSCONFIG_JSON = 'jsconfig.json'

const defaultOptions = {
configName: TSCONFIG_JSON,
Expand Down Expand Up @@ -72,6 +73,15 @@ const getAllPackageJsons = async (workspaces, cwd) => {
);
};

const detectJSConfig = (directory, configName) => {
const jsConfigName = configName.replace(/^ts/, 'js')
let detectedConfig = fs.existsSync(path.join(directory, jsConfigName)) ? jsConfigName : null
if (jsConfigName !== JSCONFIG_JSON && detectedConfig === null) {
detectedConfig = fs.existsSync(path.join(directory, JSCONFIG_JSON)) ? JSCONFIG_JSON : null
}
return detectedConfig
}

const detectTSConfig = (directory, configName, createConfig, cwd) => {
let detectedConfig = fs.existsSync(path.join(directory, configName)) ? configName : null
if (configName !== TSCONFIG_JSON && detectedConfig === null) {
Expand Down Expand Up @@ -154,6 +164,18 @@ const getReferencesFromDependencies = (
folder: relativePath,
},
];
} else {
const detectedJsConfig = detectJSConfig(dependencyDir, configName)
if (detectedJsConfig !== null) {
return [
...referenceArray,
{
name: dependency,
path: path.join(relativePath, detectedJsConfig),
folder: relativePath,
},
];
}
}
}
return referenceArray;
Expand Down Expand Up @@ -225,11 +247,12 @@ const updateTsConfig = (
}
};

function getPathsFromReferences(references, tsconfigMap, ignorePathMappings
function getPathsFromReferences(references, tsconfigMap, jsconfigMap, ignorePathMappings
= []) {
return references.reduce((paths, ref) => {
if (ignorePathMappings.includes(ref.name)) return paths
const rootFolder = tsconfigMap[ref.name]?.compilerOptions?.rootDir ?? 'src'
const config = tsconfigMap[ref.name] ?? jsconfigMap[ref.name]
const rootFolder = config?.compilerOptions?.rootDir ?? 'src'
return {
...paths,
[`${ref.name}`]: [`${ref.folder}${rootFolder === '.' ? '' : `/${rootFolder}`}`],
Expand Down Expand Up @@ -316,6 +339,7 @@ const execute = async ({
let rootReferences = [];
let rootPaths = [];
let tsconfigMap = {}
let jsconfigMap = {}
packagesMap.forEach((packageEntry, packageName) => {
const detectedConfig = detectTSConfig(packageEntry.packageDir, configName, packageEntry.hasTsEntry && createTsConfig, cwd)

Expand All @@ -329,6 +353,25 @@ const execute = async ({
compilerOptions
}
}
} else {
const detectedJsConfig = detectJSConfig(packageEntry.packageDir, configName)
if (detectedJsConfig) {

let compilerOptions
try {
compilerOptions = parse(fs.readFileSync(path.join(packageEntry.packageDir, detectedJsConfig)).toString()).compilerOptions
} catch {
//ignore
}

jsconfigMap = {
...jsconfigMap,
[packageName]: {
detectedConfig,
compilerOptions
}
}
}
}
});

Expand All @@ -349,7 +392,7 @@ const execute = async ({
verbose
) || []).map(ensurePosixPathStyle);

const paths = getPathsFromReferences(references, tsconfigMap, ignorePathMappings)
const paths = getPathsFromReferences(references, tsconfigMap, jsconfigMap, ignorePathMappings)

if (verbose) {
console.log(`references of ${packageName}`, references);
Expand All @@ -366,8 +409,11 @@ const execute = async ({
packageEntry
);
} else {
// eslint-disable-next-line no-console
console.log(`NO ${configName === TSCONFIG_JSON ? configName : `${configName} nor ${TSCONFIG_JSON}`} for ${packageName}`);
const detectedJsConfig = jsconfigMap[packageName]?.detectedConfig
if (!detectedJsConfig) {
// eslint-disable-next-line no-console
console.log(`NO ${configName === TSCONFIG_JSON ? configName : `${configName} nor ${TSCONFIG_JSON}`} for ${packageName}`);
}
rootPaths.push({
name: packageName,
path: path.relative(cwd, packageEntry.packageDir),
Expand All @@ -377,7 +423,7 @@ const execute = async ({
});

rootReferences = (rootReferences || []).map(ensurePosixPathStyle);
rootPaths = getPathsFromReferences((rootReferences || []).map(ensurePosixPathStyle), tsconfigMap, ignorePathMappings)
rootPaths = getPathsFromReferences((rootReferences || []).map(ensurePosixPathStyle), tsconfigMap, {}, ignorePathMappings)

if (verbose) {
console.log('rootReferences', rootReferences);
Expand Down
6 changes: 6 additions & 0 deletions test-scenarios/ts-paths/utils/foos/js-only/jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"compilerOptions": {
"outDir": "dist",
"rootDir": "src"
}
}
5 changes: 5 additions & 0 deletions test-scenarios/ts-paths/utils/foos/js-only/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "js-only",
"version": "1.0.0",
"dependencies": {}
}
6 changes: 4 additions & 2 deletions test-scenarios/ts-paths/workspace-a/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
"name": "workspace-a",
"version": "1.0.0",
"dependencies": {
"workspace-b": "1.0.0"
"workspace-b": "1.0.0",
"js-only": "1.0.0",
"js-only2": "1.0.0"
},
"devDependencies": {
"foo-a": "1.0.0"
"foo-a": "1.0.0"
}
}
1 change: 1 addition & 0 deletions test-scenarios/yarn-ws-check-paths/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"workspaces": [
"workspace-a",
"workspace-b",
"workspace-c",
"shared/*",
"utils/**"
],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"compilerOptions": {
"outDir": "dist",
"rootDir": "src"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "js-only",
"version": "1.0.0",
"dependencies": {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
"workspace-b": "1.0.0"
},
"devDependencies": {
"foo-a": "1.0.0"
"foo-a": "1.0.0"
}
}
7 changes: 7 additions & 0 deletions test-scenarios/yarn-ws-check-paths/workspace-c/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "workspace-c",
"version": "1.0.0",
"dependencies": {
"js-only": "1.0.0"
}
}
11 changes: 11 additions & 0 deletions test-scenarios/yarn-ws-check-paths/workspace-c/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"compilerOptions": {
"outDir": "dist",
"rootDir": "src"
},
"references": [
{
"path": "../utils/foos/js-only/jsconfig.json"
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"name": "workspace-c",
"version": "1.0.0",
"dependencies": {
"cross-env": "5.0.5"
"cross-env": "5.0.5",
"js-only2": "1.0.0"
},
"peerDependencies": {
"foo-a": "1.0.0"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"compilerOptions": {
"outDir": "dist",
"rootDir": "src"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "js-only",
"version": "1.0.0",
"dependencies": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"compilerOptions": {
"outDir": "dist",
"rootDir": "src"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "js-only2",
"version": "1.0.0",
"dependencies": {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
"name": "workspace-a",
"version": "1.0.0",
"dependencies": {
"js-only": "1.0.0",
"workspace-b": "1.0.0"
},
"devDependencies": {
"foo-a": "1.0.0"
"foo-a": "1.0.0"
}
}
30 changes: 21 additions & 9 deletions tests/update-ts-references.check.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const path = require('path');
const fs = require('fs');
const {parse} = require("comment-json")
const {promise: execSh} = require("exec-sh");
const { parse } = require("comment-json")
const { promise: execSh } = require("exec-sh");

const rootFolderYarnCheck = path.join(
process.cwd(),
Expand Down Expand Up @@ -29,7 +29,7 @@ const rootFolderYarnCheckPathsNoChanges = path.join(
'yarn-ws-check-paths-no-changes'
);

const compilerOptions = {outDir: 'dist', rootDir: 'src'};
const compilerOptions = { outDir: 'dist', rootDir: 'src' };

const rootTsConfig = [
'.',
Expand Down Expand Up @@ -215,7 +215,7 @@ test('Detect changes in paths with the --check option', async () => {
errorCode = e.code;
}

expect(errorCode).toBe(3);
expect(errorCode).toBe(4);
const root = [
'.',
{
Expand Down Expand Up @@ -259,14 +259,26 @@ test('Detect changes in paths with the --check option', async () => {
},
];

const c = [
'./workspace-c',
{
compilerOptions,
references: [
{
"path": "../utils/foos/js-only/jsconfig.json",
}
],
},
];

const fooA = [
'./utils/foos/foo-a',
{
compilerOptions: {...compilerOptions, "paths": { "remove-me": ["../utils/remove/src"]}},
compilerOptions: { ...compilerOptions, "paths": { "remove-me": ["../utils/remove/src"] } },
},
];
[root,a,b,fooA].forEach((tsconfig) => {
const [configPath,config] = tsconfig;
[root, a, b, c, fooA].forEach((tsconfig) => {
const [configPath, config] = tsconfig;

expect(
parse(fs.readFileSync(path.join(rootFolderYarnCheckPaths, configPath, 'tsconfig.json')).toString())
Expand All @@ -293,7 +305,7 @@ test('No changes paths detected with the --check option', async () => {
{
compilerOptions: {
composite: true,
paths: { "foo-b": ["utils/foos/foo-b/src"]}
paths: { "foo-b": ["utils/foos/foo-b/src"] }
},
files: [],
references: [
Expand All @@ -315,7 +327,7 @@ test('No changes paths detected with the --check option', async () => {
{
compilerOptions: {
...compilerOptions,
paths: { "foo-a": ["../utils/foos/foo-a/src"], "workspace-b": ["../workspace-b/src"], }
paths: { "foo-a": ["../utils/foos/foo-a/src"], "workspace-b": ["../workspace-b/src"], }
},
references: [
{
Expand Down
Loading