Skip to content

Commit

Permalink
feat: add worker library generator (#23)
Browse files Browse the repository at this point in the history
* feat: create empty library generator

* feat: modernize app generation to include the new nx projects format

* feat: create cloudflare worker lib generator

* docs: update readme to match new implementation

* test: adjust test to schema simplification

* fix: lint issue

* test: create library e2e files

* fix: library usage of the plugin

* fix: missing config on schema

* fix: failing test
  • Loading branch information
nacho-vazquez authored Sep 18, 2023
1 parent 3bd636f commit 4a4ad71
Show file tree
Hide file tree
Showing 12 changed files with 1,273 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ describe('Cloudflare Worker Applications', () => {
const workerapp = uniq('workerapp');

runNxCommand(
`generate @naxodev/nx-cloudflare:app ${workerapp} --directory="apps" --template="none"`
`generate @naxodev/nx-cloudflare:app --name ${workerapp} --directory="apps/${workerapp}" --template="none"`
);

expect(
Expand All @@ -39,7 +39,7 @@ describe('Cloudflare Worker Applications', () => {
const port = 8787;

runNxCommand(
`generate @naxodev/nx-cloudflare:app ${workerapp} --directory="apps" --template="fetch-handler"`
`generate @naxodev/nx-cloudflare:app --name ${workerapp} --directory="apps/${workerapp}" --template="fetch-handler"`
);

const lintResults = runNxCommand(`lint ${workerapp}`);
Expand All @@ -66,7 +66,7 @@ describe('Cloudflare Worker Applications', () => {
const port = 8787;

runNxCommand(
`generate @naxodev/nx-cloudflare:app ${workerapp} --directory="apps" --template="scheduled-handler"`
`generate @naxodev/nx-cloudflare:app --name ${workerapp} --directory="apps/${workerapp}" --template="scheduled-handler"`
);

const lintResults = runNxCommand(`lint ${workerapp}`);
Expand All @@ -93,7 +93,7 @@ describe('Cloudflare Worker Applications', () => {
const port = 8787;

runNxCommand(
`generate @naxodev/nx-cloudflare:app ${workerapp} --directory="apps" --template="hono"`
`generate @naxodev/nx-cloudflare:app --name ${workerapp} --directory="apps/${workerapp}" --template="hono"`
);

const lintResults = runNxCommand(`lint ${workerapp}`);
Expand Down
29 changes: 29 additions & 0 deletions e2e/plugins-nx-cloudflare-e2e/tests/library.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import {
uniq,
fileExists,
tmpProjPath,
runNxCommand,
} from '@nx/plugin/testing';
import { newNxProject, installPlugin, cleanup } from '@naxodev/e2e/utils';
import { join } from 'path';

describe('Cloudflare Worker Library', () => {
beforeEach(() => {
newNxProject();
installPlugin('nx-cloudflare');
});

afterEach(() => cleanup());

it('should be able to generate a library', async () => {
const workerlib = uniq('workerlib');

runNxCommand(
`generate @naxodev/nx-cloudflare:lib --name=${workerlib} --directory="libs/${workerlib}" --unitTestRunner="none"`
);

expect(
fileExists(join(tmpProjPath(), `libs/${workerlib}/project.json`))
).toBeTruthy();
}, 30_000);
});
84 changes: 59 additions & 25 deletions packages/plugins/nx-cloudflare/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@

<hr>

Nx plugin for Cloudflare, in particular Cloudflare workers.
Nx plugin for Cloudflare.

## Features

- ✅ Generate Cloudflare Worker Application
- ✅ Include Fetch Handler template
- ✅ Include Scheduled Handler template
- ✅ Vitest tests support
- ✅ Serve and Publish executors for workers.
- ✅ Include Fetch Handler template
- ✅ Include Scheduled Handler template
- ✅ Vitest tests support
- ✅ Serve and Publish executors for workers.
- ✅ Generate Cloudflare Worker Library
-[Experimental] Cloudflare Pages builder for Next.JS projects.

## Installation
Expand All @@ -39,29 +40,32 @@ Nx Cloudflare is published as the `@naxodev/nx-cloudflare` package.

## Usage

### Generating new Cloudflare Worker Application
### Cloudflare Worker Application

#### Generating a new Cloudflare Worker Application

```bash
nx g @naxodev/nx-cloudflare:application my-worker-app
```

The available options are the following:

| Option | Type | Default | Description |
| --------------- | -------------------------------------------- | ------------- | ----------------------------------------------------------------------------------------- |
| name | string | \*required | What name would you like to use? |
| template | fetch-handler, scheduled-handler, hono, none | fetch-handler | Which worker template do you want to use? |
| port | number | 8787 | The port in which the worker will be run on development mode |
| accountId | string | null | The Cloudflare account identifier where the worker will be deployed |
| js | boolean | false | Use JavaScript instead of TypeScript |
| tags | string | null | Add tags to the application (used for linting). |
| frontendProject | string | null | Frontend project that needs to access this application. This sets up proxy configuration. |
| unitTestRunner | vitest, none | vitest | Test runner to use for unit tests. |
| directory | string | null | The directory of the new application. |
| rootProject | boolean | false | Create worker application at the root of the workspace |
| skipFormat | boolean | false | Skip formatting files. |

### Serve worker on dev mode
Available options:

| Option | Type | Default | Description |
| ------------------------ | -------------------------------------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name | string | \*required | What name would you like to use? |
| template | fetch-handler, scheduled-handler, hono, none | fetch-handler | Which worker template do you want to use? |
| projectNameAndRootFormat | as-provided, derived | as-provided | Whether to generate the project name and root directory as provided (`as-provided`) or generate them composing their values and taking the configured layout into account (`derived`). |
| port | number | 8787 | The port in which the worker will be run on development mode |
| accountId | string | null | The Cloudflare account identifier where the worker will be deployed |
| js | boolean | false | Use JavaScript instead of TypeScript |
| tags | string | null | Add tags to the application (used for linting). |
| frontendProject | string | null | Frontend project that needs to access this application. This sets up proxy configuration. |
| unitTestRunner | vitest, none | vitest | Test runner to use for unit tests. |
| directory | string | null | The directory of the new application. |
| rootProject | boolean | false | Create worker application at the root of the workspace |
| skipFormat | boolean | false | Skip formatting files. |

#### Serve worker on dev mode

```bash
nx serve <my-app>
Expand All @@ -73,13 +77,42 @@ The available options are the following:
| ------ | ------ | ------- | ------------------------------------------------------------ |
| port | number | 8787 | The port in which the worker will be run on development mode |

### Publish worker to Cloudflare
### Cloudflare Worker Library

#### Generating a new Cloudflare Worker Library

```bash
nx g @naxodev/nx-cloudflare:library my-worker-lib
```

Available options:

| Option | Type | Default | Description |
| ------------------------ | ------------------------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name | string | \*required | What name would you like to use? |
| directory | string | null | The directory of the new application. |
| projectNameAndRootFormat | as-provided, derived | as-provided | Whether to generate the project name and root directory as provided (`as-provided`) or generate them composing their values and taking the configured layout into account (`derived`). |
| linter | eslint, none | eslint | The tool to use for running lint checks. |
| unitTestRunner | vitest, none | vitest | Test runner to use for unit tests. |
| tags | string | null | Add tags to the application (used for linting). |
| skipFormat | boolean | false | Skip formatting files. |
| js | boolean | false | Use JavaScript instead of TypeScript |
| strict | boolean | true | Whether to enable tsconfig strict mode or not. |
| publishable | boolean | false | Generate a publishable library. |
| importPath | string | null | The library name used to import it, like @myorg/my-awesome-lib. Required for publishable library. |
| bundler | swc, tsc, rollup, vite, esbuild, none | tsc | Which bundler would you like to use to build the library? Choose 'none' to skip build setup. |
| minimal | boolean | false | Generate a library with a minimal setup. No README.md generated. |
| simpleName | boolean | false | Don't include the directory in the generated file name. |

#### Publish worker to Cloudflare

```bash
nx publish <my-app>
```

### Build Next application.
### NextJS on Cloudflare

#### Build Next application.

> This feature is ⚠️ **experimental**. We appreciate that you let us know of any issues that you find.
Expand Down Expand Up @@ -124,4 +157,5 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<tbody>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/NachoVazquez"><img src="https://avatars3.githubusercontent.com/u/9338604?v=4?s=100" width="100px;" alt="Nacho Vazquez"/><br /><sub><b>Nacho Vazquez</b></sub></a><br /><a href="https://github.com/ngworker/lumberjack/issues?q=author%3ANachoVazquez" title="Bug reports">🐛</a> <a href="https://github.com/ngworker/lumberjack/commits?author=NachoVazquez" title="Code">💻</a> <a href="https://github.com/ngworker/lumberjack/commits?author=NachoVazquez" title="Documentation">📖</a> <a href="#example-NachoVazquez" title="Examples">💡</a> <a href="#ideas-NachoVazquez" title="Ideas, Planning, & Feedback">🤔</a> <a href="#mentoring-NachoVazquez" title="Mentoring">🧑‍🏫</a> <a href="#maintenance-NachoVazquez" title="Maintenance">🚧</a> <a href="#projectManagement-NachoVazquez" title="Project Management">📆</a> <a href="https://github.com/ngworker/lumberjack/pulls?q=is%3Apr+reviewed-by%3ANachoVazquez" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/ngworker/lumberjack/commits?author=NachoVazquez" title="Tests">⚠️</a> <a href="#tool-NachoVazquez" title="Tools">🔧</a> <a href="#userTesting-NachoVazquez" title="User Testing">📓</a></td>

<td align="center" valign="top" width="14.28%
6 changes: 6 additions & 0 deletions packages/plugins/nx-cloudflare/generators.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@
"schema": "./src/generators/init/schema.json",
"description": "Init generator",
"hidden": true
},
"library": {
"factory": "./src/generators/library/library",
"schema": "./src/generators/library/schema.json",
"description": "library generator",
"aliases": ["lib"]
}
}
}
2 changes: 1 addition & 1 deletion packages/plugins/nx-cloudflare/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@
"@cloudflare/next-on-pages": "^1.6.1"
},
"dependencies": {
"@nx/devkit": ">= 16.0.0 <= 17.0.0",
"tslib": "^2.3.0",
"@svgr/webpack": "^8.0.1",
"copy-webpack-plugin": "^11.0.0",
"dotenv": "^16.3.1",
"fs-extra": "^11.1.0",
"semver": "^7.5.4",
"url-loader": "^4.1.1",
"@nx/devkit": ">= 16.0.0 <= 17.0.0",
"@nx/node": ">= 16.0.0 <= 17.0.0",
"wrangler": ">= 3.8.0 <= 4.0.0"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ import initGenerator from '../init/init';
import { vitestImports } from './utils/vitest-imports';
import { getAccountId } from './utils/get-account-id';
import { vitestScript } from './utils/vitest-script';
import { determineProjectNameAndRootOptions } from '@nx/devkit/src/generators/project-name-and-root-utils';

export async function applicationGenerator(tree: Tree, schema: Schema) {
const options = normalizeOptions(tree, schema);
const options = await normalizeOptions(tree, schema);

// Set up the needed packages.
const initTask = await initGenerator(tree, {
Expand Down Expand Up @@ -169,21 +170,24 @@ function removeTestFiles(tree: Tree, options: NormalizedSchema) {
}

// Transform the options to the normalized schema. Loads defaults options.
function normalizeOptions(host: Tree, options: Schema): NormalizedSchema {
const { layoutDirectory, projectDirectory } = extractLayoutDirectory(
options.directory
);
const appsDir = layoutDirectory ?? getWorkspaceLayout(host).appsDir;

const appDirectory = projectDirectory
? `${names(projectDirectory).fileName}/${names(options.name).fileName}`
: names(options.name).fileName;

const appProjectName = appDirectory.replace(new RegExp('/', 'g'), '-');

const appProjectRoot = options.rootProject
? '.'
: joinPathFragments(appsDir, appDirectory);
async function normalizeOptions(
host: Tree,
options: Schema
): Promise<NormalizedSchema> {
const {
projectName: appProjectName,
projectRoot: appProjectRoot,
projectNameAndRootFormat,
} = await determineProjectNameAndRootOptions(host, {
name: options.name,
projectType: 'application',
directory: options.directory,
projectNameAndRootFormat: options.projectNameAndRootFormat,
rootProject: options.rootProject,
callingGenerator: '@nx/node:application',
});
options.rootProject = appProjectRoot === '.';
options.projectNameAndRootFormat = projectNameAndRootFormat;

return {
...options,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-and-root-utils';

export interface Schema {
name: string;
template?: 'fetch-handler' | 'scheduled-handler' | 'hono' | 'none';
js?: boolean;
unitTestRunner?: 'vitest' | 'none';
directory?: string;
projectNameAndRootFormat?: ProjectNameAndRootFormat;
rootProject?: boolean;
tags?: string;
frontendProject?: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"$schema": "http://json-schema.org/schema",
"$id": "Application",
"title": "",
"$id": "NxCloudflareWorkerApplication",
"title": "Create a Cloudflare Worker Application",
"description": "Create a Cloudflare Worker Application",
"type": "object",
"properties": {
"name": {
Expand All @@ -17,6 +18,11 @@
"type": "boolean",
"description": "Use JavaScript instead of TypeScript"
},
"projectNameAndRootFormat": {
"description": "Whether to generate the project name and root directory as provided (`as-provided`) or generate them composing their values and taking the configured layout into account (`derived`).",
"type": "string",
"enum": ["as-provided", "derived"]
},
"tags": {
"type": "string",
"description": "Add tags to the application (used for linting)."
Expand Down
Loading

0 comments on commit 4a4ad71

Please sign in to comment.