diff --git a/.github/actions/test/action.yml b/.github/actions/test/action.yml index 816cc02c..6cad8023 100644 --- a/.github/actions/test/action.yml +++ b/.github/actions/test/action.yml @@ -18,9 +18,9 @@ runs: shell: bash run: pnpx nx affected:build --base=last-release --exclude="add-nx-to-qwik" - # - name: Test - # shell: bash - # run: npx nx affected --target=test --base=last-release + - name: Test + shell: bash + run: npx nx affected --target=test --base=last-release # - name: E2E Tests # shell: bash diff --git a/README.md b/README.md index a5bee9bf..7b531dfd 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,12 @@ nx generate qwik-nx:lib nx generate qwik-nx:component ``` +### Generating a route + +``` +nx generate qwik-nx:route +``` + ### Setting up Tailwind CSS ``` diff --git a/packages/qwik-nx/README.md b/packages/qwik-nx/README.md deleted file mode 100644 index 5a5a79b5..00000000 --- a/packages/qwik-nx/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# qwik-nx - -This library was generated with [Nx](https://nx.dev). - -## Building - -Run `nx build qwik-nx` to build the library. - -## Running unit tests - -Run `nx test qwik-nx` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/packages/qwik-nx/project.json b/packages/qwik-nx/project.json index 4817faf2..6d4456a2 100644 --- a/packages/qwik-nx/project.json +++ b/packages/qwik-nx/project.json @@ -12,7 +12,12 @@ "main": "packages/qwik-nx/src/index.ts", "tsConfig": "packages/qwik-nx/tsconfig.lib.json", "assets": [ - "packages/qwik-nx/*.md", + "README.md", + { + "input": "./assets", + "glob": "qwik-nx.png", + "output": "./assets" + }, { "input": "./packages/qwik-nx/src", "glob": "**/!(*.ts)", diff --git a/packages/qwik-nx/src/generators/application/generator.ts b/packages/qwik-nx/src/generators/application/generator.ts index 56c848ab..d2e1e463 100644 --- a/packages/qwik-nx/src/generators/application/generator.ts +++ b/packages/qwik-nx/src/generators/application/generator.ts @@ -34,7 +34,10 @@ function addFiles(tree: Tree, options: NormalizedSchema) { ); } -export default async function (tree: Tree, options: QwikAppGeneratorSchema) { +export async function appGenerator( + tree: Tree, + options: QwikAppGeneratorSchema +) { const normalizedOptions = normalizeOptions(tree, options); const tasks: GeneratorCallback[] = []; @@ -90,3 +93,5 @@ export default async function (tree: Tree, options: QwikAppGeneratorSchema) { return runTasksInSerial(...tasks); } + +export default appGenerator; diff --git a/packages/qwik-nx/src/generators/application/schema.d.ts b/packages/qwik-nx/src/generators/application/schema.d.ts index 99910771..8da7a2cc 100644 --- a/packages/qwik-nx/src/generators/application/schema.d.ts +++ b/packages/qwik-nx/src/generators/application/schema.d.ts @@ -4,14 +4,13 @@ export interface QwikAppGeneratorSchema { name: string; tags?: string; directory?: string; - - style: 'css' | 'scss' | 'styl' | 'less' | 'none'; - linter: Linter; - skipFormat: boolean; + style?: 'css' | 'scss' | 'styl' | 'less' | 'none'; + linter?: Linter; + skipFormat?: boolean; tailwind?: boolean; - unitTestRunner: 'vitest' | 'none'; - strict: boolean; - e2eTestRunner: 'playwright' | 'cypress' | 'none'; + unitTestRunner?: 'vitest' | 'none'; + strict?: boolean; + e2eTestRunner?: 'playwright' | 'cypress' | 'none'; // router: 'qwik-city' | 'none'; // TODO: add setup w/o qwik-city } diff --git a/packages/qwik-nx/src/generators/route/files/layout/__routeName__/layout.tsx__template__ b/packages/qwik-nx/src/generators/route/files/layout/__routeName__/layout.tsx__template__ new file mode 100644 index 00000000..d7b4e7f6 --- /dev/null +++ b/packages/qwik-nx/src/generators/route/files/layout/__routeName__/layout.tsx__template__ @@ -0,0 +1,13 @@ +import { component$ } from '@builder.io/qwik'; + +export default component$(() => { + return ( + <> + + + + + ); +}); + + diff --git a/packages/qwik-nx/src/generators/route/files/route/__routeName__/index.tsx__template__ b/packages/qwik-nx/src/generators/route/files/route/__routeName__/index.tsx__template__ new file mode 100644 index 00000000..dc044ca4 --- /dev/null +++ b/packages/qwik-nx/src/generators/route/files/route/__routeName__/index.tsx__template__ @@ -0,0 +1,11 @@ +import { component$ } from '@builder.io/qwik'; + +export default component$(() => { + return ( +
+ This is the <%= routeName %> +
+ ); +}); + + diff --git a/packages/qwik-nx/src/generators/route/files/src/index.ts__template__ b/packages/qwik-nx/src/generators/route/files/src/index.ts__template__ deleted file mode 100644 index dde3cb69..00000000 --- a/packages/qwik-nx/src/generators/route/files/src/index.ts__template__ +++ /dev/null @@ -1 +0,0 @@ -const variable = "<%= projectName %>"; \ No newline at end of file diff --git a/packages/qwik-nx/src/generators/route/generator.spec.ts b/packages/qwik-nx/src/generators/route/generator.spec.ts index 54dc7df8..6b80ae25 100644 --- a/packages/qwik-nx/src/generators/route/generator.spec.ts +++ b/packages/qwik-nx/src/generators/route/generator.spec.ts @@ -1,20 +1,40 @@ import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing'; -import { Tree, readProjectConfiguration } from '@nrwl/devkit'; +import { Tree } from '@nrwl/devkit'; -import generator from './generator'; +import { routeGenerator } from './generator'; import { RouteGeneratorSchema } from './schema'; +import appGenerator from '../application/generator'; describe('route generator', () => { - let appTree: Tree; - const options: RouteGeneratorSchema = { name: 'test' }; + function setup() { + const appTree = createTreeWithEmptyWorkspace(); + appGenerator(appTree, { name: 'testApp' }); - beforeEach(() => { - appTree = createTreeWithEmptyWorkspace(); + const routeOptions: RouteGeneratorSchema = { + name: 'fake-route', + project: 'test-app', + }; + + return { + appTree, + routeOptions, + }; + } + + it('should generate the route index.tsx in the right location', async () => { + const { appTree, routeOptions } = setup(); + await routeGenerator(appTree, routeOptions); + expect( + appTree.exists('test-app/src/routes/fake-route/index.tsx') + ).toBeTruthy(); }); - it('should run successfully', async () => { - await generator(appTree, options); - const config = readProjectConfiguration(appTree, 'test'); - expect(config).toBeDefined(); + it('should generate layout.tsx if selected', async () => { + const { appTree, routeOptions } = setup(); + routeOptions.addLayout = true; + await routeGenerator(appTree, routeOptions); + expect( + appTree.exists('test-app/src/routes/fake-route/layout.tsx') + ).toBeTruthy(); }); }); diff --git a/packages/qwik-nx/src/generators/route/generator.ts b/packages/qwik-nx/src/generators/route/generator.ts index 82680c51..c59fb10f 100644 --- a/packages/qwik-nx/src/generators/route/generator.ts +++ b/packages/qwik-nx/src/generators/route/generator.ts @@ -1,8 +1,8 @@ import { - addProjectConfiguration, formatFiles, generateFiles, - getWorkspaceLayout, + getProjects, + logger, names, offsetFromRoot, Tree, @@ -11,10 +11,21 @@ import * as path from 'path'; import { RouteGeneratorSchema } from './schema'; interface NormalizedSchema extends RouteGeneratorSchema { - projectName: string; - projectRoot: string; - projectDirectory: string; - parsedTags: string[]; + routeName: string; + projectSourceRoot: string; + routeDirectory: string; +} + +export default routeGenerator; + +export async function routeGenerator( + tree: Tree, + options: RouteGeneratorSchema +) { + const normalizedOptions = normalizeOptions(tree, options); + + addFiles(tree, normalizedOptions); + await formatFiles(tree); } function normalizeOptions( @@ -22,21 +33,26 @@ function normalizeOptions( options: RouteGeneratorSchema ): NormalizedSchema { const name = names(options.name).fileName; - const projectDirectory = options.directory + const project = getProjects(tree).get(options.project); + const projectSourceRoot = project.sourceRoot; + + if (!project) { + logger.error( + `Cannot find the ${options.project} project. Please double check the project name.` + ); + throw new Error(); + } + + const routeDirectory = options.directory ? `${names(options.directory).fileName}/${name}` : name; - const projectName = projectDirectory.replace(new RegExp('/', 'g'), '-'); - const projectRoot = `${getWorkspaceLayout(tree).libsDir}/${projectDirectory}`; - const parsedTags = options.tags - ? options.tags.split(',').map((s) => s.trim()) - : []; + const routeName = name; return { ...options, - projectName, - projectRoot, - projectDirectory, - parsedTags, + routeName, + projectSourceRoot, + routeDirectory, }; } @@ -44,30 +60,25 @@ function addFiles(tree: Tree, options: NormalizedSchema) { const templateOptions = { ...options, ...names(options.name), - offsetFromRoot: offsetFromRoot(options.projectRoot), + routeName: names(options.name).fileName, + offsetFromRoot: offsetFromRoot(options.projectSourceRoot), template: '', }; - generateFiles( - tree, - path.join(__dirname, 'files'), - options.projectRoot, - templateOptions - ); -} -export default async function (tree: Tree, options: RouteGeneratorSchema) { - const normalizedOptions = normalizeOptions(tree, options); - addProjectConfiguration(tree, normalizedOptions.projectName, { - root: normalizedOptions.projectRoot, - projectType: 'library', - sourceRoot: `${normalizedOptions.projectRoot}/src`, - targets: { - build: { - executor: 'qwik-nx:build', - }, - }, - tags: normalizedOptions.parsedTags, - }); - addFiles(tree, normalizedOptions); - await formatFiles(tree); + const routesFolder = `${options.projectSourceRoot}/routes`; + + generateFilesByType('route'); + + if (options.addLayout) { + generateFilesByType('layout'); + } + + function generateFilesByType(fileType: 'route' | 'layout') { + generateFiles( + tree, + path.join(__dirname, `files/${fileType}`), + routesFolder, + templateOptions + ); + } } diff --git a/packages/qwik-nx/src/generators/route/schema.d.ts b/packages/qwik-nx/src/generators/route/schema.d.ts index 6a0668b2..c2b065a1 100644 --- a/packages/qwik-nx/src/generators/route/schema.d.ts +++ b/packages/qwik-nx/src/generators/route/schema.d.ts @@ -1,5 +1,6 @@ export interface RouteGeneratorSchema { name: string; - tags?: string; + project: string; + addLayout?: boolean; directory?: string; } diff --git a/packages/qwik-nx/src/generators/route/schema.json b/packages/qwik-nx/src/generators/route/schema.json index 9c408c37..596233be 100644 --- a/packages/qwik-nx/src/generators/route/schema.json +++ b/packages/qwik-nx/src/generators/route/schema.json @@ -5,24 +5,34 @@ "title": "", "type": "object", "properties": { + "project": { + "type": "string", + "description": "The name of the project.", + "alias": "p", + "$default": { + "$source": "projectName" + }, + "x-prompt": "What is the name of the project for this route?", + "x-priority": "important" + }, "name": { "type": "string", - "description": "", + "description": "The name of the route", "$default": { "$source": "argv", "index": 0 }, - "x-prompt": "What name would you like to use?" + "x-prompt": "What name would you like to use?", + "x-priority": "important" }, - "tags": { - "type": "string", - "description": "Add tags to the project (used for linting)", - "alias": "t" + "addLayout": { + "type": "boolean", + "default": false }, "directory": { "type": "string", "description": "A directory where the project is placed" } }, - "required": ["name"] + "required": ["name", "project"] }