Skip to content

Commit bcdd289

Browse files
authored
Merge pull request #1 from qwikifiers/ds/generator-enhancements
2 parents 50d5524 + ae8a17b commit bcdd289

21 files changed

+550
-47
lines changed

packages/qwik-nx/generators.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@
2525
"factory": "./src/generators/component/generator",
2626
"schema": "./src/generators/component/schema.json",
2727
"description": "Generating a Qwik component"
28+
},
29+
"library": {
30+
"factory": "./src/generators/library/generator",
31+
"schema": "./src/generators/library/schema.json",
32+
"description": "library generator"
2833
}
2934
}
3035
}

packages/qwik-nx/src/generators/component/files/__fileName__.tsx__template__

Lines changed: 0 additions & 12 deletions
This file was deleted.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { component$<%= hasStyles ? ', useStylesScoped$' : '' %> } from '@builder.io/qwik';
2+
<% if(hasStyles) { %>
3+
import styles from './<%- fileName %>.<%- style %>?inline';
4+
<% } %>
5+
6+
interface <%= className %>Props {
7+
8+
}
9+
10+
const <%= className %> = component$((props: <%= className %>Props)=>{
11+
<% if(hasStyles) { %>
12+
useStylesScoped$(styles);
13+
<% } %>
14+
return <>
15+
16+
</>;
17+
});

packages/qwik-nx/src/generators/component/files/styles/__fileName__.__style__.template

Whitespace-only changes.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { createDOM } from '@builder.io/qwik/testing';
2+
import { test, expect } from 'vitest';
3+
import { <%- className %> } from './<%- fileName %>';
4+
5+
test(`[<%- className %> Component]: Should render`, async () => {
6+
const { screen, render } = await createDOM();
7+
await render(<<%- className %> />);
8+
expect(screen.innerHTML).toBeTruthy();
9+
});
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
11
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
22
import { Tree } from '@nrwl/devkit';
33
import componentGenerator from './generator';
4+
import {createLib} from './../../utils/testing-generators';
45

56
describe('component generator', () => {
67
let appTree: Tree;
8+
const projectName = 'dummy-lib';
79

810
beforeEach(() => {
911
appTree = createTreeWithEmptyWorkspace();
12+
createLib(appTree, projectName);
1013
});
1114

1215
it('should generate a component file inside a given directory', async () => {
1316
await componentGenerator(appTree, {
1417
name: 'hello',
15-
directory: 'components'
18+
project: projectName
1619
});
1720

18-
expect(appTree.exists('libs/components/hello/hello.tsx')).toBeTruthy();
21+
expect(appTree.exists(`libs/${projectName}/src/lib/hello/hello.tsx`)).toBeTruthy();
1922

2023
});
2124
});
Lines changed: 58 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,88 @@
11
import {
2-
addProjectConfiguration,
32
formatFiles,
43
generateFiles,
5-
getWorkspaceLayout,
4+
getProjects,
5+
joinPathFragments,
6+
logger,
67
names,
7-
offsetFromRoot,
88
Tree,
99
} from '@nrwl/devkit';
10-
import * as path from 'path';
10+
import { addStyledModuleDependencies } from '../../utils/add-styled-dependencies';
1111
import { ComponentGeneratorSchema } from './schema';
1212

1313
interface NormalizedSchema extends ComponentGeneratorSchema {
14-
projectName: string;
14+
directory: string;
15+
hasStyles: boolean;
1516
projectRoot: string;
16-
projectDirectory: string;
17-
parsedTags: string[];
1817
}
1918

