Skip to content

Commit

Permalink
feat(node): allow building of publishable libs depending on other pub…
Browse files Browse the repository at this point in the history
…lishable libs

This commits adds a proper logic to automatically update the tsconfig paths s.t. they correctly
point to the compiled version of potential other dependent publishable libraries.
  • Loading branch information
juristr authored and vsavkin committed Feb 4, 2020
1 parent 5840db1 commit da1f851
Show file tree
Hide file tree
Showing 3 changed files with 622 additions and 165 deletions.
231 changes: 190 additions & 41 deletions e2e/node.test.ts
Expand Up @@ -19,8 +19,10 @@ import {
runNgAdd,
copyMissingPackages,
setMaxWorkers,
fileExists
fileExists,
newProject
} from './utils';
import { toClassName } from '@nrwl/workspace';

function getData(): Promise<any> {
return new Promise(resolve => {
Expand Down Expand Up @@ -246,51 +248,198 @@ forEachCli(currentCLIName => {
expect(result).toContain('Hello World!');
}, 60000);

it('should be able to generate a node library', async () => {
ensureProject();
const nodelib = uniq('nodelib');
describe('Node Libraries', () => {
beforeAll(() => {
// force a new project to avoid collissions with the npmScope that has been altered before
newProject();
});

runCLI(`generate @nrwl/node:lib ${nodelib}`);
it('should be able to generate a node library', async () => {
ensureProject();
const nodelib = uniq('nodelib');

const lintResults = runCLI(`lint ${nodelib}`);
expect(lintResults).toContain('All files pass linting.');
runCLI(`generate @nrwl/node:lib ${nodelib}`);

const jestResult = await runCLIAsync(`test ${nodelib}`);
expect(jestResult.stderr).toContain('Test Suites: 1 passed, 1 total');
}, 60000);
const lintResults = runCLI(`lint ${nodelib}`);
expect(lintResults).toContain('All files pass linting.');

it('should be able to generate a publishable node library', async () => {
ensureProject();
const nodeLib = uniq('nodelib');
runCLI(`generate @nrwl/node:lib ${nodeLib} --publishable`);
fileExists(`libs/${nodeLib}/package.json`);
const tslibConfig = readJson(`libs/${nodeLib}/tsconfig.lib.json`);
expect(tslibConfig).toEqual({
extends: './tsconfig.json',
compilerOptions: {
module: 'commonjs',
outDir: '../../dist/out-tsc',
declaration: true,
rootDir: './src',
types: ['node']
},
exclude: ['**/*.spec.ts'],
include: ['**/*.ts']
});
await runCLIAsync(`build ${nodeLib}`);
checkFilesExist(
`dist/libs/${nodeLib}/index.js`,
`dist/libs/${nodeLib}/index.d.ts`,
`dist/libs/${nodeLib}/package.json`
);
const jestResult = await runCLIAsync(`test ${nodelib}`);
expect(jestResult.stderr).toContain('Test Suites: 1 passed, 1 total');
}, 60000);

it('should be able to generate a publishable node library', async () => {
ensureProject();

const nodeLib = uniq('nodelib');
runCLI(`generate @nrwl/node:lib ${nodeLib} --publishable`);
fileExists(`libs/${nodeLib}/package.json`);
const tslibConfig = readJson(`libs/${nodeLib}/tsconfig.lib.json`);
expect(tslibConfig).toEqual({
extends: './tsconfig.json',
compilerOptions: {
module: 'commonjs',
outDir: '../../dist/out-tsc',
declaration: true,
rootDir: './src',
types: ['node']
},
exclude: ['**/*.spec.ts'],
include: ['**/*.ts']
});
await runCLIAsync(`build ${nodeLib}`);
checkFilesExist(
`dist/libs/${nodeLib}/index.js`,
`dist/libs/${nodeLib}/index.d.ts`,
`dist/libs/${nodeLib}/package.json`
);

const packageJson = readJson(`dist/libs/${nodeLib}/package.json`);
expect(packageJson).toEqual({
name: `@proj/${nodeLib}`,
version: '0.0.1',
main: 'index.js',
typings: 'index.d.ts'
});
}, 60000);

describe('with dependencies', () => {
/**
* Graph:
*
* childLib
* /
* parentLib =>
* \
* \
* childLib2
*
*/
let parentLib: string;
let childLib: string;
let childLib2: string;

beforeEach(() => {
parentLib = uniq('parentlib');
childLib = uniq('childlib');
childLib2 = uniq('childlib2');

ensureProject();

runCLI(`generate @nrwl/node:lib ${parentLib} --publishable=true`);
runCLI(`generate @nrwl/node:lib ${childLib} --publishable=true`);
runCLI(`generate @nrwl/node:lib ${childLib2} --publishable=true`);

// create dependencies by importing
const createDep = (parent, children: string[]) => {
updateFile(
`libs/${parent}/src/lib/${parent}.ts`,
`
${children
.map(entry => `import { ${entry} } from '@proj/${entry}';`)
.join('\n')}
export function ${parent}(): string {
return '${parent}' + ' ' + ${children
.map(entry => `${entry}()`)
.join('+')}
}
`
);
};

createDep(parentLib, [childLib, childLib2]);
});

it('should throw an error if the dependent library has not been built before building the parent lib', () => {
expect.assertions(2);

const packageJson = readJson(`dist/libs/${nodeLib}/package.json`);
expect(packageJson).toEqual({
name: nodeLib,
version: '0.0.1',
main: 'index.js',
typings: 'index.d.ts'
try {
runCLI(`build ${parentLib}`);
} catch (e) {
expect(e.stderr.toString()).toContain(
`Some of the library ${parentLib}'s dependencies have not been built yet. Please build these libraries before:`
);
expect(e.stderr.toString()).toContain(`${childLib}`);
}
});

it('should build a library without dependencies', () => {
const childLibOutput = runCLI(`build ${childLib}`);

expect(childLibOutput).toContain(
`Done compiling TypeScript files for library ${childLib}`
);
});

it('should build a parent library if the dependent libraries have been built before', () => {
const childLibOutput = runCLI(`build ${childLib}`);
expect(childLibOutput).toContain(
`Done compiling TypeScript files for library ${childLib}`
);

const childLib2Output = runCLI(`build ${childLib2}`);
expect(childLib2Output).toContain(
`Done compiling TypeScript files for library ${childLib2}`
);

const parentLibOutput = runCLI(`build ${parentLib}`);
expect(parentLibOutput).toContain(
`Done compiling TypeScript files for library ${parentLib}`
);

// assert package.json deps have been set
const assertPackageJson = (
parent: string,
lib: string,
version: string
) => {
const jsonFile = readJson(`dist/libs/${parent}/package.json`);
const childDependencyVersion =
jsonFile.dependencies[`@proj/${lib}`];
expect(childDependencyVersion).toBe(version);
};

assertPackageJson(parentLib, childLib, '0.0.1');
assertPackageJson(parentLib, childLib2, '0.0.1');
});

// it('should automatically build all deps and update package.json when passing --withDeps flags', () => {
// const parentLibOutput = runCLI(`build ${parentLib} --withDeps`);

// expect(parentLibOutput).toContain(
// `Done compiling TypeScript files for library ${parentLib}`
// );
// expect(parentLibOutput).toContain(
// `Done compiling TypeScript files for library ${childLib}`
// );
// expect(parentLibOutput).toContain(
// `Done compiling TypeScript files for library ${childChildLib}`
// );
// expect(parentLibOutput).toContain(
// `Done compiling TypeScript files for library ${childLib2}`
// );
// expect(parentLibOutput).toContain(
// `Done compiling TypeScript files for library ${childLibShared}`
// );

// // // assert package.json deps have been set
// const assertPackageJson = (
// parent: string,
// lib: string,
// version: string
// ) => {
// const jsonFile = readJson(`dist/libs/${parent}/package.json`);
// const childDependencyVersion =
// jsonFile.dependencies[`@proj/${lib}`];
// expect(childDependencyVersion).toBe(version);
// };

// assertPackageJson(parentLib, childLib, '0.0.1');
// assertPackageJson(childLib, childChildLib, '0.0.1');
// assertPackageJson(childLib, childLibShared, '0.0.1');
// assertPackageJson(childLib2, childLibShared, '0.0.1');
// });
});
}, 60000);
});
});
});

0 comments on commit da1f851

Please sign in to comment.