Skip to content

Commit

Permalink
feat(generators): allow --framework for Nx consistency
Browse files Browse the repository at this point in the history
  • Loading branch information
NathanWalker committed Apr 1, 2019
1 parent 5536604 commit bb79c28
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 57 deletions.
81 changes: 50 additions & 31 deletions src/app.web/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ import {
applyAppNamingConvention,
updateJsonFile,
formatFiles,
missingArgument
missingArgument,
supportedPlatforms
} from "../utils";
import { Schema as ApplicationOptions } from "./schema";

Expand All @@ -37,36 +38,54 @@ export default function(options: ApplicationOptions) {
// ensure sass is used
options.style = "scss";

return chain([
prerun(options),
// adjust naming convention
applyAppNamingConvention(options, 'web'),
(tree: Tree, context: SchematicContext) => externalSchematic("@nrwl/schematics", "app", {
...options,
skipInstall: true
})(tree, context),
addHeadlessE2e(options),
(tree: Tree, context: SchematicContext) => addAppFiles(options)(tree, context),
(tree: Tree, context: SchematicContext) =>
options.sample || options.routing
? addAppFiles(options, options.sample ? "sample" : "routing")(tree, context)
: noop()(tree, context),
// adjust app files
(tree: Tree) => adjustAppFiles(options, tree),
// add start/clean scripts
(tree: Tree) => {
const platformApp = options.name.replace('-', '.');
const scripts = {};
scripts[
`clean`
] = `npx rimraf hooks node_modules package-lock.json && npm i`;
scripts[`start.${platformApp}`] = `ng serve ${options.name}`;
return updatePackageScripts(tree, scripts);
},
options.skipFormat
? noop()
: formatFiles(options)
]);
const chains = [];

const useDefaultChain = function() {
chains.push(...[
prerun(options),
// adjust naming convention
applyAppNamingConvention(options, 'web'),
(tree: Tree, context: SchematicContext) => externalSchematic("@nrwl/schematics", "app", {
...options,
skipInstall: true
})(tree, context),
addHeadlessE2e(options),
(tree: Tree, context: SchematicContext) => addAppFiles(options)(tree, context),
(tree: Tree, context: SchematicContext) =>
options.sample || options.routing
? addAppFiles(options, options.sample ? "sample" : "routing")(tree, context)
: noop()(tree, context),
// adjust app files
(tree: Tree) => adjustAppFiles(options, tree),
// add start/clean scripts
(tree: Tree) => {
const platformApp = options.name.replace('-', '.');
const scripts = {};
scripts[
`clean`
] = `npx rimraf hooks node_modules package-lock.json && npm i`;
scripts[`start.${platformApp}`] = `ng serve ${options.name}`;
return updatePackageScripts(tree, scripts);
},
options.skipFormat
? noop()
: formatFiles(options)
]);
};

if (options.framework) {
// use Nx style framework flag
if (supportedPlatforms.includes(options.framework)) {
// divert to separate xplat app generators
chains.push((tree: Tree, context: SchematicContext) => externalSchematic("@nstudio/schematics", `app.${options.framework}`, options)(tree, context));
} else {
useDefaultChain();
}
} else {
useDefaultChain();
}

return chain(chains);
}

