Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(web): file-server should accept buildTarget without projectName #20240

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/generated/packages/cypress/executors/cypress.json
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@
},
"additionalProperties": true,
"required": ["cypressConfig"],
"examplesFile": "Depending on your testing type, the Cypress executor is configured in different ways. The following are sample configurations that are created via the [configuration](/packages/cypress/generators/configuration) and [cypress-component-configuration](/packages/cypress/generators/cypress-component-configuration) generators.\n\n{% tabs %}\n{% tab label=\"E2E Testing\" %}\n\n```json\n\"targets\": {\n \"e2e\": {\n \"executor\": \"@nx/cypress:cypress\",\n \"options\": {\n \"cypressConfig\": \"apps/app-e2e/cypres.config.ts\",\n \"devServerTarget\": \"my-react-app:serve\",\n \"testingType\": \"e2e\"\n }\n }\n}\n```\n\n{% callout type=\"note\" title=\"API Testing\" %}\nAPI testing with Cypress is the same setup as e2e testing. Just change which `devServerTarget` is used!\n{% /callout %}\n\n### Providing a Base URL\n\nIf `devServerTarget` is provided, the url returned from started the dev server will be passed to cypress as the `baseUrl` option.\n\nDefining a `baseUrl` in the executor options will override the inferred `baseUrl` from the `devServerTarget`.\n\nThe `baseUrl` defined in the Cypress config file is the last value used if no url is found in the `devServerTarget` or executor options.\n\n### Static Serving\n\nWhen running in CI it doesn't make sense to start up a dev server since there aren't changes to watch for.\n\nYou can use [`@nx/web:file-server`](/packages/web/executors/file-server) to serve the pre-built static files of your frontend project.\n\nIn some _frontend_ application, add a 'static-serve' target.\n\n```json\n\"serve-static\": {\n \"executor\": \"@nx/web:file-server\",\n \"options\":{\n \"buildTarget\": \"frontend:build\"\n }\n}\n```\n\nIn the _e2e_ application add a configuration to change `devServerTarget` to point to the `static-serve` from the _frontend_ application\n\n```json\n\"e2e\": {\n //...\n \"configurations\": {\n \"ci\": {\n \"devServerTarget\": \"frontend:serve-static\"\n }\n }\n}\n```\n\n{% callout type=\"note\" title=\"What about Node projects?\" %}\nThe same can be done for backend node apps with [`@nx/js:node` executor](/packages/js/executors/node)\n{% /callout %}\n\n```bash\nnx e2e my-app-e2e --configuration=ci\n```\n\n{% /tab %}\n{% tab label=\"Component Testing\" %}\n\n{% callout type=\"note\" title=\"Cypress Component Testing\" %}\nWhen adding component testing to a project, it's best to use the framework specific generator, instead `cypress-component-project` directly.\n\n- [React component testing](/packages/react/generators/cypress-component-configuration)\n- [Angular component testing](/packages/angular/generators/cypress-component-configuration)\n\n{% /callout %}\n\n```json\n\"targets\": {\n \"component-test\": {\n \"executor\": \"@nx/cypress:cypress\",\n \"options\": {\n \"cypressConfig\": \"apps/app/cypres.config.ts\",\n \"devServerTarget\": \"my-react-app:build\",\n \"testingType\": \"component\",\n \"skipServe\": true\n }\n }\n}\n```\n\nIt's important `skipServe` is set to true. Nx doesn't need to run the `devServerTarget`, Cypress creates its own dev server for component testing.\nInstead, Nx needs to know what build target to create the correct configuration to pass to Cypress, which is why it's still used in component testing.\n\n{% /tab %}\n{% /tabs %}\n\n### Environment Variables\n\nUsing [executor configurations](recipes/executors/use-executor-configurations#use-executor-configurations) offers flexibility to set environment variables\n\n```json\n\"targets\": {\n \"e2e\": {\n \"executor\": \"@nx/cypress:cypress\",\n \"options\": {\n \"cypressConfig\": \"apps/app-e2e/cypres.config.ts\",\n \"devServerTarget\": \"my-react-app:serve\",\n \"testingType\": \"e2e\"\n },\n \"configurations\": {\n \"qa\": {\n \"env\": {\n \"API_URL\": \"https://api.qa.company.com\"\n }\n },\n \"dev\": {\n \"env\": {\n \"API_URL\": \"http://localhost:3333/api\"\n }\n }\n }\n }\n}\n```\n\nRead more on different ways to use [environment variables for cypress executor](/packages/cypress#environment-variables)\n"
"examplesFile": "Depending on your testing type, the Cypress executor is configured in different ways. The following are sample configurations that are created via the [configuration](/packages/cypress/generators/configuration) and [cypress-component-configuration](/packages/cypress/generators/cypress-component-configuration) generators.\n\n{% tabs %}\n{% tab label=\"E2E Testing\" %}\n\n```json\n\"targets\": {\n \"e2e\": {\n \"executor\": \"@nx/cypress:cypress\",\n \"options\": {\n \"cypressConfig\": \"apps/app-e2e/cypres.config.ts\",\n \"devServerTarget\": \"my-react-app:serve\",\n \"testingType\": \"e2e\"\n }\n }\n}\n```\n\n{% callout type=\"note\" title=\"API Testing\" %}\nAPI testing with Cypress is the same setup as e2e testing. Just change which `devServerTarget` is used!\n{% /callout %}\n\n### Providing a Base URL\n\nIf `devServerTarget` is provided, the url returned from started the dev server will be passed to cypress as the `baseUrl` option.\n\nDefining a `baseUrl` in the executor options will override the inferred `baseUrl` from the `devServerTarget`.\n\nThe `baseUrl` defined in the Cypress config file is the last value used if no url is found in the `devServerTarget` or executor options.\n\n### Static Serving\n\nWhen running in CI it doesn't make sense to start up a dev server since there aren't changes to watch for.\n\nYou can use [`@nx/web:file-server`](/packages/web/executors/file-server) to serve the pre-built static files of your frontend project.\n\nIn some _frontend_ application, add a 'static-serve' target.\n\n```json\n\"serve-static\": {\n \"executor\": \"@nx/web:file-server\",\n \"options\":{\n \"buildTarget\": \"build\"\n }\n}\n```\n\nIn the _e2e_ application add a configuration to change `devServerTarget` to point to the `static-serve` from the _frontend_ application\n\n```json\n\"e2e\": {\n //...\n \"configurations\": {\n \"ci\": {\n \"devServerTarget\": \"frontend:serve-static\"\n }\n }\n}\n```\n\n{% callout type=\"note\" title=\"What about Node projects?\" %}\nThe same can be done for backend node apps with [`@nx/js:node` executor](/packages/js/executors/node)\n{% /callout %}\n\n```bash\nnx e2e my-app-e2e --configuration=ci\n```\n\n{% /tab %}\n{% tab label=\"Component Testing\" %}\n\n{% callout type=\"note\" title=\"Cypress Component Testing\" %}\nWhen adding component testing to a project, it's best to use the framework specific generator, instead `cypress-component-project` directly.\n\n- [React component testing](/packages/react/generators/cypress-component-configuration)\n- [Angular component testing](/packages/angular/generators/cypress-component-configuration)\n\n{% /callout %}\n\n```json\n\"targets\": {\n \"component-test\": {\n \"executor\": \"@nx/cypress:cypress\",\n \"options\": {\n \"cypressConfig\": \"apps/app/cypres.config.ts\",\n \"devServerTarget\": \"my-react-app:build\",\n \"testingType\": \"component\",\n \"skipServe\": true\n }\n }\n}\n```\n\nIt's important `skipServe` is set to true. Nx doesn't need to run the `devServerTarget`, Cypress creates its own dev server for component testing.\nInstead, Nx needs to know what build target to create the correct configuration to pass to Cypress, which is why it's still used in component testing.\n\n{% /tab %}\n{% /tabs %}\n\n### Environment Variables\n\nUsing [executor configurations](recipes/executors/use-executor-configurations#use-executor-configurations) offers flexibility to set environment variables\n\n```json\n\"targets\": {\n \"e2e\": {\n \"executor\": \"@nx/cypress:cypress\",\n \"options\": {\n \"cypressConfig\": \"apps/app-e2e/cypres.config.ts\",\n \"devServerTarget\": \"my-react-app:serve\",\n \"testingType\": \"e2e\"\n },\n \"configurations\": {\n \"qa\": {\n \"env\": {\n \"API_URL\": \"https://api.qa.company.com\"\n }\n },\n \"dev\": {\n \"env\": {\n \"API_URL\": \"http://localhost:3333/api\"\n }\n }\n }\n }\n}\n```\n\nRead more on different ways to use [environment variables for cypress executor](/packages/cypress#environment-variables)\n"
},
"description": "Run Cypress E2E tests.",
"aliases": [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ exports[`app --project-name-and-root-format=derived should generate correctly wh
"serve-static": {
"executor": "@nx/web:file-server",
"options": {
"buildTarget": "my-dir-my-app:build",
"buildTarget": "build",
"staticFilePath": "dist/apps/my-dir/my-app/browser",
},
},
Expand Down Expand Up @@ -528,7 +528,7 @@ exports[`app --project-name-and-root-format=derived should generate correctly wh
"serve-static": {
"executor": "@nx/web:file-server",
"options": {
"buildTarget": "my-app:build",
"buildTarget": "build",
"staticFilePath": "dist/apps/my-app/browser",
},
},
Expand Down Expand Up @@ -988,7 +988,7 @@ exports[`app nested should create project configs 1`] = `
"serve-static": {
"executor": "@nx/web:file-server",
"options": {
"buildTarget": "my-app:build",
"buildTarget": "build",
"staticFilePath": "dist/my-dir/my-app/browser",
},
},
Expand Down Expand Up @@ -1137,7 +1137,7 @@ exports[`app not nested should create project configs 1`] = `
"serve-static": {
"executor": "@nx/web:file-server",
"options": {
"buildTarget": "my-app:build",
"buildTarget": "build",
"staticFilePath": "dist/my-app/browser",
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ function addFileServerTarget(
projectConfig.targets[targetName] = {
executor: '@nx/web:file-server',
options: {
buildTarget: `${options.name}:build`,
buildTarget: 'build',
port: options.port,
staticFilePath: isUsingApplicationBuilder
? joinPathFragments(options.outputPath, 'browser')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export function setupServeTarget(host: Tree, options: Schema) {
executor: '@nx/web:file-server',
defaultConfiguration: 'production',
options: {
buildTarget: `${options.appName}:build`,
buildTarget: 'build',
port: options.port,
watch: false,
},
Expand Down
2 changes: 1 addition & 1 deletion packages/cypress/docs/cypress-examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ In some _frontend_ application, add a 'static-serve' target.
"serve-static": {
"executor": "@nx/web:file-server",
"options":{
"buildTarget": "frontend:build"
"buildTarget": "build"
}
}
```
Expand Down
10 changes: 5 additions & 5 deletions packages/react/src/generators/application/application.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -436,11 +436,11 @@ describe('app', () => {
const targetConfig = projectsConfigurations.get('my-app').targets;
expect(targetConfig.serve.executor).toEqual('@nx/webpack:dev-server');
expect(targetConfig.serve.options).toEqual({
buildTarget: 'my-app:build',
buildTarget: 'build',
hmr: true,
});
expect(targetConfig.serve.configurations.production).toEqual({
buildTarget: 'my-app:build:production',
buildTarget: 'build:production',
hmr: false,
});
});
Expand All @@ -456,10 +456,10 @@ describe('app', () => {
const targetConfig = projectsConfigurations.get('my-app').targets;
expect(targetConfig.serve.executor).toEqual('@nx/vite:dev-server');
expect(targetConfig.serve.options).toEqual({
buildTarget: 'my-app:build',
buildTarget: 'build',
});
expect(targetConfig.serve.configurations.production).toEqual({
buildTarget: 'my-app:build:production',
buildTarget: 'build:production',
hmr: false,
});
});
Expand Down Expand Up @@ -1026,7 +1026,7 @@ describe('app', () => {
expect(targetConfig.build.executor).toEqual('@nx/vite:build');
expect(targetConfig.serve.executor).toEqual('@nx/vite:dev-server');
expect(targetConfig.serve.options).toEqual({
buildTarget: 'my-app:build',
buildTarget: 'build',
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,15 @@ function createServeTarget(options: NormalizedSchema): TargetConfiguration {
executor: '@nx/webpack:dev-server',
defaultConfiguration: 'development',
options: {
buildTarget: `${options.projectName}:build`,
buildTarget: `build`,
hmr: true,
},
configurations: {
development: {
buildTarget: `${options.projectName}:build:development`,
buildTarget: `build:development`,
},
production: {
buildTarget: `${options.projectName}:build:production`,
buildTarget: `build:production`,
hmr: false,
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export async function addFiles(
const actualBundler =
options.buildTarget !== undefined && options.bundler
? options.bundler
: await getBundlerFromTarget(found, tree);
: await getBundlerFromTarget(tree, found, projectConfig);

if (options.bundler && options.bundler !== actualBundler) {
logger.warn(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export function updateModuleFederationProject(
executor: '@nx/web:file-server',
defaultConfiguration: 'production',
options: {
buildTarget: `${options.projectName}:build`,
buildTarget: 'build',
watch: false,
port: options.devServerPort,
},
Expand Down
25 changes: 19 additions & 6 deletions packages/react/src/utils/ct-utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
createProjectGraphAsync,
parseTargetString,
ProjectConfiguration,
readProjectConfiguration,
Tree,
updateProjectConfiguration,
Expand Down Expand Up @@ -58,8 +59,9 @@ function assertValidConfig(config: unknown) {
}

export async function getBundlerFromTarget(
tree: Tree,
found: FoundTarget,
tree: Tree
projectConfig: ProjectConfiguration
): Promise<'vite' | 'webpack'> {
if (found.target && found.config?.executor) {
return found.config.executor === '@nrwl/vite:build' ||
Expand All @@ -68,11 +70,22 @@ export async function getBundlerFromTarget(
: 'webpack';
}

const { target, project } = parseTargetString(
found.target,
await createProjectGraphAsync()
);
const projectConfig = readProjectConfiguration(tree, project);
const graph = await createProjectGraphAsync();
const { target, project } = (() => {
try {
return parseTargetString(found.target, graph);
} catch {
return parseTargetString(
[projectConfig.name, found.target].join(':'),
graph
);
}
})();

if (project !== projectConfig.name) {
projectConfig = readProjectConfiguration(tree, project);
}

const executor = projectConfig?.targets?.[target]?.executor;
return executor === '@nrwl/vite:build' || executor === '@nx/vite:build'
? 'vite'
Expand Down
14 changes: 7 additions & 7 deletions packages/vite/src/utils/generator-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ export function addOrChangeServeTarget(
if (project.targets[target]) {
const serveTarget = project.targets[target];
const serveOptions: ViteDevServerExecutorOptions = {
buildTarget: `${options.project}:build`,
buildTarget: `build`,
https: project.targets[target].options?.https,
hmr: project.targets[target].options?.hmr,
open: project.targets[target].options?.open,
Expand All @@ -271,15 +271,15 @@ export function addOrChangeServeTarget(
executor: '@nx/vite:dev-server',
defaultConfiguration: 'development',
options: {
buildTarget: `${options.project}:build`,
buildTarget: `build`,
},
configurations: {
development: {
buildTarget: `${options.project}:build:development`,
buildTarget: `build:development`,
hmr: true,
},
production: {
buildTarget: `${options.project}:build:production`,
buildTarget: `build:production`,
hmr: false,
},
},
Expand All @@ -305,7 +305,7 @@ export function addPreviewTarget(
const project = readProjectConfiguration(tree, options.project);

const previewOptions: VitePreviewServerExecutorOptions = {
buildTarget: `${options.project}:build`,
buildTarget: `build`,
};

project.targets ??= {};
Expand All @@ -327,10 +327,10 @@ export function addPreviewTarget(
options: previewOptions,
configurations: {
development: {
buildTarget: `${options.project}:build:development`,
buildTarget: `build:development`,
},
production: {
buildTarget: `${options.project}:build:production`,
buildTarget: `build:production`,
},
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,15 @@ exports[`application generator should set up project correctly with given option
"executor": "@nx/vite:dev-server",
"defaultConfiguration": "development",
"options": {
"buildTarget": "test:build"
"buildTarget": "build"
},
"configurations": {
"development": {
"buildTarget": "test:build:development",
"buildTarget": "build:development",
"hmr": true
},
"production": {
"buildTarget": "test:build:production",
"buildTarget": "build:production",
"hmr": false
}
}
Expand All @@ -129,14 +129,14 @@ exports[`application generator should set up project correctly with given option
"executor": "@nx/vite:preview-server",
"defaultConfiguration": "development",
"options": {
"buildTarget": "test:build"
"buildTarget": "build"
},
"configurations": {
"development": {
"buildTarget": "test:build:development"
"buildTarget": "build:development"
},
"production": {
"buildTarget": "test:build:production"
"buildTarget": "build:production"
}
}
},
Expand All @@ -151,7 +151,7 @@ exports[`application generator should set up project correctly with given option
"serve-static": {
"executor": "@nx/web:file-server",
"options": {
"buildTarget": "test:build"
"buildTarget": "build"
}
}
}
Expand Down
57 changes: 57 additions & 0 deletions packages/web/src/executors/file-server/file-server.impl.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { ExecutorContext } from '@nx/devkit';
import { normalizeOptions } from './file-server.impl';
import { Schema } from './schema';

describe('file-server impl', () => {
describe('normalizeOptions', () => {
it('should normalize build target', () => {
const context: ExecutorContext = {
root: '/',
cwd: '/',
isVerbose: false,
projectGraph: {
nodes: {
root: {
data: {
targets: {
build: { configurations: 'production' },
'build:test': {},
},
},
} as any,
},
dependencies: {},
},
projectName: 'root',
};
expect(
normalizeOptions({ buildTarget: 'build' } as Schema, context)
).toEqual({
buildTarget: 'root:build',
});
expect(
normalizeOptions({ buildTarget: 'root:build' } as Schema, context)
).toEqual({
buildTarget: 'root:build',
});
expect(
normalizeOptions({ buildTarget: 'build:production' } as Schema, context)
).toEqual({
buildTarget: 'root:build:production',
});
expect(
normalizeOptions(
{ buildTarget: 'root:build:production' } as Schema,
context
)
).toEqual({
buildTarget: 'root:build:production',
});
expect(
normalizeOptions({ buildTarget: 'build:test' } as Schema, context)
).toEqual({
buildTarget: 'root:build:test',
});
});
});
});
Loading