20-
function normalizeOptions(tree: Tree, options: ComponentGeneratorSchema): NormalizedSchema {
21-
const name = names(options.name).fileName;
22-
const projectDirectory = options.directory
23-
? `${names(options.directory).fileName}/${name}`
24-
: name;
25-
const projectName = projectDirectory.replace(new RegExp('/', 'g'), '-');
26-
const projectRoot = `${getWorkspaceLayout(tree).libsDir}/${projectDirectory}`;
27-
const parsedTags = options.tags
28-
? options.tags.split(',').map((s) => s.trim())
29-
: [];
19+
function getDirectory(host: Tree, options: ComponentGeneratorSchema) {
20+
const workspace = getProjects(host);
21+
let baseDir: string;
22+
if (options.directory) {
23+
baseDir = options.directory;
24+
} else {
25+
baseDir =
26+
workspace.get(options.project).projectType === 'application'
27+
? 'app'
28+
: 'lib';
29+
}
30+
return options.flat ? baseDir : joinPathFragments(baseDir, names(options.name).fileName);
31+
}
32+
33+
function normalizeOptions(
34+
host: Tree,
35+
options: ComponentGeneratorSchema
36+
): NormalizedSchema {
37+
38+
const project = getProjects(host).get(options.project);
39+
40+
if (!project) {
41+
logger.error(
42+
`Cannot find the ${options.project} project. Please double check the project name.`
43+
);
44+
throw new Error();
45+
}
46+
47+
const { sourceRoot: projectRoot } = project;
48+
49+
const directory = getDirectory(host, options);
3050

3151
return {
3252
...options,
33-
projectName,
53+
directory,
54+
hasStyles: options.style !== 'none',
3455
projectRoot,
35-
projectDirectory,
36-
parsedTags,
3756
};
3857
}
3958

4059
function createComponentFiles(tree: Tree, options: NormalizedSchema) {
60+
const libNames = names(options.name);
61+
const hasStyles = options.style && options.style !== 'none';
4162
const templateOptions = {
4263
...options,
43-
...names(options.name),
44-
offsetFromRoot: offsetFromRoot(options.projectRoot),
45-
template: ''
64+
...libNames,
65+
hasStyles
4666
};
47-
generateFiles(tree, path.join(__dirname, 'files'), options.projectRoot, templateOptions);
67+
68+
const componentDir = joinPathFragments(
69+
options.projectRoot,
70+
options.directory
71+
);
72+
73+
generateFiles(tree, joinPathFragments(__dirname, 'files/common'), componentDir, templateOptions);
74+
if (hasStyles) {
75+
generateFiles(tree, joinPathFragments(__dirname, 'files/styles'), componentDir, templateOptions);
76+
}
77+
if (!options.skipTests) {
78+
generateFiles(tree, joinPathFragments(__dirname, 'files/tests'), componentDir, templateOptions);
79+
}
4880
}
4981

5082
export default async function componentGenerator(tree: Tree, options: ComponentGeneratorSchema) {
5183
const normalizedOptions = normalizeOptions(tree, options);
5284
createComponentFiles(tree, normalizedOptions);
5385
await formatFiles(tree);
86+
87+
return addStyledModuleDependencies(tree, normalizedOptions.style)
5488
}
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
export interface ComponentGeneratorSchema {
22
name: string;
3-
tags?: string;
3+
project: string;
44
directory?: string;
5+
style?: 'none' | 'css' | 'scss' | 'styl' | 'less';
6+
skipTests?: boolean;
7+
flat?: boolean;
58
}

packages/qwik-nx/src/generators/component/schema.json

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,68 @@
77
"properties": {
88
"name": {
99
"type": "string",
10-
"description": "",
10+
"description": "The name of the component.",
1111
"$default": {
1212
"$source": "argv",
1313
"index": 0
1414
},
15-
"x-prompt": "What name would you like to use?"
15+
"x-prompt": "What name would you like to use for the component?"
1616
},
17-
"tags": {
17+
"project": {
1818
"type": "string",
19-
"description": "Add tags to the project (used for linting)",
20-
"alias": "t"
21-
},
19+
"description": "The name of the project.",
20+
"alias": "p",
21+
"$default": {
22+
"$source": "projectName"
23+
},
24+
"x-prompt": "What is the name of the project for this component?"
25+
},
2226
"directory": {
2327
"type": "string",
24-
"description": "A directory where the project is placed"
28+
"description": "Create the component under this directory (can be nested)."
29+
},
30+
"style": {
31+
"description": "The file extension to be used for style files.",
32+
"type": "string",
33+
"default": "css",
34+
"alias": "s",
35+
"x-prompt": {
36+
"message": "Which stylesheet format would you like to use?",
37+
"type": "list",
38+
"items": [
39+
{
40+
"value": "css",
41+
"label": "CSS"
42+
},
43+
{
44+
"value": "scss",
45+
"label": "SASS(.scss) [ http://sass-lang.com ]"
46+
},
47+
{
48+
"value": "styl",
49+
"label": "Stylus(.styl) [ http://stylus-lang.com ]"
50+
},
51+
{
52+
"value": "less",
53+
"label": "LESS [ http://lesscss.org ]"
54+
},
55+
{
56+
"value": "none",
57+
"label": "none"
58+
}
59+
],
60+
"default": "css"
61+
}
62+
},
63+
"skipTests": {
64+
"description": "When true, does not create `spec.ts` test files for the new component.",
65+
"type": "boolean"
66+
},
67+
"flat": {
68+
"type": "boolean",
69+
"description": "Create component at the source root rather than its own directory.",
70+
"default": false
2571
}
2672
},
27-
"required": ["name"]
73+
"required": ["name", "project"]
2874
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './lib/<%- fileName %>'

0 commit comments

Comments
 (0)