Skip to content

Commit

Permalink
feat(js): add lockfile generator to js plugin (#13968)
Browse files Browse the repository at this point in the history
  • Loading branch information
meeroslav committed Jan 17, 2023
1 parent 942a6ae commit 23c2327
Show file tree
Hide file tree
Showing 9 changed files with 315 additions and 34 deletions.
6 changes: 6 additions & 0 deletions docs/generated/packages/js/executors/swc.json
Expand Up @@ -116,6 +116,12 @@
"items": { "type": "string" },
"description": "List of target names that annotate a build target for a project",
"default": ["build"]
},
"generateLockfile": {
"type": "boolean",
"description": "Generate a lockfile (e.g. yarn.lock) that matches the workspace lockfile to ensure package versions match.",
"default": false,
"x-priority": "internal"
}
},
"required": ["main", "outputPath", "tsConfig"],
Expand Down
6 changes: 6 additions & 0 deletions docs/generated/packages/js/executors/tsc.json
Expand Up @@ -116,6 +116,12 @@
"items": { "type": "string" },
"description": "List of target names that annotate a build target for a project",
"default": ["build"]
},
"generateLockfile": {
"type": "boolean",
"description": "Generate a lockfile (e.g. yarn.lock) that matches the workspace lockfile to ensure package versions match.",
"default": false,
"x-priority": "internal"
}
},
"required": ["main", "outputPath", "tsConfig"],
Expand Down
11 changes: 11 additions & 0 deletions e2e/js/src/js-swc.test.ts
Expand Up @@ -3,10 +3,13 @@ import {
checkFilesDoNotExist,
checkFilesExist,
cleanupProject,
detectPackageManager,
newProject,
packageManagerLockFile,
readJson,
runCLI,
runCLIAsync,
tmpProjPath,
uniq,
updateFile,
updateJson,
Expand Down Expand Up @@ -80,6 +83,14 @@ describe('js e2e', () => {
expect(output).toContain('1 task it depends on');
expect(output).toContain('Successfully compiled: 2 files with swc');

runCLI(`build ${parentLib} --generateLockfile=true`);
checkFilesExist(
`dist/libs/${parentLib}/package.json`,
`dist/libs/${parentLib}/${
packageManagerLockFile[detectPackageManager(tmpProjPath())]
}`
);

updateJson(`libs/${lib}/.lib.swcrc`, (json) => {
json.jsc.externalHelpers = true;
return json;
Expand Down
15 changes: 13 additions & 2 deletions e2e/js/src/js-tsc.test.ts
Expand Up @@ -3,6 +3,7 @@ import {
checkFilesDoNotExist,
checkFilesExist,
cleanupProject,
detectPackageManager,
getPackageManagerCommand,
newProject,
packageManagerLockFile,
Expand All @@ -12,6 +13,7 @@ import {
runCLIAsync,
runCommand,
runCommandUntil,
tmpProjPath,
uniq,
updateFile,
updateJson,
Expand Down Expand Up @@ -49,6 +51,14 @@ describe('js e2e', () => {
`dist/libs/${lib}/src/lib/${lib}.d.ts`
);

runCLI(`build ${lib} --generateLockfile=true`);
checkFilesExist(
`dist/libs/${lib}/package.json`,
`dist/libs/${lib}/${
packageManagerLockFile[detectPackageManager(tmpProjPath())]
}`
);

updateJson(`libs/${lib}/project.json`, (json) => {
json.targets.build.options.assets.push({
input: `libs/${lib}/docs`,
Expand Down Expand Up @@ -187,9 +197,10 @@ describe('package.json updates', () => {
runCLI(`build ${lib}`);

// Check that only 'react' exists, don't care about version
expect(readJson(`dist/libs/${lib}/package.json`).dependencies).toEqual({});
expect(readJson(`dist/libs/${lib}/package.json`).peerDependencies).toEqual({
expect(readJson(`dist/libs/${lib}/package.json`).dependencies).toEqual({
react: expect.any(String),
});
expect(readJson(`dist/libs/${lib}/package.json`).peerDependencies).toEqual({
tslib: expect.any(String),
});
checkFilesDoNotExist(`dist/libs/${lib}/${packageManagerLockFile['npm']}`);
Expand Down
6 changes: 6 additions & 0 deletions packages/js/src/executors/swc/schema.json
Expand Up @@ -97,6 +97,12 @@
},
"description": "List of target names that annotate a build target for a project",
"default": ["build"]
},
"generateLockfile": {
"type": "boolean",
"description": "Generate a lockfile (e.g. yarn.lock) that matches the workspace lockfile to ensure package versions match.",
"default": false,
"x-priority": "internal"
}
},
"required": ["main", "outputPath", "tsConfig"],
Expand Down
6 changes: 6 additions & 0 deletions packages/js/src/executors/tsc/schema.json
Expand Up @@ -86,6 +86,12 @@
},
"description": "List of target names that annotate a build target for a project",
"default": ["build"]
},
"generateLockfile": {
"type": "boolean",
"description": "Generate a lockfile (e.g. yarn.lock) that matches the workspace lockfile to ensure package versions match.",
"default": false,
"x-priority": "internal"
}
},
"required": ["main", "outputPath", "tsConfig"],
Expand Down
168 changes: 167 additions & 1 deletion packages/js/src/utils/package-json/update-package-json.spec.ts
@@ -1,4 +1,16 @@
import { getUpdatedPackageJsonContent } from './update-package-json';
import {
getUpdatedPackageJsonContent,
updatePackageJson,
UpdatePackageJsonOption,
} from './update-package-json';
import { vol } from 'memfs';
import { ExecutorContext, ProjectGraph } from '@nrwl/devkit';
import { DependentBuildableProjectNode } from '@nrwl/workspace/src/utilities/buildable-libs-utils';

jest.mock('nx/src/utils/workspace-root', () => ({
workspaceRoot: '/root',
}));
jest.mock('fs', () => require('memfs').fs);

describe('getUpdatedPackageJsonContent', () => {
it('should update fields for commonjs only (default)', () => {
Expand Down Expand Up @@ -259,3 +271,157 @@ describe('getUpdatedPackageJsonContent', () => {
});
});
});

describe('updatePackageJson', () => {
const originalPackageJson = {
name: '@org/lib1',
version: '0.0.3',
dependencies: { lib2: '^0.0.1' },
devDependencies: { jest: '27' },
};
const rootPackageJson = {
name: '@org/root',
version: '1.2.3',
dependencies: { external1: '~1.0.0', external2: '^4.0.0' },
devDependencies: { jest: '27' },
};
const projectGraph: ProjectGraph = {
nodes: {
'@org/lib1': {
type: 'lib',
name: '@org/lib1',
data: {
root: 'libs/lib1',
targets: {
build: {
outputs: ['{workspaceRoot}/dist/libs/lib1'],
},
},
files: [],
},
},
},
externalNodes: {
'npm:external1': {
type: 'npm',
name: 'npm:external1',
data: {
packageName: 'external1',
version: '1.0.0',
},
},
'npm:external2': {
type: 'npm',
name: 'npm:external2',
data: {
packageName: 'external2',
version: '4.5.6',
},
},
'npm:jest': {
type: 'npm',
name: 'npm:jest',
data: {
packageName: 'jest',
version: '21.1.0',
},
},
},
dependencies: {
'@org/lib1': [
{ source: '@org/lib1', target: 'npm:external1', type: 'static' },
{ source: '@org/lib1', target: 'npm:external2', type: 'static' },
],
},
};
const context: ExecutorContext = {
root: '/root',
projectName: '@org/lib1',
isVerbose: false,
cwd: '',
targetName: 'build',
projectGraph,
};

it('should generate new package if missing', () => {
const fsJson = {};
vol.fromJSON(fsJson, '/root');
const options: UpdatePackageJsonOption = {
outputPath: 'dist/libs/lib1',
projectRoot: 'libs/lib1',
main: 'libs/lib1/main.ts',
};
const dependencies: DependentBuildableProjectNode[] = [];
updatePackageJson(options, context, undefined, dependencies);

expect(vol.existsSync('dist/libs/lib1/package.json')).toEqual(true);
const distPackageJson = JSON.parse(
vol.readFileSync('dist/libs/lib1/package.json', 'utf-8').toString()
);
expect(distPackageJson).toMatchInlineSnapshot(`
Object {
"main": "./main.js",
"name": "@org/lib1",
"types": "./main.d.ts",
"version": "0.0.1",
}
`);
});

it('should keep package unchanged if "updateBuildableProjectDepsInPackageJson" not set', () => {
const fsJson = {
'libs/lib1/package.json': JSON.stringify(originalPackageJson, null, 2),
};
vol.fromJSON(fsJson, '/root');
const options: UpdatePackageJsonOption = {
outputPath: 'dist/libs/lib1',
projectRoot: 'libs/lib1',
main: 'libs/lib1/main.ts',
};
const dependencies: DependentBuildableProjectNode[] = [];
updatePackageJson(options, context, undefined, dependencies);

expect(vol.existsSync('dist/libs/lib1/package.json')).toEqual(true);
const distPackageJson = JSON.parse(
vol.readFileSync('dist/libs/lib1/package.json', 'utf-8').toString()
);
expect(distPackageJson.dependencies).toEqual(
originalPackageJson.dependencies
);
expect(distPackageJson.main).toEqual('./main.js');
expect(distPackageJson.types).toEqual('./main.d.ts');
});

it('should modify package if "updateBuildableProjectDepsInPackageJson" is set', () => {
const fsJson = {
'package.json': JSON.stringify(rootPackageJson, null, 2),
'libs/lib1/package.json': JSON.stringify(originalPackageJson, null, 2),
};
vol.fromJSON(fsJson, '/root');
const options: UpdatePackageJsonOption = {
outputPath: 'dist/libs/lib1',
projectRoot: 'libs/lib1',
main: 'libs/lib1/main.ts',
updateBuildableProjectDepsInPackageJson: true,
};
const dependencies: DependentBuildableProjectNode[] = [];
updatePackageJson(options, context, undefined, dependencies);

expect(vol.existsSync('dist/libs/lib1/package.json')).toEqual(true);
const distPackageJson = JSON.parse(
vol.readFileSync('dist/libs/lib1/package.json', 'utf-8').toString()
);
expect(distPackageJson).toMatchInlineSnapshot(`
Object {
"dependencies": Object {
"external1": "1.0.0",
"external2": "4.5.6",
},
"main": "./main.js",
"name": "@org/lib1",
"types": "./main.d.ts",
"version": "0.0.1",
}
`);
});
});

1 comment on commit 23c2327

@vercel
Copy link

@vercel vercel bot commented on 23c2327 Jan 17, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

nx-dev – ./

nx-dev-nrwl.vercel.app
nx-five.vercel.app
nx-dev-git-master-nrwl.vercel.app
nx.dev

Please sign in to comment.