Skip to content

Commit a95cba3

Browse files
committed
feat(core): support different workspace layouts
1 parent 6e8d461 commit a95cba3

File tree

26 files changed

+231
-105
lines changed

26 files changed

+231
-105
lines changed

e2e/angular-package.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { toClassName } from '@nrwl/workspace';
22
import {
3-
ensureProject,
43
forEachCli,
4+
newProject,
55
readJson,
66
runCLI,
77
uniq,
@@ -30,7 +30,7 @@ forEachCli('angular', (cli) => {
3030
childLib = uniq('childlib');
3131
childLib2 = uniq('childlib2');
3232

33-
ensureProject();
33+
newProject();
3434

3535
runCLI(
3636
`generate @nrwl/angular:library ${parentLib} --publishable=true --no-interactive`

e2e/cli.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ forEachCli(() => {
151151

152152
describe('migrate', () => {
153153
it('should run migrations', () => {
154-
ensureProject();
154+
newProject();
155155

156156
updateFile(
157157
`./node_modules/migrate-parent-package/package.json`,

e2e/custom-layout.test.ts

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import {
2+
checkFilesExist,
3+
forEachCli,
4+
newProject,
5+
readFile,
6+
readJson,
7+
runCLI,
8+
runCLIAsync,
9+
uniq,
10+
updateFile,
11+
} from './utils';
12+
13+
forEachCli('nx', () => {
14+
describe('custom workspace layout', () => {
15+
it('should work', async () => {
16+
newProject();
17+
18+
const nxJson = readJson('nx.json');
19+
nxJson.workspaceLayout = {
20+
libsDir: 'packages',
21+
appsDir: 'packages',
22+
};
23+
24+
updateFile('nx.json', JSON.stringify(nxJson));
25+
26+
const reactApp = uniq('reactapp');
27+
const reactLib = uniq('reactlib');
28+
29+
const ngApp = uniq('ngapp');
30+
const ngLib = uniq('nglib');
31+
32+
const expressApp = uniq('expessapp');
33+
const expressLib = uniq('expresslib');
34+
35+
runCLI(`generate @nrwl/react:app ${reactApp} --no-interactive`);
36+
runCLI(`generate @nrwl/react:lib ${reactLib} --no-interactive`);
37+
38+
runCLI(`generate @nrwl/angular:app ${ngApp} --no-interactive`);
39+
runCLI(`generate @nrwl/angular:lib ${ngLib} --no-interactive`);
40+
41+
runCLI(`generate @nrwl/express:app ${expressApp} --no-interactive`);
42+
runCLI(`generate @nrwl/express:lib ${expressLib} --no-interactive`);
43+
44+
checkFilesExist(
45+
`packages/${reactLib}/src/index.ts`,
46+
`packages/${reactApp}/src/main.tsx`,
47+
`packages/${reactApp}-e2e/cypress.json`,
48+
49+
`packages/${ngLib}/src/index.ts`,
50+
`packages/${ngApp}/src/main.ts`,
51+
`packages/${ngApp}-e2e/cypress.json`,
52+
53+
`packages/${expressLib}/src/index.ts`,
54+
`packages/${expressApp}/src/main.ts`
55+
);
56+
57+
const workspaceJson = readFile('workspace.json');
58+
expect(workspaceJson).not.toContain('apps/');
59+
expect(workspaceJson).not.toContain('libs/');
60+
61+
const libTestResults = await runCLIAsync(`test ${expressLib}`);
62+
expect(libTestResults.stdout).toContain(
63+
'No tests found, exiting with code 0'
64+
);
65+
66+
const appBuildResults = await runCLIAsync(`build ${expressApp}`);
67+
expect(appBuildResults.stdout).toContain(`nx run ${expressApp}:build`);
68+
69+
checkFilesExist(`dist/packages/${expressApp}/main.js`);
70+
}, 1000000);
71+
});
72+
});
73+
74+
forEachCli('angular', () => {
75+
describe('custom workspace layout', () => {
76+
it('should work', () => {});
77+
});
78+
});

e2e/react.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
checkFilesExist,
55
ensureProject,
66
forEachCli,
7+
newProject,
78
readFile,
89
readJson,
910
renameFile,

e2e/utils.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -166,11 +166,9 @@ export function newProject(): void {
166166
cleanup();
167167
if (!directoryExists(tmpBackupProjPath())) {
168168
runNew('--collection=@nrwl/workspace --npmScope=proj', true);
169-
170-
const packages = getDirectories('./build/packages')
171-
.filter((pkg) => !pkg.startsWith('create-'))
172-
.map((pkg) => `@nrwl/${pkg}`);
173-
yarnAdd(packages.join(' '));
169+
yarnAdd(
170+
`@nrwl/angular @nrwl/express @nrwl/nest @nrwl/next @nrwl/react @nrwl/storybook @nrwl/nx-plugin @nrwl/bazel`
171+
);
174172

175173
execSync(`mv ${tmpProjPath()} ${tmpBackupProjPath()}`);
176174
}
@@ -185,7 +183,9 @@ export function newProject(): void {
185183
* If one is not found, it creates a new project.
186184
*/
187185
export function ensureProject(): void {
186+
// if (!directoryExists(tmpProjPath())) {
188187
newProject();
188+
// }
189189
}
190190

191191
export function supportUi() {
@@ -271,7 +271,10 @@ export function runCLI(
271271
/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,
272272
''
273273
);
274-
console.log(r);
274+
275+
if (process.env.VERBOSE_OUTPUT) {
276+
console.log(r);
277+
}
275278

276279
const needsMaxWorkers = /g.*(express|nest|node|web|react):app.*/;
277280
if (needsMaxWorkers.test(command)) {

packages/angular/src/schematics/application/application.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import {
4040
insertImport,
4141
getProjectConfig,
4242
updateWorkspaceInTree,
43+
appsDir,
4344
} from '@nrwl/workspace/src/utils/ast-utils';
4445

4546
interface NormalizedSchema extends Schema {
@@ -760,8 +761,8 @@ function normalizeOptions(host: Tree, options: Schema): NormalizedSchema {
760761
e2eProjectName = `${appProjectName}-e2e`;
761762
}
762763

763-
const appProjectRoot = `apps/${appDirectory}`;
764-
const e2eProjectRoot = `apps/${appDirectory}-e2e`;
764+
const appProjectRoot = `${appsDir(host)}/${appDirectory}`;
765+
const e2eProjectRoot = `${appsDir(host)}/${appDirectory}-e2e`;
765766

766767
const parsedTags = options.tags
767768
? options.tags.split(',').map((s) => s.trim())

packages/angular/src/schematics/library/library.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import {
3838
} from '@nrwl/workspace';
3939
import { addUnitTestRunner } from '../init/init';
4040
import { addImportToModule, addRoute } from '../../utils/ast-utils';
41-
import { insertImport } from '@nrwl/workspace/src/utils/ast-utils';
41+
import { insertImport, libsDir } from '@nrwl/workspace/src/utils/ast-utils';
4242

4343
interface NormalizedSchema extends Schema {
4444
name: string;
@@ -219,11 +219,11 @@ function addChildren(options: NormalizedSchema): Rule {
219219
};
220220
}
221221

222-
function updateNgPackage(options: NormalizedSchema): Rule {
222+
function updateNgPackage(host: Tree, options: NormalizedSchema): Rule {
223223
if (!options.publishable) {
224224
return noop();
225225
}
226-
const dest = `${offsetFromRoot(options.projectRoot)}dist/libs/${
226+
const dest = `${offsetFromRoot(options.projectRoot)}dist/${libsDir(host)}/${
227227
options.projectDirectory
228228
}`;
229229
return chain([
@@ -395,7 +395,7 @@ function updateProject(options: NormalizedSchema): Rule {
395395
},
396396
};
397397
}),
398-
updateNgPackage(options),
398+
updateNgPackage(host, options),
399399
])(host, context);
400400
};
401401
}
@@ -408,7 +408,7 @@ function updateTsConfig(options: NormalizedSchema): Rule {
408408
const c = json.compilerOptions;
409409
delete c.paths[options.name];
410410
c.paths[`@${nxJson.npmScope}/${options.projectDirectory}`] = [
411-
`libs/${options.projectDirectory}/src/index.ts`,
411+
`${libsDir(host)}/${options.projectDirectory}/src/index.ts`,
412412
];
413413
return json;
414414
})(host, context);
@@ -490,7 +490,7 @@ function normalizeOptions(host: Tree, options: Schema): NormalizedSchema {
490490

491491
const projectName = projectDirectory.replace(new RegExp('/', 'g'), '-');
492492
const fileName = options.simpleModuleName ? name : projectName;
493-
const projectRoot = `libs/${projectDirectory}`;
493+
const projectRoot = `${libsDir(host)}/${projectDirectory}`;
494494

495495
const moduleName = `${toClassName(fileName)}Module`;
496496
const parsedTags = options.tags

packages/cypress/src/schematics/cypress-project/cypress-project.ts

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import {
55
move,
66
noop,
77
Rule,
8+
SchematicContext,
89
template,
10+
Tree,
911
url,
1012
} from '@angular-devkit/schematics';
1113
import { join, normalize } from '@angular-devkit/core';
@@ -21,6 +23,7 @@ import { offsetFromRoot } from '@nrwl/workspace';
2123
import { toFileName } from '@nrwl/workspace';
2224
import { Schema } from './schema';
2325
import { toJS } from '@nrwl/workspace/src/utils/rules/to-js';
26+
import { appsDir } from '@nrwl/workspace/src/utils/ast-utils';
2427

2528
export interface CypressProjectSchema extends Schema {
2629
projectName: string;
@@ -29,7 +32,6 @@ export interface CypressProjectSchema extends Schema {
2932

3033
function generateFiles(options: CypressProjectSchema): Rule {
3134
return (): Rule => {
32-
// host.delete(`${options.projectRoot}/tsconfig.e2e.json`);
3335
return mergeWith(
3436
apply(url('./files'), [
3537
template({
@@ -90,38 +92,47 @@ function updateWorkspaceJson(options: CypressProjectSchema): Rule {
9092
}
9193

9294
export default function (options: CypressProjectSchema): Rule {
93-
options = normalizeOptions(options);
94-
return chain([
95-
addLintFiles(options.projectRoot, options.linter, {
96-
localConfig: {
97-
// we need this overrides because we enabled
98-
// allowJS in the tsconfig to allow for JS based
99-
// Cypress tests. That however leads to issues
100-
// with the CommonJS Cypress plugin file
101-
overrides: [
102-
{
103-
files: ['src/plugins/index.js'],
104-
rules: {
105-
'@typescript-eslint/no-var-requires': 'off',
106-
'no-undef': 'off',
95+
return (host: Tree, context: SchematicContext) => {
96+
options = normalizeOptions(host, options);
97+
return chain([
98+
addLintFiles(options.projectRoot, options.linter, {
99+
localConfig: {
100+
// we need this overrides because we enabled
101+
// allowJS in the tsconfig to allow for JS based
102+
// Cypress tests. That however leads to issues
103+
// with the CommonJS Cypress plugin file
104+
overrides: [
105+
{
106+
files: ['src/plugins/index.js'],
107+
rules: {
108+
'@typescript-eslint/no-var-requires': 'off',
109+
'no-undef': 'off',
110+
},
107111
},
108-
},
109-
],
110-
},
111-
}),
112-
generateFiles(options),
113-
updateWorkspaceJson(options),
114-
updateNxJson(options),
115-
]);
112+
],
113+
},
114+
}),
115+
generateFiles(options),
116+
updateWorkspaceJson(options),
117+
updateNxJson(options),
118+
])(host, context);
119+
};
116120
}
117121

118-
function normalizeOptions(options: CypressProjectSchema): CypressProjectSchema {
122+
function normalizeOptions(
123+
host: Tree,
124+
options: CypressProjectSchema
125+
): CypressProjectSchema {
119126
const projectName = options.directory
120127
? toFileName(options.directory) + '-' + options.name
121128
: options.name;
122129
const projectRoot = options.directory
123-
? join(normalize('apps'), toFileName(options.directory), options.name)
124-
: join(normalize('apps'), options.name);
130+
? join(
131+
normalize(appsDir(host)),
132+
toFileName(options.directory),
133+
options.name
134+
)
135+
: join(normalize(appsDir(host)), options.name);
125136
return {
126137
...options,
127138
projectName,

packages/express/src/schematics/application/application.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { Schema } from './schema';
1010
import { updateJsonInTree } from '@nrwl/workspace';
1111
import { toFileName, formatFiles } from '@nrwl/workspace';
1212
import init from '../init/init';
13+
import { appsDir } from '@nrwl/workspace/src/utils/ast-utils';
1314

1415
interface NormalizedSchema extends Schema {
1516
appProjectRoot: Path;
@@ -52,7 +53,7 @@ server.on('error', console.error);
5253

5354
export default function (schema: Schema): Rule {
5455
return (host: Tree, context: SchematicContext) => {
55-
const options = normalizeOptions(schema);
56+
const options = normalizeOptions(host, schema);
5657
return chain([
5758
init({ ...options, skipFormat: true }),
5859
externalSchematic('@nrwl/node', 'application', schema),
@@ -63,11 +64,11 @@ export default function (schema: Schema): Rule {
6364
};
6465
}
6566

66-
function normalizeOptions(options: Schema): NormalizedSchema {
67+
function normalizeOptions(host: Tree, options: Schema): NormalizedSchema {
6768
const appDirectory = options.directory
6869
? `${toFileName(options.directory)}/${toFileName(options.name)}`
6970
: toFileName(options.name);
70-
const appProjectRoot = join(normalize('apps'), appDirectory);
71+
const appProjectRoot = join(normalize(appsDir(host)), appDirectory);
7172

7273
return {
7374
...options,

packages/nest/src/schematics/application/application.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { join, normalize, Path } from '@angular-devkit/core';
1414
import { Schema } from './schema';
1515
import { formatFiles, toFileName, updateJsonInTree } from '@nrwl/workspace';
1616
import init from '../init/init';
17+
import { appsDir } from '@nrwl/workspace/src/utils/ast-utils';
1718

1819
interface NormalizedSchema extends Schema {
1920
appProjectRoot: Path;
@@ -64,7 +65,7 @@ function addAppFiles(options: NormalizedSchema): Rule {
6465

6566
export default function (schema: Schema): Rule {
6667
return (host: Tree, context: SchematicContext) => {
67-
const options = normalizeOptions(schema);
68+
const options = normalizeOptions(host, schema);
6869
return chain([
6970
init({
7071
...options,
@@ -86,11 +87,11 @@ export default function (schema: Schema): Rule {
8687
};
8788
}
8889

89-
function normalizeOptions(options: Schema): NormalizedSchema {
90+
function normalizeOptions(host: Tree, options: Schema): NormalizedSchema {
9091
const appDirectory = options.directory
9192
? `${toFileName(options.directory)}/${toFileName(options.name)}`
9293
: toFileName(options.name);
93-
const appProjectRoot = join(normalize('apps'), appDirectory);
94+
const appProjectRoot = join(normalize(appsDir(host)), appDirectory);
9495

9596
return {
9697
...options,

0 commit comments

Comments
 (0)