fix(frontend): fix react component for apps
This commit is contained in:
parent
c3fc1fd95e
commit
2958f503f7
@ -27,7 +27,8 @@
|
|||||||
"component": {
|
"component": {
|
||||||
"factory": "./src/schematics/component/component",
|
"factory": "./src/schematics/component/component",
|
||||||
"schema": "./src/schematics/component/schema.json",
|
"schema": "./src/schematics/component/schema.json",
|
||||||
"description": "Create a component"
|
"description": "Create a component",
|
||||||
|
"aliases": "c"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,18 +1,18 @@
|
|||||||
import { Tree } from '@angular-devkit/schematics';
|
import { Tree } from '@angular-devkit/schematics';
|
||||||
import { createEmptyWorkspace } from '@nrwl/workspace/testing';
|
import { createEmptyWorkspace } from '@nrwl/workspace/testing';
|
||||||
import { runSchematic } from '../../utils/testing';
|
import { runSchematic, createApp, createLib } from '../../utils/testing';
|
||||||
import { names } from '@nrwl/workspace/src/utils/name-utils';
|
|
||||||
import { readJsonInTree } from '@nrwl/workspace/src/utils/ast-utils';
|
import { readJsonInTree } from '@nrwl/workspace/src/utils/ast-utils';
|
||||||
|
|
||||||
describe('component', () => {
|
describe('component', () => {
|
||||||
let appTree: Tree;
|
let appTree: Tree;
|
||||||
let projectName: string;
|
let projectName: string;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(async () => {
|
||||||
projectName = 'my-lib';
|
projectName = 'my-lib';
|
||||||
appTree = Tree.empty();
|
appTree = Tree.empty();
|
||||||
appTree = createEmptyWorkspace(appTree);
|
appTree = createEmptyWorkspace(appTree);
|
||||||
appTree = createLib(appTree, projectName);
|
appTree = await createApp(appTree, 'my-app');
|
||||||
|
appTree = await createLib(appTree, projectName);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate files', async () => {
|
it('should generate files', async () => {
|
||||||
@ -29,6 +29,20 @@ describe('component', () => {
|
|||||||
expect(tree.exists('libs/my-lib/src/lib/hello/hello.css')).toBeTruthy();
|
expect(tree.exists('libs/my-lib/src/lib/hello/hello.css')).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should generate files for an app', async () => {
|
||||||
|
const tree = await runSchematic(
|
||||||
|
'component',
|
||||||
|
{ name: 'hello', project: 'my-app' },
|
||||||
|
appTree
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(tree.exists('apps/my-app/src/app/hello/hello.tsx')).toBeTruthy();
|
||||||
|
expect(
|
||||||
|
tree.exists('apps/my-app/src/app/hello/hello.spec.tsx')
|
||||||
|
).toBeTruthy();
|
||||||
|
expect(tree.exists('apps/my-app/src/app/hello/hello.css')).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
describe('--export', () => {
|
describe('--export', () => {
|
||||||
it('should add to index.ts barrel', async () => {
|
it('should add to index.ts barrel', async () => {
|
||||||
const tree = await runSchematic(
|
const tree = await runSchematic(
|
||||||
@ -41,6 +55,18 @@ describe('component', () => {
|
|||||||
|
|
||||||
expect(indexContent).toMatch(/lib\/hello\/hello/);
|
expect(indexContent).toMatch(/lib\/hello\/hello/);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not export from an app', async () => {
|
||||||
|
const tree = await runSchematic(
|
||||||
|
'component',
|
||||||
|
{ name: 'hello', project: 'my-app', export: true },
|
||||||
|
appTree
|
||||||
|
);
|
||||||
|
|
||||||
|
const indexContent = tree.read('libs/my-lib/src/index.ts').toString();
|
||||||
|
|
||||||
|
expect(indexContent).not.toMatch(/lib\/hello\/hello/);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('--pascalCaseFiles', () => {
|
describe('--pascalCaseFiles', () => {
|
||||||
@ -123,27 +149,3 @@ describe('component', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
export function createLib(tree: Tree, libName: string): Tree {
|
|
||||||
const { fileName } = names(libName);
|
|
||||||
|
|
||||||
tree.create(`/libs/${fileName}/src/index.ts`, `\n`);
|
|
||||||
|
|
||||||
tree.overwrite(
|
|
||||||
'/angular.json',
|
|
||||||
`
|
|
||||||
{
|
|
||||||
"projects": {
|
|
||||||
"${libName}": {
|
|
||||||
"root": "libs/${fileName}",
|
|
||||||
"sourceRoot": "libs/${fileName}/src",
|
|
||||||
"projectType": "library",
|
|
||||||
"schematics": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
);
|
|
||||||
|
|
||||||
return tree;
|
|
||||||
}
|
|
||||||
|
|||||||
@ -8,12 +8,13 @@ import {
|
|||||||
move,
|
move,
|
||||||
noop,
|
noop,
|
||||||
Rule,
|
Rule,
|
||||||
|
SchematicContext,
|
||||||
template,
|
template,
|
||||||
Tree,
|
Tree,
|
||||||
url
|
url
|
||||||
} from '@angular-devkit/schematics';
|
} from '@angular-devkit/schematics';
|
||||||
import { Schema } from './schema';
|
import { Schema } from './schema';
|
||||||
import { names } from '@nrwl/workspace';
|
import { getWorkspace, names, formatFiles } from '@nrwl/workspace';
|
||||||
import {
|
import {
|
||||||
addDepsToPackageJson,
|
addDepsToPackageJson,
|
||||||
addGlobal,
|
addGlobal,
|
||||||
@ -21,7 +22,6 @@ import {
|
|||||||
insert
|
insert
|
||||||
} from '@nrwl/workspace/src/utils/ast-utils';
|
} from '@nrwl/workspace/src/utils/ast-utils';
|
||||||
import { CSS_IN_JS_DEPENDENCIES } from '../../utils/styled';
|
import { CSS_IN_JS_DEPENDENCIES } from '../../utils/styled';
|
||||||
import { formatFiles } from '@nrwl/workspace';
|
|
||||||
|
|
||||||
interface NormalizedSchema extends Schema {
|
interface NormalizedSchema extends Schema {
|
||||||
projectSourceRoot: Path;
|
projectSourceRoot: Path;
|
||||||
@ -31,8 +31,8 @@ interface NormalizedSchema extends Schema {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function(schema: Schema): Rule {
|
export default function(schema: Schema): Rule {
|
||||||
return (host: Tree) => {
|
return (host: Tree, context: SchematicContext) => {
|
||||||
const options = normalizeOptions(host, schema);
|
const options = normalizeOptions(host, schema, context);
|
||||||
return chain([
|
return chain([
|
||||||
createComponentFiles(options),
|
createComponentFiles(options),
|
||||||
addStyledModuleDependencies(options),
|
addStyledModuleDependencies(options),
|
||||||
@ -43,19 +43,29 @@ export default function(schema: Schema): Rule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function createComponentFiles(options: NormalizedSchema): Rule {
|
function createComponentFiles(options: NormalizedSchema): Rule {
|
||||||
return mergeWith(
|
return async (host: Tree, context: SchematicContext) => {
|
||||||
apply(url(`./files`), [
|
const workspace = await getWorkspace(host);
|
||||||
template({
|
const directory = join(
|
||||||
...options,
|
options.projectSourceRoot,
|
||||||
tmpl: ''
|
workspace.projects.get(options.project).extensions.projectType ===
|
||||||
}),
|
'application'
|
||||||
options.skipTests ? filter(file => !/.*spec.tsx/.test(file)) : noop(),
|
? 'app'
|
||||||
options.styledModule
|
: 'lib'
|
||||||
? filter(file => !file.endsWith(`.${options.style}`))
|
);
|
||||||
: noop(),
|
return mergeWith(
|
||||||
move(join(options.projectSourceRoot, 'lib'))
|
apply(url(`./files`), [
|
||||||
])
|
template({
|
||||||
);
|
...options,
|
||||||
|
tmpl: ''
|
||||||
|
}),
|
||||||
|
options.skipTests ? filter(file => !/.*spec.tsx/.test(file)) : noop(),
|
||||||
|
options.styledModule
|
||||||
|
? filter(file => !file.endsWith(`.${options.style}`))
|
||||||
|
: noop(),
|
||||||
|
move(directory)
|
||||||
|
])
|
||||||
|
);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function addStyledModuleDependencies(options: NormalizedSchema): Rule {
|
function addStyledModuleDependencies(options: NormalizedSchema): Rule {
|
||||||
@ -70,48 +80,62 @@ function addStyledModuleDependencies(options: NormalizedSchema): Rule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function addExportsToBarrel(options: NormalizedSchema): Rule {
|
function addExportsToBarrel(options: NormalizedSchema): Rule {
|
||||||
return options.export
|
return async (host: Tree) => {
|
||||||
? (host: Tree) => {
|
const workspace = await getWorkspace(host);
|
||||||
const indexFilePath = join(options.projectSourceRoot, 'index.ts');
|
const isApp =
|
||||||
const buffer = host.read(indexFilePath);
|
workspace.projects.get(options.project).extensions.type === 'application';
|
||||||
|
return options.export && !isApp
|
||||||
if (!!buffer) {
|
? (host: Tree) => {
|
||||||
const indexSource = buffer!.toString('utf-8');
|
const indexFilePath = join(options.projectSourceRoot, 'index.ts');
|
||||||
const indexSourceFile = ts.createSourceFile(
|
const buffer = host.read(indexFilePath);
|
||||||
indexFilePath,
|
if (!!buffer) {
|
||||||
indexSource,
|
const indexSource = buffer!.toString('utf-8');
|
||||||
ts.ScriptTarget.Latest,
|
const indexSourceFile = ts.createSourceFile(
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
insert(
|
|
||||||
host,
|
|
||||||
indexFilePath,
|
|
||||||
addGlobal(
|
|
||||||
indexSourceFile,
|
|
||||||
indexFilePath,
|
indexFilePath,
|
||||||
`export { default as ${options.className}, ${
|
indexSource,
|
||||||
options.className
|
ts.ScriptTarget.Latest,
|
||||||
}Props } from './lib/${options.name}/${options.fileName}';`
|
true
|
||||||
)
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return host;
|
insert(
|
||||||
}
|
host,
|
||||||
: noop();
|
indexFilePath,
|
||||||
|
addGlobal(
|
||||||
|
indexSourceFile,
|
||||||
|
indexFilePath,
|
||||||
|
`export { default as ${options.className}, ${
|
||||||
|
options.className
|
||||||
|
}Props } from './lib/${options.name}/${options.fileName}';`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
: noop();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizeOptions(host: Tree, options: Schema): NormalizedSchema {
|
function normalizeOptions(
|
||||||
|
host: Tree,
|
||||||
|
options: Schema,
|
||||||
|
context: SchematicContext
|
||||||
|
): NormalizedSchema {
|
||||||
const { className, fileName } = names(options.name);
|
const { className, fileName } = names(options.name);
|
||||||
|
|
||||||
const componentFileName = options.pascalCaseFiles ? className : fileName;
|
const componentFileName = options.pascalCaseFiles ? className : fileName;
|
||||||
|
|
||||||
const { sourceRoot: projectSourceRoot } = getProjectConfig(
|
const { sourceRoot: projectSourceRoot, projectType } = getProjectConfig(
|
||||||
host,
|
host,
|
||||||
options.project
|
options.project
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (options.export && projectType === 'application') {
|
||||||
|
context.logger.warn(
|
||||||
|
`The "--export" option should not be used with applications and will do nothing.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const styledModule = /^(css|scss|less|styl)$/.test(options.style)
|
const styledModule = /^(css|scss|less|styl)$/.test(options.style)
|
||||||
? null
|
? null
|
||||||
: options.style;
|
: options.style;
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
|
import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
|
||||||
import { Rule, Tree } from '@angular-devkit/schematics';
|
import { Rule, Tree } from '@angular-devkit/schematics';
|
||||||
|
import { names } from '@nrwl/workspace/src/utils/name-utils';
|
||||||
|
import { updateWorkspace } from '@nrwl/workspace/src/utils/workspace';
|
||||||
|
|
||||||
const testRunner = new SchematicTestRunner(
|
const testRunner = new SchematicTestRunner(
|
||||||
'@nrwl/react',
|
'@nrwl/react',
|
||||||
@ -14,3 +16,39 @@ export function runSchematic(schematicName: string, options: any, tree: Tree) {
|
|||||||
export function callRule(rule: Rule, tree: Tree) {
|
export function callRule(rule: Rule, tree: Tree) {
|
||||||
return testRunner.callRule(rule, tree).toPromise();
|
return testRunner.callRule(rule, tree).toPromise();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function createApp(tree: Tree, appName: string): Promise<Tree> {
|
||||||
|
const { fileName } = names(appName);
|
||||||
|
|
||||||
|
return callRule(
|
||||||
|
updateWorkspace(workspace => {
|
||||||
|
workspace.projects.add({
|
||||||
|
name: fileName,
|
||||||
|
root: `apps/${fileName}`,
|
||||||
|
projectType: 'application',
|
||||||
|
sourceRoot: `apps/${fileName}/src`,
|
||||||
|
targets: {}
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
tree
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createLib(tree: Tree, libName: string): Promise<Tree> {
|
||||||
|
const { fileName } = names(libName);
|
||||||
|
|
||||||
|
tree.create(`/libs/${fileName}/src/index.ts`, `\n`);
|
||||||
|
|
||||||
|
return callRule(
|
||||||
|
updateWorkspace(workspace => {
|
||||||
|
workspace.projects.add({
|
||||||
|
name: fileName,
|
||||||
|
root: `libs/${fileName}`,
|
||||||
|
projectType: 'library',
|
||||||
|
sourceRoot: `libs/${fileName}/src`,
|
||||||
|
targets: {}
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
tree
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user