Skip to content

Commit

Permalink
feat(vue): init, app, component and lib generators
Browse files Browse the repository at this point in the history
Co-Authored-By: Jack Hsu <jack.hsu@gmail.com>
  • Loading branch information
mandarini and jaysoo committed Sep 12, 2023
1 parent fdbf000 commit 46f5b74
Show file tree
Hide file tree
Showing 83 changed files with 4,850 additions and 392 deletions.
14 changes: 14 additions & 0 deletions docs/map.json
Original file line number Diff line number Diff line change
Expand Up @@ -2079,6 +2079,20 @@
}
]
},
{
"name": "vue",
"id": "vue",
"description": "Vue package.",
"itemList": [
{
"id": "overview",
"path": "/packages/vue",
"name": "Overview of the Nx Vue Plugin",
"description": "The Nx Plugin for Vue contains generators for managing Vue applications and libraries within an Nx workspace. This page also explains how to configure Vue on your Nx workspace.",
"file": "shared/packages/vue/vue-plugin"
}
]
},
{
"name": "webpack",
"id": "webpack",
Expand Down
10 changes: 10 additions & 0 deletions docs/packages.json
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,16 @@
"generators": ["init", "configuration", "vitest"]
}
},
{
"name": "vue",
"packageName": "vue",
"description": "The Vue plugin for Nx contains executors and generators for managing Vue applications and libraries within an Nx workspace. It provides:\n\n\n- Integration with libraries such as Jest, Cypress, and Storybook.\n\n- Generators for applications, libraries, components, hooks, and more.\n\n- Library build support for publishing packages to npm or other registries.\n\n- Utilities for automatic workspace refactoring.",
"path": "generated/packages/vite.json",
"schemas": {
"executors": [],
"generators": ["init", "library", "application", "component"]
}
},
{
"name": "web",
"packageName": "web",
Expand Down
60 changes: 60 additions & 0 deletions docs/shared/packages/vue/vue-plugin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
title: Overview of the Nx Vue Plugin
description: The Nx Plugin for Vue contains generators for managing Vue applications and libraries within an Nx workspace. This page also explains how to configure Vue on your Nx workspace.
---

The Nx plugin for [Vue](https://vuejs.org/).

## Setting up a new Nx workspace with Vue

You can create a new workspace that uses Vue with one of the following commands:

- Generate a new monorepo with a Vue app set up with Vue

```shell
npx create-nx-workspace@latest --preset=vue
```

## Add Vue to an existing workspace

There are a number of ways to use Vue in your existing workspace.

### Install the `@nx/vue` plugin

{% tabs %}
{% tab label="npm" %}

```shell
npm install -D @nx/vue
```

{% /tab %}
{% tab label="yarn" %}

```shell
yarn add -D @nx/vue
```

{% /tab %}
{% tab label="pnpm" %}

```shell
pnpm install -D @nx/vue
```

{% /tab %}
{% /tabs %}

### Generate a new project using Vue

To generate a Vue application, run the following:

```bash
nx g @nx/vue:app my-app
```

To generate a Vue library, run the following:

```bash
nx g @nx/vue:lib my-lib
```
1 change: 1 addition & 0 deletions e2e/utils/create-project-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export function newProject({
`@nx/rollup`,
`@nx/react`,
`@nx/storybook`,
`@nx/vue`,
`@nx/vite`,
`@nx/web`,
`@nx/webpack`,
Expand Down
63 changes: 63 additions & 0 deletions e2e/vue/src/vue.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import {
cleanupProject,
killPorts,
newProject,
promisifiedTreeKill,
runCLI,
runCLIAsync,
runCommandUntil,
uniq,
} from '@nx/e2e/utils';

const myApp = uniq('my-app');
const myLib = uniq('my-lib');

describe('Vue Plugin', () => {
let proj: string;

describe('Vite on React apps', () => {
describe('successfully create and serve a vue app', () => {
beforeEach(() => {
proj = newProject({
unsetProjectNameAndRootFormat: false,
});
runCLI(`generate @nx/vue:app ${myApp}`);
runCLI(`generate @nx/vue:lib ${myLib} --bundler=vite`);
});
afterEach(() => cleanupProject());

it('should serve application in dev mode', async () => {
const p = await runCommandUntil(`run ${myApp}:serve`, (output) => {
return output.includes('Local:');
});
try {
await promisifiedTreeKill(p.pid, 'SIGKILL');
await killPorts(4200);
} catch (e) {
// ignore
}
}, 200_000);

it('should test application', async () => {
const result = await runCLIAsync(`test ${myApp}`);
expect(result.combinedOutput).toContain(
`Successfully ran target test for project ${myApp}`
);
});

it('should build application', async () => {
const result = await runCLIAsync(`build ${myApp}`);
expect(result.combinedOutput).toContain(
`Successfully ran target build for project ${myApp}`
);
});

it('should build library', async () => {
const result = await runCLIAsync(`build ${myLib}`);
expect(result.combinedOutput).toContain(
`Successfully ran target build for project ${myLib}`
);
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ describe('app', () => {
'vitest/importMeta',
'vite/client',
'node',
'vitest',
]);
});

Expand Down
45 changes: 45 additions & 0 deletions packages/react/src/generators/application/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
addExtendsToLintConfig,
isEslintConfigSupported,
} from '@nx/linter/src/generators/utils/eslint-file';
import { createOrEditViteConfig } from '@nx/vite';

async function addLinting(host: Tree, options: NormalizedSchema) {
const tasks: GeneratorCallback[] = [];
Expand Down Expand Up @@ -138,6 +139,28 @@ export async function applicationGeneratorInternal(
skipFormat: true,
});
tasks.push(viteTask);
createOrEditViteConfig(
host,
{
project: options.projectName,
includeLib: false,
includeVitest: options.unitTestRunner === 'vitest',
inSourceTests: options.inSourceTests,
rollupOptionsExternal: [
`'react'`,
`'react-dom'`,
`'react/jsx-runtime'`,
],
rollupOptionsExternalString: `"'react', 'react-dom', 'react/jsx-runtime'"`,
imports: [
options.compiler === 'swc'
? `import react from '@vitejs/plugin-react-swc'`
: `import react from '@vitejs/plugin-react'`,
],
plugins: ['react()'],
},
false
);
} else if (options.bundler === 'webpack') {
const { webpackInitGenerator } = ensurePackage<
typeof import('@nx/webpack')
Expand Down Expand Up @@ -180,6 +203,28 @@ export async function applicationGeneratorInternal(
skipFormat: true,
});
tasks.push(vitestTask);
createOrEditViteConfig(
host,
{
project: options.projectName,
includeLib: false,
includeVitest: true,
inSourceTests: options.inSourceTests,
rollupOptionsExternal: [
`'react'`,
`'react-dom'`,
`'react/jsx-runtime'`,
],
rollupOptionsExternalString: `"'react', 'react-dom', 'react/jsx-runtime'"`,
imports: [
options.compiler === 'swc'
? `import react from '@vitejs/plugin-react-swc'`
: `import react from '@vitejs/plugin-react'`,
],
plugins: ['react()'],
},
true
);
}

if (
Expand Down
1 change: 1 addition & 0 deletions packages/react/src/generators/library/library.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ describe('lib', () => {
'vitest/importMeta',
'vite/client',
'node',
'vitest',
]);
});

Expand Down
52 changes: 45 additions & 7 deletions packages/react/src/generators/library/library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,8 @@ export async function libraryGeneratorInternal(host: Tree, schema: Schema) {

// Set up build target
if (options.buildable && options.bundler === 'vite') {
const { viteConfigurationGenerator } = ensurePackage<
typeof import('@nx/vite')
>('@nx/vite', nxVersion);
const { viteConfigurationGenerator, createOrEditViteConfig } =
ensurePackage<typeof import('@nx/vite')>('@nx/vite', nxVersion);
const viteTask = await viteConfigurationGenerator(host, {
uiFramework: 'react',
project: options.name,
Expand All @@ -84,6 +83,28 @@ export async function libraryGeneratorInternal(host: Tree, schema: Schema) {
testEnvironment: 'jsdom',
});
tasks.push(viteTask);
createOrEditViteConfig(
host,
{
project: options.name,
includeLib: true,
includeVitest: options.unitTestRunner === 'vitest',
inSourceTests: options.inSourceTests,
rollupOptionsExternal: [
`'react'`,
`'react-dom'`,
`'react/jsx-runtime'`,
],
rollupOptionsExternalString: `"'react', 'react-dom', 'react/jsx-runtime'"`,
imports: [
options.compiler === 'swc'
? `import react from '@vitejs/plugin-react-swc'`
: `import react from '@vitejs/plugin-react'`,
],
plugins: ['react()'],
},
false
);
} else if (options.buildable && options.bundler === 'rollup') {
const rollupTask = await addRollupBuildTarget(host, options);
tasks.push(rollupTask);
Expand Down Expand Up @@ -120,10 +141,9 @@ export async function libraryGeneratorInternal(host: Tree, schema: Schema) {
options.unitTestRunner === 'vitest' &&
options.bundler !== 'vite' // tests are already configured if bundler is vite
) {
const { vitestGenerator } = ensurePackage<typeof import('@nx/vite')>(
'@nx/vite',
nxVersion
);
const { vitestGenerator, createOrEditViteConfig } = ensurePackage<
typeof import('@nx/vite')
>('@nx/vite', nxVersion);
const vitestTask = await vitestGenerator(host, {
uiFramework: 'react',
project: options.name,
Expand All @@ -133,6 +153,24 @@ export async function libraryGeneratorInternal(host: Tree, schema: Schema) {
testEnvironment: 'jsdom',
});
tasks.push(vitestTask);
createOrEditViteConfig(
host,
{
project: options.name,
includeLib: true,
includeVitest: true,
inSourceTests: options.inSourceTests,
rollupOptionsExternal: [
`'react'`,
`'react-dom'`,
`'react/jsx-runtime'`,
],
rollupOptionsExternalString: `"'react', 'react-dom', 'react/jsx-runtime'"`,
imports: [`import react from '@vitejs/plugin-react'`],
plugins: ['react()'],
},
true
);
}

if (options.component) {
Expand Down

0 comments on commit 46f5b74

Please sign in to comment.