fix(vite): project conversion generator (#21646)
This commit is contained in:
parent
246fd1907b
commit
fe17fc3287
File diff suppressed because one or more lines are too long
@ -925,10 +925,7 @@ describe('app', () => {
|
||||
|
||||
it('should create correct tsconfig compilerOptions', () => {
|
||||
const tsconfigJson = readJson(viteAppTree, '/my-app/tsconfig.json');
|
||||
expect(tsconfigJson.compilerOptions.types).toMatchObject([
|
||||
'vite/client',
|
||||
'vitest',
|
||||
]);
|
||||
expect(tsconfigJson.compilerOptions.jsx).toBe('react-jsx');
|
||||
});
|
||||
|
||||
it('should create index.html and vite.config file at the root of the app', () => {
|
||||
|
||||
@ -3,9 +3,9 @@ title: Examples for the Vite configuration generator
|
||||
description: This page contains examples for the Vite @nx/vite:configuration generator, which helps you set up Vite on your Nx workspace, or convert an existing project to use Vite.
|
||||
---
|
||||
|
||||
This generator is used for converting an existing React or Web project to use [Vite.js](https://vitejs.dev/) and the [@nx/vite executors](/packages/vite#executors).
|
||||
This generator is used for converting an existing React or Web project to use [Vite.js](https://vitejs.dev/).
|
||||
|
||||
It will change the `build` and `serve` targets to use the `@nx/vite` executors for serving and building the application. If you choose so, it will also change your `test` target to use the `@nx/vite:test` executor. It will create a `vite.config.ts` file at the root of your project with the correct settings, or if there's already a `vite.config.ts` file, it will modify it to include the correct settings.
|
||||
It will create a `vite.config.ts` file at the root of your project with the correct settings, or if there's already a `vite.config.ts` file, it will modify it to include the correct settings.
|
||||
|
||||
{% callout type="caution" title="Your code will be modified!" %}
|
||||
This generator will modify your code, so make sure to commit your changes before running it.
|
||||
@ -22,15 +22,14 @@ When running this generator, you will be prompted to provide the following:
|
||||
|
||||
You must provide a `project` and a `uiFramework` for the generator to work.
|
||||
|
||||
You may also pass the `includeVitest` flag. This will also change your `test` target to use the `@nx/vite:test` executor, and configure your project for testing with [Vitest](https://vitest.dev/), by adding the `test` configuration in your `vite.config.ts` file.
|
||||
You may also pass the `includeVitest` flag. This will also configure your project for testing with [Vitest](https://vitest.dev/), by adding the `test` configuration in your `vite.config.ts` file.
|
||||
|
||||
## Converting custom (specific) targets
|
||||
## How to use
|
||||
|
||||
By default, the `@nx/vite:configuration` generator will search your project's configuration to find the targets for serving, building, and testing your project, and it will attempt to convert these targets to use the `@nx/vite` executors.
|
||||
If you have an existing project that does not use Vite, you may want to convert it to use Vite. This can be a `webpack` project, a buildable JS library that uses the `@nx/js:babel`, the `@nx/js:swc` or the `@nx/rollup:rollup` executor, or even a non-buildable library.
|
||||
By default, the `@nx/vite:configuration` generator will search your project to find the relevant configuration (either a `webpack.config.ts` file for example, or the `@nx/js` executors). If it determines that your project can be converted, then Nx will generate the configuration for you. If it cannot determine that your project can be converted, it will ask you if you want to convert it anyway or throw an error if it determines that it cannot be converted.
|
||||
|
||||
Your targets for building, serving and testing may not be named `build`, `serve` and `test`. Nx will try to infer the correct targets to convert, and it will attempt to convert the first one it finds for each of these actions if you have more than one. If you have more than one target for serving, building, or testing your project, you can pass the `--serveTarget`, `--buildTarget`, and `--testTarget` flags to the generator, to tell Nx specifically which targets to convert.
|
||||
|
||||
Nx will determine if the targets you provided (or the ones it inferred) are valid and can be converted to use the `@nx/vite` executors. If the targets are not valid, the generator will fail. If no targets are found - or recognized to be either supported or unsupported - Nx will ask you whether you want to convert your project anyway. If you choose to do so, Nx will configure your project to use Vite.js, creating new targets for you, and creating or modifying your `vite.config.ts` file. You can then test on your own if the result works or not, and modify the configuration as needed. It's suggested that if Nx does not recognize your targets automatically, you commit your changes before running the generator, so you can revert the changes if needed.
|
||||
You can then test on your own if the result works or not, and modify the configuration as needed. It's suggested that you commit your changes before running the generator, so you can revert the changes if needed.
|
||||
|
||||
## Projects that can be converted to use the `@nx/vite` executors
|
||||
|
||||
@ -43,20 +42,10 @@ The list of executors for building, testing and serving that can be converted to
|
||||
- `@nxext/vite:build`
|
||||
- `@nx/js:babel`
|
||||
- `@nx/js:swc`
|
||||
- `@nx/webpack:webpack`
|
||||
- `@nx/rollup:rollup`
|
||||
- `@nx/webpack:webpack`
|
||||
- `@nx/web:rollup`
|
||||
|
||||
### Supported `serve` executors
|
||||
|
||||
- `@nxext/vite:dev`
|
||||
- `@nx/webpack:dev-server`
|
||||
|
||||
### Supported `test` executors
|
||||
|
||||
- `@nx/jest:jest`
|
||||
- `@nxext/vitest:vitest`
|
||||
|
||||
### Unsupported executors
|
||||
|
||||
- `@nx/angular:ng-packagr-lite`
|
||||
@ -72,34 +61,24 @@ The list of executors for building, testing and serving that can be converted to
|
||||
- any executor _not_ listed in the lists of "supported executors"
|
||||
- any project that does _not_ have a target for building, serving or testing
|
||||
|
||||
We **cannot** guarantee that projects using unsupported executors - _or any executor that is NOT listed in the list of "supported executors"_ - for either building, testing or serving will work correctly when converted to use the `@nx/vite` executors.
|
||||
|
||||
If you have a project that does _not_ use one of the supported executors you can try to [configure it to use the `@nx/vite` executors manually](/recipes/vite/configure-vite), but it may not work properly.
|
||||
We **cannot** guarantee that projects using unsupported executors - _or any executor that is NOT listed in the list of "supported executors"_ - for either building, testing or serving will work correctly when converted to use Vite.
|
||||
|
||||
You can read more in the [Vite package overview page](/packages/vite).
|
||||
|
||||
## Examples
|
||||
|
||||
### Change a React app to use Vite
|
||||
### Convert a React app to use Vite
|
||||
|
||||
```bash
|
||||
nx g @nx/vite:configuration --project=my-react-app --uiFramework=react --includeVitest
|
||||
```
|
||||
|
||||
This will change the `my-react-app` project to use the `@nx/vite` executors for building, serving and testing the application.
|
||||
This will configure the `my-react-app` project to use Vite.
|
||||
|
||||
### Change a Web app to use Vite
|
||||
### Convert a Web app to use Vite
|
||||
|
||||
```bash
|
||||
nx g @nx/vite:configuration --project=my-web-app --uiFramework=none --includeVitest
|
||||
```
|
||||
|
||||
This will change the `my-web-app` project to use the `@nx/vite` executors for building, serving and testing the application.
|
||||
|
||||
### Change only my custom provided targets to use Vite
|
||||
|
||||
```bash
|
||||
nx g @nx/vite:configuration --project=my-react-app --uiFramework=react --includeVitest --buildTarget=my-build --serveTarget=my-serve --testTarget=my-test
|
||||
```
|
||||
|
||||
This will change the `my-build`, `my-serve` and `my-test` targets to use the `@nx/vite` executors for building, serving and testing the application, even if you have other targets for these actions as well.
|
||||
This will configure the `my-web-app` project to use Vite.
|
||||
|
||||
@ -121,36 +121,6 @@ export default defineConfig({
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`@nx/vite:configuration library mode should set up non buildable library correctly 2`] = `
|
||||
"{
|
||||
"projects": {
|
||||
"react-lib-nonb-jest": {
|
||||
"name": "react-lib-nonb-jest",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"root": "libs/react-lib-nonb-jest",
|
||||
"sourceRoot": "libs/react-lib-nonb-jest/src",
|
||||
"projectType": "library",
|
||||
"targets": {
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint",
|
||||
"outputs": ["{options.outputFile}"]
|
||||
},
|
||||
"test": {
|
||||
"executor": "@nx/jest:jest",
|
||||
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
|
||||
"options": {
|
||||
"jestConfig": "libs/react-lib-nonb-jest/jest.config.ts",
|
||||
"passWithNoTests": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
}
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`@nx/vite:configuration library mode should set up non buildable library which already has vite.config.ts correctly 1`] = `
|
||||
"import dts from 'vite-plugin-dts';
|
||||
import * as path from 'path';
|
||||
@ -207,91 +177,6 @@ export default defineConfig({
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`@nx/vite:configuration library mode should set up non buildable library which already has vite.config.ts correctly 2`] = `
|
||||
"{
|
||||
"projects": {
|
||||
"react-lib-nonb-vitest": {
|
||||
"name": "react-lib-nonb-vitest",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"root": "libs/react-lib-nonb-vitest",
|
||||
"sourceRoot": "libs/react-lib-nonb-vitest/src",
|
||||
"projectType": "library",
|
||||
"targets": {
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint",
|
||||
"outputs": ["{options.outputFile}"]
|
||||
},
|
||||
"test": {
|
||||
"executor": "@nx/vite:test",
|
||||
"outputs": ["{projectRoot}/coverage"],
|
||||
"options": {
|
||||
"passWithNoTests": true,
|
||||
"reportsDirectory": "{workspaceRoot}/coverage/{projectRoot}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
}
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`@nx/vite:configuration transform React app to use Vite by providing custom targets transform React app if supported executor is provided should transform workspace.json project config 1`] = `
|
||||
"{
|
||||
"projects": {
|
||||
"my-test-mixed-react-app": {
|
||||
"name": "my-test-mixed-react-app",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"root": "apps/my-test-mixed-react-app",
|
||||
"sourceRoot": "apps/my-test-mixed-react-app/src",
|
||||
"projectType": "application",
|
||||
"targets": {
|
||||
"invalid-build": {
|
||||
"executor": "@nx/js:tsc",
|
||||
"outputs": ["{options.outputPath}"]
|
||||
},
|
||||
"valid-build": {
|
||||
"executor": "@nx/webpack:webpack",
|
||||
"outputs": ["{options.outputPath}"]
|
||||
},
|
||||
"serve": {
|
||||
"executor": "@nx/webpack:dev-server",
|
||||
"defaultConfiguration": "development",
|
||||
"options": {
|
||||
"buildTarget": "my-test-mixed-react-app:build",
|
||||
"hmr": true
|
||||
},
|
||||
"configurations": {
|
||||
"development": {
|
||||
"buildTarget": "my-test-mixed-react-app:build:development"
|
||||
},
|
||||
"production": {
|
||||
"buildTarget": "my-test-mixed-react-app:build:production",
|
||||
"hmr": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint",
|
||||
"outputs": ["{options.outputFile}"]
|
||||
},
|
||||
"test": {
|
||||
"executor": "@nx/jest:jest",
|
||||
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
|
||||
"options": {
|
||||
"jestConfig": "apps/my-test-mixed-react-app/jest.config.ts",
|
||||
"passWithNoTests": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
}
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`@nx/vite:configuration transform React app to use Vite should create vite.config file at the root of the app 1`] = `
|
||||
"/// <reference types='vitest' />
|
||||
import { defineConfig } from 'vite';
|
||||
@ -349,96 +234,6 @@ exports[`@nx/vite:configuration transform React app to use Vite should move inde
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`@nx/vite:configuration transform React app to use Vite should transform workspace.json project config 1`] = `
|
||||
"{
|
||||
"projects": {
|
||||
"my-test-react-app": {
|
||||
"name": "my-test-react-app",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"root": "apps/my-test-react-app",
|
||||
"sourceRoot": "apps/my-test-react-app/src",
|
||||
"projectType": "application",
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@nx/webpack:webpack",
|
||||
"outputs": ["{options.outputPath}"],
|
||||
"defaultConfiguration": "production",
|
||||
"options": {
|
||||
"compiler": "babel",
|
||||
"outputPath": "dist/apps/my-test-react-app",
|
||||
"index": "apps/my-test-react-app/src/index.html",
|
||||
"baseHref": "/",
|
||||
"main": "apps/my-test-react-app/src/main.tsx",
|
||||
"polyfills": "apps/my-test-react-app/src/polyfills.ts",
|
||||
"tsConfig": "apps/my-test-react-app/tsconfig.app.json",
|
||||
"assets": [
|
||||
"apps/my-test-react-app/src/favicon.ico",
|
||||
"apps/my-test-react-app/src/assets"
|
||||
],
|
||||
"styles": ["apps/my-test-react-app/src/styles.css"],
|
||||
"scripts": [],
|
||||
"webpackConfig": "@nx/react/plugins/webpack"
|
||||
},
|
||||
"configurations": {
|
||||
"development": {
|
||||
"extractLicenses": false,
|
||||
"optimization": false,
|
||||
"sourceMap": true,
|
||||
"vendorChunk": true
|
||||
},
|
||||
"production": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "apps/my-test-react-app/src/environments/environment.ts",
|
||||
"with": "apps/my-test-react-app/src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": false,
|
||||
"namedChunks": false,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"executor": "@nx/webpack:dev-server",
|
||||
"defaultConfiguration": "development",
|
||||
"options": {
|
||||
"buildTarget": "my-test-react-app:build",
|
||||
"hmr": true
|
||||
},
|
||||
"configurations": {
|
||||
"development": {
|
||||
"buildTarget": "my-test-react-app:build:development"
|
||||
},
|
||||
"production": {
|
||||
"buildTarget": "my-test-react-app:build:production",
|
||||
"hmr": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint",
|
||||
"outputs": ["{options.outputFile}"]
|
||||
},
|
||||
"test": {
|
||||
"executor": "@nx/jest:jest",
|
||||
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
|
||||
"options": {
|
||||
"jestConfig": "apps/my-test-react-app/jest.config.ts",
|
||||
"passWithNoTests": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
}
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`@nx/vite:configuration transform Web app to use Vite should create vite.config file at the root of the app 1`] = `
|
||||
"/// <reference types='vitest' />
|
||||
import { defineConfig } from 'vite';
|
||||
@ -496,83 +291,6 @@ exports[`@nx/vite:configuration transform Web app to use Vite should move index.
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`@nx/vite:configuration transform Web app to use Vite should transform workspace.json project config 1`] = `
|
||||
"{
|
||||
"projects": {
|
||||
"my-test-web-app": {
|
||||
"name": "my-test-web-app",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"projectType": "application",
|
||||
"root": "apps/my-test-web-app",
|
||||
"sourceRoot": "apps/my-test-web-app/src",
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@nx/webpack:webpack",
|
||||
"outputs": ["{options.outputPath}"],
|
||||
"defaultConfiguration": "production",
|
||||
"options": {
|
||||
"outputPath": "dist/apps/my-test-web-app",
|
||||
"compiler": "babel",
|
||||
"main": "apps/my-test-web-app/src/main.ts",
|
||||
"tsConfig": "apps/my-test-web-app/tsconfig.app.json",
|
||||
"assets": [
|
||||
"apps/my-test-web-app/src/favicon.ico",
|
||||
"apps/my-test-web-app/src/assets"
|
||||
],
|
||||
"index": "apps/my-test-web-app/src/index.html",
|
||||
"baseHref": "/",
|
||||
"polyfills": "apps/my-test-web-app/src/polyfills.ts",
|
||||
"styles": ["apps/my-test-web-app/src/styles.css"],
|
||||
"scripts": []
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": false,
|
||||
"namedChunks": false,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false,
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "apps/my-test-web-app/src/environments/environment.ts",
|
||||
"with": "apps/my-test-web-app/src/environments/environment.prod.ts"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"executor": "@nx/webpack:dev-server",
|
||||
"options": {
|
||||
"buildTarget": "my-test-web-app:build"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"buildTarget": "my-test-web-app:build:production"
|
||||
}
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint",
|
||||
"outputs": ["{options.outputFile}"]
|
||||
},
|
||||
"test": {
|
||||
"executor": "@nx/jest:jest",
|
||||
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
|
||||
"options": {
|
||||
"jestConfig": "apps/my-test-web-app/jest.config.ts",
|
||||
"passWithNoTests": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`@nx/vite:configuration vitest should create a vitest configuration if "includeVitest" is true 1`] = `
|
||||
"/// <reference types='vitest' />
|
||||
import { defineConfig } from 'vite';
|
||||
|
||||
@ -12,7 +12,6 @@ import {
|
||||
mockUnknownAppGenerator,
|
||||
mockWebAppGenerator,
|
||||
} from '../../utils/test-utils';
|
||||
import { ViteConfigurationGeneratorSchema } from './schema';
|
||||
|
||||
describe('@nx/vite:configuration', () => {
|
||||
let tree: Tree;
|
||||
@ -56,7 +55,7 @@ describe('@nx/vite:configuration', () => {
|
||||
tree,
|
||||
'apps/my-test-react-app/tsconfig.json'
|
||||
);
|
||||
expect(tsconfigJson.compilerOptions.types).toMatchObject(['vite/client']);
|
||||
expect(tsconfigJson.compilerOptions.jsx).toBe('react-jsx');
|
||||
});
|
||||
|
||||
it('should create vite.config file at the root of the app', () => {
|
||||
@ -65,10 +64,6 @@ describe('@nx/vite:configuration', () => {
|
||||
tree.read('apps/my-test-react-app/vite.config.ts', 'utf-8')
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should transform workspace.json project config', () => {
|
||||
expect(tree.read('workspace.json', 'utf-8')).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('transform Web app to use Vite', () => {
|
||||
@ -84,7 +79,6 @@ describe('@nx/vite:configuration', () => {
|
||||
);
|
||||
await viteConfigurationGenerator(tree, {
|
||||
addPlugin: true,
|
||||
uiFramework: 'react',
|
||||
uiFramework: 'none',
|
||||
project: 'my-test-web-app',
|
||||
});
|
||||
@ -106,7 +100,7 @@ describe('@nx/vite:configuration', () => {
|
||||
|
||||
it('should create correct tsconfig compilerOptions', () => {
|
||||
const tsconfigJson = readJson(tree, 'apps/my-test-web-app/tsconfig.json');
|
||||
expect(tsconfigJson.compilerOptions.types).toMatchObject(['vite/client']);
|
||||
expect(tsconfigJson.compilerOptions.noImplicitReturns).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should create vite.config file at the root of the app', () => {
|
||||
@ -115,10 +109,6 @@ describe('@nx/vite:configuration', () => {
|
||||
tree.read('apps/my-test-web-app/vite.config.ts', 'utf-8')
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should transform workspace.json project config', () => {
|
||||
expect(tree.read('workspace.json', 'utf-8')).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('do not transform Angular app to use Vite', () => {
|
||||
@ -132,14 +122,13 @@ describe('@nx/vite:configuration', () => {
|
||||
try {
|
||||
await viteConfigurationGenerator(tree, {
|
||||
addPlugin: true,
|
||||
uiFramework: 'react',
|
||||
uiFramework: 'none',
|
||||
project: 'my-test-angular-app',
|
||||
});
|
||||
} catch (e) {
|
||||
expect(e).toBeDefined();
|
||||
expect(e.toString()).toContain(
|
||||
'The project my-test-angular-app cannot be converted to use the @nx/vite executors'
|
||||
'Nx cannot convert your project to use vite.'
|
||||
);
|
||||
}
|
||||
});
|
||||
@ -151,27 +140,6 @@ describe('@nx/vite:configuration', () => {
|
||||
mockUnknownAppGenerator(tree);
|
||||
});
|
||||
|
||||
it('should throw when trying to convert something unknown', async () => {
|
||||
const { Confirm } = require('enquirer');
|
||||
const confirmSpy = jest.spyOn(Confirm.prototype, 'run');
|
||||
confirmSpy.mockResolvedValue(true);
|
||||
expect.assertions(2);
|
||||
|
||||
try {
|
||||
await viteConfigurationGenerator(tree, {
|
||||
addPlugin: true,
|
||||
uiFramework: 'react',
|
||||
uiFramework: 'none',
|
||||
project: 'my-test-random-app',
|
||||
});
|
||||
} catch (e) {
|
||||
expect(e).toBeDefined();
|
||||
expect(e.toString()).toContain(
|
||||
'Error: Cannot find apps/my-test-random-app/tsconfig.json'
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it('should throw when trying to convert something unknown and user denies conversion', async () => {
|
||||
const { Confirm } = require('enquirer');
|
||||
const confirmSpy = jest.spyOn(Confirm.prototype, 'run');
|
||||
@ -182,115 +150,18 @@ describe('@nx/vite:configuration', () => {
|
||||
try {
|
||||
await viteConfigurationGenerator(tree, {
|
||||
addPlugin: true,
|
||||
uiFramework: 'react',
|
||||
uiFramework: 'none',
|
||||
project: 'my-test-random-app',
|
||||
});
|
||||
} catch (e) {
|
||||
expect(e).toBeDefined();
|
||||
expect(e.toString()).toContain(
|
||||
'Nx could not verify that the executors you are using can be converted to the @nx/vite executors.'
|
||||
'Nx could not verify that your project can be converted to use Vite.'
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('transform React app to use Vite by providing custom targets', () => {
|
||||
describe('transform React app if supported executor is provided', () => {
|
||||
beforeEach(async () => {
|
||||
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
||||
mockReactMixedAppGenerator(tree);
|
||||
const existing = 'existing';
|
||||
const existingVersion = '1.0.0';
|
||||
addDependenciesToPackageJson(
|
||||
tree,
|
||||
{ '@nx/vite': nxVersion, [existing]: existingVersion },
|
||||
{ [existing]: existingVersion }
|
||||
);
|
||||
await viteConfigurationGenerator(tree, {
|
||||
addPlugin: true,
|
||||
uiFramework: 'react',
|
||||
project: 'my-test-mixed-react-app',
|
||||
buildTarget: 'valid-build',
|
||||
});
|
||||
});
|
||||
it('should add vite packages and react-related dependencies for vite', async () => {
|
||||
const packageJson = readJson(tree, '/package.json');
|
||||
expect(packageJson.devDependencies).toMatchObject({
|
||||
vite: expect.any(String),
|
||||
'@vitejs/plugin-react': expect.any(String),
|
||||
});
|
||||
});
|
||||
|
||||
it('should create vite.config file at the root of the app', () => {
|
||||
expect(tree.exists('apps/my-test-mixed-react-app/vite.config.ts')).toBe(
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
it('should transform workspace.json project config', () => {
|
||||
expect(tree.read('workspace.json', 'utf-8')).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('do NOT transform React app if unsupported executor is provided', () => {
|
||||
beforeEach(async () => {
|
||||
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
||||
mockReactMixedAppGenerator(tree);
|
||||
const existing = 'existing';
|
||||
const existingVersion = '1.0.0';
|
||||
addDependenciesToPackageJson(
|
||||
tree,
|
||||
{ '@nx/vite': nxVersion, [existing]: existingVersion },
|
||||
{ [existing]: existingVersion }
|
||||
);
|
||||
});
|
||||
it('should throw when trying to convert and user denies', async () => {
|
||||
const { Confirm } = require('enquirer');
|
||||
const confirmSpy = jest.spyOn(Confirm.prototype, 'run');
|
||||
confirmSpy.mockResolvedValue(false);
|
||||
expect.assertions(2);
|
||||
|
||||
try {
|
||||
await viteConfigurationGenerator(tree, {
|
||||
addPlugin: true,
|
||||
uiFramework: 'react',
|
||||
uiFramework: 'none',
|
||||
project: 'my-test-mixed-react-app',
|
||||
buildTarget: 'invalid-build',
|
||||
});
|
||||
} catch (e) {
|
||||
expect(e).toBeDefined();
|
||||
expect(e.toString()).toContain(
|
||||
'The build target invalid-build cannot be converted to use the @nx/vite:build executor'
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it('should NOT throw error when trying to convert and user confirms', async () => {
|
||||
const { Confirm } = require('enquirer');
|
||||
const confirmSpy = jest.spyOn(Confirm.prototype, 'run');
|
||||
confirmSpy.mockResolvedValue(true);
|
||||
expect.assertions(1);
|
||||
|
||||
try {
|
||||
await viteConfigurationGenerator(tree, {
|
||||
addPlugin: true,
|
||||
uiFramework: 'react',
|
||||
uiFramework: 'none',
|
||||
project: 'my-test-mixed-react-app',
|
||||
buildTarget: 'invalid-build',
|
||||
});
|
||||
expect(
|
||||
tree.exists('apps/my-test-mixed-react-app/vite.config.ts')
|
||||
).toBe(true);
|
||||
} catch (e) {
|
||||
throw new Error('Should not throw error');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('vitest', () => {
|
||||
beforeAll(async () => {
|
||||
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
||||
@ -351,8 +222,6 @@ describe('@nx/vite:configuration', () => {
|
||||
expect(
|
||||
tree.read('libs/react-lib-nonb-jest/vite.config.ts', 'utf-8')
|
||||
).toMatchSnapshot();
|
||||
|
||||
expect(tree.read('workspace.json', 'utf-8')).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should set up non buildable library which already has vite.config.ts correctly', async () => {
|
||||
@ -372,8 +241,6 @@ describe('@nx/vite:configuration', () => {
|
||||
expect(
|
||||
tree.read('libs/react-lib-nonb-vitest/vite.config.ts', 'utf-8')
|
||||
).toMatchSnapshot();
|
||||
|
||||
expect(tree.read('workspace.json', 'utf-8')).toMatchSnapshot();
|
||||
} catch (e) {
|
||||
throw new Error('Should not throw error');
|
||||
}
|
||||
|
||||
@ -11,24 +11,18 @@ import {
|
||||
import { initGenerator as jsInitGenerator } from '@nx/js';
|
||||
|
||||
import {
|
||||
addOrChangeBuildTarget,
|
||||
addOrChangeServeTarget,
|
||||
addBuildTarget,
|
||||
addServeTarget,
|
||||
addPreviewTarget,
|
||||
createOrEditViteConfig,
|
||||
deleteWebpackConfig,
|
||||
editTsConfig,
|
||||
findExistingTargetsInProject,
|
||||
handleUnknownExecutors,
|
||||
handleUnsupportedUserProvidedTargets,
|
||||
moveAndEditIndexHtml,
|
||||
TargetFlags,
|
||||
UserProvidedTargetName,
|
||||
} from '../../utils/generator-utils';
|
||||
|
||||
import initGenerator from '../init/init';
|
||||
import vitestGenerator from '../vitest/vitest-generator';
|
||||
import { ViteConfigurationGeneratorSchema } from './schema';
|
||||
import { ensureDependencies } from '../../utils/ensure-dependencies';
|
||||
import { convertNonVite } from './lib/convert-non-vite';
|
||||
|
||||
export function viteConfigurationGenerator(
|
||||
host: Tree,
|
||||
@ -49,16 +43,9 @@ export async function viteConfigurationGeneratorInternal(
|
||||
schema.addPlugin ??= process.env.NX_ADD_PLUGINS !== 'false';
|
||||
|
||||
const projectConfig = readProjectConfiguration(tree, schema.project);
|
||||
const {
|
||||
targets,
|
||||
|
||||
root: projectRoot,
|
||||
} = projectConfig;
|
||||
const { targets, root: projectRoot } = projectConfig;
|
||||
|
||||
const projectType = projectConfig.projectType ?? 'library';
|
||||
let buildTargetName = 'build';
|
||||
let serveTargetName = 'serve';
|
||||
let testTargetName = 'test';
|
||||
|
||||
schema.includeLib ??= projectType === 'library';
|
||||
|
||||
@ -73,104 +60,7 @@ export async function viteConfigurationGeneratorInternal(
|
||||
let projectAlreadyHasViteTargets: TargetFlags = {};
|
||||
|
||||
if (!schema.newProject) {
|
||||
const userProvidedTargetName: UserProvidedTargetName = {
|
||||
build: schema.buildTarget,
|
||||
serve: schema.serveTarget,
|
||||
test: schema.testTarget,
|
||||
};
|
||||
|
||||
const {
|
||||
validFoundTargetName,
|
||||
projectContainsUnsupportedExecutor,
|
||||
userProvidedTargetIsUnsupported,
|
||||
alreadyHasNxViteTargets,
|
||||
} = findExistingTargetsInProject(targets, userProvidedTargetName);
|
||||
projectAlreadyHasViteTargets = alreadyHasNxViteTargets;
|
||||
/**
|
||||
* This means that we only found unsupported build targets in that project.
|
||||
* The only way that buildTarget is defined, means that it is supported.
|
||||
*
|
||||
* If the `unsupported` flag was false, it would mean that we did not find
|
||||
* a build target at all, so we can create a new one.
|
||||
*
|
||||
* So we only throw if we found a target, but it is unsupported.
|
||||
*/
|
||||
if (!validFoundTargetName.build && projectContainsUnsupportedExecutor) {
|
||||
throw new Error(
|
||||
`The project ${schema.project} cannot be converted to use the @nx/vite executors.`
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
alreadyHasNxViteTargets.build &&
|
||||
(alreadyHasNxViteTargets.serve || projectType === 'library') &&
|
||||
alreadyHasNxViteTargets.test
|
||||
) {
|
||||
throw new Error(
|
||||
`The project ${schema.project} is already configured to use the @nx/vite executors.
|
||||
Please try a different project, or remove the existing targets
|
||||
and re-run this generator to reset the existing Vite Configuration.
|
||||
`
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This means that we did not find any supported executors
|
||||
* so we don't have any valid target names.
|
||||
*
|
||||
* However, the executors that we may have found are not in the
|
||||
* list of the specifically unsupported executors either.
|
||||
*
|
||||
* So, we should warn the user about it.
|
||||
*/
|
||||
|
||||
if (
|
||||
!projectContainsUnsupportedExecutor &&
|
||||
!validFoundTargetName.build &&
|
||||
!validFoundTargetName.serve &&
|
||||
!validFoundTargetName.test
|
||||
) {
|
||||
await handleUnknownExecutors(schema.project);
|
||||
}
|
||||
|
||||
/**
|
||||
* There is a possibility at this stage that the user has provided
|
||||
* targets with unsupported executors.
|
||||
* We keep track here of which of the targets that the user provided
|
||||
* are unsupported.
|
||||
* We do this with the `userProvidedTargetIsUnsupported` object,
|
||||
* which contains flags for each target (whether it is supported or not).
|
||||
*
|
||||
* We also keep track of the targets that we found in the project,
|
||||
* through the findExistingTargetsInProject function, which returns
|
||||
* targets for build/serve/test that use supported executors, and
|
||||
* can be converted to use the vite executors. These are the
|
||||
* kept in the validFoundTargetName object.
|
||||
*/
|
||||
await handleUnsupportedUserProvidedTargets(
|
||||
userProvidedTargetIsUnsupported,
|
||||
userProvidedTargetName,
|
||||
validFoundTargetName
|
||||
);
|
||||
|
||||
/**
|
||||
* Once the user is at this stage, then they can go ahead and convert.
|
||||
*/
|
||||
|
||||
buildTargetName = validFoundTargetName.build ?? buildTargetName;
|
||||
serveTargetName = validFoundTargetName.serve ?? serveTargetName;
|
||||
|
||||
if (projectType === 'application') {
|
||||
moveAndEditIndexHtml(tree, schema, buildTargetName);
|
||||
}
|
||||
|
||||
deleteWebpackConfig(
|
||||
tree,
|
||||
projectRoot,
|
||||
targets?.[buildTargetName]?.options?.webpackConfig
|
||||
);
|
||||
|
||||
editTsConfig(tree, schema);
|
||||
await convertNonVite(tree, schema, projectRoot, projectType, targets);
|
||||
}
|
||||
|
||||
const jsInitTask = await jsInitGenerator(tree, {
|
||||
@ -192,15 +82,15 @@ export async function viteConfigurationGeneratorInternal(
|
||||
|
||||
if (!hasPlugin) {
|
||||
if (!projectAlreadyHasViteTargets.build) {
|
||||
addOrChangeBuildTarget(tree, schema, buildTargetName);
|
||||
addBuildTarget(tree, schema, 'build');
|
||||
}
|
||||
|
||||
if (!schema.includeLib) {
|
||||
if (!projectAlreadyHasViteTargets.serve) {
|
||||
addOrChangeServeTarget(tree, schema, serveTargetName);
|
||||
addServeTarget(tree, schema, 'serve');
|
||||
}
|
||||
if (!projectAlreadyHasViteTargets.preview) {
|
||||
addPreviewTarget(tree, schema, serveTargetName);
|
||||
addPreviewTarget(tree, schema, 'preview');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -267,7 +157,7 @@ export async function viteConfigurationGeneratorInternal(
|
||||
inSourceTests: schema.inSourceTests,
|
||||
coverageProvider: 'v8',
|
||||
skipViteConfig: true,
|
||||
testTarget: testTargetName,
|
||||
testTarget: 'test',
|
||||
skipFormat: true,
|
||||
addPlugin: schema.addPlugin,
|
||||
});
|
||||
|
||||
@ -0,0 +1,100 @@
|
||||
import {
|
||||
TargetConfiguration,
|
||||
Tree,
|
||||
joinPathFragments,
|
||||
logger,
|
||||
} from '@nx/devkit';
|
||||
import {
|
||||
findViteConfig,
|
||||
findWebpackConfig,
|
||||
} from '../../../utils/find-vite-config';
|
||||
import { ViteConfigurationGeneratorSchema } from '../schema';
|
||||
import {
|
||||
deleteWebpackConfig,
|
||||
editTsConfig,
|
||||
findExistingJsBuildTargetInProject,
|
||||
handleUnknownConfiguration,
|
||||
moveAndEditIndexHtml,
|
||||
} from '../../../utils/generator-utils';
|
||||
|
||||
export async function convertNonVite(
|
||||
tree: Tree,
|
||||
schema: ViteConfigurationGeneratorSchema,
|
||||
projectRoot: string,
|
||||
projectType: string,
|
||||
targets: {
|
||||
[targetName: string]: TargetConfiguration<any>;
|
||||
}
|
||||
) {
|
||||
// Check if it has vite
|
||||
const hasViteConfig = findViteConfig(tree, projectRoot);
|
||||
const hasIndexHtmlAtRoot = tree.exists(
|
||||
joinPathFragments(projectRoot, 'index.html')
|
||||
);
|
||||
|
||||
// Check if it has webpack
|
||||
const hasWebpackConfig = findWebpackConfig(tree, projectRoot);
|
||||
if (hasWebpackConfig) {
|
||||
if (projectType === 'application') {
|
||||
moveAndEditIndexHtml(tree, schema);
|
||||
}
|
||||
deleteWebpackConfig(tree, projectRoot, hasWebpackConfig);
|
||||
editTsConfig(tree, schema);
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
projectType === 'application' &&
|
||||
hasViteConfig &&
|
||||
hasIndexHtmlAtRoot &&
|
||||
!hasWebpackConfig
|
||||
) {
|
||||
throw new Error(
|
||||
`The project ${schema.project} is already configured to use Vite.`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (projectType === 'library' && hasViteConfig) {
|
||||
// continue anyway - it could need to be updated - only update vite.config.ts in any case
|
||||
editTsConfig(tree, schema);
|
||||
return;
|
||||
}
|
||||
|
||||
// Does the project have js executors?
|
||||
const { supported: jsTargetName, unsupported } =
|
||||
findExistingJsBuildTargetInProject(targets);
|
||||
if (jsTargetName) {
|
||||
editTsConfig(tree, schema);
|
||||
return;
|
||||
}
|
||||
|
||||
if (unsupported) {
|
||||
throw new Error(`
|
||||
Nx cannot convert your project to use vite.
|
||||
Please try again with a different project.
|
||||
`);
|
||||
}
|
||||
|
||||
// If it's a library, it's most possible it's non-buildable
|
||||
// So fix the tsconfig and return, to continue with the rest of the setup
|
||||
if (
|
||||
projectType === 'library' &&
|
||||
!hasViteConfig &&
|
||||
!hasWebpackConfig &&
|
||||
!jsTargetName
|
||||
) {
|
||||
editTsConfig(tree, schema);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* The project is an app.
|
||||
* The project has no js executors, no webpack config, no vite config.
|
||||
* We did not find any configuration that hints the project can
|
||||
* definitely be converted.
|
||||
* So, we should warn the user about it.
|
||||
* They can choose whether to convert it or not
|
||||
*/
|
||||
await handleUnknownConfiguration(schema.project);
|
||||
}
|
||||
@ -6,9 +6,6 @@ export interface ViteConfigurationGeneratorSchema {
|
||||
includeVitest?: boolean;
|
||||
inSourceTests?: boolean;
|
||||
includeLib?: boolean;
|
||||
buildTarget?: string;
|
||||
serveTarget?: string;
|
||||
testTarget?: string;
|
||||
skipFormat?: boolean;
|
||||
testEnvironment?: 'node' | 'jsdom' | 'happy-dom' | 'edge-runtime' | string;
|
||||
addPlugin?: boolean;
|
||||
|
||||
@ -44,18 +44,6 @@
|
||||
"default": false,
|
||||
"hidden": true
|
||||
},
|
||||
"buildTarget": {
|
||||
"type": "string",
|
||||
"description": "The build target of the project to be transformed to use the @nx/vite:build executor."
|
||||
},
|
||||
"serveTarget": {
|
||||
"type": "string",
|
||||
"description": "The serve target of the project to be transformed to use the @nx/vite:dev-server and @nx/vite:preview-server executors."
|
||||
},
|
||||
"testTarget": {
|
||||
"type": "string",
|
||||
"description": "The test target of the project to be transformed to use the @nx/vite:test executor."
|
||||
},
|
||||
"skipFormat": {
|
||||
"description": "Skip formatting files.",
|
||||
"type": "boolean",
|
||||
|
||||
@ -14,7 +14,6 @@ import {
|
||||
import {
|
||||
addOrChangeTestTarget,
|
||||
createOrEditViteConfig,
|
||||
findExistingTargetsInProject,
|
||||
} from '../../utils/generator-utils';
|
||||
import { VitestGeneratorSchema } from './schema';
|
||||
|
||||
@ -68,10 +67,7 @@ export async function vitestGeneratorInternal(
|
||||
: p.plugin === '@nx/vite/plugin') || hasPlugin
|
||||
);
|
||||
if (!hasPluginCheck) {
|
||||
const testTarget =
|
||||
schema.testTarget ??
|
||||
findExistingTargetsInProject(targets).validFoundTargetName.test ??
|
||||
'test';
|
||||
const testTarget = schema.testTarget ?? 'test';
|
||||
addOrChangeTestTarget(tree, schema, testTarget);
|
||||
}
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ import { Tree, getProjects, joinPathFragments } from '@nx/devkit';
|
||||
import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils';
|
||||
import { ViteBuildExecutorOptions } from '../../executors/build/schema';
|
||||
import { tsquery } from '@phenomnomnominal/tsquery';
|
||||
import { findViteConfig } from '../../utils/find-vite-config';
|
||||
|
||||
export default function update(tree: Tree) {
|
||||
const projects = getProjects(tree);
|
||||
@ -51,13 +52,3 @@ export default function update(tree: Tree) {
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function findViteConfig(tree: Tree, searchRoot: string) {
|
||||
const allowsExt = ['js', 'mjs', 'ts', 'cjs', 'mts', 'cts'];
|
||||
|
||||
for (const ext of allowsExt) {
|
||||
if (tree.exists(joinPathFragments(searchRoot, `vite.config.${ext}`))) {
|
||||
return joinPathFragments(searchRoot, `vite.config.${ext}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ import { updateTestConfig } from './lib/edit-test-config';
|
||||
import { addFileReplacements } from './lib/add-file-replacements';
|
||||
import { tsquery } from '@phenomnomnominal/tsquery';
|
||||
import ts = require('typescript');
|
||||
import { findViteConfig } from '../../utils/find-vite-config';
|
||||
|
||||
export default async function updateBuildDir(tree: Tree) {
|
||||
const projects = getProjects(tree);
|
||||
@ -54,16 +55,6 @@ export default async function updateBuildDir(tree: Tree) {
|
||||
await formatFiles(tree);
|
||||
}
|
||||
|
||||
function findViteConfig(tree: Tree, searchRoot: string) {
|
||||
const allowsExt = ['js', 'mjs', 'ts', 'cjs', 'mts', 'cts'];
|
||||
|
||||
for (const ext of allowsExt) {
|
||||
if (tree.exists(joinPathFragments(searchRoot, `vite.config.${ext}`))) {
|
||||
return joinPathFragments(searchRoot, `vite.config.${ext}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function getConfigNode(configFileContents: string): ts.Node | undefined {
|
||||
if (!configFileContents) {
|
||||
return;
|
||||
|
||||
@ -9,3 +9,13 @@ export function findViteConfig(tree: Tree, searchRoot: string) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function findWebpackConfig(tree: Tree, searchRoot: string) {
|
||||
const allowsExt = ['js', 'ts', 'mjs', 'cjs'];
|
||||
|
||||
for (const ext of allowsExt) {
|
||||
if (tree.exists(joinPathFragments(searchRoot, `webpack.config.${ext}`))) {
|
||||
return joinPathFragments(searchRoot, `webpack.config.${ext}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5,9 +5,8 @@ import {
|
||||
} from '@nx/devkit';
|
||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
||||
import {
|
||||
findExistingTargetsInProject,
|
||||
findExistingJsBuildTargetInProject,
|
||||
getViteConfigPathForProject,
|
||||
handleUnsupportedUserProvidedTargets,
|
||||
} from './generator-utils';
|
||||
import {
|
||||
mockReactAppGenerator,
|
||||
@ -97,105 +96,22 @@ describe('generator utils', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('findExistingTargetsInProject', () => {
|
||||
it('should return the correct targets', () => {
|
||||
describe('findExistingJsBuildTargetInProject', () => {
|
||||
it('should return no targets', () => {
|
||||
mockReactAppGenerator(tree);
|
||||
const { targets } = readProjectConfiguration(tree, 'my-test-react-app');
|
||||
|
||||
const existingTargets = findExistingTargetsInProject(targets);
|
||||
expect(existingTargets).toMatchObject({
|
||||
userProvidedTargetIsUnsupported: {},
|
||||
validFoundTargetName: {
|
||||
build: 'build',
|
||||
serve: 'serve',
|
||||
test: 'test',
|
||||
},
|
||||
projectContainsUnsupportedExecutor: false,
|
||||
});
|
||||
const existingTargets = findExistingJsBuildTargetInProject(targets);
|
||||
expect(existingTargets).toMatchObject({});
|
||||
});
|
||||
|
||||
it('should return the correct - undefined - targets for Angular apps', () => {
|
||||
mockAngularAppGenerator(tree);
|
||||
const { targets } = readProjectConfiguration(tree, 'my-test-angular-app');
|
||||
const existingTargets = findExistingTargetsInProject(targets);
|
||||
const existingTargets = findExistingJsBuildTargetInProject(targets);
|
||||
expect(existingTargets).toMatchObject({
|
||||
userProvidedTargetIsUnsupported: {},
|
||||
validFoundTargetName: {
|
||||
test: 'test',
|
||||
},
|
||||
projectContainsUnsupportedExecutor: true,
|
||||
unsupported: 'build',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('handleUnsupportedUserProvidedTargets', () => {
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
it('should throw error if unsupported and user does not want to confirm', async () => {
|
||||
const { Confirm } = require('enquirer');
|
||||
const confirmSpy = jest.spyOn(Confirm.prototype, 'run');
|
||||
confirmSpy.mockResolvedValueOnce(false);
|
||||
const object = {
|
||||
unsupportedUserProvidedTarget: {
|
||||
build: true,
|
||||
},
|
||||
userProvidedTargets: {
|
||||
build: 'my-build',
|
||||
serve: 'my-serve',
|
||||
test: 'my-test',
|
||||
},
|
||||
targets: {
|
||||
build: 'build',
|
||||
serve: 'serve',
|
||||
test: 'test',
|
||||
},
|
||||
};
|
||||
|
||||
expect(async () => {
|
||||
await handleUnsupportedUserProvidedTargets(
|
||||
object.unsupportedUserProvidedTarget,
|
||||
object.userProvidedTargets,
|
||||
object.targets
|
||||
);
|
||||
}).rejects.toThrowErrorMatchingInlineSnapshot(`
|
||||
"The build target my-build cannot be converted to use the @nx/vite:build executor.
|
||||
Please try again, either by providing a different build target or by not providing a target at all (Nx will
|
||||
convert the first one it finds, most probably this one: build)
|
||||
|
||||
Please note that converting a potentially non-compatible project to use Vite.js may result in unexpected behavior. Always commit
|
||||
your changes before converting a project to use Vite.js, and test the converted project thoroughly before deploying it.
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
it('should NOT throw error if unsupported and user confirms', async () => {
|
||||
const { Confirm } = require('enquirer');
|
||||
const confirmSpy = jest.spyOn(Confirm.prototype, 'run');
|
||||
confirmSpy.mockResolvedValue(true);
|
||||
const object = {
|
||||
unsupportedUserProvidedTarget: {
|
||||
build: true,
|
||||
},
|
||||
userProvidedTargets: {
|
||||
build: 'my-build',
|
||||
serve: 'my-serve',
|
||||
test: 'my-test',
|
||||
},
|
||||
targets: {
|
||||
build: 'build',
|
||||
serve: 'serve',
|
||||
test: 'test',
|
||||
},
|
||||
};
|
||||
|
||||
expect(async () => {
|
||||
await handleUnsupportedUserProvidedTargets(
|
||||
object.unsupportedUserProvidedTarget,
|
||||
object.userProvidedTargets,
|
||||
object.targets
|
||||
);
|
||||
}).not.toThrow();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -10,7 +10,6 @@ import {
|
||||
writeJson,
|
||||
} from '@nx/devkit';
|
||||
import { ViteBuildExecutorOptions } from '../executors/build/schema';
|
||||
import { ViteDevServerExecutorOptions } from '../executors/dev-server/schema';
|
||||
import { VitePreviewServerExecutorOptions } from '../executors/preview-server/schema';
|
||||
import { VitestExecutorOptions } from '../executors/test/schema';
|
||||
import { ViteConfigurationGeneratorSchema } from '../generators/configuration/schema';
|
||||
@ -22,45 +21,20 @@ export type TargetFlags = Partial<Record<Target, boolean>>;
|
||||
export type UserProvidedTargetName = Partial<Record<Target, string>>;
|
||||
export type ValidFoundTargetName = Partial<Record<Target, string>>;
|
||||
|
||||
export function findExistingTargetsInProject(
|
||||
targets: {
|
||||
[targetName: string]: TargetConfiguration;
|
||||
},
|
||||
userProvidedTargets?: UserProvidedTargetName
|
||||
): {
|
||||
validFoundTargetName: ValidFoundTargetName;
|
||||
projectContainsUnsupportedExecutor: boolean;
|
||||
userProvidedTargetIsUnsupported: TargetFlags;
|
||||
alreadyHasNxViteTargets: TargetFlags;
|
||||
export function findExistingJsBuildTargetInProject(targets: {
|
||||
[targetName: string]: TargetConfiguration;
|
||||
}): {
|
||||
supported?: string;
|
||||
unsupported?: string;
|
||||
} {
|
||||
const output: ReturnType<typeof findExistingTargetsInProject> = {
|
||||
validFoundTargetName: {},
|
||||
projectContainsUnsupportedExecutor: false,
|
||||
userProvidedTargetIsUnsupported: {},
|
||||
alreadyHasNxViteTargets: {},
|
||||
};
|
||||
const output: {
|
||||
supported?: string;
|
||||
unsupported?: string;
|
||||
} = {};
|
||||
|
||||
const supportedExecutors = {
|
||||
build: [
|
||||
'@nxext/vite:build',
|
||||
'@nx/js:babel',
|
||||
'@nx/js:swc',
|
||||
'@nx/webpack:webpack',
|
||||
'@nx/rollup:rollup',
|
||||
'@nrwl/js:babel',
|
||||
'@nrwl/js:swc',
|
||||
'@nrwl/webpack:webpack',
|
||||
'@nrwl/rollup:rollup',
|
||||
'@nrwl/web:rollup',
|
||||
],
|
||||
serve: [
|
||||
'@nxext/vite:dev',
|
||||
'@nx/webpack:dev-server',
|
||||
'@nrwl/webpack:dev-server',
|
||||
],
|
||||
test: ['@nx/jest:jest', '@nrwl/jest:jest', '@nxext/vitest:vitest'],
|
||||
build: ['@nx/js:babel', '@nx/js:swc', '@nx/rollup:rollup'],
|
||||
};
|
||||
|
||||
const unsupportedExecutors = [
|
||||
'@nx/angular:ng-packagr-lite',
|
||||
'@nx/angular:package',
|
||||
@ -73,7 +47,6 @@ export function findExistingTargetsInProject(
|
||||
'@nx/react-native:build-android',
|
||||
'@nx/react-native:bundle',
|
||||
'@nx/next:build',
|
||||
'@nx/next:server',
|
||||
'@nx/js:tsc',
|
||||
'@nrwl/angular:ng-packagr-lite',
|
||||
'@nrwl/angular:package',
|
||||
@ -86,81 +59,22 @@ export function findExistingTargetsInProject(
|
||||
'@nrwl/react-native:build-android',
|
||||
'@nrwl/react-native:bundle',
|
||||
'@nrwl/next:build',
|
||||
'@nrwl/next:server',
|
||||
'@nrwl/js:tsc',
|
||||
'@angular-devkit/build-angular:browser',
|
||||
'@angular-devkit/build-angular:dev-server',
|
||||
'@angular-devkit/build-angular:browser-esbuild',
|
||||
'@angular-devkit/build-angular:application',
|
||||
];
|
||||
|
||||
// First, we check if the user has provided a target
|
||||
// If they have, we check if the executor the target is using is supported
|
||||
// If it's not supported, then we set the unsupported flag to true for that target
|
||||
|
||||
function checkUserProvidedTarget(target: Target) {
|
||||
if (userProvidedTargets?.[target]) {
|
||||
if (
|
||||
supportedExecutors[target].includes(
|
||||
targets[userProvidedTargets[target]]?.executor
|
||||
)
|
||||
) {
|
||||
output.validFoundTargetName[target] = userProvidedTargets[target];
|
||||
} else {
|
||||
output.userProvidedTargetIsUnsupported[target] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
checkUserProvidedTarget('build');
|
||||
checkUserProvidedTarget('serve');
|
||||
checkUserProvidedTarget('test');
|
||||
|
||||
// Returns early when we have a build, serve, and test targets.
|
||||
if (
|
||||
output.validFoundTargetName.build &&
|
||||
output.validFoundTargetName.serve &&
|
||||
output.validFoundTargetName.test
|
||||
) {
|
||||
return output;
|
||||
}
|
||||
|
||||
// We try to find the targets that are using the supported executors
|
||||
// for build, serve and test, since these are the ones we will be converting
|
||||
// We try to find the target that is using the supported executors
|
||||
// for build since this is the one we will be converting
|
||||
for (const target in targets) {
|
||||
const executorName = targets[target].executor;
|
||||
|
||||
const hasViteTargets = output.alreadyHasNxViteTargets;
|
||||
hasViteTargets.build ||=
|
||||
executorName === '@nx/vite:build' || executorName === '@nrwl/vite:build';
|
||||
hasViteTargets.serve ||=
|
||||
executorName === '@nx/vite:dev-server' ||
|
||||
executorName === '@nrwl/vite:dev-server';
|
||||
hasViteTargets.test ||=
|
||||
executorName === '@nx/vite:test' || executorName === '@nrwl/vite:test';
|
||||
hasViteTargets.preview ||=
|
||||
executorName === '@nx/vite:preview-server' ||
|
||||
executorName === '@nrwl/vite:preview-server';
|
||||
|
||||
const foundTargets = output.validFoundTargetName;
|
||||
if (
|
||||
!foundTargets.build &&
|
||||
supportedExecutors.build.includes(executorName)
|
||||
) {
|
||||
foundTargets.build = target;
|
||||
if (supportedExecutors.build.includes(executorName)) {
|
||||
output.supported = target;
|
||||
} else if (unsupportedExecutors.includes(executorName)) {
|
||||
output.unsupported = target;
|
||||
}
|
||||
if (
|
||||
!foundTargets.serve &&
|
||||
supportedExecutors.serve.includes(executorName)
|
||||
) {
|
||||
foundTargets.serve = target;
|
||||
}
|
||||
if (!foundTargets.test && supportedExecutors.test.includes(executorName)) {
|
||||
foundTargets.test = target;
|
||||
}
|
||||
|
||||
output.projectContainsUnsupportedExecutor ||=
|
||||
unsupportedExecutors.includes(executorName);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
@ -196,51 +110,39 @@ export function addOrChangeTestTarget(
|
||||
updateProjectConfiguration(tree, options.project, project);
|
||||
}
|
||||
|
||||
export function addOrChangeBuildTarget(
|
||||
export function addBuildTarget(
|
||||
tree: Tree,
|
||||
options: ViteConfigurationGeneratorSchema,
|
||||
target: string
|
||||
) {
|
||||
addBuildTargetDefaults(tree, '@nx/vite:build');
|
||||
const project = readProjectConfiguration(tree, options.project);
|
||||
|
||||
const buildOptions: ViteBuildExecutorOptions = {
|
||||
outputPath: joinPathFragments(
|
||||
'dist',
|
||||
project.root != '.' ? project.root : options.project
|
||||
),
|
||||
};
|
||||
|
||||
project.targets ??= {};
|
||||
|
||||
if (project.targets[target]) {
|
||||
if (project.targets[target].executor === '@nxext/vite:build') {
|
||||
buildOptions['base'] = project.targets[target].options?.baseHref;
|
||||
buildOptions['sourcemap'] = project.targets[target].options?.sourcemaps;
|
||||
}
|
||||
project.targets[target].options = { ...buildOptions };
|
||||
project.targets[target].executor = '@nx/vite:build';
|
||||
} else {
|
||||
project.targets[target] = {
|
||||
executor: '@nx/vite:build',
|
||||
outputs: ['{options.outputPath}'],
|
||||
defaultConfiguration: 'production',
|
||||
options: buildOptions,
|
||||
configurations: {
|
||||
development: {
|
||||
mode: 'development',
|
||||
},
|
||||
production: {
|
||||
mode: 'production',
|
||||
},
|
||||
project.targets[target] = {
|
||||
executor: '@nx/vite:build',
|
||||
outputs: ['{options.outputPath}'],
|
||||
defaultConfiguration: 'production',
|
||||
options: buildOptions,
|
||||
configurations: {
|
||||
development: {
|
||||
mode: 'development',
|
||||
},
|
||||
};
|
||||
}
|
||||
production: {
|
||||
mode: 'production',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
updateProjectConfiguration(tree, options.project, project);
|
||||
}
|
||||
|
||||
export function addOrChangeServeTarget(
|
||||
export function addServeTarget(
|
||||
tree: Tree,
|
||||
options: ViteConfigurationGeneratorSchema,
|
||||
target: string
|
||||
@ -249,35 +151,23 @@ export function addOrChangeServeTarget(
|
||||
|
||||
project.targets ??= {};
|
||||
|
||||
if (project.targets[target]) {
|
||||
const serveTarget = project.targets[target];
|
||||
const serveOptions: ViteDevServerExecutorOptions = {
|
||||
project.targets[target] = {
|
||||
executor: '@nx/vite:dev-server',
|
||||
defaultConfiguration: 'development',
|
||||
options: {
|
||||
buildTarget: `${options.project}:build`,
|
||||
};
|
||||
if (serveTarget.executor === '@nxext/vite:dev') {
|
||||
serveOptions.proxyConfig = project.targets[target].options.proxyConfig;
|
||||
}
|
||||
serveTarget.executor = '@nx/vite:dev-server';
|
||||
serveTarget.options = serveOptions;
|
||||
} else {
|
||||
project.targets[target] = {
|
||||
executor: '@nx/vite:dev-server',
|
||||
defaultConfiguration: 'development',
|
||||
options: {
|
||||
buildTarget: `${options.project}:build`,
|
||||
},
|
||||
configurations: {
|
||||
development: {
|
||||
buildTarget: `${options.project}:build:development`,
|
||||
hmr: true,
|
||||
},
|
||||
configurations: {
|
||||
development: {
|
||||
buildTarget: `${options.project}:build:development`,
|
||||
hmr: true,
|
||||
},
|
||||
production: {
|
||||
buildTarget: `${options.project}:build:production`,
|
||||
hmr: false,
|
||||
},
|
||||
production: {
|
||||
buildTarget: `${options.project}:build:production`,
|
||||
hmr: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
updateProjectConfiguration(tree, options.project, project);
|
||||
}
|
||||
@ -288,7 +178,6 @@ export function addOrChangeServeTarget(
|
||||
* @param tree
|
||||
* @param options
|
||||
* @param serveTarget An existing serve target.
|
||||
* @param previewTarget The preview target to create.
|
||||
*/
|
||||
export function addPreviewTarget(
|
||||
tree: Tree,
|
||||
@ -339,44 +228,26 @@ export function editTsConfig(
|
||||
|
||||
const config = readJson(tree, `${projectConfig.root}/tsconfig.json`);
|
||||
|
||||
const commonCompilerOptions = {
|
||||
target: 'ESNext',
|
||||
useDefineForClassFields: true,
|
||||
module: 'ESNext',
|
||||
strict: true,
|
||||
moduleResolution: 'Node',
|
||||
resolveJsonModule: true,
|
||||
isolatedModules: true,
|
||||
types: ['vite/client'],
|
||||
noEmit: true,
|
||||
};
|
||||
|
||||
switch (options.uiFramework) {
|
||||
case 'react':
|
||||
config.compilerOptions = {
|
||||
...commonCompilerOptions,
|
||||
lib: ['DOM', 'DOM.Iterable', 'ESNext'],
|
||||
jsx: 'react-jsx',
|
||||
allowJs: false,
|
||||
esModuleInterop: false,
|
||||
skipLibCheck: true,
|
||||
allowSyntheticDefaultImports: true,
|
||||
forceConsistentCasingInFileNames: true,
|
||||
jsx: 'react-jsx',
|
||||
strict: true,
|
||||
};
|
||||
config.include = [...config.include, 'src'];
|
||||
break;
|
||||
case 'none':
|
||||
config.compilerOptions = {
|
||||
...commonCompilerOptions,
|
||||
lib: ['ESNext', 'DOM'],
|
||||
skipLibCheck: true,
|
||||
esModuleInterop: true,
|
||||
module: 'commonjs',
|
||||
forceConsistentCasingInFileNames: true,
|
||||
strict: true,
|
||||
noUnusedLocals: true,
|
||||
noUnusedParameters: true,
|
||||
noImplicitOverride: true,
|
||||
noPropertyAccessFromIndexSignature: true,
|
||||
noImplicitReturns: true,
|
||||
noFallthroughCasesInSwitch: true,
|
||||
};
|
||||
config.include = [...config.include, 'src'];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -405,19 +276,14 @@ export function deleteWebpackConfig(
|
||||
|
||||
export function moveAndEditIndexHtml(
|
||||
tree: Tree,
|
||||
options: ViteConfigurationGeneratorSchema,
|
||||
buildTarget: string
|
||||
options: ViteConfigurationGeneratorSchema
|
||||
) {
|
||||
const projectConfig = readProjectConfiguration(tree, options.project);
|
||||
|
||||
let indexHtmlPath =
|
||||
projectConfig.targets?.[buildTarget]?.options?.index ??
|
||||
`${projectConfig.root}/src/index.html`;
|
||||
let mainPath =
|
||||
projectConfig.targets?.[buildTarget]?.options?.main ??
|
||||
`${projectConfig.root}/src/main.ts${
|
||||
options.uiFramework === 'react' ? 'x' : ''
|
||||
}`;
|
||||
let indexHtmlPath = `${projectConfig.root}/src/index.html`;
|
||||
let mainPath = `${projectConfig.root}/src/main.ts${
|
||||
options.uiFramework === 'react' ? 'x' : ''
|
||||
}`;
|
||||
|
||||
if (projectConfig.root !== '.') {
|
||||
mainPath = mainPath.replace(projectConfig.root, '');
|
||||
@ -763,21 +629,17 @@ async function handleUnsupportedUserProvidedTargetsErrors(
|
||||
}
|
||||
}
|
||||
|
||||
export async function handleUnknownExecutors(projectName: string) {
|
||||
export async function handleUnknownConfiguration(projectName: string) {
|
||||
if (process.env.NX_INTERACTIVE === 'false') {
|
||||
return;
|
||||
}
|
||||
|
||||
logger.warn(
|
||||
`
|
||||
We could not find any targets in project ${projectName} that use executors which
|
||||
can be converted to the @nx/vite executors.
|
||||
|
||||
This either means that your project may not have a target
|
||||
for building, serving, or testing at all, or that your targets are
|
||||
using executors that are not known to Nx.
|
||||
We could not find any configuration in project ${projectName} that
|
||||
indicates whether we can definitely convert to Vite.
|
||||
|
||||
If you still want to convert your project to use the @nx/vite executors,
|
||||
If you still want to convert your project to use Vite,
|
||||
please make sure to commit your changes before running this generator.
|
||||
`
|
||||
);
|
||||
@ -785,13 +647,13 @@ export async function handleUnknownExecutors(projectName: string) {
|
||||
const { Confirm } = require('enquirer');
|
||||
const prompt = new Confirm({
|
||||
name: 'question',
|
||||
message: `Should Nx convert your project to use the @nx/vite executors?`,
|
||||
message: `Should Nx convert your project to use Vite?`,
|
||||
initial: true,
|
||||
});
|
||||
const shouldConvert = await prompt.run();
|
||||
if (!shouldConvert) {
|
||||
throw new Error(`
|
||||
Nx could not verify that the executors you are using can be converted to the @nx/vite executors.
|
||||
Nx could not verify that your project can be converted to use Vite.
|
||||
Please try again with a different project.
|
||||
`);
|
||||
}
|
||||
|
||||
@ -1,82 +0,0 @@
|
||||
{
|
||||
"name": "my-test-react-app",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"root": "apps/my-test-react-app",
|
||||
"sourceRoot": "apps/my-test-react-app/src",
|
||||
"projectType": "application",
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@nx/webpack:webpack",
|
||||
"outputs": ["{options.outputPath}"],
|
||||
"defaultConfiguration": "production",
|
||||
"options": {
|
||||
"compiler": "babel",
|
||||
"outputPath": "dist/apps/my-test-react-app",
|
||||
"index": "apps/my-test-react-app/src/index.html",
|
||||
"baseHref": "/",
|
||||
"main": "apps/my-test-react-app/src/main.tsx",
|
||||
"polyfills": "apps/my-test-react-app/src/polyfills.ts",
|
||||
"tsConfig": "apps/my-test-react-app/tsconfig.app.json",
|
||||
"assets": [
|
||||
"apps/my-test-react-app/src/favicon.ico",
|
||||
"apps/my-test-react-app/src/assets"
|
||||
],
|
||||
"styles": ["apps/my-test-react-app/src/styles.css"],
|
||||
"scripts": [],
|
||||
"webpackConfig": "@nx/react/plugins/webpack"
|
||||
},
|
||||
"configurations": {
|
||||
"development": {
|
||||
"extractLicenses": false,
|
||||
"optimization": false,
|
||||
"sourceMap": true,
|
||||
"vendorChunk": true
|
||||
},
|
||||
"production": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "apps/my-test-react-app/src/environments/environment.ts",
|
||||
"with": "apps/my-test-react-app/src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": false,
|
||||
"namedChunks": false,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"executor": "@nx/webpack:dev-server",
|
||||
"defaultConfiguration": "development",
|
||||
"options": {
|
||||
"buildTarget": "my-test-react-app:build",
|
||||
"hmr": true
|
||||
},
|
||||
"configurations": {
|
||||
"development": {
|
||||
"buildTarget": "my-test-react-app:build:development"
|
||||
},
|
||||
"production": {
|
||||
"buildTarget": "my-test-react-app:build:production",
|
||||
"hmr": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint",
|
||||
"outputs": ["{options.outputFile}"]
|
||||
},
|
||||
"test": {
|
||||
"executor": "@nx/jest:jest",
|
||||
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
|
||||
"options": {
|
||||
"jestConfig": "apps/my-test-react-app/jest.config.ts",
|
||||
"passWithNoTests": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
@ -1,69 +0,0 @@
|
||||
{
|
||||
"name": "my-test-web-app",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"projectType": "application",
|
||||
"root": "apps/my-test-web-app",
|
||||
"sourceRoot": "apps/my-test-web-app/src",
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@nx/webpack:webpack",
|
||||
"outputs": ["{options.outputPath}"],
|
||||
"defaultConfiguration": "production",
|
||||
"options": {
|
||||
"outputPath": "dist/apps/my-test-web-app",
|
||||
"compiler": "babel",
|
||||
"main": "apps/my-test-web-app/src/main.ts",
|
||||
"tsConfig": "apps/my-test-web-app/tsconfig.app.json",
|
||||
"assets": [
|
||||
"apps/my-test-web-app/src/favicon.ico",
|
||||
"apps/my-test-web-app/src/assets"
|
||||
],
|
||||
"index": "apps/my-test-web-app/src/index.html",
|
||||
"baseHref": "/",
|
||||
"polyfills": "apps/my-test-web-app/src/polyfills.ts",
|
||||
"styles": ["apps/my-test-web-app/src/styles.css"],
|
||||
"scripts": []
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": false,
|
||||
"namedChunks": false,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false,
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "apps/my-test-web-app/src/environments/environment.ts",
|
||||
"with": "apps/my-test-web-app/src/environments/environment.prod.ts"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"executor": "@nx/webpack:dev-server",
|
||||
"options": {
|
||||
"buildTarget": "my-test-web-app:build"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"buildTarget": "my-test-web-app:build:production"
|
||||
}
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint",
|
||||
"outputs": ["{options.outputFile}"]
|
||||
},
|
||||
"test": {
|
||||
"executor": "@nx/jest:jest",
|
||||
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
|
||||
"options": {
|
||||
"jestConfig": "apps/my-test-web-app/jest.config.ts",
|
||||
"passWithNoTests": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,5 @@
|
||||
import { Tree, writeJson } from '@nx/devkit';
|
||||
import * as reactAppConfig from './test-files/react-project.config.json';
|
||||
import * as reactViteConfig from './test-files/react-vite-project.config.json';
|
||||
import * as webAppConfig from './test-files/web-project.config.json';
|
||||
import * as angularAppConfig from './test-files/angular-project.config.json';
|
||||
import * as randomAppConfig from './test-files/unknown-project.config.json';
|
||||
import * as mixedAppConfig from './test-files/react-mixed-project.config.json';
|
||||
@ -147,6 +145,8 @@ export function mockReactAppGenerator(tree: Tree): Tree {
|
||||
`import ReactDOM from 'react-dom';\n`
|
||||
);
|
||||
|
||||
tree.write(`apps/${appName}/webpack.config.ts`, ``);
|
||||
|
||||
tree.write(
|
||||
`apps/${appName}/tsconfig.json`,
|
||||
`{
|
||||
@ -221,18 +221,7 @@ export function mockReactAppGenerator(tree: Tree): Tree {
|
||||
</html>`
|
||||
);
|
||||
|
||||
writeJson(tree, 'workspace.json', {
|
||||
projects: {
|
||||
'my-test-react-app': {
|
||||
...reactAppConfig,
|
||||
root: `apps/${appName}`,
|
||||
projectType: 'application',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
writeJson(tree, `apps/${appName}/project.json`, {
|
||||
...reactAppConfig,
|
||||
root: `apps/${appName}`,
|
||||
projectType: 'application',
|
||||
});
|
||||
@ -363,6 +352,8 @@ export function mockWebAppGenerator(tree: Tree): Tree {
|
||||
`
|
||||
);
|
||||
|
||||
tree.write(`apps/${appName}/webpack.config.ts`, ``);
|
||||
|
||||
tree.write(
|
||||
`apps/${appName}/src/index.html`,
|
||||
`<!DOCTYPE html>
|
||||
@ -382,23 +373,16 @@ export function mockWebAppGenerator(tree: Tree): Tree {
|
||||
`
|
||||
);
|
||||
|
||||
writeJson(
|
||||
tree,
|
||||
'workspace.json',
|
||||
|
||||
{
|
||||
projects: {
|
||||
'my-test-web-app': {
|
||||
...webAppConfig,
|
||||
root: `apps/${appName}`,
|
||||
projectType: 'application',
|
||||
},
|
||||
writeJson(tree, 'workspace.json', {
|
||||
projects: {
|
||||
'my-test-web-app': {
|
||||
root: `apps/${appName}`,
|
||||
projectType: 'application',
|
||||
},
|
||||
}
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
writeJson(tree, `apps/${appName}/project.json`, {
|
||||
...webAppConfig,
|
||||
root: `apps/${appName}`,
|
||||
projectType: 'application',
|
||||
});
|
||||
|
||||
@ -179,8 +179,6 @@ describe('app', () => {
|
||||
path: './tsconfig.spec.json',
|
||||
},
|
||||
]);
|
||||
expect(tsconfig.compilerOptions.types).toMatchObject(['vite/client']);
|
||||
|
||||
expect(tree.exists('my-app-e2e/cypress.config.ts')).toBeTruthy();
|
||||
expect(tree.exists('my-app/index.html')).toBeTruthy();
|
||||
expect(tree.exists('my-app/vite.config.ts')).toBeTruthy();
|
||||
@ -578,7 +576,7 @@ describe('app', () => {
|
||||
|
||||
it('should create correct tsconfig compilerOptions', () => {
|
||||
const tsconfigJson = readJson(viteAppTree, '/my-app/tsconfig.json');
|
||||
expect(tsconfigJson.compilerOptions.types).toMatchObject(['vite/client']);
|
||||
expect(tsconfigJson.compilerOptions.noImplicitReturns).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should create index.html and vite.config file at the root of the app', () => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user