Skip to content

Commit

Permalink
fix(core): fix(core): add option in nx json to cache tsconfig during …
Browse files Browse the repository at this point in the history
…hashing
  • Loading branch information
yharaskrik committed May 27, 2021
1 parent afd4833 commit b56bfef
Show file tree
Hide file tree
Showing 2 changed files with 164 additions and 54 deletions.
180 changes: 136 additions & 44 deletions packages/workspace/src/core/hasher/hasher.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,37 @@ import fs = require('fs');

jest.mock('fs');

describe('Hasher', () => {
describe.only('Hasher', () => {
const nxJson = {
npmScope: 'nrwl',
projects: {
parent: { implicitDependencies: [], tags: [] },
child: { implicitDependencies: [], tags: [] },
},
};

const workSpaceJson = {
projects: {
parent: { root: 'libs/parent' },
child: { root: 'libs/child' },
},
};

const tsConfigBaseJsonHash = JSON.stringify({
compilerOptions: {
paths: {
'@nrwl/parent': ['libs/parent/src/index.ts'],
'@nrwl/child': ['libs/child/src/index.ts'],
},
},
});
let hashes = {
'yarn.lock': 'yarn.lock.hash',
'nx.json': 'nx.json.hash',
'package-lock.json': 'package-lock.json.hash',
'package.json': 'package.json.hash',
'pnpm-lock.yaml': 'pnpm-lock.yaml.hash',
'tsconfig.base.json': 'tsconfig.base.json.hash',
'tsconfig.base.json': tsConfigBaseJsonHash,
'workspace.json': 'workspace.json.hash',
global1: 'global1.hash',
global2: 'global2.hash',
Expand All @@ -23,24 +46,28 @@ describe('Hasher', () => {
};
}

it('should create project hash', async () => {
beforeAll(() => {
fs.readFileSync = (file) => {
if (file === 'workspace.json') {
return JSON.stringify({
projects: { proj: 'proj-from-workspace.json' },
});
return JSON.stringify(workSpaceJson);
}
if (file === 'nx.json') {
return JSON.stringify({ projects: { proj: 'proj-from-nx.json' } });
return JSON.stringify(nxJson);
}
if (file === 'tsconfig.base.json') {
return tsConfigBaseJsonHash;
}
return file;
};
});

it('should create project hash', async () => {
hashes['/file'] = 'file.hash';
const hasher = new Hasher(
{
nodes: {
proj: {
name: 'proj',
parent: {
name: 'parent',
type: 'lib',
data: {
root: '',
Expand All @@ -49,7 +76,7 @@ describe('Hasher', () => {
},
},
dependencies: {
proj: [],
parent: [],
},
},
{} as any,
Expand All @@ -62,8 +89,8 @@ describe('Hasher', () => {
const hash = (
await hasher.hashTasks([
{
target: { project: 'proj', target: 'build' },
id: 'proj-build',
target: { project: 'parent', target: 'build' },
id: 'parent-build',
overrides: { prop: 'prop-value' },
},
])
Expand All @@ -72,21 +99,80 @@ describe('Hasher', () => {
expect(hash.value).toContain('yarn.lock.hash'); //implicits
expect(hash.value).toContain('file.hash'); //project files
expect(hash.value).toContain('prop-value'); //overrides
expect(hash.value).toContain('proj'); //project
expect(hash.value).toContain('parent'); //project
expect(hash.value).toContain('build'); //target
expect(hash.value).toContain('runtime123'); //target
expect(hash.value).toContain('runtime456'); //target

expect(hash.details.command).toEqual('proj|build||{"prop":"prop-value"}');
expect(hash.details.command).toEqual('parent|build||{"prop":"prop-value"}');
expect(hash.details.sources).toEqual({
proj: '/file|file.hash|"proj-from-workspace.json"|"proj-from-nx.json"',
parent:
'/file|file.hash|{"root":"libs/parent"}|{"implicitDependencies":[],"tags":[]}|{"compilerOptions":{"paths":{"@nrwl/parent":["libs/parent/src/index.ts"],"@nrwl/child":["libs/child/src/index.ts"]}}}',
});
expect(hash.details.implicitDeps).toEqual({
'yarn.lock': 'yarn.lock.hash',
'package-lock.json': 'package-lock.json.hash',
'pnpm-lock.yaml': 'pnpm-lock.yaml.hash',
});
expect(hash.details.runtime).toEqual({
'echo runtime123': 'runtime123',
'echo runtime456': 'runtime456',
});
});

it('should create project hash with tsconfig.base.json cache', async () => {
hashes['/file'] = 'file.hash';
const hasher = new Hasher(
{
nodes: {
parent: {
name: 'parent',
type: 'lib',
data: {
root: '',
files: [{ file: '/file', ext: '.ts', hash: 'file.hash' }],
},
},
},
dependencies: {
parent: [],
},
},
{} as any,
{
runtimeCacheInputs: ['echo runtime123', 'echo runtime456'],
cacheTsConfig: true,
},
createHashing()
);

const hash = (
await hasher.hashTasks([
{
target: { project: 'parent', target: 'build' },
id: 'parent-build',
overrides: { prop: 'prop-value' },
},
])
)[0];

expect(hash.value).toContain('yarn.lock.hash'); //implicits
expect(hash.value).toContain('file.hash'); //project files
expect(hash.value).toContain('prop-value'); //overrides
expect(hash.value).toContain('parent'); //project
expect(hash.value).toContain('build'); //target
expect(hash.value).toContain('runtime123'); //target
expect(hash.value).toContain('runtime456'); //target

expect(hash.details.command).toEqual('parent|build||{"prop":"prop-value"}');
expect(hash.details.sources).toEqual({
parent:
'/file|file.hash|{"root":"libs/parent"}|{"implicitDependencies":[],"tags":[]}|{"compilerOptions":{"paths":{"@nrwl/parent":["libs/parent/src/index.ts"]}}}',
});
expect(hash.details.implicitDeps).toEqual({
'yarn.lock': 'yarn.lock.hash',
'nx.json': '{}',
'package-lock.json': 'package-lock.json.hash',
'pnpm-lock.yaml': 'pnpm-lock.yaml.hash',
'tsconfig.base.json': 'tsconfig.base.json.hash',
});
expect(hash.details.runtime).toEqual({
'echo runtime123': 'runtime123',
Expand All @@ -98,8 +184,8 @@ describe('Hasher', () => {
const hasher = new Hasher(
{
nodes: {
proj: {
name: 'proj',
parent: {
name: 'parent',
type: 'lib',
data: {
root: '',
Expand All @@ -108,7 +194,7 @@ describe('Hasher', () => {
},
},
dependencies: {
proj: [],
parent: [],
},
},
{} as any,
Expand All @@ -121,8 +207,8 @@ describe('Hasher', () => {
try {
await hasher.hashTasks([
{
target: { project: 'proj', target: 'build' },
id: 'proj-build',
target: { project: 'parent', target: 'build' },
id: 'parent-build',
overrides: {},
},
]);
Expand Down Expand Up @@ -180,8 +266,10 @@ describe('Hasher', () => {

// note that the parent hash is based on parent source files only!
expect(hash.details.sources).toEqual({
parent: '/filea|a.hash|""|""',
child: '/fileb|b.hash|""|""',
child:
'/fileb|b.hash|{"root":"libs/child"}|{"implicitDependencies":[],"tags":[]}|{"compilerOptions":{"paths":{"@nrwl/parent":["libs/parent/src/index.ts"],"@nrwl/child":["libs/child/src/index.ts"]}}}',
parent:
'/filea|a.hash|{"root":"libs/parent"}|{"implicitDependencies":[],"tags":[]}|{"compilerOptions":{"paths":{"@nrwl/parent":["libs/parent/src/index.ts"],"@nrwl/child":["libs/child/src/index.ts"]}}}',
});
});

Expand All @@ -191,16 +279,16 @@ describe('Hasher', () => {
const hasher = new Hasher(
{
nodes: {
proja: {
name: 'proja',
parent: {
name: 'parent',
type: 'lib',
data: {
root: '',
files: [{ file: '/filea', ext: '.ts', hash: 'a.hash' }],
},
},
projb: {
name: 'projb',
child: {
name: 'child',
type: 'lib',
data: {
root: '',
Expand All @@ -209,8 +297,8 @@ describe('Hasher', () => {
},
},
dependencies: {
proja: [{ source: 'proja', target: 'projb', type: 'static' }],
projb: [{ source: 'projb', target: 'proja', type: 'static' }],
parent: [{ source: 'parent', target: 'child', type: 'static' }],
child: [{ source: 'child', target: 'parent', type: 'static' }],
},
},
{} as any,
Expand All @@ -221,8 +309,8 @@ describe('Hasher', () => {
const tasksHash = (
await hasher.hashTasks([
{
target: { project: 'proja', target: 'build' },
id: 'proja-build',
target: { project: 'parent', target: 'build' },
id: 'parent-build',
overrides: { prop: 'prop-value' },
},
])
Expand All @@ -232,18 +320,20 @@ describe('Hasher', () => {
expect(tasksHash.value).toContain('a.hash'); //project files
expect(tasksHash.value).toContain('b.hash'); //project files
expect(tasksHash.value).toContain('prop-value'); //overrides
expect(tasksHash.value).toContain('proj'); //project
expect(tasksHash.value).toContain('parent|build'); //project and target
expect(tasksHash.value).toContain('build'); //target
expect(tasksHash.details.sources).toEqual({
proja: '/filea|a.hash|""|""',
projb: '/fileb|b.hash|""|""',
child:
'/fileb|b.hash|{"root":"libs/child"}|{"implicitDependencies":[],"tags":[]}|{"compilerOptions":{"paths":{"@nrwl/parent":["libs/parent/src/index.ts"],"@nrwl/child":["libs/child/src/index.ts"]}}}',
parent:
'/filea|a.hash|{"root":"libs/parent"}|{"implicitDependencies":[],"tags":[]}|{"compilerOptions":{"paths":{"@nrwl/parent":["libs/parent/src/index.ts"],"@nrwl/child":["libs/child/src/index.ts"]}}}',
});

const hashb = (
await hasher.hashTasks([
{
target: { project: 'projb', target: 'build' },
id: 'projb-build',
target: { project: 'child', target: 'build' },
id: 'child-build',
overrides: { prop: 'prop-value' },
},
])
Expand All @@ -253,11 +343,13 @@ describe('Hasher', () => {
expect(hashb.value).toContain('a.hash'); //project files
expect(hashb.value).toContain('b.hash'); //project files
expect(hashb.value).toContain('prop-value'); //overrides
expect(hashb.value).toContain('proj'); //project
expect(hashb.value).toContain('child|build'); //project and target
expect(hashb.value).toContain('build'); //target
expect(hashb.details.sources).toEqual({
proja: '/filea|a.hash|""|""',
projb: '/fileb|b.hash|""|""',
child:
'/fileb|b.hash|{"root":"libs/child"}|{"implicitDependencies":[],"tags":[]}|{"compilerOptions":{"paths":{"@nrwl/parent":["libs/parent/src/index.ts"],"@nrwl/child":["libs/child/src/index.ts"]}}}',
parent:
'/filea|a.hash|{"root":"libs/parent"}|{"implicitDependencies":[],"tags":[]}|{"compilerOptions":{"paths":{"@nrwl/parent":["libs/parent/src/index.ts"],"@nrwl/child":["libs/child/src/index.ts"]}}}',
});
});

Expand All @@ -267,8 +359,8 @@ describe('Hasher', () => {
const hasher = new Hasher(
{
nodes: {
proja: {
name: 'proja',
parent: {
name: 'parent',
type: 'lib',
data: {
root: '',
Expand Down Expand Up @@ -302,8 +394,8 @@ describe('Hasher', () => {
const tasksHash = (
await hasher.hashTasks([
{
target: { project: 'proja', target: 'build' },
id: 'proja-build',
target: { project: 'parent', target: 'build' },
id: 'parent-build',
overrides: { prop: 'prop-value' },
},
])
Expand Down
38 changes: 28 additions & 10 deletions packages/workspace/src/core/hasher/hasher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ export class Hasher {
this.fileHasher = new FileHasher(hashing);
this.fileHasher.clear();
}
this.projectHashes = new ProjectHasher(this.projectGraph, this.hashing);
this.projectHashes = new ProjectHasher(this.projectGraph, this.hashing, {
cacheTsConfig: this.options.cacheTsConfig ?? false,
});
}

async hashTasks(tasks: Task[]): Promise<Hash[]> {
Expand Down Expand Up @@ -235,7 +237,8 @@ class ProjectHasher {

constructor(
private readonly projectGraph: ProjectGraph,
private readonly hashing: HashingImpl
private readonly hashing: HashingImpl,
private readonly options: { cacheTsConfig: boolean }
) {
this.workspaceJson = this.readConfigFile(workspaceFileName());
this.nxJson = this.readConfigFile('nx.json');
Expand Down Expand Up @@ -287,16 +290,31 @@ class ProjectHasher {
);
const nxJson = JSON.stringify(this.nxJson.projects[projectName] ?? '');

const { paths, ...compilerOptions } = this.tsConfigJson.compilerOptions;
let tsConfig: string;

if (this.options.cacheTsConfig) {
const {
paths,
...compilerOptions
} = this.tsConfigJson.compilerOptions;

const tsConfig = JSON.stringify({
compilerOptions: {
...compilerOptions,
paths: {
[projectName]: paths[projectName] ?? [],
const rootPath = this.workspaceJson.projects[projectName].root.split(
'/'
);
rootPath.shift();
const pathAlias = `@${this.nxJson.npmScope}/${rootPath.join('/')}`;

tsConfig = JSON.stringify({
compilerOptions: {
...compilerOptions,
paths: {
[pathAlias]: paths[pathAlias] ?? [],
},
},
},
});
});
} else {
tsConfig = JSON.stringify(this.tsConfigJson);
}

res(
this.hashing.hashArray([
Expand Down

0 comments on commit b56bfef

Please sign in to comment.