diff --git a/packages/devkit/src/generators/artifact-name-and-directory-utils.ts b/packages/devkit/src/generators/artifact-name-and-directory-utils.ts
index fcf2872ee4248..ac71f7d5c5f35 100644
--- a/packages/devkit/src/generators/artifact-name-and-directory-utils.ts
+++ b/packages/devkit/src/generators/artifact-name-and-directory-utils.ts
@@ -23,7 +23,7 @@ export type ArtifactGenerationOptions = {
name: string;
directory?: string;
disallowPathInNameForDerived?: boolean;
- fileExtension?: 'js' | 'jsx' | 'ts' | 'tsx';
+ fileExtension?: 'js' | 'jsx' | 'ts' | 'tsx' | 'vue';
fileName?: string;
flat?: boolean;
nameAndDirectoryFormat?: NameAndDirectoryFormat;
diff --git a/packages/nuxt/src/generators/component/component.ts b/packages/nuxt/src/generators/component/component.ts
index e5710103d4240..cbfe22c37433b 100644
--- a/packages/nuxt/src/generators/component/component.ts
+++ b/packages/nuxt/src/generators/component/component.ts
@@ -1,4 +1,4 @@
-import { formatFiles, runTasksInSerial, Tree } from '@nx/devkit';
+import { formatFiles, Tree } from '@nx/devkit';
import { componentGenerator as vueComponentGenerator } from '@nx/vue';
import { Schema } from './schema';
@@ -7,17 +7,16 @@ import { Schema } from './schema';
* are just adjusting some options
*/
export async function componentGenerator(host: Tree, options: Schema) {
- const componentGenerator = await vueComponentGenerator(host, {
+ await vueComponentGenerator(host, {
...options,
routing: false,
skipFormat: true,
+ directory: options.directory ?? 'components',
});
if (!options.skipFormat) {
await formatFiles(host);
}
-
- return runTasksInSerial(componentGenerator);
}
export default componentGenerator;
diff --git a/packages/nuxt/src/generators/page/page.spec.ts b/packages/nuxt/src/generators/page/page.spec.ts
index bde9733e59a50..7f36e64acce03 100644
--- a/packages/nuxt/src/generators/page/page.spec.ts
+++ b/packages/nuxt/src/generators/page/page.spec.ts
@@ -16,12 +16,8 @@ describe('page', () => {
expect(getDirectory('pages/someDir')).toEqual('pages/someDir');
});
- it('should append "/pages" to the directory if it does not start with "pages/" 2', () => {
- expect(getDirectory('someDir/')).toEqual('someDir/pages');
- });
-
- it('should append "/pages" to the directory if it does not start with "pages/"', () => {
- expect(getDirectory('someDir')).toEqual('someDir/pages');
+ it('should prepend "pages/" to the directory if it does not start with "pages/"', () => {
+ expect(getDirectory('someDir')).toEqual('pages/someDir');
});
it('should work with an empty string', () => {
diff --git a/packages/nuxt/src/generators/page/page.ts b/packages/nuxt/src/generators/page/page.ts
index aa16daab5b1d4..d005920f002a7 100644
--- a/packages/nuxt/src/generators/page/page.ts
+++ b/packages/nuxt/src/generators/page/page.ts
@@ -1,14 +1,9 @@
-import {
- formatFiles,
- joinPathFragments,
- runTasksInSerial,
- Tree,
-} from '@nx/devkit';
+import { formatFiles, joinPathFragments, Tree } from '@nx/devkit';
import { componentGenerator } from '../component/component';
import { Schema } from './schema';
export async function pageGenerator(host: Tree, options: Schema) {
- const pageGenerator = await componentGenerator(host, {
+ await componentGenerator(host, {
...options,
directory: getDirectory(options.directory),
skipTests: true,
@@ -21,15 +16,13 @@ export async function pageGenerator(host: Tree, options: Schema) {
if (!options.skipFormat) {
await formatFiles(host);
}
-
- return runTasksInSerial(pageGenerator);
}
export function getDirectory(directory: string) {
return directory?.length > 0
? directory.startsWith('pages/')
? directory
- : joinPathFragments(directory + '/pages')
+ : joinPathFragments('pages', directory)
: 'pages';
}
diff --git a/packages/vue/generators.json b/packages/vue/generators.json
index b601513ac5036..77c2beff5d8dd 100644
--- a/packages/vue/generators.json
+++ b/packages/vue/generators.json
@@ -23,7 +23,7 @@
"description": "Create a Vue library."
},
"component": {
- "factory": "./src/generators/component/component",
+ "factory": "./src/generators/component/component#componentGeneratorInternal",
"schema": "./src/generators/component/schema.json",
"aliases": ["c"],
"x-type": "component",
diff --git a/packages/vue/src/generators/component/__snapshots__/component.spec.ts.snap b/packages/vue/src/generators/component/__snapshots__/component.spec.ts.snap
deleted file mode 100644
index a25bc2f454d5f..0000000000000
--- a/packages/vue/src/generators/component/__snapshots__/component.spec.ts.snap
+++ /dev/null
@@ -1,62 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`component --export should add to index.ts barrel 1`] = `
-"export { default as Hello } from './components/hello/hello.vue';
-"
-`;
-
-exports[`component --export should not export from an app 1`] = `null`;
-
-exports[`component should generate files with jest 1`] = `
-"
-
-
- Welcome to Hello!
-
-
-
-"
-`;
-
-exports[`component should generate files with jest 2`] = `
-"import { mount } from '@vue/test-utils';
-import Hello from './hello.vue';
-
-describe('Hello', () => {
- it('renders properly', () => {
- const wrapper = mount(Hello, {});
- expect(wrapper.text()).toContain('Welcome to Hello');
- });
-});
-"
-`;
-
-exports[`component should generate files with vitest 1`] = `
-"
-
-
- Welcome to Hello!
-
-
-
-"
-`;
-
-exports[`component should generate files with vitest 2`] = `
-"import { describe, it, expect } from 'vitest';
-
-import { mount } from '@vue/test-utils';
-import Hello from './hello.vue';
-
-describe('Hello', () => {
- it('renders properly', () => {
- const wrapper = mount(Hello, {});
- expect(wrapper.text()).toContain('Welcome to Hello');
- });
-});
-"
-`;
diff --git a/packages/vue/src/generators/component/component.spec.ts b/packages/vue/src/generators/component/component.spec.ts
index 546f29173d932..683cefb871518 100644
--- a/packages/vue/src/generators/component/component.spec.ts
+++ b/packages/vue/src/generators/component/component.spec.ts
@@ -29,12 +29,34 @@ describe('component', () => {
unitTestRunner: 'vitest',
});
- expect(
- appTree.read(`${libName}/src/components/hello/hello.vue`, 'utf-8')
- ).toMatchSnapshot();
- expect(
- appTree.read(`${libName}/src/components/hello/hello.spec.ts`, 'utf-8')
- ).toMatchSnapshot();
+ expect(appTree.read(`${libName}/src/lib/hello/hello.vue`, 'utf-8'))
+ .toMatchInlineSnapshot(`
+ "
+
+
+ Welcome to Hello!
+
+
+
+ "
+ `);
+ expect(appTree.read(`${libName}/src/lib/hello/hello.spec.ts`, 'utf-8'))
+ .toMatchInlineSnapshot(`
+ "import { describe, it, expect } from 'vitest';
+
+ import { mount } from '@vue/test-utils';
+ import Hello from './hello.vue';
+
+ describe('Hello', () => {
+ it('renders properly', () => {
+ const wrapper = mount(Hello, {});
+ expect(wrapper.text()).toContain('Welcome to Hello');
+ });
+ });
+ "
+ `);
});
it('should generate files with jest', async () => {
@@ -44,12 +66,32 @@ describe('component', () => {
unitTestRunner: 'jest',
});
- expect(
- appTree.read(`${libName}/src/components/hello/hello.vue`, 'utf-8')
- ).toMatchSnapshot();
- expect(
- appTree.read(`${libName}/src/components/hello/hello.spec.ts`, 'utf-8')
- ).toMatchSnapshot();
+ expect(appTree.read(`${libName}/src/lib/hello/hello.vue`, 'utf-8'))
+ .toMatchInlineSnapshot(`
+ "
+
+
+ Welcome to Hello!
+
+
+
+ "
+ `);
+ expect(appTree.read(`${libName}/src/lib/hello/hello.spec.ts`, 'utf-8'))
+ .toMatchInlineSnapshot(`
+ "import { mount } from '@vue/test-utils';
+ import Hello from './hello.vue';
+
+ describe('Hello', () => {
+ it('renders properly', () => {
+ const wrapper = mount(Hello, {});
+ expect(wrapper.text()).toContain('Welcome to Hello');
+ });
+ });
+ "
+ `);
});
it('should have correct component name based on directory', async () => {
@@ -61,7 +103,10 @@ describe('component', () => {
});
expect(
- appTree.read(`${libName}/src/foo/bar/hello-world.vue`, 'utf-8')
+ appTree.read(
+ `${libName}/src/foo/bar/hello-world/hello-world.vue`,
+ 'utf-8'
+ )
).toContain('HelloWorld');
});
@@ -74,7 +119,10 @@ describe('component', () => {
});
expect(
- appTree.read(`${libName}/src/foo/bar-baz/hello-world.vue`, 'utf-8')
+ appTree.read(
+ `${libName}/src/foo/bar-baz/hello-world/hello-world.vue`,
+ 'utf-8'
+ )
).toContain('HelloWorld');
});
@@ -86,10 +134,10 @@ describe('component', () => {
});
expect(
- appTree.read(`${appName}/src/components/hello/hello.vue`, 'utf-8')
+ appTree.read(`${appName}/src/app/hello/hello.vue`, 'utf-8')
).toContain('Hello');
expect(
- appTree.exists(`${appName}/src/components/hello/hello.spec.ts`)
+ appTree.exists(`${appName}/src/app/hello/hello.spec.ts`)
).toBeTruthy();
});
@@ -100,9 +148,11 @@ describe('component', () => {
project: libName,
export: true,
});
- expect(
- appTree.read(`${libName}/src/index.ts`, 'utf-8')
- ).toMatchSnapshot();
+ expect(appTree.read(`${libName}/src/index.ts`, 'utf-8'))
+ .toMatchInlineSnapshot(`
+ "export { default as Hello } from './lib/hello/hello.vue';
+ "
+ `);
});
it('should not export from an app', async () => {
@@ -112,9 +162,7 @@ describe('component', () => {
export: true,
});
- expect(
- appTree.read(`${appName}/src/index.ts`, 'utf-8')
- ).toMatchSnapshot();
+ expect(appTree.exists(`${appName}/src/index.ts`)).toBe(false);
});
});
@@ -127,10 +175,10 @@ describe('component', () => {
directory: 'foo/bar',
});
expect(
- appTree.read(`${libName}/src/foo/bar/Hello.vue`, 'utf-8')
+ appTree.read(`${libName}/src/foo/bar/hello/Hello.vue`, 'utf-8')
).toContain('Hello');
expect(
- appTree.exists(`${libName}/src/foo/bar/Hello.spec.ts`)
+ appTree.exists(`${libName}/src/foo/bar/hello/Hello.spec.ts`)
).toBeTruthy();
});
});
@@ -144,12 +192,10 @@ describe('component', () => {
pascalCaseDirectory: true,
});
expect(
- appTree.exists(`${libName}/src/components/HelloWorld/HelloWorld.vue`)
+ appTree.exists(`${libName}/src/lib/HelloWorld/HelloWorld.vue`)
).toBeTruthy();
expect(
- appTree.exists(
- `${libName}/src/components/HelloWorld/HelloWorld.spec.ts`
- )
+ appTree.exists(`${libName}/src/lib/HelloWorld/HelloWorld.spec.ts`)
).toBeTruthy();
});
});
@@ -162,7 +208,7 @@ describe('component', () => {
flat: true,
});
- expect(appTree.exists(`${libName}/src/components/hello.vue`));
+ expect(appTree.exists(`${libName}/src/lib/hello.vue`));
});
it('should work with custom directory path', async () => {
await componentGenerator(appTree, {
diff --git a/packages/vue/src/generators/component/component.ts b/packages/vue/src/generators/component/component.ts
index c2ba8210f27fa..5f5cc37aac83a 100644
--- a/packages/vue/src/generators/component/component.ts
+++ b/packages/vue/src/generators/component/component.ts
@@ -1,39 +1,28 @@
-import {
- formatFiles,
- generateFiles,
- GeneratorCallback,
- joinPathFragments,
- runTasksInSerial,
- toJS,
- Tree,
-} from '@nx/devkit';
-import { NormalizedSchema, Schema } from './schema';
+import { formatFiles, generateFiles, toJS, Tree } from '@nx/devkit';
import { join } from 'path';
import { addExportsToBarrel, normalizeOptions } from './lib/utils';
+import { NormalizedSchema, Schema } from './schema';
export async function componentGenerator(host: Tree, schema: Schema) {
+ return componentGeneratorInternal(host, {
+ nameAndDirectoryFormat: 'derived',
+ ...schema,
+ });
+}
+
+export async function componentGeneratorInternal(host: Tree, schema: Schema) {
const options = await normalizeOptions(host, schema);
createComponentFiles(host, options);
-
- const tasks: GeneratorCallback[] = [];
-
addExportsToBarrel(host, options);
if (!options.skipFormat) {
await formatFiles(host);
}
-
- return runTasksInSerial(...tasks);
}
function createComponentFiles(host: Tree, options: NormalizedSchema) {
- const componentDir = joinPathFragments(
- options.projectSourceRoot,
- options.directory
- );
-
- generateFiles(host, join(__dirname, './files'), componentDir, {
+ generateFiles(host, join(__dirname, './files'), options.directory, {
...options,
tmpl: '',
unitTestRunner: options.unitTestRunner,
diff --git a/packages/vue/src/generators/component/lib/utils.ts b/packages/vue/src/generators/component/lib/utils.ts
index 1864103e5fb73..ce1c9407889c1 100644
--- a/packages/vue/src/generators/component/lib/utils.ts
+++ b/packages/vue/src/generators/component/lib/utils.ts
@@ -6,8 +6,11 @@ import {
names,
Tree,
} from '@nx/devkit';
-import { NormalizedSchema, Schema } from '../schema';
+import { parse, relative, dirname } from 'path';
import { ensureTypescript } from '@nx/js/src/utils/typescript/ensure-typescript';
+import { determineArtifactNameAndDirectoryOptions } from '@nx/devkit/src/generators/artifact-name-and-directory-utils';
+
+import { NormalizedSchema, Schema } from '../schema';
import { addImport } from '../../../utils/ast-utils';
let tsModule: typeof import('typescript');
@@ -18,21 +21,31 @@ export async function normalizeOptions(
): Promise {
assertValidOptions(options);
- const { className, fileName } = names(options.name);
- const componentFileName =
- options.fileName ?? (options.pascalCaseFiles ? className : fileName);
- const project = getProjects(host).get(options.project);
-
- if (!project) {
- throw new Error(
- `Cannot find the ${options.project} project. Please double check the project name.`
- );
- }
+ const {
+ artifactName: name,
+ directory,
+ fileName,
+ filePath,
+ project: projectName,
+ } = await determineArtifactNameAndDirectoryOptions(host, {
+ artifactType: 'component',
+ callingGenerator: '@nx/vue:component',
+ name: options.name,
+ directory: options.directory,
+ derivedDirectory: options.directory,
+ flat: options.flat,
+ nameAndDirectoryFormat: options.nameAndDirectoryFormat,
+ project: options.project,
+ fileExtension: 'vue',
+ pascalCaseFile: options.pascalCaseFiles,
+ pascalCaseDirectory: options.pascalCaseDirectory,
+ });
+ let { className } = names(fileName);
+ const componentFileName = fileName;
+ const project = getProjects(host).get(projectName);
const { sourceRoot: projectSourceRoot, projectType } = project;
- const directory = await getDirectory(options);
-
if (options.export && projectType === 'application') {
logger.warn(
`The "--export" option should not be used with applications and will do nothing.`
@@ -44,6 +57,7 @@ export async function normalizeOptions(
return {
...options,
+ filePath,
directory,
className,
fileName: componentFileName,
@@ -71,11 +85,16 @@ export function addExportsToBarrel(host: Tree, options: NormalizedSchema) {
tsModule.ScriptTarget.Latest,
true
);
+
+ const relativePathFromIndex = getRelativeImportToFile(
+ indexFilePath,
+ options.filePath
+ );
const changes = applyChangesToString(
indexSource,
addImport(
indexSourceFile,
- `export { default as ${options.className} } from './${options.directory}/${options.fileName}.vue';`
+ `export { default as ${options.className} } from '${relativePathFromIndex}';`
)
);
host.write(indexFilePath, changes);
@@ -83,12 +102,10 @@ export function addExportsToBarrel(host: Tree, options: NormalizedSchema) {
}
}
-export async function getDirectory(options: Schema) {
- if (options.directory) return options.directory;
- if (options.flat) return 'components';
- const { className, fileName } = names(options.name);
- const nestedDir = options.pascalCaseDirectory === true ? className : fileName;
- return joinPathFragments('components', nestedDir);
+function getRelativeImportToFile(indexPath: string, filePath: string) {
+ const { base, dir } = parse(filePath);
+ const relativeDirToTarget = relative(dirname(indexPath), dir);
+ return `./${joinPathFragments(relativeDirToTarget, base)}`;
}
export function assertValidOptions(options: Schema) {
diff --git a/packages/vue/src/generators/component/schema.d.ts b/packages/vue/src/generators/component/schema.d.ts
index 42cae02cd4f3c..ed24fc3272a96 100644
--- a/packages/vue/src/generators/component/schema.d.ts
+++ b/packages/vue/src/generators/component/schema.d.ts
@@ -1,22 +1,37 @@
export interface Schema {
name: string;
- project: string;
skipTests?: boolean;
directory?: string;
export?: boolean;
- pascalCaseFiles?: boolean;
- pascalCaseDirectory?: boolean;
routing?: boolean;
js?: boolean;
- flat?: boolean;
fileName?: string;
inSourceTests?: boolean;
skipFormat?: boolean;
unitTestRunner?: 'jest' | 'vitest' | 'none';
+ nameAndDirectoryFormat?: 'as-provided' | 'derived';
+
+ /**
+ * @deprecated Provide the `directory` option instead and use the `as-provided` format. It will be removed in Nx v18.
+ */
+ flat?: boolean;
+ /**
+ * @deprecated Provide the desired `directory` option instead and use the `as-provided` format. It will be removed in Nx v18.
+ */
+ pascalCaseDirectory?: boolean;
+ /**
+ * @deprecated Provide the desired `name` option instead and use the `as-provided` format. It will be removed in Nx v18.
+ */
+ pascalCaseFiles?: boolean;
+ /**
+ * @deprecated Provide the `directory` option instead. The project will be determined from the directory provided. It will be removed in Nx v18.
+ */
+ project?: string;
}
export interface NormalizedSchema extends Schema {
projectSourceRoot: string;
fileName: string;
className: string;
+ filePath: string;
}
diff --git a/packages/vue/src/generators/component/schema.json b/packages/vue/src/generators/component/schema.json
index 27a4305b95995..daa4f3cb4de0b 100644
--- a/packages/vue/src/generators/component/schema.json
+++ b/packages/vue/src/generators/component/schema.json
@@ -23,8 +23,7 @@
"$default": {
"$source": "projectName"
},
- "x-prompt": "What is the name of the project for this component?",
- "x-priority": "important"
+ "x-deprecated": "Provide the `directory` option instead and use the `as-provided` format. The project will be determined from the directory provided. It will be removed in Nx v18."
},
"name": {
"type": "string",
@@ -36,6 +35,11 @@
"x-prompt": "What name would you like to use for the component?",
"x-priority": "important"
},
+ "nameAndDirectoryFormat": {
+ "description": "Whether to generate the component in the directory as provided, relative to the current working directory and ignoring the project (`as-provided`) or generate it using the project and directory relative to the workspace root (`derived`).",
+ "type": "string",
+ "enum": ["as-provided", "derived"]
+ },
"js": {
"type": "boolean",
"description": "Generate JavaScript files rather than TypeScript files.",
@@ -49,14 +53,15 @@
},
"directory": {
"type": "string",
- "description": "Create the component under this directory (can be nested).",
+ "description": "The directory at which to create the component file. When `--nameAndDirectoryFormat=as-provided`, it will be relative to the current working directory. Otherwise, it will be relative to the workspace root.",
"alias": "dir",
"x-priority": "important"
},
"flat": {
"type": "boolean",
"description": "Create component at the source root rather than its own directory.",
- "default": false
+ "default": false,
+ "x-deprecated": "Provide the `directory` option instead and use the `as-provided` format. It will be removed in Nx v18."
},
"export": {
"type": "boolean",
@@ -69,13 +74,15 @@
"type": "boolean",
"description": "Use pascal case component file name (e.g. `App.tsx`).",
"alias": "P",
- "default": false
+ "default": false,
+ "x-deprecated": "Provide the desired `name` option instead and use the `as-provided` format. It will be removed in Nx v18."
},
"pascalCaseDirectory": {
"type": "boolean",
"description": "Use pascal case directory name (e.g. `App/App.tsx`).",
"alias": "R",
- "default": false
+ "default": false,
+ "x-deprecated": "Provide the desired `directory` option instead and use the `as-provided` format. It will be removed in Nx v18."
},
"routing": {
"type": "boolean",
@@ -103,5 +110,5 @@
"x-prompt": "What unit test runner should be used?"
}
},
- "required": ["name", "project"]
+ "required": ["name"]
}
diff --git a/packages/vue/src/generators/library/library.spec.ts b/packages/vue/src/generators/library/library.spec.ts
index 2713f20d5e7a8..01d0e0c4df0a7 100644
--- a/packages/vue/src/generators/library/library.spec.ts
+++ b/packages/vue/src/generators/library/library.spec.ts
@@ -162,8 +162,8 @@ describe('lib', () => {
await libraryGenerator(tree, defaultSchema);
expect(tree.exists('my-lib/package.json')).toBeFalsy();
expect(tree.exists('my-lib/src/index.ts')).toBeTruthy();
- expect(tree.exists('my-lib/src/components/my-lib.vue')).toBeTruthy();
- expect(tree.exists('my-lib/src/components/my-lib.spec.ts')).toBeTruthy();
+ expect(tree.exists('my-lib/src/lib/my-lib.vue')).toBeTruthy();
+ expect(tree.exists('my-lib/src/lib/my-lib.spec.ts')).toBeTruthy();
const eslintJson = readJson(tree, 'my-lib/.eslintrc.json');
expect(eslintJson).toMatchSnapshot();
});
@@ -201,10 +201,10 @@ describe('lib', () => {
await libraryGenerator(tree, { ...defaultSchema, directory: 'myDir' });
expect(tree.exists('my-dir/my-lib/src/index.ts')).toBeTruthy();
expect(
- tree.exists('my-dir/my-lib/src/components/my-dir-my-lib.vue')
+ tree.exists('my-dir/my-lib/src/lib/my-dir-my-lib.vue')
).toBeTruthy();
expect(
- tree.exists('my-dir/my-lib/src/components/my-dir-my-lib.spec.ts')
+ tree.exists('my-dir/my-lib/src/lib/my-dir-my-lib.spec.ts')
).toBeTruthy();
});
diff --git a/packages/vue/src/generators/library/library.ts b/packages/vue/src/generators/library/library.ts
index 78a755e37dec1..7e76b6ba22d63 100644
--- a/packages/vue/src/generators/library/library.ts
+++ b/packages/vue/src/generators/library/library.ts
@@ -56,23 +56,20 @@ export async function libraryGenerator(tree: Tree, schema: Schema) {
tasks.push(await addJest(tree, options));
if (options.component) {
- tasks.push(
- await componentGenerator(tree, {
- name: options.name,
- project: options.name,
- flat: true,
- skipTests:
- options.unitTestRunner === 'none' ||
- (options.unitTestRunner === 'vitest' &&
- options.inSourceTests == true),
- export: true,
- routing: options.routing,
- js: options.js,
- pascalCaseFiles: options.pascalCaseFiles,
- inSourceTests: options.inSourceTests,
- skipFormat: true,
- })
- );
+ await componentGenerator(tree, {
+ name: options.name,
+ project: options.name,
+ flat: true,
+ skipTests:
+ options.unitTestRunner === 'none' ||
+ (options.unitTestRunner === 'vitest' && options.inSourceTests == true),
+ export: true,
+ routing: options.routing,
+ js: options.js,
+ pascalCaseFiles: options.pascalCaseFiles,
+ inSourceTests: options.inSourceTests,
+ skipFormat: true,
+ });
}
if (options.publishable || options.bundler !== 'none') {
diff --git a/packages/vue/src/generators/stories/lib/component-story.spec.ts b/packages/vue/src/generators/stories/lib/component-story.spec.ts
index 6e68c1cb07e9d..3d332912ad69d 100644
--- a/packages/vue/src/generators/stories/lib/component-story.spec.ts
+++ b/packages/vue/src/generators/stories/lib/component-story.spec.ts
@@ -6,8 +6,8 @@ import { Linter } from '@nx/eslint';
describe('vue:component-story', () => {
let appTree: Tree;
- let cmpPath = 'test-ui-lib/src/components/test-ui-lib.vue';
- let storyFilePath = 'test-ui-lib/src/components/test-ui-lib.stories.ts';
+ let cmpPath = 'test-ui-lib/src/lib/test-ui-lib.vue';
+ let storyFilePath = 'test-ui-lib/src/lib/test-ui-lib.stories.ts';
describe('default setup', () => {
beforeEach(async () => {
@@ -22,7 +22,7 @@ describe('vue:component-story', () => {
interactionTests: true,
project: 'test-ui-lib',
},
- 'components/test-ui-lib.vue'
+ 'lib/test-ui-lib.vue'
);
});
@@ -58,7 +58,7 @@ describe('vue:component-story', () => {
interactionTests: true,
project: 'test-ui-lib',
},
- 'components/test-ui-lib.vue'
+ 'lib/test-ui-lib.vue'
);
});
@@ -97,7 +97,7 @@ describe('vue:component-story', () => {
interactionTests: true,
project: 'test-ui-lib',
},
- 'components/test-ui-lib.vue'
+ 'lib/test-ui-lib.vue'
);
});
diff --git a/packages/vue/src/generators/stories/stories.app.spec.ts b/packages/vue/src/generators/stories/stories.app.spec.ts
index dded11aaa60fd..cead472d3001c 100644
--- a/packages/vue/src/generators/stories/stories.app.spec.ts
+++ b/packages/vue/src/generators/stories/stories.app.spec.ts
@@ -28,7 +28,7 @@ describe('vue:stories for applications', () => {
// create another component
appTree.write(
- 'test-ui-app/src/components/another-cmp/another-cmp.vue',
+ 'test-ui-app/src/app/another-cmp/another-cmp.vue',
componentContent
);
});
@@ -43,7 +43,7 @@ describe('vue:stories for applications', () => {
).toMatchSnapshot();
expect(
appTree.read(
- 'test-ui-app/src/components/another-cmp/another-cmp.stories.ts',
+ 'test-ui-app/src/app/another-cmp/another-cmp.stories.ts',
'utf-8'
)
).toMatchSnapshot();
@@ -60,7 +60,7 @@ describe('vue:stories for applications', () => {
).toMatchSnapshot();
expect(
appTree.read(
- 'test-ui-app/src/components/another-cmp/another-cmp.stories.ts',
+ 'test-ui-app/src/app/another-cmp/another-cmp.stories.ts',
'utf-8'
)
).toMatchSnapshot();
@@ -84,12 +84,12 @@ describe('vue:stories for applications', () => {
describe('ignore paths', () => {
beforeEach(() => {
appTree.write(
- 'test-ui-app/src/components/test-path/ignore-it/another-one.vue',
+ 'test-ui-app/src/app/test-path/ignore-it/another-one.vue',
componentContent
);
appTree.write(
- 'test-ui-app/src/components/another-cmp/another-cmp-test.skip.vue',
+ 'test-ui-app/src/app/another-cmp/another-cmp-test.skip.vue',
componentContent
);
});
@@ -102,20 +102,18 @@ describe('vue:stories for applications', () => {
appTree.exists('test-ui-app/src/app/NxWelcome.stories.ts')
).toBeTruthy();
expect(
- appTree.exists(
- 'test-ui-app/src/components/another-cmp/another-cmp.stories.ts'
- )
+ appTree.exists('test-ui-app/src/app/another-cmp/another-cmp.stories.ts')
).toBeTruthy();
expect(
appTree.exists(
- 'test-ui-app/src/components/test-path/ignore-it/another-one.stories.ts'
+ 'test-ui-app/src/app/test-path/ignore-it/another-one.stories.ts'
)
).toBeTruthy();
expect(
appTree.exists(
- 'test-ui-app/src/components/another-cmp/another-cmp-test.skip.stories.ts'
+ 'test-ui-app/src/app/another-cmp/another-cmp-test.skip.stories.ts'
)
).toBeTruthy();
});
@@ -124,7 +122,7 @@ describe('vue:stories for applications', () => {
await storiesGenerator(appTree, {
project: 'test-ui-app',
ignorePaths: [
- `test-ui-app/src/components/another-cmp/**`,
+ `test-ui-app/src/app/another-cmp/**`,
`**/**/src/**/test-path/ignore-it/**`,
],
});
@@ -133,20 +131,18 @@ describe('vue:stories for applications', () => {
appTree.exists('test-ui-app/src/app/NxWelcome.stories.ts')
).toBeTruthy();
expect(
- appTree.exists(
- 'test-ui-app/src/components/another-cmp/another-cmp.stories.ts'
- )
+ appTree.exists('test-ui-app/src/app/another-cmp/another-cmp.stories.ts')
).toBeFalsy();
expect(
appTree.exists(
- 'test-ui-app/src/components/test-path/ignore-it/another-one.stories.ts'
+ 'test-ui-app/src/app/test-path/ignore-it/another-one.stories.ts'
)
).toBeFalsy();
expect(
appTree.exists(
- 'test-ui-app/src/components/another-cmp/another-cmp-test.skip.stories.ts'
+ 'test-ui-app/src/app/another-cmp/another-cmp-test.skip.stories.ts'
)
).toBeFalsy();
});
@@ -155,7 +151,7 @@ describe('vue:stories for applications', () => {
await storiesGenerator(appTree, {
project: 'test-ui-app',
ignorePaths: [
- 'test-ui-app/src/components/another-cmp/**/*.skip.*',
+ 'test-ui-app/src/app/another-cmp/**/*.skip.*',
'**/**/src/**/test-path/**',
],
});
@@ -164,20 +160,18 @@ describe('vue:stories for applications', () => {
appTree.exists('test-ui-app/src/app/NxWelcome.stories.ts')
).toBeTruthy();
expect(
- appTree.exists(
- 'test-ui-app/src/components/another-cmp/another-cmp.stories.ts'
- )
+ appTree.exists('test-ui-app/src/app/another-cmp/another-cmp.stories.ts')
).toBeTruthy();
expect(
appTree.exists(
- 'test-ui-app/src/components/test-path/ignore-it/another-one.stories.ts'
+ 'test-ui-app/src/app/test-path/ignore-it/another-one.stories.ts'
)
).toBeFalsy();
expect(
appTree.exists(
- 'test-ui-app/src/components/another-cmp/another-cmp-test.skip.stories.ts'
+ 'test-ui-app/src/app/another-cmp/another-cmp-test.skip.stories.ts'
)
).toBeFalsy();
});
@@ -185,41 +179,39 @@ describe('vue:stories for applications', () => {
it('should ignore direct path to component', async () => {
await storiesGenerator(appTree, {
project: 'test-ui-app',
- ignorePaths: ['test-ui-app/src/components/another-cmp/**/*.skip.vue'],
+ ignorePaths: ['test-ui-app/src/app/another-cmp/**/*.skip.vue'],
});
expect(
appTree.exists('test-ui-app/src/app/NxWelcome.stories.ts')
).toBeTruthy();
expect(
- appTree.exists(
- 'test-ui-app/src/components/another-cmp/another-cmp.stories.ts'
- )
+ appTree.exists('test-ui-app/src/app/another-cmp/another-cmp.stories.ts')
).toBeTruthy();
expect(
appTree.exists(
- 'test-ui-app/src/components/test-path/ignore-it/another-one.stories.ts'
+ 'test-ui-app/src/app/test-path/ignore-it/another-one.stories.ts'
)
).toBeTruthy();
expect(
appTree.exists(
- 'test-ui-app/src/components/another-cmp/another-cmp-test.skip.stories.ts'
+ 'test-ui-app/src/app/another-cmp/another-cmp-test.skip.stories.ts'
)
).toBeFalsy();
});
it('should ignore a path that has a nested component, but still generate nested component stories', async () => {
appTree.write(
- 'test-ui-app/src/components/another-cmp/comp-a/comp-a.vue',
+ 'test-ui-app/src/app/another-cmp/comp-a/comp-a.vue',
componentContent
);
await storiesGenerator(appTree, {
project: 'test-ui-app',
ignorePaths: [
- 'test-ui-app/src/components/another-cmp/another-cmp-test.skip.vue',
+ 'test-ui-app/src/app/another-cmp/another-cmp-test.skip.vue',
],
});
@@ -227,20 +219,18 @@ describe('vue:stories for applications', () => {
appTree.exists('test-ui-app/src/app/NxWelcome.stories.ts')
).toBeTruthy();
expect(
- appTree.exists(
- 'test-ui-app/src/components/another-cmp/another-cmp.stories.ts'
- )
+ appTree.exists('test-ui-app/src/app/another-cmp/another-cmp.stories.ts')
).toBeTruthy();
expect(
appTree.exists(
- 'test-ui-app/src/components/another-cmp/comp-a/comp-a.stories.ts'
+ 'test-ui-app/src/app/another-cmp/comp-a/comp-a.stories.ts'
)
).toBeTruthy();
expect(
appTree.exists(
- 'test-ui-app/src/components/another-cmp/another-cmp-test.skip.stories.ts'
+ 'test-ui-app/src/app/another-cmp/another-cmp-test.skip.stories.ts'
)
).toBeFalsy();
});
diff --git a/packages/vue/src/generators/stories/stories.lib.spec.ts b/packages/vue/src/generators/stories/stories.lib.spec.ts
index 55cf9a5ac02f9..99960d0ca3d53 100644
--- a/packages/vue/src/generators/stories/stories.lib.spec.ts
+++ b/packages/vue/src/generators/stories/stories.lib.spec.ts
@@ -26,7 +26,7 @@ describe('vue:stories for libraries', () => {
beforeEach(async () => {
appTree = await createTestUILib('test-ui-lib');
appTree.write(
- 'test-ui-lib/src/components/another-cmp/another-cmp.vue',
+ 'test-ui-lib/src/lib/another-cmp/another-cmp.vue',
componentContent
);
});
@@ -37,11 +37,11 @@ describe('vue:stories for libraries', () => {
});
expect(
- appTree.read('test-ui-lib/src/components/test-ui-lib.stories.ts', 'utf-8')
+ appTree.read('test-ui-lib/src/lib/test-ui-lib.stories.ts', 'utf-8')
).toMatchSnapshot();
expect(
appTree.read(
- 'test-ui-lib/src/components/another-cmp/another-cmp.stories.ts',
+ 'test-ui-lib/src/lib/another-cmp/another-cmp.stories.ts',
'utf-8'
)
).toMatchSnapshot();
@@ -62,11 +62,11 @@ describe('vue:stories for libraries', () => {
interactionTests: false,
});
expect(
- appTree.read('test-ui-lib/src/components/test-ui-lib.stories.ts', 'utf-8')
+ appTree.read('test-ui-lib/src/lib/test-ui-lib.stories.ts', 'utf-8')
).toMatchSnapshot();
expect(
appTree.read(
- 'test-ui-lib/src/components/another-cmp/another-cmp.stories.ts',
+ 'test-ui-lib/src/lib/another-cmp/another-cmp.stories.ts',
'utf-8'
)
).toMatchSnapshot();
@@ -85,12 +85,12 @@ describe('vue:stories for libraries', () => {
describe('ignore paths', () => {
beforeEach(() => {
appTree.write(
- 'test-ui-lib/src/components/test-path/ignore-it/another-one.vue',
+ 'test-ui-lib/src/lib/test-path/ignore-it/another-one.vue',
componentContent
);
appTree.write(
- 'test-ui-lib/src/components/another-cmp/another-cmp.skip.vue',
+ 'test-ui-lib/src/lib/another-cmp/another-cmp.skip.vue',
componentContent
);
});
@@ -100,20 +100,18 @@ describe('vue:stories for libraries', () => {
});
expect(
- appTree.exists(
- 'test-ui-lib/src/components/another-cmp/another-cmp.stories.ts'
- )
+ appTree.exists('test-ui-lib/src/lib/another-cmp/another-cmp.stories.ts')
).toBeTruthy();
expect(
appTree.exists(
- 'test-ui-lib/src/components/test-path/ignore-it/another-one.stories.ts'
+ 'test-ui-lib/src/lib/test-path/ignore-it/another-one.stories.ts'
)
).toBeTruthy();
expect(
appTree.exists(
- 'test-ui-lib/src/components/another-cmp/another-cmp.skip.stories.ts'
+ 'test-ui-lib/src/lib/another-cmp/another-cmp.skip.stories.ts'
)
).toBeTruthy();
});
@@ -122,26 +120,24 @@ describe('vue:stories for libraries', () => {
await storiesGenerator(appTree, {
project: 'test-ui-lib',
ignorePaths: [
- 'test-ui-lib/src/components/another-cmp/**',
+ 'test-ui-lib/src/lib/another-cmp/**',
'**/**/src/**/test-path/ignore-it/**',
],
});
expect(
- appTree.exists(
- 'test-ui-lib/src/components/another-cmp/another-cmp.stories.ts'
- )
+ appTree.exists('test-ui-lib/src/lib/another-cmp/another-cmp.stories.ts')
).toBeFalsy();
expect(
appTree.exists(
- 'test-ui-lib/src/components/test-path/ignore-it/another-one.stories.ts'
+ 'test-ui-lib/src/lib/test-path/ignore-it/another-one.stories.ts'
)
).toBeFalsy();
expect(
appTree.exists(
- 'test-ui-lib/src/components/another-cmp/another-cmp.skip.stories.ts'
+ 'test-ui-lib/src/lib/another-cmp/another-cmp.skip.stories.ts'
)
).toBeFalsy();
});
@@ -150,26 +146,24 @@ describe('vue:stories for libraries', () => {
await storiesGenerator(appTree, {
project: 'test-ui-lib',
ignorePaths: [
- 'test-ui-lib/src/components/another-cmp/**/*.skip.*',
+ 'test-ui-lib/src/lib/another-cmp/**/*.skip.*',
'**/test-ui-lib/src/**/test-path/**',
],
});
expect(
- appTree.exists(
- 'test-ui-lib/src/components/another-cmp/another-cmp.stories.ts'
- )
+ appTree.exists('test-ui-lib/src/lib/another-cmp/another-cmp.stories.ts')
).toBeTruthy();
expect(
appTree.exists(
- 'test-ui-lib/src/components/test-path/ignore-it/another-one.stories.ts'
+ 'test-ui-lib/src/lib/test-path/ignore-it/another-one.stories.ts'
)
).toBeFalsy();
expect(
appTree.exists(
- 'test-ui-lib/src/components/another-cmp/another-cmp.skip.stories.ts'
+ 'test-ui-lib/src/lib/another-cmp/another-cmp.skip.stories.ts'
)
).toBeFalsy();
});
diff --git a/packages/vue/src/generators/stories/stories.ts b/packages/vue/src/generators/stories/stories.ts
index c9bb3149c8609..97132d1557e08 100644
--- a/packages/vue/src/generators/stories/stories.ts
+++ b/packages/vue/src/generators/stories/stories.ts
@@ -37,7 +37,8 @@ export async function createAllStories(
let componentPaths: string[] = [];
const pathsToCheck = [
joinPathFragments(sourceRoot, 'app'), // Default component folder for apps
- joinPathFragments(sourceRoot, 'components'), // Additional component folder
+ joinPathFragments(sourceRoot, 'lib'), // Default component folder for libs
+ joinPathFragments(sourceRoot, 'components'), // Additional component folder used by Nuxt
];
for (const p of pathsToCheck) {
diff --git a/packages/vue/src/generators/storybook-configuration/configuration.spec.ts b/packages/vue/src/generators/storybook-configuration/configuration.spec.ts
index a01eb66673b06..06585122157db 100644
--- a/packages/vue/src/generators/storybook-configuration/configuration.spec.ts
+++ b/packages/vue/src/generators/storybook-configuration/configuration.spec.ts
@@ -67,7 +67,7 @@ describe('vue:storybook-configuration', () => {
it('should generate stories for components', async () => {
appTree = await createTestUILib('test-ui-lib');
appTree.write(
- 'test-ui-lib/src/components/my-component/my-component.vue',
+ 'test-ui-lib/src/lib/my-component/my-component.vue',
componentContent
);
@@ -77,11 +77,11 @@ describe('vue:storybook-configuration', () => {
});
expect(
- appTree.exists('test-ui-lib/src/components/test-ui-lib.stories.ts')
+ appTree.exists('test-ui-lib/src/lib/test-ui-lib.stories.ts')
).toBeTruthy();
expect(
appTree.read(
- 'test-ui-lib/src/components/my-component/my-component.stories.ts',
+ 'test-ui-lib/src/lib/my-component/my-component.stories.ts',
'utf-8'
)
).toMatchSnapshot();
@@ -100,7 +100,7 @@ describe('vue:storybook-configuration', () => {
it('should generate stories for components for app', async () => {
appTree = await createTestAppLib('test-ui-app');
appTree.write(
- 'test-ui-app/src/components/my-component/my-component.vue',
+ 'test-ui-app/src/app/my-component/my-component.vue',
componentContent
);
await storybookConfigurationGenerator(appTree, {
@@ -110,7 +110,7 @@ describe('vue:storybook-configuration', () => {
expect(
appTree.read(
- 'test-ui-app/src/components/my-component/my-component.stories.ts',
+ 'test-ui-app/src/app/my-component/my-component.stories.ts',
'utf-8'
)
).toMatchSnapshot();
@@ -119,7 +119,7 @@ describe('vue:storybook-configuration', () => {
it('should generate stories for components without interaction tests', async () => {
appTree = await createTestAppLib('test-ui-app');
appTree.write(
- 'test-ui-app/src/components/my-component/my-component.vue',
+ 'test-ui-app/src/app/my-component/my-component.vue',
componentContent
);
await storybookConfigurationGenerator(appTree, {
@@ -130,7 +130,7 @@ describe('vue:storybook-configuration', () => {
expect(
appTree.read(
- 'test-ui-app/src/components/my-component/my-component.stories.ts',
+ 'test-ui-app/src/app/my-component/my-component.stories.ts',
'utf-8'
)
).toMatchSnapshot();