Skip to content

Commit 635947f

Browse files
NickersWebNick W
and
Nick W
authored
Feature/ticket 1159 nxext stencil vue integration (#1160)
feat(stencil): Add Vue as a OutputTarget framework * #1159 package.json including @nx/vue for stencil vue integration * #1159 versions.ts STENCIL_OUTPUTTARGET_VERSION including vue * #1159 fetch-latest-versions.ts including @stencil/vue-output-target * #1159 add-outputtarget/add-vue generator.ts for vue * #1159 schema.d.ts and schema.json OutputTargetType including vue * #1159 .github ISSUE_TEMPLATE - including Vue * #1159 add-outputtarget.ts outputtargetGenerator extend with addVueGenerator, including related tests * #1159 generators.md mention vue in @nxext/stencil:add-outputtarget section, likewise for outputType * #1159 e2e stencil e2e library.test.ts - include test 'should generate vue lib' * #1159 README.md mention vue as part of stencil integration * #1159 pnpm format code * #1159 generators.md outputType format * #1159 generators.md and json for stencil outputtarget * #1159 generators.md stencil output target; including vue * #1159 stencil project.json include e2e * #1159 stencil add-outputtarget-react.spec.ts remove xdescribe to describe to not skip test * #1159 stencil add-outputtarget-vue.spec.ts remove xdescribe to describe to not skip test * #1159 stencil project.json ran pnpm format --------- Co-authored-by: Nick W <[email protected]>
1 parent f567156 commit 635947f

20 files changed

+284
-22
lines changed

.github/ISSUE_TEMPLATE/bug_report.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
name: '🐞 Bug Report'
33
about: Create a report to help us improve
4-
title: 'Stencil | Svelte | Sveltekit | Solid | Vite | Vitest | React | Angular: <your title>'
4+
title: 'Stencil | Svelte | Sveltekit | Solid | Vite | Vitest | Vue | React | Angular: <your title>'
55
labels: bug
66
assignees: ''
77
---

.github/ISSUE_TEMPLATE/documentation.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
name: '📄 Documentation'
33
about: Suggest an idea for the docs
4-
title: 'Stencil | Svelte | Sveltekit | Solid | Vite | Vitest | React | Angular: <your title>'
4+
title: 'Stencil | Svelte | Sveltekit | Solid | Vite | Vitest | Vue | React | Angular: <your title>'
55
labels: documentation
66
assignees: ''
77
---

.github/ISSUE_TEMPLATE/feature_request.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
name: "\U0001F680 Feature Request"
33
about: Suggest an idea for this project
4-
title: 'Stencil | Svelte | Sveltekit | Solid | Vite | Vitest | React | Angular: <your title>'
4+
title: 'Stencil | Svelte | Sveltekit | Solid | Vite | Vitest | Vue | React | Angular: <your title>'
55
labels: feature request
66
assignees: ''
77
---

.github/ISSUE_TEMPLATE/guides.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
name: '⚙️ Guides'
33
about: Suggest an idea for the guides
4-
title: 'Stencil | Svelte | Sveltekit | Solid | Vite | Vitest | React | Angular: <your title>'
4+
title: 'Stencil | Svelte | Sveltekit | Solid | Vite | Vitest | Vue | React | Angular: <your title>'
55
labels: guides
66
assignees: ''
77
---

docs/docs/stencil/generators.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ Type: `boolean`
286286

287287
## @nxext/stencil:add-outputtarget
288288

289-
Add react/angular libraries for the component library
289+
Add react/angular/vue libraries for the component library
290290

291291
### Usage
292292

@@ -314,7 +314,7 @@ nx g add-outputtarget ... --dry-run
314314

315315
Type: `string`
316316

317-
Possible values: `angular`, `react`, `svelte`
317+
Possible values: `angular`, `react`, `svelte`, `vue`
318318

319319
Select what kind of library you want to generate.
320320

e2e/stencil-e2e/tests/library.test.ts

+15
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,21 @@ describe('library e2e', () => {
120120
).not.toThrow();
121121
});
122122

