From a8f0c0e69c25efcf6da68e49d887994a4c297384 Mon Sep 17 00:00:00 2001 From: neverland Date: Sat, 8 Aug 2026 15:05:39 +0800 Subject: [PATCH] feat(create-rstack): add Vue library templates --- packages/create-rstack/README.md | 2 + packages/create-rstack/src/index.ts | 3 ++ .../template-lib-vue-js/AGENTS.md | 14 +++++++ .../template-lib-vue-js/README.md | 40 ++++++++++++++++++ .../template-lib-vue-js/package.json | 37 ++++++++++++++++ .../template-lib-vue-js/rstack.config.js | 30 +++++++++++++ .../template-lib-vue-js/src/Button.vue | 41 ++++++++++++++++++ .../template-lib-vue-js/src/button.css | 34 +++++++++++++++ .../template-lib-vue-js/src/index.js | 1 + .../template-lib-vue-js/tests/index.test.js | 16 +++++++ .../template-lib-vue-js/tests/rstest.setup.js | 4 ++ .../template-lib-vue-ts/AGENTS.md | 14 +++++++ .../template-lib-vue-ts/README.md | 40 ++++++++++++++++++ .../template-lib-vue-ts/package.json | 42 +++++++++++++++++++ .../template-lib-vue-ts/rstack.config.ts | 29 +++++++++++++ .../template-lib-vue-ts/src/Button.vue | 33 +++++++++++++++ .../template-lib-vue-ts/src/button.css | 34 +++++++++++++++ .../template-lib-vue-ts/src/index.ts | 1 + .../template-lib-vue-ts/tests/index.test.ts | 16 +++++++ .../template-lib-vue-ts/tests/rstest.setup.ts | 4 ++ .../template-lib-vue-ts/tests/tsconfig.json | 8 ++++ .../template-lib-vue-ts/tsconfig.json | 27 ++++++++++++ packages/create-rstack/tests/create.test.ts | 12 ++++++ 23 files changed, 482 insertions(+) create mode 100644 packages/create-rstack/template-lib-vue-js/AGENTS.md create mode 100644 packages/create-rstack/template-lib-vue-js/README.md create mode 100644 packages/create-rstack/template-lib-vue-js/package.json create mode 100644 packages/create-rstack/template-lib-vue-js/rstack.config.js create mode 100644 packages/create-rstack/template-lib-vue-js/src/Button.vue create mode 100644 packages/create-rstack/template-lib-vue-js/src/button.css create mode 100644 packages/create-rstack/template-lib-vue-js/src/index.js create mode 100644 packages/create-rstack/template-lib-vue-js/tests/index.test.js create mode 100644 packages/create-rstack/template-lib-vue-js/tests/rstest.setup.js create mode 100644 packages/create-rstack/template-lib-vue-ts/AGENTS.md create mode 100644 packages/create-rstack/template-lib-vue-ts/README.md create mode 100644 packages/create-rstack/template-lib-vue-ts/package.json create mode 100644 packages/create-rstack/template-lib-vue-ts/rstack.config.ts create mode 100644 packages/create-rstack/template-lib-vue-ts/src/Button.vue create mode 100644 packages/create-rstack/template-lib-vue-ts/src/button.css create mode 100644 packages/create-rstack/template-lib-vue-ts/src/index.ts create mode 100644 packages/create-rstack/template-lib-vue-ts/tests/index.test.ts create mode 100644 packages/create-rstack/template-lib-vue-ts/tests/rstest.setup.ts create mode 100644 packages/create-rstack/template-lib-vue-ts/tests/tsconfig.json create mode 100644 packages/create-rstack/template-lib-vue-ts/tsconfig.json diff --git a/packages/create-rstack/README.md b/packages/create-rstack/README.md index c0b7c4f0..bdf20f28 100644 --- a/packages/create-rstack/README.md +++ b/packages/create-rstack/README.md @@ -31,6 +31,8 @@ npx create-rstack -d my-project -t app-vanilla-ts - `lib-node-ts` - TypeScript Node.js library - `lib-react-js` - JavaScript React library - `lib-react-ts` - TypeScript React library +- `lib-vue-js` - JavaScript Vue library +- `lib-vue-ts` - TypeScript Vue library ## Documentation diff --git a/packages/create-rstack/src/index.ts b/packages/create-rstack/src/index.ts index e895cecd..360d67a5 100644 --- a/packages/create-rstack/src/index.ts +++ b/packages/create-rstack/src/index.ts @@ -50,6 +50,7 @@ const getTemplateName = async ({ template }: Argv): Promise => { : [ { value: 'node', label: 'Node.js' }, { value: 'react', label: 'React' }, + { value: 'vue', label: 'Vue' }, ], }), ); @@ -81,6 +82,8 @@ await create({ 'lib-node-ts', 'lib-react-js', 'lib-react-ts', + 'lib-vue-js', + 'lib-vue-ts', ], builtinTools: [], getTemplateName, diff --git a/packages/create-rstack/template-lib-vue-js/AGENTS.md b/packages/create-rstack/template-lib-vue-js/AGENTS.md new file mode 100644 index 00000000..234cc720 --- /dev/null +++ b/packages/create-rstack/template-lib-vue-js/AGENTS.md @@ -0,0 +1,14 @@ +# AGENTS.md + +## Commands + +- `{{ packageManager }} run build` - Build the library for production +- `{{ packageManager }} run dev` - Rebuild the library when source files change +- `{{ packageManager }} run test` - Run tests +- `{{ packageManager }} run test:watch` - Run tests in watch mode + +## Docs + +- Rslib: https://rslib.rs/llms.txt +- Rspack: https://rspack.rs/llms.txt +- Rstest: https://rstest.rs/llms.txt diff --git a/packages/create-rstack/template-lib-vue-js/README.md b/packages/create-rstack/template-lib-vue-js/README.md new file mode 100644 index 00000000..ab4b6927 --- /dev/null +++ b/packages/create-rstack/template-lib-vue-js/README.md @@ -0,0 +1,40 @@ +# Rstack library + +## Setup + +Install the dependencies: + +```bash +{{ packageManager }} install +``` + +## Get started + +Build the library: + +```bash +{{ packageManager }} run build +``` + +Build the library in watch mode: + +```bash +{{ packageManager }} run dev +``` + +Run tests: + +```bash +{{ packageManager }} run test +``` + +Run tests in watch mode: + +```bash +{{ packageManager }} run test:watch +``` + +## Learn more + +- [Rstack documentation](https://rstack.rs) +- [Rslib documentation](https://rslib.rs) diff --git a/packages/create-rstack/template-lib-vue-js/package.json b/packages/create-rstack/template-lib-vue-js/package.json new file mode 100644 index 00000000..3edaf57e --- /dev/null +++ b/packages/create-rstack/template-lib-vue-js/package.json @@ -0,0 +1,37 @@ +{ + "name": "rstack-lib-vue-js", + "version": "0.0.0", + "type": "module", + "exports": { + ".": { + "default": "./dist/index.js" + } + }, + "files": [ + "dist", + "README.md" + ], + "scripts": { + "build": "rs lib", + "dev": "rs lib --watch", + "format": "rs fmt", + "lint": "rs lint", + "test": "rs test", + "test:watch": "rs test --watch" + }, + "devDependencies": { + "@rsbuild/plugin-vue": "^2.0.1", + "@testing-library/jest-dom": "^7.0.0", + "@testing-library/vue": "^8.1.0", + "@vue/test-utils": "^2.4.11", + "happy-dom": "^20.11.1", + "rstack": "^0.3.5", + "vue": "^3.5.40" + }, + "peerDependencies": { + "vue": ">=3.2.0" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/create-rstack/template-lib-vue-js/rstack.config.js b/packages/create-rstack/template-lib-vue-js/rstack.config.js new file mode 100644 index 00000000..555838c9 --- /dev/null +++ b/packages/create-rstack/template-lib-vue-js/rstack.config.js @@ -0,0 +1,30 @@ +// @ts-check +// Rstack configuration guide: https://rstack.rs/config +import { define } from 'rstack'; + +define.lib(async () => { + const { pluginVue } = await import('@rsbuild/plugin-vue'); + + return { + bundle: false, + source: { + entry: { + index: ['./src/**'], + }, + }, + output: { + target: 'web', + }, + plugins: [pluginVue()], + }; +}); + +define.test({ + setupFiles: ['./tests/rstest.setup.js'], +}); + +define.lint(async () => { + const { js } = await import('rstack/lint'); + + return [js.configs.recommended]; +}); diff --git a/packages/create-rstack/template-lib-vue-js/src/Button.vue b/packages/create-rstack/template-lib-vue-js/src/Button.vue new file mode 100644 index 00000000..1df2ae6c --- /dev/null +++ b/packages/create-rstack/template-lib-vue-js/src/Button.vue @@ -0,0 +1,41 @@ + + + diff --git a/packages/create-rstack/template-lib-vue-js/src/button.css b/packages/create-rstack/template-lib-vue-js/src/button.css new file mode 100644 index 00000000..257ef46f --- /dev/null +++ b/packages/create-rstack/template-lib-vue-js/src/button.css @@ -0,0 +1,34 @@ +.demo-button { + font-weight: 700; + border: 0; + border-radius: 3em; + cursor: pointer; + display: inline-block; + line-height: 1; +} + +.demo-button--primary { + color: white; + background-color: #1ea7fd; +} + +.demo-button--secondary { + color: #333; + background-color: transparent; + box-shadow: rgba(0, 0, 0, 0.15) 0 0 0 1px inset; +} + +.demo-button--small { + font-size: 12px; + padding: 10px 16px; +} + +.demo-button--medium { + font-size: 14px; + padding: 11px 20px; +} + +.demo-button--large { + font-size: 16px; + padding: 12px 24px; +} diff --git a/packages/create-rstack/template-lib-vue-js/src/index.js b/packages/create-rstack/template-lib-vue-js/src/index.js new file mode 100644 index 00000000..652e7950 --- /dev/null +++ b/packages/create-rstack/template-lib-vue-js/src/index.js @@ -0,0 +1 @@ +export { default as Button } from './Button.vue'; diff --git a/packages/create-rstack/template-lib-vue-js/tests/index.test.js b/packages/create-rstack/template-lib-vue-js/tests/index.test.js new file mode 100644 index 00000000..bdb34a0e --- /dev/null +++ b/packages/create-rstack/template-lib-vue-js/tests/index.test.js @@ -0,0 +1,16 @@ +import { expect, test } from 'rstack/test'; +import { render, screen } from '@testing-library/vue'; +import Button from '../src/Button.vue'; + +test('The button should have correct background color', async () => { + render(Button, { + props: { + backgroundColor: '#ccc', + label: 'Demo Button', + }, + }); + const button = screen.getByText('Demo Button'); + expect(button).toHaveStyle({ + backgroundColor: '#ccc', + }); +}); diff --git a/packages/create-rstack/template-lib-vue-js/tests/rstest.setup.js b/packages/create-rstack/template-lib-vue-js/tests/rstest.setup.js new file mode 100644 index 00000000..93951b15 --- /dev/null +++ b/packages/create-rstack/template-lib-vue-js/tests/rstest.setup.js @@ -0,0 +1,4 @@ +import { expect } from 'rstack/test'; +import * as jestDomMatchers from '@testing-library/jest-dom/matchers'; + +expect.extend(jestDomMatchers); diff --git a/packages/create-rstack/template-lib-vue-ts/AGENTS.md b/packages/create-rstack/template-lib-vue-ts/AGENTS.md new file mode 100644 index 00000000..234cc720 --- /dev/null +++ b/packages/create-rstack/template-lib-vue-ts/AGENTS.md @@ -0,0 +1,14 @@ +# AGENTS.md + +## Commands + +- `{{ packageManager }} run build` - Build the library for production +- `{{ packageManager }} run dev` - Rebuild the library when source files change +- `{{ packageManager }} run test` - Run tests +- `{{ packageManager }} run test:watch` - Run tests in watch mode + +## Docs + +- Rslib: https://rslib.rs/llms.txt +- Rspack: https://rspack.rs/llms.txt +- Rstest: https://rstest.rs/llms.txt diff --git a/packages/create-rstack/template-lib-vue-ts/README.md b/packages/create-rstack/template-lib-vue-ts/README.md new file mode 100644 index 00000000..ab4b6927 --- /dev/null +++ b/packages/create-rstack/template-lib-vue-ts/README.md @@ -0,0 +1,40 @@ +# Rstack library + +## Setup + +Install the dependencies: + +```bash +{{ packageManager }} install +``` + +## Get started + +Build the library: + +```bash +{{ packageManager }} run build +``` + +Build the library in watch mode: + +```bash +{{ packageManager }} run dev +``` + +Run tests: + +```bash +{{ packageManager }} run test +``` + +Run tests in watch mode: + +```bash +{{ packageManager }} run test:watch +``` + +## Learn more + +- [Rstack documentation](https://rstack.rs) +- [Rslib documentation](https://rslib.rs) diff --git a/packages/create-rstack/template-lib-vue-ts/package.json b/packages/create-rstack/template-lib-vue-ts/package.json new file mode 100644 index 00000000..9d269690 --- /dev/null +++ b/packages/create-rstack/template-lib-vue-ts/package.json @@ -0,0 +1,42 @@ +{ + "name": "rstack-lib-vue-ts", + "version": "0.0.0", + "type": "module", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + } + }, + "types": "./dist/index.d.ts", + "files": [ + "dist", + "README.md" + ], + "scripts": { + "build": "rs lib && vue-tsc", + "dev": "rs lib --watch", + "format": "rs fmt", + "lint": "rs lint", + "test": "rs test", + "test:watch": "rs test --watch" + }, + "devDependencies": { + "@rsbuild/plugin-vue": "^2.0.1", + "@testing-library/jest-dom": "^7.0.0", + "@testing-library/vue": "^8.1.0", + "@types/node": "^24.13.3", + "@vue/test-utils": "^2.4.11", + "happy-dom": "^20.11.1", + "rstack": "^0.3.5", + "typescript": "^6.0.3", + "vue": "^3.5.40", + "vue-tsc": "^3.3.9" + }, + "peerDependencies": { + "vue": ">=3.2.0" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/create-rstack/template-lib-vue-ts/rstack.config.ts b/packages/create-rstack/template-lib-vue-ts/rstack.config.ts new file mode 100644 index 00000000..c5d70cf7 --- /dev/null +++ b/packages/create-rstack/template-lib-vue-ts/rstack.config.ts @@ -0,0 +1,29 @@ +// Rstack configuration guide: https://rstack.rs/config +import { define } from 'rstack'; + +define.lib(async () => { + const { pluginVue } = await import('@rsbuild/plugin-vue'); + + return { + bundle: false, + source: { + entry: { + index: ['./src/**'], + }, + }, + output: { + target: 'web', + }, + plugins: [pluginVue()], + }; +}); + +define.test({ + setupFiles: ['./tests/rstest.setup.ts'], +}); + +define.lint(async () => { + const { js, ts } = await import('rstack/lint'); + + return [js.configs.recommended, ts.configs.recommended]; +}); diff --git a/packages/create-rstack/template-lib-vue-ts/src/Button.vue b/packages/create-rstack/template-lib-vue-ts/src/Button.vue new file mode 100644 index 00000000..1d4d9cb8 --- /dev/null +++ b/packages/create-rstack/template-lib-vue-ts/src/Button.vue @@ -0,0 +1,33 @@ + + + diff --git a/packages/create-rstack/template-lib-vue-ts/src/button.css b/packages/create-rstack/template-lib-vue-ts/src/button.css new file mode 100644 index 00000000..257ef46f --- /dev/null +++ b/packages/create-rstack/template-lib-vue-ts/src/button.css @@ -0,0 +1,34 @@ +.demo-button { + font-weight: 700; + border: 0; + border-radius: 3em; + cursor: pointer; + display: inline-block; + line-height: 1; +} + +.demo-button--primary { + color: white; + background-color: #1ea7fd; +} + +.demo-button--secondary { + color: #333; + background-color: transparent; + box-shadow: rgba(0, 0, 0, 0.15) 0 0 0 1px inset; +} + +.demo-button--small { + font-size: 12px; + padding: 10px 16px; +} + +.demo-button--medium { + font-size: 14px; + padding: 11px 20px; +} + +.demo-button--large { + font-size: 16px; + padding: 12px 24px; +} diff --git a/packages/create-rstack/template-lib-vue-ts/src/index.ts b/packages/create-rstack/template-lib-vue-ts/src/index.ts new file mode 100644 index 00000000..652e7950 --- /dev/null +++ b/packages/create-rstack/template-lib-vue-ts/src/index.ts @@ -0,0 +1 @@ +export { default as Button } from './Button.vue'; diff --git a/packages/create-rstack/template-lib-vue-ts/tests/index.test.ts b/packages/create-rstack/template-lib-vue-ts/tests/index.test.ts new file mode 100644 index 00000000..bdb34a0e --- /dev/null +++ b/packages/create-rstack/template-lib-vue-ts/tests/index.test.ts @@ -0,0 +1,16 @@ +import { expect, test } from 'rstack/test'; +import { render, screen } from '@testing-library/vue'; +import Button from '../src/Button.vue'; + +test('The button should have correct background color', async () => { + render(Button, { + props: { + backgroundColor: '#ccc', + label: 'Demo Button', + }, + }); + const button = screen.getByText('Demo Button'); + expect(button).toHaveStyle({ + backgroundColor: '#ccc', + }); +}); diff --git a/packages/create-rstack/template-lib-vue-ts/tests/rstest.setup.ts b/packages/create-rstack/template-lib-vue-ts/tests/rstest.setup.ts new file mode 100644 index 00000000..93951b15 --- /dev/null +++ b/packages/create-rstack/template-lib-vue-ts/tests/rstest.setup.ts @@ -0,0 +1,4 @@ +import { expect } from 'rstack/test'; +import * as jestDomMatchers from '@testing-library/jest-dom/matchers'; + +expect.extend(jestDomMatchers); diff --git a/packages/create-rstack/template-lib-vue-ts/tests/tsconfig.json b/packages/create-rstack/template-lib-vue-ts/tests/tsconfig.json new file mode 100644 index 00000000..b13d0ac4 --- /dev/null +++ b/packages/create-rstack/template-lib-vue-ts/tests/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "rootDir": "..", + "types": ["@testing-library/jest-dom"] + }, + "include": ["./"] +} diff --git a/packages/create-rstack/template-lib-vue-ts/tsconfig.json b/packages/create-rstack/template-lib-vue-ts/tsconfig.json new file mode 100644 index 00000000..9d608297 --- /dev/null +++ b/packages/create-rstack/template-lib-vue-ts/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "lib": ["DOM", "ES2022"], + "jsx": "preserve", + "target": "ES2022", + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "dist", + "skipLibCheck": true, + "types": ["rstack/types", "node"], + "jsxImportSource": "vue", + "useDefineForClassFields": true, + "rootDir": "src", + + /* modules */ + "moduleDetection": "force", + "moduleResolution": "bundler", + "verbatimModuleSyntax": true, + "resolveJsonModule": true, + "allowImportingTsExtensions": true, + + /* type checking */ + "noUnusedLocals": true, + "noUnusedParameters": true + }, + "include": ["src"] +} diff --git a/packages/create-rstack/tests/create.test.ts b/packages/create-rstack/tests/create.test.ts index 74306421..920301f5 100644 --- a/packages/create-rstack/tests/create.test.ts +++ b/packages/create-rstack/tests/create.test.ts @@ -122,6 +122,18 @@ test.each([ sourceExtension: 'tsx', hasTypeScript: true, }, + { + template: 'lib-vue-js', + configExtension: 'js', + sourceExtension: 'js', + hasTypeScript: false, + }, + { + template: 'lib-vue-ts', + configExtension: 'ts', + sourceExtension: 'ts', + hasTypeScript: true, + }, ])( 'creates the $template template', async ({ template, configExtension, sourceExtension, hasTypeScript }) => {