/**
Expand Down
64 changes: 62 additions & 2 deletions src/app.web/index_spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Tree, VirtualTree } from "@angular-devkit/schematics";
import { Schema as ApplicationOptions } from "./schema";
import { SchematicTestRunner } from "@angular-devkit/schematics/testing";
import { SchematicTestRunner, UnitTestTree } from "@angular-devkit/schematics/testing";

import * as path from "path";
import { createEmptyWorkspace, getFileContent, jsonParse } from "../utils";
import { createEmptyWorkspace, getFileContent, jsonParse, Framework } from "../utils";

describe("app.web schematic", () => {
const schematicRunner = new SchematicTestRunner(
Expand Down Expand Up @@ -118,4 +118,64 @@ describe("app.web schematic", () => {
const angularJson: any = jsonParse(checkFile);
expect(angularJson.projects[`${appName}-e2e`].architect.e2e.configurations.ci).toBeDefined();
});

it("should create app with --framework flag Ionic", async () => {
const options: ApplicationOptions = { ...defaultOptions };
options.framework = Framework.Ionic;
const tree = await schematicRunner.runSchematicAsync("app", options, appTree).toPromise();
const files = tree.files;
// console.log(files);

expect(
files.indexOf("/apps/ionic-foo/package.json")
).toBeGreaterThanOrEqual(0);

const checkPath = "/package.json";
expect(files.indexOf(checkPath)).toBeGreaterThanOrEqual(0);

let checkFile = getFileContent(tree, checkPath);
// console.log(checkFile);
const packageData: any = jsonParse(checkFile);
expect(packageData.scripts["start.ionic.foo"]).toBeDefined();
});

it("should create app with --framework flag for NativeScript", async () => {
const options: ApplicationOptions = { ...defaultOptions };
options.framework = Framework.NativeScript;
const tree = await schematicRunner.runSchematicAsync("app", options, appTree).toPromise();
const files = tree.files;
// console.log(files);

expect(
files.indexOf("/apps/nativescript-foo/package.json")
).toBeGreaterThanOrEqual(0);

const checkPath = "/package.json";
expect(files.indexOf(checkPath)).toBeGreaterThanOrEqual(0);

let checkFile = getFileContent(tree, checkPath);
// console.log(checkFile);
const packageData: any = jsonParse(checkFile);
expect(packageData.scripts["start.nativescript.foo.ios"]).toBeDefined();
});

it("should create app with --framework flag Nest", async () => {
const options: ApplicationOptions = { ...defaultOptions };
options.framework = Framework.Nest;
const tree = await schematicRunner.runSchematicAsync("app", options, appTree).toPromise();
const files = tree.files;
// console.log(files);

expect(
files.indexOf("/apps/nest-foo/package.json")
).toBeGreaterThanOrEqual(0);

const checkPath = "/package.json";
expect(files.indexOf(checkPath)).toBeGreaterThanOrEqual(0);

let checkFile = getFileContent(tree, checkPath);
// console.log(checkFile);
const packageData: any = jsonParse(checkFile);
expect(packageData.scripts["start.nest.foo"]).toBeDefined();
});
});
51 changes: 27 additions & 24 deletions src/app.web/schema.d.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
import { Framework } from "../utils";

export interface Schema {
name: string;
skipFormat?: boolean;
inlineStyle?: boolean;
inlineTemplate?: boolean;
viewEncapsulation?: 'Emulated' | 'Native' | 'None';
routing?: boolean;
prefix?: string;
style?: string;
skipTests?: boolean;
directory?: string;
tags?: string;
unitTestRunner?: any;
e2eTestRunner?: any;
framework?: Framework;
name: string;
skipFormat?: boolean;
inlineStyle?: boolean;
inlineTemplate?: boolean;
viewEncapsulation?: "Emulated" | "Native" | "None";
routing?: boolean;
prefix?: string;
style?: string;
skipTests?: boolean;
directory?: string;
tags?: string;
unitTestRunner?: any;
e2eTestRunner?: any;

// xplat additional options
sample?: boolean;
/**
* Group by app name (appname-platform) instead of the default (platform-appname)
*/
groupByName?: boolean;
/**
* Add headless e2e configuration suitable for CI
*/
addHeadlessE2e?: boolean;
}
// xplat additional options
sample?: boolean;
/**
* Group by app name (appname-platform) instead of the default (platform-appname)
*/
groupByName?: boolean;
/**
* Add headless e2e configuration suitable for CI
*/
addHeadlessE2e?: boolean;
}
40 changes: 40 additions & 0 deletions src/app.web/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,46 @@
"title": "Create a web application",
"type": "object",
"properties": {
"framework": {
"description": "The Framework for the application.",
"type": "string",
"enum": ["angular", "react", "web-components", "electron", "ionic", "nativescript", "nest"],
"default": "angular",
"x-prompt": {
"message": "What framework would you like to use for the application?",
"type": "list",
"items": [
{
"value": "angular",
"label": "Angular [ https://angular.io ]"
},
{
"value": "react",
"label": "React [ https://reactjs.org/ ]"
},
{
"value": "web-components",
"label": "Web Components"
},
{
"value": "electron",
"label": "Electron [ https://electronjs.org/ ]"
},
{
"value": "ionic",
"label": "Ionic [ https://ionicframework.com/ ]"
},
{
"value": "nativescript",
"label": "NativeScript [ https://www.nativescript.org/ ]"
},
{
"value": "nest",
"label": "Nest [ https://nestjs.com/ ]"
}
]
}
},
"name": {
"description": "The name of the application.",
"type": "string",
Expand Down
11 changes: 11 additions & 0 deletions src/utils/general.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ const xml2js = require('xml2js');
import * as stripJsonComments from 'strip-json-comments';
import { NodePackageInstallTask } from "@angular-devkit/schematics/tasks";

export const enum Framework {
Angular = 'angular',
React = 'react',
WebComponents = 'web-components',
Electron = 'electron',
Ionic = 'ionic',
NativeScript = 'nativescript',
Nest = 'nest',
None = 'none'
}

export const supportedPlatforms = [
"web",
"nativescript",
Expand Down

0 comments on commit bb79c28

Please sign in to comment.