123+
it(`should generate vue lib`, async () => {
124+
const plugin = uniq('lib');
125+
await runNxCommandAsync(
126+
`generate @nxext/stencil:lib ${plugin} --style='css' --buildable --e2eTestRunner='none' --junitTestRunner='none'`
127+
);
128+
await runNxCommandAsync(
129+
`generate @nxext/stencil:add-outputtarget ${plugin} --outputType=vue`
130+
);
131+
await runNxCommandAsync(`build ${plugin}`);
132+
133+
expect(() =>
134+
checkFilesExist(`libs/${plugin}-vue/src/index.ts`)
135+
).not.toThrow();
136+
});
137+
123138
it(`should generate angular lib`, async () => {
124139
const plugin = uniq('lib');
125140
await runNxCommandAsync(

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
"@nx/playwright": "20.0.0",
6363
"@nx/plugin": "20.0.0",
6464
"@nx/react": "20.0.0",
65+
"@nx/vue": "20.0.0",
6566
"@nx/storybook": "20.0.0",
6667
"@nx/vite": "20.0.0",
6768
"@nx/web": "20.0.0",

packages/stencil/README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -148,12 +148,12 @@ nx storybook my-lib
148148

149149
_The Storybook startup needs an successful `nx build` cause of the generated loaders to work_
150150

151-
## React and Angular
151+
## React, Angular and Vue
152152

153-
You're able to generate angular/react libraries for yout stencil libraries using stencils outputtargets:
153+
You're able to generate angular/react/vue libraries for yout stencil libraries using stencils outputtargets:
154154

155155
```
156156
nx g @nxext/stencil:add-outputtarget my-lib
157157
```
158158

159-
With the `--outputType='react'` or `--outputType='angular'` you can define the kind of library.
159+
With the `--outputType='react'` or `--outputType='angular'` or `--outputType='vue'` you can define the kind of library.

packages/stencil/generators.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"add-outputtarget": {
3131
"factory": "./src/generators/add-outputtarget/add-outputtarget",
3232
"schema": "./src/generators/add-outputtarget/schema.json",
33-
"description": "Add react/angular libraries for the component library"
33+
"description": "Add react/angular/vue libraries for the component library"
3434
},
3535
"add-outputtarget/add-angular": {
3636
"factory": "./src/generators/add-outputtarget/add-angular/generator",

packages/stencil/package.json

+5-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@
4242
"nx": "^20.0.0",
4343
"fs-extra": "^10.1.0",
4444
"@nx/angular": "^20.0.0",
45-
"@nx/react": "^20.0.0"
45+
"@nx/react": "^20.0.0",
46+
"@nx/vue": "^20.0.0"
4647
},
4748
"peerDependencies": {},
4849
"peerDependenciesMeta": {
@@ -55,6 +56,9 @@
5556
"@nx/react": {
5657
"optional": true
5758
},
59+
"@nx/vue": {
60+
"optional": true
61+
},
5862
"@nx/angular": {
5963
"optional": true
6064
},

packages/stencil/project.json

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
},
1616
"outputs": ["{workspaceRoot}/coverage/packages/stencil"]
1717
},
18+
"e2e": {},
1819
"build": {
1920
"executor": "@nx/js:tsc",
2021
"options": {

packages/stencil/src/generators/add-outputtarget/add-outputtarget-react.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Tree } from '@nx/devkit';
44
import { outputtargetGenerator } from './add-outputtarget';
55
import { AddOutputtargetSchematicSchema } from './schema';
66

7-
xdescribe('add-outputtarget react', () => {
7+
describe('add-outputtarget react', () => {
88
let tree: Tree;
99
const projectName = uniq('testprojekt');
1010
const projectAppDirectory = `apps/${projectName}`;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import { createTestUILib } from '../../utils/testing';
2+
import { uniq } from '@nx/plugin/testing';
3+
import { Tree } from '@nx/devkit';
4+
import { outputtargetGenerator } from './add-outputtarget';
5+
import { AddOutputtargetSchematicSchema } from './schema';
6+
7+
describe('add-outputtarget vue', () => {
8+
let tree: Tree;
9+
const projectName = uniq('testprojekt');
10+
const projectAppDirectory = `apps/${projectName}`;
11+
const projectLibDirectory = `libs/${projectName}`;
12+
const options = {
13+
projectName: projectName,
14+
publishable: false,
15+
skipFormat: false,
16+
};
17+
18+
beforeEach(async () => {
19+
tree = await createTestUILib(projectLibDirectory);
20+
});
21+
22+
describe('using vue', () => {
23+
const vueOptions: AddOutputtargetSchematicSchema = {
24+
...options,
25+
unitTestRunner: 'none',
26+
outputType: 'vue',
27+
};
28+
29+
it('should not generate default vue library', async () => {
30+
await outputtargetGenerator(tree, vueOptions);
31+
32+
expect(
33+
tree.exists(`libs/${projectName}-vue/src/lib/${projectName}-vue.tsx`)
34+
).toBeFalsy();
35+
expect(
36+
tree.exists(
37+
`libs/${projectName}-vue/src/lib/${projectName}-vue.spec.tsx`
38+
)
39+
).toBeFalsy();
40+
expect(
41+
tree.exists(`libs/${projectName}-vue/src/lib/${projectName}-vue.css`)
42+
).toBeFalsy();
43+
44+
const indexFile: Buffer = tree.read(
45+
`libs/${projectName}-vue/src/index.ts`
46+
);
47+
expect(indexFile.toString()).toMatch(
48+
`export * from './generated/components';`
49+
);
50+
});
51+
52+
it('should add vueOutputTarget', async () => {
53+
await outputtargetGenerator(tree, vueOptions);
54+
55+
expect(
56+
tree
57+
.read(`libs/${projectName}/stencil.config.ts`)
58+
.includes(
59+
`import { vueOutputTarget } from '@stencil/vue-output-target';`
60+
)
61+
).toBeTruthy();
62+
63+
expect(
64+
tree
65+
.read(`libs/${projectName}/stencil.config.ts`)
66+
.includes(`vueOutputTarget({`)
67+
).toBeTruthy();
68+
});
69+
70+
it('should be able to generate a publishable lib', async () => {
71+
await outputtargetGenerator(tree, {
72+
...vueOptions,
73+
publishable: true,
74+
importPath: '@proj/mylib',
75+
});
76+
77+
expect(tree.exists(`libs/${projectName}/package.json`)).toBeTruthy();
78+
});
79+
});
80+
});

packages/stencil/src/generators/add-outputtarget/add-outputtarget.ts

+5
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { isBuildableStencilProject } from '../../utils/utillities';
1010
import { AddOutputtargetSchematicSchema } from './schema';
1111
import { addAngularGenerator } from './add-angular/generator';
1212
import { addReactGenerator } from './add-react/generator';
13+
import addVueGenerator from './add-vue/generator';
1314
import { assertNotUsingTsSolutionSetup } from '@nx/js/src/utils/typescript/ts-solution-setup';
1415

1516
export async function outputtargetGenerator(
@@ -30,6 +31,10 @@ export async function outputtargetGenerator(
3031
tasks.push(await addReactGenerator(host, options));
3132
}
3233

34+
if (options.outputType === 'vue') {
35+
tasks.push(await addVueGenerator(host, options));
36+
}
37+
3338
if (!options.skipFormat) {
3439
await formatFiles(host);
3540
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import {
2+
addDependenciesToPackageJson,
3+
applyChangesToString,
4+
ensurePackage,
5+
getWorkspaceLayout,
6+
NX_VERSION,
7+
readProjectConfiguration,
8+
runTasksInSerial,
9+
Tree,
10+
} from '@nx/devkit';
11+
import { initGenerator as jsInitGenerator } from '@nx/js';
12+
import { AddOutputtargetSchematicSchema } from '../schema';
13+
import { Linter } from '@nx/eslint';
14+
import { STENCIL_OUTPUTTARGET_VERSION } from '../../../utils/versions';
15+
import * as ts from 'typescript';
16+
import { getDistDir, getRelativePath } from '../../../utils/fileutils';
17+
import { addImport } from '@nxext/common';
18+
import { addOutputTarget } from '../../../stencil-core-utils';
19+
import { calculateStencilSourceOptions } from '../lib/calculate-stencil-source-options';
20+
21+
async function prepareVueLibrary(
22+
host: Tree,
23+
options: AddOutputtargetSchematicSchema
24+
) {
25+
const { libsDir } = getWorkspaceLayout(host);
26+
const vueProjectName = `${options.projectName}-vue`;
27+
const vueProjectDir = `libs/${vueProjectName}`;
28+
29+
const jsInitTask = await jsInitGenerator(host, {
30+
...options,
31+
tsConfigName: 'tsconfig.base.json',
32+
skipFormat: true,
33+
});
34+
35+
ensurePackage('@nx/vue', NX_VERSION);
36+
const { libraryGenerator } = await import('@nx/vue');
37+
const libraryTarget = await libraryGenerator(host, {
38+
directory: vueProjectDir,
39+
publishable: options.publishable,
40+
bundler: options.publishable ? 'vite' : 'none',
41+
importPath: options.importPath,
42+
component: false,
43+
skipTsConfig: false,
44+
skipFormat: true,
45+
unitTestRunner: 'vitest',
46+
linter: Linter.EsLint,
47+
});
48+
49+
await addDependenciesToPackageJson(
50+
host,
51+
{},
52+
{
53+
'@stencil/vue-output-target': STENCIL_OUTPUTTARGET_VERSION['vue'],
54+
}
55+
);
56+
57+
host.write(
58+
`${libsDir}/${vueProjectName}/src/index.ts`,
59+
`export * from './generated/components';`
60+
);
61+
62+
return runTasksInSerial(jsInitTask, libraryTarget);
63+
}
64+
65+
function addVueOutputtarget(
66+
tree: Tree,
67+
projectName: string,
68+
stencilProjectConfig,
69+
stencilConfigPath: string,
70+
stencilConfigSource: ts.SourceFile,
71+
packageName: string
72+
) {
73+
const vueProjectConfig = readProjectConfiguration(tree, `${projectName}-vue`);
74+
const realtivePath = getRelativePath(
75+
getDistDir(stencilProjectConfig.root),
76+
vueProjectConfig.root
77+
);
78+
79+
const changes = applyChangesToString(stencilConfigSource.text, [
80+
...addImport(
81+
stencilConfigSource,
82+
`import { vueOutputTarget } from '@stencil/vue-output-target';`
83+
),
84+
...addOutputTarget(
85+
stencilConfigSource,
86+
`
87+
vueOutputTarget({
88+
componentCorePackage: '${packageName}',
89+
proxiesFile: '${realtivePath}/src/generated/components.ts',
90+
includeDefineCustomElements: true,
91+
})
92+
`
93+
),
94+
]);
95+
tree.write(stencilConfigPath, changes);
96+
}
97+
98+
export async function addVueGenerator(
99+
host: Tree,
100+
options: AddOutputtargetSchematicSchema
101+
) {
102+
const libraryTarget = await prepareVueLibrary(host, options);
103+
104+
const {
105+
stencilProjectConfig,
106+
stencilConfigPath,
107+
stencilConfigSource,
108+
packageName,
109+
} = calculateStencilSourceOptions(host, options.projectName);
110+
111+
addVueOutputtarget(
112+
host,
113+
options.projectName,
114+
stencilProjectConfig,
115+
stencilConfigPath,
116+
stencilConfigSource,
117+
packageName
118+
);
119+
120+
return libraryTarget;
121+
}
122+
123+
export default addVueGenerator;

packages/stencil/src/generators/add-outputtarget/schema.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { OutputTargetType } from './lib/add-outputtarget-to-config';
22

3-
export type OutputTargetType = 'angular' | 'react' | 'vue' | 'svelte';
3+
export type OutputTargetType = 'angular' | 'react' | 'svelte' | 'vue';
44

55
export interface AddOutputtargetSchematicSchema {
66
projectName: string;

packages/stencil/src/generators/add-outputtarget/schema.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
},
1616
"outputType": {
1717
"type": "string",
18-
"enum": ["angular", "react", "svelte"],
18+
"enum": ["angular", "react", "svelte", "vue"],
1919
"description": "Select what kind of library you want to generate.",
2020
"x-prompt": "Which framework do you use?"
2121
},

packages/stencil/src/utils/versions.ts

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export const ESLINT_PLUGIN_VERSIONS = {
1515
export const STENCIL_OUTPUTTARGET_VERSION = {
1616
react: '^0.5.3',
1717
angular: '^0.8.3',
18+
vue: '^0.9.0',
1819
};
1920

2021
export const STENCIL_STYLE_PLUGIN_VERSION = {

0 commit comments

Comments
 (0)