Skip to content

Commit

Permalink
feat(nx): generating apps works without ng-add (#1287)
Browse files Browse the repository at this point in the history
  • Loading branch information
FrozenPandaz authored Apr 26, 2019
1 parent 422fef7 commit a3be21c
Show file tree
Hide file tree
Showing 18 changed files with 305 additions and 129 deletions.
9 changes: 3 additions & 6 deletions packages/express/src/schematics/application/application.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
import {
apply,
chain,
externalSchematic,
mergeWith,
move,
Rule,
SchematicContext,
template,
Tree,
url
Tree
} from '@angular-devkit/schematics';
import { join, normalize, Path } from '@angular-devkit/core';
import { Schema } from './schema';
import { updateJsonInTree } from '@nrwl/workspace';
import { toFileName } from '@nrwl/workspace';
import ngAdd from '../ng-add/ng-add';

interface NormalizedSchema extends Schema {
appProjectRoot: Path;
Expand Down Expand Up @@ -60,6 +56,7 @@ export default function(schema: Schema): Rule {
return (host: Tree, context: SchematicContext) => {
const options = normalizeOptions(schema);
return chain([
ngAdd(),
externalSchematic('@nrwl/node', 'application', schema),
addMainFile(options),
addTypes(options)
Expand Down
18 changes: 15 additions & 3 deletions packages/express/src/schematics/ng-add/ng-add.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
import { Rule, chain, externalSchematic } from '@angular-devkit/schematics';
import { addDepsToPackageJson, updateJsonInTree } from '@nrwl/workspace';
import {
Rule,
chain,
externalSchematic,
Tree,
noop
} from '@angular-devkit/schematics';
import {
addDepsToPackageJson,
updateJsonInTree,
readJsonInTree,
addPackageWithNgAdd
} from '@nrwl/workspace';
import {
expressTypingsVersion,
expressVersion,
Expand Down Expand Up @@ -29,7 +40,8 @@ function moveDependency(): Rule {

export default function() {
return chain([
externalSchematic('@nrwl/node', 'ng-add', {}),
addPackageWithNgAdd('@nrwl/node'),
addPackageWithNgAdd('@nrwl/jest'),
addDependencies(),
moveDependency()
]);
Expand Down
2 changes: 2 additions & 0 deletions packages/nest/src/schematics/application/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import { join, normalize, Path } from '@angular-devkit/core';
import { Schema } from './schema';
import { toFileName } from '@nrwl/workspace';
import ngAdd from '../ng-add/ng-add';

interface NormalizedSchema extends Schema {
appProjectRoot: Path;
Expand Down Expand Up @@ -64,6 +65,7 @@ export default function(schema: Schema): Rule {
return (host: Tree, context: SchematicContext) => {
const options = normalizeOptions(schema);
return chain([
ngAdd(),
externalSchematic('@nrwl/node', 'application', schema),
addMainFile(options),
addAppFiles(options)
Expand Down
13 changes: 9 additions & 4 deletions packages/nest/src/schematics/ng-add/ng-add.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { Rule, chain, externalSchematic } from '@angular-devkit/schematics';
import { addDepsToPackageJson, updateJsonInTree } from '@nrwl/workspace';
import { Rule, chain } from '@angular-devkit/schematics';
import {
addPackageWithNgAdd,
addDepsToPackageJson,
updateJsonInTree
} from '@nrwl/workspace';
import {
nestJsSchematicsVersion,
nestJsVersion,
nxVersion
} from '../../utils/versions';

function addDependencies(): Rule {
export function addDependencies(): Rule {
return addDepsToPackageJson(
{
'@nestjs/common': nestJsVersion,
Expand All @@ -31,7 +35,8 @@ function moveDependency(): Rule {

export default function() {
return chain([
externalSchematic('@nrwl/node', 'ng-add', {}),
addPackageWithNgAdd('@nrwl/node'),
addPackageWithNgAdd('@nrwl/jest'),
addDependencies(),
moveDependency()
]);
Expand Down
2 changes: 1 addition & 1 deletion packages/node/src/builders/build/build.builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { map } from 'rxjs/operators';
import { getNodeWebpackConfig } from '../../utils/node.config';
import { OUT_FILENAME } from '../../utils/config';
import { BuildBuilderOptions } from '../../utils/types';
import { normalizeBuildOptions } from '../../../../web/src/utils/normalize';
import { normalizeBuildOptions } from '../../utils/normalize';

try {
require('dotenv').config();
Expand Down
2 changes: 2 additions & 0 deletions packages/node/src/schematics/application/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { updateJsonInTree } from '@nrwl/workspace';
import { toFileName } from '@nrwl/workspace';
import { getProjectConfig } from '@nrwl/workspace';
import { offsetFromRoot } from '@nrwl/workspace';
import ngAdd from '../ng-add/ng-add';

interface NormalizedSchema extends Schema {
appProjectRoot: Path;
Expand Down Expand Up @@ -145,6 +146,7 @@ export default function(schema: Schema): Rule {
return (host: Tree, context: SchematicContext) => {
const options = normalizeOptions(schema);
return chain([
ngAdd(),
addAppFiles(options),
updateAngularJson(options),
updateNxJson(options),
Expand Down
12 changes: 10 additions & 2 deletions packages/node/src/schematics/ng-add/ng-add.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { Rule, chain } from '@angular-devkit/schematics';
import { addDepsToPackageJson, updateJsonInTree } from '@nrwl/workspace';
import {
addDepsToPackageJson,
updateJsonInTree,
addPackageWithNgAdd
} from '@nrwl/workspace';
import { nxVersion } from '../../utils/versions';

function addDependencies(): Rule {
Expand All @@ -21,5 +25,9 @@ function moveDependency(): Rule {
}

export default function() {
return chain([addDependencies(), moveDependency()]);
return chain([
addPackageWithNgAdd('@nrwl/jest'),
addDependencies(),
moveDependency()
]);
}
102 changes: 102 additions & 0 deletions packages/node/src/utils/normalize.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { normalizeBuildOptions } from './normalize';
import { BuildBuilderOptions } from './types';
import { Path, normalize } from '@angular-devkit/core';

import * as fs from 'fs';

describe('normalizeBuildOptions', () => {
let testOptions: BuildBuilderOptions;
let root: string;
let sourceRoot: Path;

beforeEach(() => {
testOptions = {
main: 'apps/nodeapp/src/main.ts',
tsConfig: 'apps/nodeapp/tsconfig.app.json',
outputPath: 'dist/apps/nodeapp',
fileReplacements: [
{
replace: 'apps/environment/environment.ts',
with: 'apps/environment/environment.prod.ts'
},
{
replace: 'module1.ts',
with: 'module2.ts'
}
],
assets: [],
statsJson: false
};
root = '/root';
sourceRoot = normalize('apps/nodeapp/src');
});
it('should add the root', () => {
const result = normalizeBuildOptions(testOptions, root, sourceRoot);
expect(result.root).toEqual('/root');
});

it('should resolve main from root', () => {
const result = normalizeBuildOptions(testOptions, root, sourceRoot);
expect(result.main).toEqual('/root/apps/nodeapp/src/main.ts');
});

it('should resolve the output path', () => {
const result = normalizeBuildOptions(testOptions, root, sourceRoot);
expect(result.outputPath).toEqual('/root/dist/apps/nodeapp');
});

it('should resolve the tsConfig path', () => {
const result = normalizeBuildOptions(testOptions, root, sourceRoot);
expect(result.tsConfig).toEqual('/root/apps/nodeapp/tsconfig.app.json');
});

it('should normalize asset patterns', () => {
spyOn(fs, 'statSync').and.returnValue({
isDirectory: () => true
});
const result = normalizeBuildOptions(
<BuildBuilderOptions>{
...testOptions,
root,
assets: [
'apps/nodeapp/src/assets',
{
input: '/outsideroot',
output: 'output',
glob: '**/*',
ignore: ['**/*.json']
}
]
},
root,
sourceRoot
);
expect(result.assets).toEqual([
{
input: '/root/apps/nodeapp/src/assets',
output: 'assets',
glob: '**/*'
},
{
input: '/outsideroot',
output: 'output',
glob: '**/*',
ignore: ['**/*.json']
}
]);
});

it('should resolve the file replacement paths', () => {
const result = normalizeBuildOptions(testOptions, root, sourceRoot);
expect(result.fileReplacements).toEqual([
{
replace: '/root/apps/environment/environment.ts',
with: '/root/apps/environment/environment.prod.ts'
},
{
replace: '/root/module1.ts',
with: '/root/module2.ts'
}
]);
});
});
86 changes: 86 additions & 0 deletions packages/node/src/utils/normalize.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { Path, normalize } from '@angular-devkit/core';
import { resolve, dirname, relative, basename } from 'path';
import {
AssetPattern,
AssetPatternObject
} from '@angular-devkit/build-angular';
import { BuildBuilderOptions } from './types';
import { statSync } from 'fs';

export interface FileReplacement {
replace: string;
with: string;
}

export function normalizeBuildOptions<T extends BuildBuilderOptions>(
options: T,
root: string,
sourceRoot: Path
): T {
return {
...options,
root: root,
sourceRoot: sourceRoot,
main: resolve(root, options.main),
outputPath: resolve(root, options.outputPath),
tsConfig: resolve(root, options.tsConfig),
fileReplacements: normalizeFileReplacements(root, options.fileReplacements),
assets: normalizeAssets(options.assets, root, sourceRoot),
webpackConfig: options.webpackConfig
? resolve(root, options.webpackConfig)
: options.webpackConfig
};
}

function normalizeAssets(
assets: AssetPattern[],
root: string,
sourceRoot: Path
): AssetPatternObject[] {
return assets.map(asset => {
if (typeof asset === 'string') {
const assetPath = normalize(asset);
const resolvedAssetPath = resolve(root, assetPath);
const resolvedSourceRoot = resolve(root, sourceRoot);

if (!resolvedAssetPath.startsWith(resolvedSourceRoot)) {
throw new Error(
`The ${resolvedAssetPath} asset path must start with the project source root: ${sourceRoot}`
);
}

const isDirectory = statSync(resolvedAssetPath).isDirectory();
const input = isDirectory
? resolvedAssetPath
: dirname(resolvedAssetPath);
const output = relative(resolvedSourceRoot, resolve(root, input));
const glob = isDirectory ? '**/*' : basename(resolvedAssetPath);
return {
input,
output,
glob
};
} else {
if (asset.output.startsWith('..')) {
throw new Error(
'An asset cannot be written to a location outside of the output path.'
);
}
return {
...asset,
// Now we remove starting slash to make Webpack place it from the output root.
output: asset.output.replace(/^\//, '')
};
}
});
}

function normalizeFileReplacements(
root: string,
fileReplacements: FileReplacement[]
): FileReplacement[] {
return fileReplacements.map(fileReplacement => ({
replace: resolve(root, fileReplacement.replace),
with: resolve(root, fileReplacement.with)
}));
}
20 changes: 13 additions & 7 deletions packages/react/src/schematics/application/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,16 @@ import {
filter
} from '@angular-devkit/schematics';
import { Schema } from './schema';
import { updateJsonInTree, NxJson } from '@nrwl/workspace';
import { toFileName, names } from '@nrwl/workspace';
import { offsetFromRoot } from '@nrwl/workspace';
import { getNpmScope } from '@nrwl/workspace';
import { formatFiles } from '@nrwl/workspace';
import {
updateJsonInTree,
NxJson,
toFileName,
names,
offsetFromRoot,
getNpmScope,
formatFiles
} from '@nrwl/workspace';
import ngAdd from '../ng-add/ng-add';

interface NormalizedSchema extends Schema {
projectName: string;
Expand Down Expand Up @@ -139,10 +144,11 @@ function addProject(options: NormalizedSchema): Rule {
}

export default function(schema: Schema): Rule {
return (host: Tree, context: SchematicContext) => {
return (host: Tree) => {
const options = normalizeOptions(host, schema);

return chain([
ngAdd(),
createApplicationFiles(options),
updateNxJson(options),
addProject(options),
Expand All @@ -163,7 +169,7 @@ export default function(schema: Schema): Rule {
})
: noop(),
formatFiles(options)
])(host, context);
]);
};
}

Expand Down
Loading

0 comments on commit a3be21c

Please sign in to comment.