diff --git a/tools/workspace-plugin/src/executors/build/executor.spec.ts b/tools/workspace-plugin/src/executors/build/executor.spec.ts
index 1e256f152ed6a..ea26f7c24e652 100644
--- a/tools/workspace-plugin/src/executors/build/executor.spec.ts
+++ b/tools/workspace-plugin/src/executors/build/executor.spec.ts
@@ -203,7 +203,7 @@ describe('Build Executor', () => {
"
`);
expect(readFileSync(join(workspaceRoot, 'libs/proj/lib/greeter.js.map'), 'utf-8')).toMatchInlineSnapshot(
- `"{\\"version\\":3,\\"sources\\":[\\"greeter.ts\\"],\\"sourcesContent\\":[\\"import { useStyles } from './greeter.styles';\\\\nexport function greeter(greeting: string, user: User): string {\\\\n const styles = useStyles();\\\\n return \`
\${greeting} \${user.name} from \${user.hometown?.name}
\`;\\\\n}\\\\n\\\\ntype User = {\\\\n name: string;\\\\n hometown?: {\\\\n name: string;\\\\n };\\\\n};\\\\n\\"],\\"names\\":[\\"useStyles\\",\\"greeter\\",\\"greeting\\",\\"user\\",\\"styles\\",\\"name\\",\\"hometown\\"],\\"rangeMappings\\":\\";;;;;\\",\\"mappings\\":\\"AAAA,SAASA,SAAS,QAAQ,mBAAmB;AAC7C,OAAO,SAASC,QAAQC,QAAgB,EAAEC,IAAU;QAEYA;IAD9D,MAAMC,SAASJ;IACf,OAAO,CAAC,WAAW,EAAEI,OAAO,EAAE,EAAEF,SAAS,CAAC,EAAEC,KAAKE,IAAI,CAAC,MAAM,GAAEF,iBAAAA,KAAKG,QAAQ,cAAbH,qCAAAA,eAAeE,IAAI,CAAC,KAAK,CAAC;AAC1F\\"}"`,
+ `"{\\"version\\":3,\\"sources\\":[\\"../src/greeter.ts\\"],\\"sourcesContent\\":[\\"import { useStyles } from './greeter.styles';\\\\nexport function greeter(greeting: string, user: User): string {\\\\n const styles = useStyles();\\\\n return \`\${greeting} \${user.name} from \${user.hometown?.name}
\`;\\\\n}\\\\n\\\\ntype User = {\\\\n name: string;\\\\n hometown?: {\\\\n name: string;\\\\n };\\\\n};\\\\n\\"],\\"names\\":[\\"useStyles\\",\\"greeter\\",\\"greeting\\",\\"user\\",\\"styles\\",\\"name\\",\\"hometown\\"],\\"rangeMappings\\":\\";;;;;\\",\\"mappings\\":\\"AAAA,SAASA,SAAS,QAAQ,mBAAmB;AAC7C,OAAO,SAASC,QAAQC,QAAgB,EAAEC,IAAU;QAEYA;IAD9D,MAAMC,SAASJ;IACf,OAAO,CAAC,WAAW,EAAEI,OAAO,EAAE,EAAEF,SAAS,CAAC,EAAEC,KAAKE,IAAI,CAAC,MAAM,GAAEF,iBAAAA,KAAKG,QAAQ,cAAbH,qCAAAA,eAAeE,IAAI,CAAC,KAAK,CAAC;AAC1F\\"}"`,
);
expect(readFileSync(join(workspaceRoot, 'libs/proj/lib-commonjs/greeter.js'), 'utf-8')).toMatchInlineSnapshot(`
diff --git a/tools/workspace-plugin/src/executors/build/lib/babel.ts b/tools/workspace-plugin/src/executors/build/lib/babel.ts
index 04576101348ab..4939d90f209f9 100644
--- a/tools/workspace-plugin/src/executors/build/lib/babel.ts
+++ b/tools/workspace-plugin/src/executors/build/lib/babel.ts
@@ -85,6 +85,7 @@ async function babel(esmModuleOutput: NormalizedOptions['moduleOutput'][number],
const sourceCode = codeBuffer.toString().replace(EOL_REGEX, '\n');
const result = (await transformAsync(sourceCode, {
+ cwd: normalizedOptions.absoluteProjectRoot,
ast: false,
sourceMaps: true,
diff --git a/tools/workspace-plugin/src/executors/build/lib/swc.ts b/tools/workspace-plugin/src/executors/build/lib/swc.ts
index afd89dcaa018c..a3c2dd9f887b5 100644
--- a/tools/workspace-plugin/src/executors/build/lib/swc.ts
+++ b/tools/workspace-plugin/src/executors/build/lib/swc.ts
@@ -1,14 +1,20 @@
-import { readFileSync } from 'node:fs';
import { mkdir, writeFile } from 'node:fs/promises';
-import { basename, dirname, join } from 'node:path';
+import { dirname, join } from 'node:path';
import { globSync } from 'fast-glob';
import { isMatch } from 'micromatch';
-import { transform, type Config } from '@swc/core';
+import { transformFile, type Config } from '@swc/core';
import { logger, readJsonFile } from '@nx/devkit';
import { type NormalizedOptions } from './shared';
+// extend @swc/core types by missing apis
+declare module '@swc/core' {
+ interface BaseModuleConfig {
+ resolveFully?: boolean;
+ }
+}
+
interface Options {
module: 'es6' | 'commonjs' | 'amd';
outputPath: string;
@@ -35,15 +41,10 @@ export async function compileSwc(options: Options, normalizedOptions: Normalized
continue;
}
- const sourceCode = readFileSync(srcFilePath, 'utf-8');
-
- const result = await transform(sourceCode, {
- filename: fileName,
- sourceFileName: basename(fileName),
- module: { type: module },
- outputPath,
- // this is crucial in order to transpile with project config SWC
- configFile: swcConfigPath,
+ const result = await transformFile(srcFilePath, {
+ module: { type: module, resolveFully: Boolean(swcConfig.jsc?.baseUrl) },
+ // srcFilePath is absolute path so outputPath needs to be as well in order to properly emit relative path within .map (eg: `"sources":["../src/utils/createDarkTheme.ts"]`)
+ outputPath: join(normalizedOptions.absoluteProjectRoot, outputPath),
});
// Strip @jsx comments, see https://github.com/microsoft/fluentui/issues/29126
diff --git a/tools/workspace-plugin/src/executors/build/schema.d.ts b/tools/workspace-plugin/src/executors/build/schema.d.ts
index 1c099ab6cef01..26b5481c0e2cc 100644
--- a/tools/workspace-plugin/src/executors/build/schema.d.ts
+++ b/tools/workspace-plugin/src/executors/build/schema.d.ts
@@ -55,14 +55,7 @@ export interface BuildExecutorSchema {
* Key-value pairs to replace in the output path
*/
substitutions?: {
- /**
- * The key to replace.
- */
- key: string;
- /**
- * The value to replace.
- */
- value: string;
+ [k: string]: string;
};
}
| string
diff --git a/tools/workspace-plugin/src/executors/build/schema.json b/tools/workspace-plugin/src/executors/build/schema.json
index bf4373b83626b..f8dabb4fd107e 100644
--- a/tools/workspace-plugin/src/executors/build/schema.json
+++ b/tools/workspace-plugin/src/executors/build/schema.json
@@ -47,12 +47,9 @@
"substitutions": {
"type": "object",
"description": "Key-value pairs to replace in the output path",
- "properties": {
- "key": { "type": "string", "description": "The key to replace." },
- "value": { "type": "string", "description": "The value to replace." }
- },
- "additionalProperties": false,
- "required": ["key", "value"]
+ "additionalProperties": {
+ "type": "string"
+ }
}
},
"additionalProperties": false,
diff --git a/tools/workspace-plugin/src/executors/generate-api/executor.spec.ts b/tools/workspace-plugin/src/executors/generate-api/executor.spec.ts
index 0bdead569d8d6..b68417b56b479 100644
--- a/tools/workspace-plugin/src/executors/generate-api/executor.spec.ts
+++ b/tools/workspace-plugin/src/executors/generate-api/executor.spec.ts
@@ -148,8 +148,10 @@ describe('GenerateApi Executor', () => {
const output = await executor(options, context);
+ const projectRootAbsolutePath = `${__dirname}/__fixtures__/proj`;
+
expect(execSyncMock.mock.calls.flat()).toEqual([
- `tsc -p ${__dirname}/__fixtures__/proj/tsconfig.lib.json --pretty --emitDeclarationOnly --baseUrl .`,
+ `tsc -p ${projectRootAbsolutePath}/tsconfig.lib.json --pretty --emitDeclarationOnly --baseUrl ${projectRootAbsolutePath}`,
{ stdio: 'inherit' },
]);
diff --git a/tools/workspace-plugin/src/executors/generate-api/executor.ts b/tools/workspace-plugin/src/executors/generate-api/executor.ts
index d878979c731ce..17bb673b99aa4 100644
--- a/tools/workspace-plugin/src/executors/generate-api/executor.ts
+++ b/tools/workspace-plugin/src/executors/generate-api/executor.ts
@@ -84,7 +84,7 @@ function generateTypeDeclarations(options: NormalizedOptions) {
'--pretty',
'--emitDeclarationOnly',
// turn off path aliases.
- '--baseUrl .',
+ `--baseUrl ${options.projectAbsolutePath}`,
].join(' ');
verboseLog(`Emitting '.d.ts' files via: "${cmd}"`);
diff --git a/tools/workspace-plugin/src/executors/type-check/executor.spec.ts b/tools/workspace-plugin/src/executors/type-check/executor.spec.ts
index 22fd3495e896d..280e08803b990 100644
--- a/tools/workspace-plugin/src/executors/type-check/executor.spec.ts
+++ b/tools/workspace-plugin/src/executors/type-check/executor.spec.ts
@@ -75,8 +75,8 @@ describe('TypeCheck Executor', () => {
const output = await executor(options, mockContext);
expect(promisifyCallMock.mock.calls.flat()).toEqual([
- 'tsc -p /root/libs/my-lib/tsconfig.lib.json --pretty --noEmit --baseUrl .',
- 'tsc -p /root/libs/my-lib/tsconfig.spec.json --pretty --noEmit --baseUrl .',
+ 'tsc -p /root/libs/my-lib/tsconfig.lib.json --pretty --noEmit --baseUrl /root/libs/my-lib',
+ 'tsc -p /root/libs/my-lib/tsconfig.spec.json --pretty --noEmit --baseUrl /root/libs/my-lib',
]);
expect(output.success).toBe(true);
@@ -93,7 +93,7 @@ describe('TypeCheck Executor', () => {
const output = await executor({ ...options, excludeProject: { spec: true, e2e: false } }, mockContext);
expect(promisifyCallMock.mock.calls.flat()).toEqual([
- 'tsc -p /root/libs/my-lib/tsconfig.lib.json --pretty --noEmit --baseUrl .',
+ 'tsc -p /root/libs/my-lib/tsconfig.lib.json --pretty --noEmit --baseUrl /root/libs/my-lib',
]);
expect(output.success).toBe(true);
diff --git a/tools/workspace-plugin/src/executors/type-check/executor.ts b/tools/workspace-plugin/src/executors/type-check/executor.ts
index dfd0a6fdafc74..33673193983a0 100644
--- a/tools/workspace-plugin/src/executors/type-check/executor.ts
+++ b/tools/workspace-plugin/src/executors/type-check/executor.ts
@@ -43,7 +43,7 @@ async function runTypeCheck(options: NormalizedOptions, context: ExecutorContext
const asyncQueue = [];
for (const ref of tsConfigsRefs) {
- const program = `tsc -p ${ref} --pretty --noEmit --baseUrl .`;
+ const program = `tsc -p ${ref} --pretty --noEmit --baseUrl ${projectRootAbsolutePath}`;
verboseLog(`Running "${program}"`);
diff --git a/tools/workspace-plugin/src/executors/verify-packaging/executor.ts b/tools/workspace-plugin/src/executors/verify-packaging/executor.ts
index 4a48934f5da7b..37033028b6faa 100644
--- a/tools/workspace-plugin/src/executors/verify-packaging/executor.ts
+++ b/tools/workspace-plugin/src/executors/verify-packaging/executor.ts
@@ -122,7 +122,8 @@ function assertions(
);
}
- if (isV8package) {
+ // apply only for non cross domain v8 packages (eg: react-migration-* is v9/v8)
+ if (isV8package && !isV9package) {
issues.push(assertEmpty(npmPackResult, '(lib|lib-commonjs)/**/*.d.ts', `ships dts`));
if (options.isProduction && shipsBundle) {
diff --git a/tools/workspace-plugin/src/plugins/workspace-plugin.spec.ts b/tools/workspace-plugin/src/plugins/workspace-plugin.spec.ts
index 4eef49a2c1c3b..819c0972eb4d0 100644
--- a/tools/workspace-plugin/src/plugins/workspace-plugin.spec.ts
+++ b/tools/workspace-plugin/src/plugins/workspace-plugin.spec.ts
@@ -136,32 +136,40 @@ describe(`workspace-plugin`, () => {
describe(`v9 project nodes`, () => {
it('should create default nodes for v9 library project', async () => {
await tempFs.createFiles({
- 'proj/project.json': serializeJson({
+ 'proj/library/project.json': serializeJson({
root: 'proj',
+ name: 'proj',
projectType: 'library',
tags: ['vNext'],
} satisfies ProjectConfiguration),
- 'proj/package.json': serializeJson({ name: '@proj/proj', private: true } satisfies Partial),
+ 'proj/library/package.json': serializeJson({
+ name: '@proj/proj',
+ private: true,
+ } satisfies Partial),
+ 'proj/stories/project.json': serializeJson({
+ root: 'proj/stories',
+ name: 'proj-stories',
+ } satisfies ProjectConfiguration),
});
- const results = await createNodesFunction(['proj/project.json'], {}, context);
+ const results = await createNodesFunction(['proj/library/project.json'], {}, context);
- expect(getTargetsNames(results)).toEqual([
+ expect(getTargetsNames(results, 'proj/library')).toEqual([
'clean',
'format',
'type-check',
'generate-api',
'build',
- 'start',
'storybook',
+ 'start',
]);
expect(results).toMatchInlineSnapshot(`
Array [
Array [
- "proj/project.json",
+ "proj/library/project.json",
Object {
"projects": Object {
- "proj": Object {
+ "proj/library": Object {
"targets": Object {
"build": Object {
"cache": true,
@@ -189,7 +197,7 @@ describe(`workspace-plugin`, () => {
],
"metadata": Object {
"help": Object {
- "command": "yarn nx run undefined:build --help",
+ "command": "yarn nx run proj:build --help",
"example": Object {},
},
"technologies": Array [
@@ -217,7 +225,7 @@ describe(`workspace-plugin`, () => {
"{projectRoot}/lib-commonjs",
"{projectRoot}/dist",
"{projectRoot}/dist/index.d.ts",
- "{projectRoot}/etc/undefined.api.md",
+ "{projectRoot}/etc/proj.api.md",
],
},
"clean": Object {
@@ -266,7 +274,7 @@ describe(`workspace-plugin`, () => {
],
"metadata": Object {
"help": Object {
- "command": "yarn nx run undefined:generate-api --help",
+ "command": "yarn nx run proj:generate-api --help",
"example": Object {},
},
"technologies": Array [
@@ -276,26 +284,16 @@ describe(`workspace-plugin`, () => {
},
"outputs": Array [
"{projectRoot}/dist/index.d.ts",
- "{projectRoot}/etc/undefined.api.md",
+ "{projectRoot}/etc/proj.api.md",
],
},
"start": Object {
- "command": "yarn storybook",
- "options": Object {
- "cwd": "proj",
- },
+ "cache": true,
+ "command": "nx run proj-stories:storybook",
},
"storybook": Object {
"cache": true,
- "command": "yarn --cwd ../stories storybook",
- "metadata": Object {
- "technologies": Array [
- "storybook",
- ],
- },
- "options": Object {
- "cwd": "proj",
- },
+ "command": "nx run proj-stories:storybook",
},
"type-check": Object {
"cache": true,
@@ -323,6 +321,7 @@ describe(`workspace-plugin`, () => {
it('should create default nodes for v9 stories project', async () => {
await tempFs.createFiles({
+ 'proj/stories/.storybook/main.js': '',
'proj/stories/project.json': serializeJson({
root: 'proj/stories',
projectType: 'library',
@@ -339,15 +338,16 @@ describe(`workspace-plugin`, () => {
'clean',
'format',
'type-check',
+ 'storybook',
'test-ssr',
'start',
- 'storybook',
]);
const targets = getTargets(results, 'proj/stories');
expect(targets?.storybook).toMatchInlineSnapshot(`
Object {
+ "cache": true,
"command": "yarn storybook dev",
"inputs": Array [
"production",
diff --git a/tools/workspace-plugin/src/plugins/workspace-plugin.ts b/tools/workspace-plugin/src/plugins/workspace-plugin.ts
index a7f191c4870a9..27a2f365b69ca 100644
--- a/tools/workspace-plugin/src/plugins/workspace-plugin.ts
+++ b/tools/workspace-plugin/src/plugins/workspace-plugin.ts
@@ -22,34 +22,73 @@ import { assertProjectExists, projectConfigGlob } from './shared';
import { buildCleanTarget } from './clean-plugin';
import { buildFormatTarget } from './format-plugin';
import { buildTypeCheckTarget } from './type-check-plugin';
+import { measureStart, measureEnd } from '../utils';
-interface WorkspacePluginOptions {}
+interface WorkspacePluginOptions {
+ testSSR?: TargetPluginOption;
+ verifyPackaging?: TargetPluginOption;
+}
+interface TargetPluginOption {
+ targetName?: string;
+ /**
+ * project names to exclude from adding target
+ */
+ exclude?: string[];
+ /**
+ * project names to include for adding target
+ */
+ include?: string[];
+}
export const createNodesV2: CreateNodesV2 = [
projectConfigGlob,
- (configFiles, options, context) => {
- return createNodesFromFiles(
+ async (configFiles, options, context) => {
+ const globalConfig: Pick = { pmc: getPackageManagerCommand('yarn') };
+
+ measureStart('workspace-plugin');
+ const nodes = await createNodesFromFiles(
(configFile, options, context) => {
- return createNodesInternal(configFile, options ?? {}, context);
+ return createNodesInternal(configFile, options ?? {}, context, globalConfig);
},
configFiles,
options,
context,
);
+
+ measureEnd('workspace-plugin');
+
+ return nodes;
},
];
// ===================================================================================================================
-function normalizeOptions(options: WorkspacePluginOptions | undefined): Required {
+type NormalizedOptions = ReturnType;
+
+type DeepRequired = {
+ [K in keyof T]-?: NonNullable extends object ? DeepRequired : NonNullable;
+};
+
+function normalizeOptions(options: WorkspacePluginOptions | undefined): DeepRequired {
options ??= {};
- return options as Required;
+ options.testSSR ??= {};
+ options.testSSR.targetName ??= 'test-ssr';
+ options.testSSR.include ??= [];
+ options.testSSR.exclude ??= [];
+
+ options.verifyPackaging ??= {};
+ options.verifyPackaging.targetName ??= 'verify-packaging';
+ options.verifyPackaging.include ??= [];
+ options.verifyPackaging.exclude ??= [];
+
+ return options as DeepRequired;
}
function createNodesInternal(
configFilePath: string,
options: WorkspacePluginOptions,
context: CreateNodesContextV2,
+ globalConfig: Pick,
): CreateNodesResult {
const projectRoot = dirname(configFilePath);
@@ -58,7 +97,8 @@ function createNodesInternal(
}
const normalizedOptions = normalizeOptions(options);
- const config = { pmc: getPackageManagerCommand('yarn') };
+
+ const config = { ...globalConfig };
const targetsConfig = buildWorkspaceTargets(projectRoot, normalizedOptions, context, config);
@@ -78,7 +118,7 @@ interface TaskBuilderConfig {
function buildWorkspaceTargets(
projectRoot: string,
- options: Required,
+ options: NormalizedOptions,
context: CreateNodesContextV2,
sharedConfig: Pick,
) {
@@ -94,50 +134,33 @@ function buildWorkspaceTargets(
targets.format = buildFormatTarget({}, context, config);
targets['type-check'] = buildTypeCheckTarget({}, context, config);
- const lintTarget = buildLintTarget(projectRoot, normalizeOptions, context, config);
+ const lintTarget = buildLintTarget(projectRoot, options, context, config);
if (lintTarget) {
targets.lint = lintTarget;
}
- const testTarget = buildTestTarget(projectRoot, normalizeOptions, context, config);
+ const testTarget = buildTestTarget(projectRoot, options, context, config);
if (testTarget) {
targets.test = testTarget;
}
+ const storybookTarget = buildStorybookTarget(projectRoot, options, context, config);
+ if (storybookTarget) {
+ targets.storybook = storybookTarget;
+ }
+
// react v9 lib
if (projectJSON.projectType === 'library' && tags.includes('vNext')) {
// *-stories projects
if (tags.includes('type:stories')) {
- targets['test-ssr'] = {
- cache: true,
- command: `${config.pmc.exec} test-ssr "./src/**/*.stories.tsx"`,
- options: { cwd: projectRoot },
- metadata: {
- technologies: ['test-ssr'],
- help: {
- command: `${config.pmc.exec} test-ssr --help`,
- example: {},
- },
- },
- };
- targets.start = { command: `${config.pmc.exec} storybook`, options: { cwd: projectRoot } };
- targets.storybook = {
- command: `${config.pmc.exec} storybook dev`,
- inputs: [
- 'production',
- '{workspaceRoot}/.storybook/**',
- '{projectRoot}/.storybook/**',
- { externalDependencies: ['storybook'] },
- ],
- options: { cwd: projectRoot },
- metadata: {
- technologies: ['storybook'],
- help: {
- command: `${config.pmc.exec} storybook dev --help`,
- example: {},
- },
- },
- };
+ const testSsrTarget = buildTestSsrTarget(projectRoot, options, context, config);
+ if (testSsrTarget) {
+ targets[options.testSSR.targetName] = testSsrTarget;
+ }
+
+ if (storybookTarget) {
+ targets.start = { command: `nx run ${config.projectJSON.name}:storybook`, cache: true };
+ }
return targets;
}
@@ -204,18 +227,11 @@ function buildWorkspaceTargets(
},
};
- targets.start = {
- command: `${config.pmc.exec} storybook`,
- options: { cwd: projectRoot },
- };
- targets.storybook = {
- cache: true,
- command: `${config.pmc.exec} --cwd ../stories storybook`,
- options: { cwd: projectRoot },
- metadata: {
- technologies: ['storybook'],
- },
- };
+ if (existsSync(join(projectRoot, '../stories/project.json'))) {
+ const storybookTarget = { command: `nx run ${config.projectJSON.name}-stories:storybook`, cache: true };
+ targets.storybook = storybookTarget;
+ targets.start = storybookTarget;
+ }
const bundleSizeTarget = buildBundleSizeTarget(projectRoot, options, context, config);
if (bundleSizeTarget) {
@@ -227,9 +243,9 @@ function buildWorkspaceTargets(
targets.e2e = e2eTarget;
}
- const verifyPackagingTarget = buildVerifyPackagingTarget(projectRoot, normalizeOptions, context, config);
+ const verifyPackagingTarget = buildVerifyPackagingTarget(projectRoot, options, context, config);
if (verifyPackagingTarget) {
- targets['verify-packaging'] = verifyPackagingTarget;
+ targets[options.verifyPackaging.targetName] = verifyPackagingTarget;
}
return targets;
@@ -310,10 +326,17 @@ function buildLintTarget(
function buildVerifyPackagingTarget(
projectRoot: string,
- options: Required,
+ options: NormalizedOptions,
context: CreateNodesContextV2,
config: TaskBuilderConfig,
): TargetConfiguration | null {
+ if (options.verifyPackaging.include.length && !options.verifyPackaging.include.includes(config.projectJSON.name!)) {
+ return null;
+ }
+ if (options.verifyPackaging.exclude.length && options.verifyPackaging.exclude.includes(config.projectJSON.name!)) {
+ return null;
+ }
+
if (config.packageJSON.private) {
return null;
}
@@ -386,6 +409,7 @@ function buildE2eTarget(
{ externalDependencies: ['cypress', '@cypress/react'] },
],
metadata: {
+ technologies: ['cypress'],
help: {
command: `${config.pmc.exec} cypress run --help`,
example: {},
@@ -408,9 +432,10 @@ function buildE2eTarget(
'{projectRoot}/playwright.config.ts',
'!{projectRoot}/**/?(*.)+spec.[jt]s?(x)?',
'!{projectRoot}/**/?(*.)+spec-e2e.[jt]s?(x)?',
- { externalDependencies: ['playwright'] },
+ { externalDependencies: ['@playwright/test'] },
],
metadata: {
+ technologies: ['playwright'],
help: {
command: `${config.pmc.exec} playwright test --help`,
example: {},
@@ -421,3 +446,60 @@ function buildE2eTarget(
return null;
}
+
+function buildTestSsrTarget(
+ projectRoot: string,
+ options: NormalizedOptions,
+ context: CreateNodesContextV2,
+ config: TaskBuilderConfig,
+): TargetConfiguration | null {
+ if (options.testSSR.include.length && !options.testSSR.include.includes(config.projectJSON.name!)) {
+ return null;
+ }
+ if (options.testSSR.exclude.length && options.testSSR.exclude.includes(config.projectJSON.name!)) {
+ return null;
+ }
+
+ return {
+ cache: true,
+ command: `${config.pmc.exec} test-ssr "./src/**/*.stories.tsx"`,
+ options: { cwd: projectRoot },
+ metadata: {
+ technologies: ['test-ssr'],
+ help: {
+ command: `${config.pmc.exec} test-ssr --help`,
+ example: {},
+ },
+ },
+ };
+}
+
+function buildStorybookTarget(
+ projectRoot: string,
+ options: NormalizedOptions,
+ context: CreateNodesContextV2,
+ config: TaskBuilderConfig,
+): TargetConfiguration | null {
+ if (!existsSync(join(projectRoot, '.storybook/main.js'))) {
+ return null;
+ }
+
+ return {
+ command: `${config.pmc.exec} storybook dev`,
+ cache: true,
+ inputs: [
+ 'production',
+ '{workspaceRoot}/.storybook/**',
+ '{projectRoot}/.storybook/**',
+ { externalDependencies: ['storybook'] },
+ ],
+ options: { cwd: projectRoot },
+ metadata: {
+ technologies: ['storybook'],
+ help: {
+ command: `${config.pmc.exec} storybook dev --help`,
+ example: {},
+ },
+ },
+ };
+}