From c100560eaea46cb8eb5daf5c7eb514b4c190ff29 Mon Sep 17 00:00:00 2001 From: brightwu <1521488775@qq.com> Date: Sat, 25 Mar 2023 18:11:47 +0800 Subject: [PATCH] Support Vue (#130) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * update cli * feat: submit changeset * add template of vue * update pnpm-lock.yaml * add template of vue in cli/template * feat: add @farmfe/js-vue-plugin * fix: fix some files * fix: add some words in cspell.json * feat: support Vue SFC * fix: ci issues * chore: add prepublishOnly and files for js plugin vue --------- Co-authored-by: 余尚运 Co-authored-by: 余尚运 --- .changeset/gorgeous-horses-return.md | 5 + .changeset/shaggy-jars-watch.md | 5 + .gitattributes | 1 + cspell.json | 1 + examples/vue/.eslintrc.json | 8 + examples/vue/.gitignore | 2 + examples/vue/assets/logo.svg | 105 + examples/vue/assets/plug.svg | 59 + examples/vue/assets/rocket.svg | 396 ++ examples/vue/assets/toolbox.svg | 4272 +++++++++++++++++ examples/vue/farm.config.ts | 15 + examples/vue/index.html | 14 + examples/vue/package.json | 17 + examples/vue/src/Main.vue | 37 + examples/vue/src/components/Button.vue | 36 + examples/vue/src/components/Description.vue | 34 + examples/vue/src/components/Feature.vue | 31 + .../vue/src/components/HomepageFeatures.vue | 90 + examples/vue/src/components/Title.vue | 37 + examples/vue/src/env.d.ts | 2 + examples/vue/src/index.ts | 4 + examples/vue/tsconfig.json | 17 + js-plugins/vue/README.md | 39 + js-plugins/vue/package.json | 42 + js-plugins/vue/src/farm-vue-hmr.ts | 142 + js-plugins/vue/src/farm-vue-plugin.ts | 136 + js-plugins/vue/src/farm-vue-types.ts | 260 + js-plugins/vue/src/generatorCode.ts | 284 ++ js-plugins/vue/src/utils.ts | 36 + js-plugins/vue/tsconfig.json | 10 + packages/cli/src/create/index.ts | 42 +- packages/cli/templates/vue/.gitignore | 2 + packages/cli/templates/vue/assets/logo.svg | 105 + packages/cli/templates/vue/assets/plug.svg | 59 + packages/cli/templates/vue/assets/rocket.svg | 396 ++ packages/cli/templates/vue/assets/toolbox.svg | 4272 +++++++++++++++++ packages/cli/templates/vue/farm.config.ts | 14 + packages/cli/templates/vue/index.html | 14 + packages/cli/templates/vue/package.json | 17 + packages/cli/templates/vue/src/Main.vue | 37 + .../templates/vue/src/components/Button.vue | 36 + .../vue/src/components/Description.vue | 34 + .../templates/vue/src/components/Feature.vue | 31 + .../vue/src/components/HomepageFeatures.vue | 90 + .../templates/vue/src/components/Title.vue | 37 + packages/cli/templates/vue/src/env.d.ts | 2 + packages/cli/templates/vue/src/index.ts | 4 + packages/cli/templates/vue/tsconfig.json | 17 + pnpm-lock.yaml | 211 +- pnpm-workspace.yaml | 1 + 50 files changed, 11532 insertions(+), 26 deletions(-) create mode 100644 .changeset/gorgeous-horses-return.md create mode 100644 .changeset/shaggy-jars-watch.md create mode 100644 .gitattributes create mode 100644 examples/vue/.eslintrc.json create mode 100644 examples/vue/.gitignore create mode 100644 examples/vue/assets/logo.svg create mode 100644 examples/vue/assets/plug.svg create mode 100644 examples/vue/assets/rocket.svg create mode 100644 examples/vue/assets/toolbox.svg create mode 100644 examples/vue/farm.config.ts create mode 100644 examples/vue/index.html create mode 100644 examples/vue/package.json create mode 100644 examples/vue/src/Main.vue create mode 100644 examples/vue/src/components/Button.vue create mode 100644 examples/vue/src/components/Description.vue create mode 100644 examples/vue/src/components/Feature.vue create mode 100644 examples/vue/src/components/HomepageFeatures.vue create mode 100644 examples/vue/src/components/Title.vue create mode 100644 examples/vue/src/env.d.ts create mode 100644 examples/vue/src/index.ts create mode 100644 examples/vue/tsconfig.json create mode 100644 js-plugins/vue/README.md create mode 100644 js-plugins/vue/package.json create mode 100644 js-plugins/vue/src/farm-vue-hmr.ts create mode 100644 js-plugins/vue/src/farm-vue-plugin.ts create mode 100644 js-plugins/vue/src/farm-vue-types.ts create mode 100644 js-plugins/vue/src/generatorCode.ts create mode 100644 js-plugins/vue/src/utils.ts create mode 100644 js-plugins/vue/tsconfig.json create mode 100644 packages/cli/templates/vue/.gitignore create mode 100644 packages/cli/templates/vue/assets/logo.svg create mode 100644 packages/cli/templates/vue/assets/plug.svg create mode 100644 packages/cli/templates/vue/assets/rocket.svg create mode 100644 packages/cli/templates/vue/assets/toolbox.svg create mode 100644 packages/cli/templates/vue/farm.config.ts create mode 100644 packages/cli/templates/vue/index.html create mode 100644 packages/cli/templates/vue/package.json create mode 100644 packages/cli/templates/vue/src/Main.vue create mode 100644 packages/cli/templates/vue/src/components/Button.vue create mode 100644 packages/cli/templates/vue/src/components/Description.vue create mode 100644 packages/cli/templates/vue/src/components/Feature.vue create mode 100644 packages/cli/templates/vue/src/components/HomepageFeatures.vue create mode 100644 packages/cli/templates/vue/src/components/Title.vue create mode 100644 packages/cli/templates/vue/src/env.d.ts create mode 100644 packages/cli/templates/vue/src/index.ts create mode 100644 packages/cli/templates/vue/tsconfig.json diff --git a/.changeset/gorgeous-horses-return.md b/.changeset/gorgeous-horses-return.md new file mode 100644 index 0000000000..87df07c581 --- /dev/null +++ b/.changeset/gorgeous-horses-return.md @@ -0,0 +1,5 @@ +--- +'@farmfe/cli': minor +--- + +Add vue template diff --git a/.changeset/shaggy-jars-watch.md b/.changeset/shaggy-jars-watch.md new file mode 100644 index 0000000000..1401447919 --- /dev/null +++ b/.changeset/shaggy-jars-watch.md @@ -0,0 +1,5 @@ +--- +'@farmfe/js-plugin-vue': minor +--- + +Vue SFC compilation support by js plugin diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..02c348c202 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.svg binary \ No newline at end of file diff --git a/cspell.json b/cspell.json index 02b3e393e2..f1be17eeea 100644 --- a/cspell.json +++ b/cspell.json @@ -7,6 +7,7 @@ // words - list of words to be always considered correct "words": [ "aarch", + "Basepath", "bindgen", "brightwu", "Bytedance", diff --git a/examples/vue/.eslintrc.json b/examples/vue/.eslintrc.json new file mode 100644 index 0000000000..eb005654d7 --- /dev/null +++ b/examples/vue/.eslintrc.json @@ -0,0 +1,8 @@ +{ + "root": true, + "extends": "../../.eslintrc.base.json", + "parserOptions": { + "project": ["./examples/vue/tsconfig.json"] + }, + "rules": {} +} diff --git a/examples/vue/.gitignore b/examples/vue/.gitignore new file mode 100644 index 0000000000..2cf1da454a --- /dev/null +++ b/examples/vue/.gitignore @@ -0,0 +1,2 @@ +dist +build \ No newline at end of file diff --git a/examples/vue/assets/logo.svg b/examples/vue/assets/logo.svg new file mode 100644 index 0000000000..9a554bb938 --- /dev/null +++ b/examples/vue/assets/logo.svg @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/vue/assets/plug.svg b/examples/vue/assets/plug.svg new file mode 100644 index 0000000000..929a811caa --- /dev/null +++ b/examples/vue/assets/plug.svg @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + Openclipart + + + icon bus bar + 2007-04-18T02:48:48 + simple red circular icon with white simplified power cord + http://openclipart.org/detail/3987/icon-bus-bar-by-jportugall + + + JPortugall + + + + + clip art + clipart + event + icon + image + media + microphone + organization + public domain + svg + + + + + + + + + + + diff --git a/examples/vue/assets/rocket.svg b/examples/vue/assets/rocket.svg new file mode 100644 index 0000000000..b46f58aed0 --- /dev/null +++ b/examples/vue/assets/rocket.svg @@ -0,0 +1,396 @@ + + + + + image/svg+xml + + image/svg+xml + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/vue/assets/toolbox.svg b/examples/vue/assets/toolbox.svg new file mode 100644 index 0000000000..83b3e7a5a3 --- /dev/null +++ b/examples/vue/assets/toolbox.svg @@ -0,0 +1,4272 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + Openclipart + + + + + + + + + + + diff --git a/examples/vue/farm.config.ts b/examples/vue/farm.config.ts new file mode 100644 index 0000000000..d26c00a5b1 --- /dev/null +++ b/examples/vue/farm.config.ts @@ -0,0 +1,15 @@ +// change to @farmfe/core/config when resolve support conditional exports +import { defineFarmConfig } from '@farmfe/core/dist/config'; +import farmJsPluginVue from '@farmfe/js-plugin-vue'; + +export default defineFarmConfig({ + compilation: { + input: { + index: './index.html' + }, + output: { + path: './build' + } + }, + plugins: [farmJsPluginVue()] +}); diff --git a/examples/vue/index.html b/examples/vue/index.html new file mode 100644 index 0000000000..59711c609f --- /dev/null +++ b/examples/vue/index.html @@ -0,0 +1,14 @@ + + + + + + + Document + + +
+ + + + \ No newline at end of file diff --git a/examples/vue/package.json b/examples/vue/package.json new file mode 100644 index 0000000000..480a59eeaa --- /dev/null +++ b/examples/vue/package.json @@ -0,0 +1,17 @@ +{ + "name": "@farmfe-examples/vue", + "version": "0.0.0", + "private": true, + "dependencies": { + "vue": "^3.2.45" + }, + "devDependencies": { + "@farmfe/cli": "../../packages/cli", + "@farmfe/core": "../../packages/core", + "@farmfe/js-plugin-vue": "workspace:^0.0.0" + }, + "scripts": { + "start": "farm start", + "build": "farm build" + } +} diff --git a/examples/vue/src/Main.vue b/examples/vue/src/Main.vue new file mode 100644 index 0000000000..ca3e12f899 --- /dev/null +++ b/examples/vue/src/Main.vue @@ -0,0 +1,37 @@ + + + + + + + + + diff --git a/examples/vue/src/components/Button.vue b/examples/vue/src/components/Button.vue new file mode 100644 index 0000000000..1f6b393d4e --- /dev/null +++ b/examples/vue/src/components/Button.vue @@ -0,0 +1,36 @@ + + + + + + \ No newline at end of file diff --git a/examples/vue/src/components/Description.vue b/examples/vue/src/components/Description.vue new file mode 100644 index 0000000000..b90f1e3f9a --- /dev/null +++ b/examples/vue/src/components/Description.vue @@ -0,0 +1,34 @@ + + + + + \ No newline at end of file diff --git a/examples/vue/src/components/Feature.vue b/examples/vue/src/components/Feature.vue new file mode 100644 index 0000000000..50346696c8 --- /dev/null +++ b/examples/vue/src/components/Feature.vue @@ -0,0 +1,31 @@ + + + + + \ No newline at end of file diff --git a/examples/vue/src/components/HomepageFeatures.vue b/examples/vue/src/components/HomepageFeatures.vue new file mode 100644 index 0000000000..3fea1e22bb --- /dev/null +++ b/examples/vue/src/components/HomepageFeatures.vue @@ -0,0 +1,90 @@ + + + + \ No newline at end of file diff --git a/examples/vue/src/components/Title.vue b/examples/vue/src/components/Title.vue new file mode 100644 index 0000000000..fddd7393ce --- /dev/null +++ b/examples/vue/src/components/Title.vue @@ -0,0 +1,37 @@ + + + + + \ No newline at end of file diff --git a/examples/vue/src/env.d.ts b/examples/vue/src/env.d.ts new file mode 100644 index 0000000000..fa9cf42560 --- /dev/null +++ b/examples/vue/src/env.d.ts @@ -0,0 +1,2 @@ +declare module "*.vue"; +declare module "*.svg"; diff --git a/examples/vue/src/index.ts b/examples/vue/src/index.ts new file mode 100644 index 0000000000..e4455f4cec --- /dev/null +++ b/examples/vue/src/index.ts @@ -0,0 +1,4 @@ +import { createApp } from "vue"; +import Main from "./Main.vue"; + +createApp(Main).mount("#app"); diff --git a/examples/vue/tsconfig.json b/examples/vue/tsconfig.json new file mode 100644 index 0000000000..17ba6bd830 --- /dev/null +++ b/examples/vue/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "moduleResolution": "Node", + "strict": true, + "jsx": "preserve", + "resolveJsonModule": true, + "isolatedModules": true, + "esModuleInterop": true, + "lib": ["ESNext", "DOM"], + "skipLibCheck": true, + "noEmit": true + }, + "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.vue", "farm.config.ts"] +} diff --git a/js-plugins/vue/README.md b/js-plugins/vue/README.md new file mode 100644 index 0000000000..679a917428 --- /dev/null +++ b/js-plugins/vue/README.md @@ -0,0 +1,39 @@ +# Vue Js Plugin for Farm + +Support compiling Vue SFC in Farm. + +## Usage + +Install `@farmfe/js-plugin-vue` by your favorite package manager(npm, yarn, pnpm and so on): + +```bash +npm i @farmfe/js-plugin-vue --save-dev # or pnpm/yarn add @farmfe/js-plugin-vue -D +``` + +Configuring the plugin in `farm.config.ts`: + +```ts +import { defineFarmConfig } from '@farmfe/core/dist/config'; +import farmJsPluginVue from '@farmfe/js-plugin-vue'; // import the plugin + +export default defineFarmConfig({ + compilation: { + input: { + index: './index.html', + }, + output: { + path: './build', + }, + }, + plugins: [ + // use the vue plugin. + farmJsPluginVue({ + // custom options here + }), + ], +}); +``` + +## Options + +WIP. diff --git a/js-plugins/vue/package.json b/js-plugins/vue/package.json new file mode 100644 index 0000000000..7fcc936cb7 --- /dev/null +++ b/js-plugins/vue/package.json @@ -0,0 +1,42 @@ +{ + "name": "@farmfe/js-plugin-vue", + "version": "0.0.0", + "description": "support vue sfc for farm.", + "main": "./dist/farm-vue-plugin.js", + "types": "./dist/farm-vue-plugin.d.ts", + "type": "module", + "scripts": { + "build": "tsc", + "prepublishOnly": "npm run build", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "files": [ + "dist" + ], + "exports": { + ".": { + "import": "./dist/farm-vue-plugin.js" + } + }, + "repository": { + "type": "git", + "url": "https://github.com/farm-fe/farm", + "directory": "js-plugins/vue" + }, + "bugs": { + "url": "https://github.com/farm-fe/farm/issues" + }, + "homepage": "https://github.com/farm-fe/farm/tree/main/js-plugins/vue", + "author": "ysy945", + "license": "MIT", + "devDependencies": { + "@farmfe/core": "workspace:^0.5.2", + "@types/node": "^18.15.3" + }, + "dependencies": { + "@vue/compiler-sfc": "^3.2.47" + }, + "peerDependencies": { + "@farmfe/core": "^0.5.2" + } +} diff --git a/js-plugins/vue/src/farm-vue-hmr.ts b/js-plugins/vue/src/farm-vue-hmr.ts new file mode 100644 index 0000000000..f64e7dac57 --- /dev/null +++ b/js-plugins/vue/src/farm-vue-hmr.ts @@ -0,0 +1,142 @@ +import { + SFCDescriptor, + SFCScriptBlock, + SFCTemplateBlock, + SFCStyleBlock, +} from "@vue/compiler-sfc"; +import { CacheDescriptor, QueryObj, StylesCodeCache } from "./farm-vue-types.js"; +import { genMainCode } from "./generatorCode.js"; + +export const cacheScript = new WeakMap(); + +export function handleHmr( + cacheDescriptor: CacheDescriptor, + descriptor: SFCDescriptor, + stylesCodeCache: StylesCodeCache, + query: QueryObj, + resolvedPath: string +) { + const beforeDescriptor = cacheDescriptor[resolvedPath]; + //set descriptors cache to hmr + if (!beforeDescriptor) { + if (Object.keys(query).length === 0) + cacheDescriptor[resolvedPath] = descriptor; + return null; + } + //diff beforeDescriptor and currentDescriptor + else { + return diffDescriptor( + beforeDescriptor, + descriptor, + stylesCodeCache, + resolvedPath + ); + } +} + +function diffDescriptor( + prevDescriptor: SFCDescriptor, + descriptor: SFCDescriptor, + stylesCodeCache: StylesCodeCache, + resolvedPath: string +) { + let _rerender_only = false; + //If script changed, rerender from root. + const scriptChanged = hasScriptChanged(prevDescriptor, descriptor); + //If only template changed,rerender from current node. + const templateChanged = hasTemplateChanged( + prevDescriptor.template!, + descriptor.template! + ); + //If style changed,insert new style. + const [deleteStyles, addStyles] = hasStyleChanged( + prevDescriptor.styles || [], + descriptor.styles || [] + ); + + if (!scriptChanged && templateChanged) { + _rerender_only = true; + } + + const { source, moduleType } = genMainCode( + descriptor, + stylesCodeCache, + resolvedPath, + true, + _rerender_only, + deleteStyles, + addStyles + ); + + return { source, moduleType }; +} + +function hasStyleChanged(prev: SFCStyleBlock[], next: SFCStyleBlock[]) { + let p = 0, + q = 0; + const deleteStyles: SFCStyleBlock[] = []; + const addStyles: SFCStyleBlock[] = []; + while (prev[p] && next[q]) { + const prevStyle = prev[p++]; + const nextStyle = next[q++]; + if (isEqualBlock(prevStyle, nextStyle)) { + continue; + } else { + deleteStyles.push(prevStyle); + addStyles.push(nextStyle); + } + } + //prev should be delete + if (prev[p] && !next[q]) { + while (prev[p]) { + deleteStyles.push(prev[p++]); + } + } + //next has more new styles + else if (!prev[p] && next[q]) { + while (next[q]) { + addStyles.push(next[q++]); + } + } + + return [deleteStyles, addStyles]; +} + +function hasTemplateChanged(prev: SFCTemplateBlock, next: SFCTemplateBlock) { + return isEqualBlock(prev, next); +} + +function hasScriptChanged(prev: SFCDescriptor, next: SFCDescriptor) { + if (!isEqualBlock(prev.script!, next.script!)) { + return true; + } + if (!isEqualBlock(prev.scriptSetup!, next.scriptSetup!)) { + return true; + } + //If cssVars changed,it means that script changed + if (prev.cssVars.join("") !== next.cssVars.join("")) { + return true; + } + const prevResolvedScript = cacheScript.get(prev); + const prevImports = prevResolvedScript?.imports; + if (prevImports) { + return !next.template || next.shouldForceReload(prevImports); + } + return false; +} + +function isEqualBlock( + a: SFCScriptBlock | SFCTemplateBlock | SFCStyleBlock, + b: SFCScriptBlock | SFCTemplateBlock | SFCStyleBlock +) { + if (!a && !b) return true; + if (!a || !b) return false; + if (a.src && b.src && a.src === b.src) return true; + if (a.content !== b.content) return false; + const keysA = Object.keys(a.attrs); + const keysB = Object.keys(b.attrs); + if (keysA.length !== keysB.length) { + return false; + } + return keysA.every((key) => a.attrs[key] === b.attrs[key]); +} diff --git a/js-plugins/vue/src/farm-vue-plugin.ts b/js-plugins/vue/src/farm-vue-plugin.ts new file mode 100644 index 0000000000..af19ac4d3c --- /dev/null +++ b/js-plugins/vue/src/farm-vue-plugin.ts @@ -0,0 +1,136 @@ +import fs from 'fs'; +import path from 'path'; +import { parse } from '@vue/compiler-sfc'; +import { JsPlugin } from '@farmfe/core'; +import { handleHmr } from './farm-vue-hmr.js'; +import { StylesCodeCache, CacheDescriptor, LessStatic } from './farm-vue-types.js'; +import { genMainCode } from './generatorCode.js'; +import { error } from './utils.js'; + +//apply style langs +type ApplyStyleLangs = ['less']; + +const stylesCodeCache: StylesCodeCache = {}; +const applyStyleLangs = ['less']; +const VueRegExp = /.vue$/; +const JsOrTsExp = /.(ts|js)$/; +const cacheDescriptor: CacheDescriptor = {}; + +export default function farmVuePlugin(options: object = {}): JsPlugin { + //options hooks to get farmConfig + let farmConfig = null; + return { + name: 'farm-vue-plugin', + load: { + filters: { + resolvedPaths: ['.vue$'], + }, + async executor(params, ctx) { + const query: Record = {}; + params.query.forEach(([key, value]) => { + query[key] = value; + }); + const { vue, lang, hash } = query; + const { resolvedPath } = params; + const extname = path.extname(resolvedPath); + //handle .vue file + if (VueRegExp.test(extname)) { + if (vue === 'true' && hash) { + let styleCode = stylesCodeCache[hash]; + //if lang is not "css",use preProcessor to handle + if (applyStyleLangs.includes(lang)) { + const { css } = await preProcession(styleCode, lang); + styleCode = css; + } + return { + content: typeof styleCode === 'string' ? styleCode : '', + moduleType: 'css', + }; + } + let source = ''; + try { + source = await fs.promises.readFile(resolvedPath, 'utf-8'); + } catch (err) { + error({ + id: resolvedPath, + message: "path is not right,can't readFile", + }); + } + try { + parse(source); + } catch (e) { + console.log(e); + } + const { descriptor } = parse(source); + + const isHmr = handleHmr( + cacheDescriptor, + descriptor, + stylesCodeCache, + query, + resolvedPath + ); + if (isHmr) + return { content: isHmr.source, moduleType: isHmr.moduleType }; + + const { source: mainCode, moduleType } = genMainCode( + descriptor, + stylesCodeCache, + resolvedPath + ); + + return { + content: mainCode, + moduleType, + }; + } + //default + else { + console.error( + `[farm-vue-plugin]:there is no path can be match,please check!` + ); + return { + content: + 'console.log(`[farm-vue-plugin]:error:there is no path can be match,please check!`)', + moduleType: 'js', + }; + } + }, + }, + // add hmr code In root file + transform: { + filters: { + resolvedPaths: ['.html$'], + }, + executor(params, ctx) { + return { + content: params.content, + moduleType: params.moduleType, + }; + }, + }, + }; +} + +async function preProcession(styleCode: string, moduleType: string) { + const __default = { css: styleCode, map: '' }; + try { + switch (moduleType) { + case 'less': + let lessProcessor = (await import(moduleType)) || {}; + if (lessProcessor.default) { + lessProcessor = lessProcessor.default; + } + return await transformLessToCss(styleCode, lessProcessor as LessStatic); + default: + return __default; + } + } catch (err) { + error({ id: 'less', message: err }); + } + return __default; +} + +async function transformLessToCss(lessCode: string, lessProcessor: LessStatic) { + return await lessProcessor.render(lessCode, {}); +} diff --git a/js-plugins/vue/src/farm-vue-types.ts b/js-plugins/vue/src/farm-vue-types.ts new file mode 100644 index 0000000000..5760aacda3 --- /dev/null +++ b/js-plugins/vue/src/farm-vue-types.ts @@ -0,0 +1,260 @@ +import { SFCDescriptor } from '@vue/compiler-sfc'; + +export interface outputData { + id: string; + message: string | object; +} +export interface QueryObj { + [key: string]: string | number | boolean; +} +export interface StylesCodeCache { + [key: string]: string; +} + +export type CacheDescriptor = Record; + +export declare namespace Less { + interface RootFileInfo { + rewriteUrls?: boolean | undefined; + filename: string; + relativeUrls: boolean; + rootPath: string; + currentDirectory: string; + entryPath: string; + rootFilename: string; + reference: boolean; + } + + class PluginManager { + constructor(less: LessStatic); + addPreProcessor(preProcessor: PreProcessor, priority?: number): void; + addFileManager(fileManager: FileManager): void; + } + + interface Plugin { + install: (less: LessStatic, pluginManager: PluginManager) => void; + minVersion?: [number, number, number] | undefined; + } + + interface PreProcessor { + process: (src: string, extra: PreProcessorExtraInfo) => string; + } + + interface PreProcessorExtraInfo { + context: { + pluginManager: PluginManager; + }; + + fileInfo: RootFileInfo; + + imports: { + [key: string]: any; + }; + } + + interface FileLoadResult { + /** Full resolved path to file. */ + filename: string; + + /** The contents of the file, as a string. */ + contents: string; + } + + interface FileLoadError { + /** Error object if an error occurs. */ + error: unknown; + } + + class FileManager extends AbstractFileManager { + supports( + filename: string, + currentDirectory: string, + options: LoadFileOptions, + environment: Environment + ): boolean; + + loadFile( + filename: string, + currentDirectory: string, + options: LoadFileOptions, + environment: Environment + ): Promise; + + loadFileSync( + filename: string, + currentDirectory: string, + options: LoadFileOptions, + environment: Environment + ): FileLoadResult | FileLoadError; + } + + class AbstractFileManager { + getPath(filename: string): string; + tryAppendLessExtension(filename: string): string; + alwaysMakePathsAbsolute(): boolean; + isPathAbsolute(path: string): boolean; + join(basePath: string, laterPath: string): string; + pathDiff(url: string, baseUrl: string): string; + supportsSync( + filename: string, + currentDirectory: string, + options: LoadFileOptions, + environment: Environment + ): boolean; + } + + interface LoadFileOptions { + paths?: string[] | undefined; + prefixes?: string[] | undefined; + ext?: string | undefined; + rawBuffer?: any; + syncImport?: boolean | undefined; + } + + interface Environment { + encodeBase64(str: string): string; + mimeLookup(filename: string): string; + charsetLookup(mime: string): string; + getSourceMapGenerator(): any; + } + + interface SourceMapOption { + sourceMapURL?: string | undefined; + sourceMapBasepath?: string | undefined; + sourceMapRootPath?: string | undefined; + outputSourceFiles?: boolean | undefined; + sourceMapFileInline?: boolean | undefined; + } + + interface StaticOptions { + async: boolean; + fileAsync: boolean; + modifyVars: { [variable: string]: string }; + } + + interface ImportManager { + contents: { [fileName: string]: string }; + } + + interface Options { + sourceMap?: SourceMapOption | undefined; + /** Filename of the main file to be passed to less.render() */ + filename?: string | undefined; + /** The locations for less looking for files in @import rules */ + paths?: string[] | undefined; + /** True, if run the less parser and just reports errors without any output. */ + lint?: boolean | undefined; + /** Pre-load global Less.js plugins */ + plugins?: Plugin[] | undefined; + /** @deprecated If true, compress using less built-in compression. */ + compress?: boolean | undefined; + strictImports?: boolean | undefined; + /** If true, allow imports from insecure https hosts. */ + insecure?: boolean | undefined; + depends?: boolean | undefined; + maxLineLen?: number | undefined; + /** @deprecated If false, No color in compiling. */ + color?: boolean | undefined; + /** @deprecated False by default. */ + ieCompat?: boolean | undefined; + /** @deprecated If true, enable evaluation of JavaScript inline in `.less` files. */ + javascriptEnabled?: boolean | undefined; + /** Whether output file information and line numbers in compiled CSS code. */ + dumpLineNumbers?: 'comment' | string | undefined; + /** Add a path to every generated import and url in output css files. */ + rootPath?: string | undefined; + /** Math mode options for avoiding symbol conflicts on math expressions. */ + math?: + | 'always' + | 'strict' + | 'parens-division' + | 'parens' + | 'strict-legacy' + | number + | undefined; + /** If true, stops any warnings from being shown. */ + silent?: boolean | undefined; + /** Without this option, Less attempts to guess at the output unit when it does maths. */ + strictUnits?: boolean | undefined; + /** Defines a variable that can be referenced by the file. */ + globalVars?: + | { + [key: string]: string; + } + | undefined; + /** Puts Var declaration at the end of base file. */ + modifyVars?: + | { + [key: string]: string; + } + | undefined; + /** Read files synchronously in Node.js */ + syncImport?: boolean | undefined; + } + + interface RenderError { + column: number; + extract: string[]; + filename: string; + index: number; + line: number; + message: string; + type: string; + } + + interface RenderOutput { + css: string; + map: string; + imports: string[]; + } + + interface RefreshOutput { + endTime: Date; + startTime: Date; + sheets: number; + totalMilliseconds: number; + } +} + +export interface LessStatic { + options: Less.StaticOptions; + + importManager?: Less.ImportManager | undefined; + sheets: HTMLLinkElement[]; + + modifyVars(vars: { [name: string]: string }): Promise; + + refreshStyles(): void; + + render( + input: string, + callback: ( + error: Less.RenderError, + output: Less.RenderOutput | undefined + ) => void + ): void; + render( + input: string, + options: Less.Options, + callback: ( + error: Less.RenderError, + output: Less.RenderOutput | undefined + ) => void + ): void; + + render(input: string): Promise; + render(input: string, options: Less.Options): Promise; + + refresh( + reload?: boolean, + modifyVars?: { [variable: string]: string }, + clearFileCache?: boolean + ): Promise; + + version: number[]; + + watch(): void; + + FileManager: typeof Less.FileManager; + PluginManager: typeof Less.PluginManager; +} diff --git a/js-plugins/vue/src/generatorCode.ts b/js-plugins/vue/src/generatorCode.ts new file mode 100644 index 0000000000..d25e4e681e --- /dev/null +++ b/js-plugins/vue/src/generatorCode.ts @@ -0,0 +1,284 @@ +import path from "path"; +import { + compileScript, + compileTemplate, + compileStyle, + SFCDescriptor, + SFCScriptBlock, + SFCTemplateBlock, + BindingMetadata, + rewriteDefault, + SFCStyleBlock, + SFCTemplateCompileResults, +} from "@vue/compiler-sfc"; +import { error, warn, getHash, parsePath } from "./utils.js"; +import { QueryObj, StylesCodeCache } from "./farm-vue-types.js"; +import { cacheScript } from "./farm-vue-hmr.js"; + +const assignFilenameCode = genFileNameCode("App.vue"); +const assignRenderCode = `_sfc_main.render = typeof render === "function" ? render : undefined`; +const exportDefaultCode = `export default _sfc_main`; +const defaultScriptCode = `const _sfc_main = {}`; +const defaultHmrCode = ` +typeof __VUE_HMR_RUNTIME__ !== "undefined" && __VUE_HMR_RUNTIME__.createRecord(_sfc_main.__hmrId, _sfc_main); +module.meta.hot.accept((mod) => { + if (!mod) + return; + const { default: updated } = mod; + if (updated._rerender_only) { + __VUE_HMR_RUNTIME__.rerender(updated.__hmrId, updated.render); + } else { + __VUE_HMR_RUNTIME__.reload(updated.__hmrId, updated); + } +}); +`; + +export function genTemplateCode( + descriptor: SFCDescriptor, + template: SFCTemplateBlock | null, + filename: string, + bindings: BindingMetadata, + hasScoped: boolean, + hash: string +): { code: string; map?: any } & Partial { + if (template) { + const result = compileTemplate({ + source: template.content, + filename, + id: filename, + compilerOptions: { + bindingMetadata: bindings ? bindings : undefined, + scopeId: hasScoped ? `data-v-${hash}` : undefined, + }, + inMap: template.map, + slotted: descriptor.slotted, + preprocessLang: template.lang, + scoped: hasScoped, + }); + const { code, map, errors, tips } = result; + + if (errors.length) { + errors.forEach((err) => error({ id: filename, message: err })); + } + if (tips.length) { + tips.forEach((tip) => + warn({ + id: filename, + message: tip, + }) + ); + } + return { + ...result, + code: code.replace(/\nexport (function|const)/, "\n$1"), + }; + } + + throw new Error("template is null"); +} + +export function genScriptCode(descriptor: SFCDescriptor, filename: string): { + moduleType: string; + code: string; +} & Partial { + let moduleType = "js"; + let code = ""; + let result: Partial = {}; + const script = descriptor.script || descriptor.scriptSetup; + // if script exist,add transformed code + if (script) { + const { content } = (result = compileScript(descriptor, { + id: filename, + })); + cacheScript.set(descriptor, result); + code += rewriteDefault(content, "_sfc_main"); + if (script && script.lang === "ts") moduleType = "ts"; + } + // default script code + else { + code += defaultScriptCode; + } + return { + moduleType, + code, + ...result, + }; +} + +function genStyleCode( + style: SFCStyleBlock, + stylesCodeCache: StylesCodeCache, + stylesCodeArr: string[], + filename: string, + hash: string, + resolvedPath: string, + index: number, + isHmr: boolean = false +) { + const { + attrs: { lang = "css", scoped }, + } = style; + const { code: styleCode, errors } = compileStyle({ + source: style.content, + id: `data-v-${hash}`, + scoped: Boolean(scoped), + filename, + }); + if (errors.length) { + errors.forEach((err) => { + error({ id: err.name, message: err.message }); + }); + return; + } + const queryStr = genQueryStr({ + lang, + scoped: scoped ? hash : scoped, + index, + vue: true, + t: isHmr ? Date.now() : 0, + }); + + const importPath = path.normalize(resolvedPath) + "?" + queryStr; + + const hashName = getHash(importPath); + if (!stylesCodeCache[hashName]) { + stylesCodeCache[hashName] = styleCode; + } + stylesCodeArr.push( + "import " + JSON.stringify(importPath + `&hash=${hashName}`) + ); +} + +export function genStylesCode( + descriptor: SFCDescriptor, + stylesCodeCache: StylesCodeCache, + resolvedPath: string, + hash: string, + filename: string, + isHmr: boolean = false, + deleteStyles: SFCStyleBlock[] = [], + addStyles: SFCStyleBlock[] = [] +) { + const stylesCodeArr: string[] = []; + const { styles } = descriptor; + if (styles.length) { + for (let i = 0; i < styles.length; i++) { + genStyleCode( + styles[i], + stylesCodeCache, + stylesCodeArr, + filename, + hash, + resolvedPath, + i, + false + ); + } + } + + if (isHmr && addStyles.length) { + for (let i = 0; i < addStyles.length; i++) { + genStyleCode( + styles[i], + stylesCodeCache, + stylesCodeArr, + filename, + hash, + resolvedPath, + i, + true + ); + } + } + return stylesCodeArr.join("\r\n"); +} + +export function genQueryStr(queryObj: QueryObj) { + const queryStrArr: string[] = []; + for (let key in queryObj) { + if (queryObj[key] === 0 || queryObj[key]) + queryStrArr.push(`${key}=${queryObj[key]}`); + } + return queryStrArr.join("&"); +} + +export function genAssignHmrIdCode(hash: string) { + return `_sfc_main.__hmrId = "${hash}"`; +} + +export function genOtherCode( + hasScoped: boolean, + hash: string, + isHmr = false, + rerenderOnly: boolean +) { + const otherCodeArr = [ + assignRenderCode, + assignFilenameCode, + hasScoped ? genAssignScopedCode(hash) : "", + genAssignHmrIdCode(hash), + defaultHmrCode, + isHmr ? `_sfc_main._rerender_only=${rerenderOnly}` : "", + exportDefaultCode, + ]; + + return otherCodeArr.join("\r\n"); +} + +export function genAssignScopedCode(hash: string) { + return `_sfc_main.__scopeId = "data-v-${hash}";`; +} + +export function genMainCode( + descriptor: SFCDescriptor, + stylesCodeCache: StylesCodeCache, + resolvedPath: string, + isHmr: boolean = false, + rerenderOnly: boolean = false, + deleteStyles: SFCStyleBlock[] = [], + addStyles: SFCStyleBlock[] = [] +) { + const output: string[] = []; + const { template, scriptSetup, script, styles } = descriptor; + const hasScoped = styles.some((style) => style.scoped); + const hash = getHash(resolvedPath); + const { filename } = parsePath(resolvedPath); + + const { + code: scriptCode, + map: scriptMap, + moduleType, + bindings, + } = genScriptCode(descriptor, filename); + + const { code: templateCode, map: templateMap } = genTemplateCode( + descriptor, + template, + filename, + bindings || {}, + hasScoped, + hash + ); + const stylesCode = genStylesCode( + descriptor, + stylesCodeCache, + resolvedPath, + hash, + filename, + isHmr, + deleteStyles, + addStyles + ); + const otherCode = genOtherCode(hasScoped, hash, isHmr, rerenderOnly); + + output.push(templateCode, scriptCode, stylesCode, otherCode); + return { + source: output.join("\r\n"), + moduleType, + map: "", + }; +} + +export function genFileNameCode(resolvedPath: string) { + return `_sfc_main.__file = "${resolvedPath}"`; +} diff --git a/js-plugins/vue/src/utils.ts b/js-plugins/vue/src/utils.ts new file mode 100644 index 0000000000..ac514117f1 --- /dev/null +++ b/js-plugins/vue/src/utils.ts @@ -0,0 +1,36 @@ +import path from "path"; +import crypto from "crypto"; +import { outputData } from "./farm-vue-types.js"; +export function warn({ id, message }: outputData) { + console.warn(`[${id}:warn]:"${message}"`); +} + +export function error({ id, message }: outputData) { + console.error(`[${id}-(error)]:"${message}"`); +} + +export function parsePath(resolvedPath: string) { + const { dir, base } = path.parse(resolvedPath); + const [filename, query] = base.split("?"); + const queryObj: Record = {}; + if (query) { + query.split("&").forEach((keyValue) => { + const [key, value] = keyValue.split("="); + queryObj[key] = value; + }); + } + return { + filename, + filePath: path.join(dir, filename), + query: queryObj, + }; +} + +export function getHash(text: string, start: number = 0, end: number = 8) { + return crypto + .createHash("sha256") + .update(text) + .digest("hex") + .substring(start, end) + .toLocaleLowerCase(); +} diff --git a/js-plugins/vue/tsconfig.json b/js-plugins/vue/tsconfig.json new file mode 100644 index 0000000000..d6db55ba6b --- /dev/null +++ b/js-plugins/vue/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "noUnusedLocals": false, + "noUnusedParameters": false, + "outDir": "dist" + }, + "include": ["**/*.ts", "./*.ts"], + "exclude": ["node_modules"] +} diff --git a/packages/cli/src/create/index.ts b/packages/cli/src/create/index.ts index c5c10d73f5..d4cef51118 100644 --- a/packages/cli/src/create/index.ts +++ b/packages/cli/src/create/index.ts @@ -1,15 +1,49 @@ import path from 'node:path'; import { copyFiles, TEMPLATES_DIR } from '../utils.js'; - +import inquirer from 'inquirer'; import chalk from 'chalk'; const TEMPLATE_REACT = path.join(TEMPLATES_DIR, 'react'); +const TEMPLATE_VUE = path.join(TEMPLATES_DIR, 'vue'); +const REACT = 'React'; +const VUE = 'Vue'; export async function create(): Promise { - const dest = path.join(process.cwd(), 'farm-react'); + const { name: projectName } = await inquirer.prompt({ + type: 'input', + name: 'name', + message: 'please input project name', + default: 'my-farm-project', + }); - copyFiles(TEMPLATE_REACT, dest); + const { framework } = await inquirer.prompt({ + type: 'list', + name: 'framework', + message: 'please choose a framework', + choices: [ + { + name: '1) React', + value: REACT, + }, + { + name: '2) Vue', + value: VUE, + }, + ], + }); + const dest = path.join(process.cwd(), projectName); + if (framework === REACT) { + copyFiles(TEMPLATE_REACT, dest); + logger(dest, projectName); + } else if (framework === VUE) { + copyFiles(TEMPLATE_VUE, dest); + logger(dest, projectName); + } else { + throw new Error(`Please choose legal template!`); + } +} +function logger(dest: string, projectName: string) { console.log( chalk.green('Created a new Farm app in ') + chalk.bold(dest) + @@ -17,7 +51,7 @@ export async function create(): Promise { ); console.log( `Run ${chalk.cyan.bold( - 'cd farm-react && npm i && npm start' + `cd ${projectName} && npm i && npm start` )} to get started.` ); } diff --git a/packages/cli/templates/vue/.gitignore b/packages/cli/templates/vue/.gitignore new file mode 100644 index 0000000000..2cf1da454a --- /dev/null +++ b/packages/cli/templates/vue/.gitignore @@ -0,0 +1,2 @@ +dist +build \ No newline at end of file diff --git a/packages/cli/templates/vue/assets/logo.svg b/packages/cli/templates/vue/assets/logo.svg new file mode 100644 index 0000000000..9a554bb938 --- /dev/null +++ b/packages/cli/templates/vue/assets/logo.svg @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/cli/templates/vue/assets/plug.svg b/packages/cli/templates/vue/assets/plug.svg new file mode 100644 index 0000000000..929a811caa --- /dev/null +++ b/packages/cli/templates/vue/assets/plug.svg @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + Openclipart + + + icon bus bar + 2007-04-18T02:48:48 + simple red circular icon with white simplified power cord + http://openclipart.org/detail/3987/icon-bus-bar-by-jportugall + + + JPortugall + + + + + clip art + clipart + event + icon + image + media + microphone + organization + public domain + svg + + + + + + + + + + + diff --git a/packages/cli/templates/vue/assets/rocket.svg b/packages/cli/templates/vue/assets/rocket.svg new file mode 100644 index 0000000000..b46f58aed0 --- /dev/null +++ b/packages/cli/templates/vue/assets/rocket.svg @@ -0,0 +1,396 @@ + + + + + image/svg+xml + + image/svg+xml + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/cli/templates/vue/assets/toolbox.svg b/packages/cli/templates/vue/assets/toolbox.svg new file mode 100644 index 0000000000..83b3e7a5a3 --- /dev/null +++ b/packages/cli/templates/vue/assets/toolbox.svg @@ -0,0 +1,4272 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + Openclipart + + + + + + + + + + + diff --git a/packages/cli/templates/vue/farm.config.ts b/packages/cli/templates/vue/farm.config.ts new file mode 100644 index 0000000000..2d282c093c --- /dev/null +++ b/packages/cli/templates/vue/farm.config.ts @@ -0,0 +1,14 @@ +import { defineFarmConfig } from '@farmfe/core/dist/config'; +import farmJsPluginVue from '@farmfe/js-plugin-vue'; + +export default defineFarmConfig({ + compilation: { + input: { + index: './index.html', + }, + output: { + path: './build', + }, + }, + plugins: [farmJsPluginVue()], +}); diff --git a/packages/cli/templates/vue/index.html b/packages/cli/templates/vue/index.html new file mode 100644 index 0000000000..59711c609f --- /dev/null +++ b/packages/cli/templates/vue/index.html @@ -0,0 +1,14 @@ + + + + + + + Document + + +
+ + + + \ No newline at end of file diff --git a/packages/cli/templates/vue/package.json b/packages/cli/templates/vue/package.json new file mode 100644 index 0000000000..4358a288d5 --- /dev/null +++ b/packages/cli/templates/vue/package.json @@ -0,0 +1,17 @@ +{ + "name": "@farmfe-examples/vue", + "version": "0.0.0", + "private": true, + "dependencies": { + "vue": "^3.2.45" + }, + "devDependencies": { + "@farmfe/cli": "*", + "@farmfe/core": "*", + "@farmfe/js-plugin-vue": "*" + }, + "scripts": { + "start": "farm start", + "build":"farm build" + } +} \ No newline at end of file diff --git a/packages/cli/templates/vue/src/Main.vue b/packages/cli/templates/vue/src/Main.vue new file mode 100644 index 0000000000..ca3e12f899 --- /dev/null +++ b/packages/cli/templates/vue/src/Main.vue @@ -0,0 +1,37 @@ + + + + + + + + + diff --git a/packages/cli/templates/vue/src/components/Button.vue b/packages/cli/templates/vue/src/components/Button.vue new file mode 100644 index 0000000000..1f6b393d4e --- /dev/null +++ b/packages/cli/templates/vue/src/components/Button.vue @@ -0,0 +1,36 @@ + + + + + + \ No newline at end of file diff --git a/packages/cli/templates/vue/src/components/Description.vue b/packages/cli/templates/vue/src/components/Description.vue new file mode 100644 index 0000000000..b90f1e3f9a --- /dev/null +++ b/packages/cli/templates/vue/src/components/Description.vue @@ -0,0 +1,34 @@ + + + + + \ No newline at end of file diff --git a/packages/cli/templates/vue/src/components/Feature.vue b/packages/cli/templates/vue/src/components/Feature.vue new file mode 100644 index 0000000000..50346696c8 --- /dev/null +++ b/packages/cli/templates/vue/src/components/Feature.vue @@ -0,0 +1,31 @@ + + + + + \ No newline at end of file diff --git a/packages/cli/templates/vue/src/components/HomepageFeatures.vue b/packages/cli/templates/vue/src/components/HomepageFeatures.vue new file mode 100644 index 0000000000..3fea1e22bb --- /dev/null +++ b/packages/cli/templates/vue/src/components/HomepageFeatures.vue @@ -0,0 +1,90 @@ + + + + \ No newline at end of file diff --git a/packages/cli/templates/vue/src/components/Title.vue b/packages/cli/templates/vue/src/components/Title.vue new file mode 100644 index 0000000000..fddd7393ce --- /dev/null +++ b/packages/cli/templates/vue/src/components/Title.vue @@ -0,0 +1,37 @@ + + + + + \ No newline at end of file diff --git a/packages/cli/templates/vue/src/env.d.ts b/packages/cli/templates/vue/src/env.d.ts new file mode 100644 index 0000000000..4ae8e90af7 --- /dev/null +++ b/packages/cli/templates/vue/src/env.d.ts @@ -0,0 +1,2 @@ +declare module '*.vue'; +declare module '*.svg'; diff --git a/packages/cli/templates/vue/src/index.ts b/packages/cli/templates/vue/src/index.ts new file mode 100644 index 0000000000..17fa711a18 --- /dev/null +++ b/packages/cli/templates/vue/src/index.ts @@ -0,0 +1,4 @@ +import { createApp } from 'vue'; +import Main from './Main.vue'; + +createApp(Main).mount('#app'); diff --git a/packages/cli/templates/vue/tsconfig.json b/packages/cli/templates/vue/tsconfig.json new file mode 100644 index 0000000000..17ba6bd830 --- /dev/null +++ b/packages/cli/templates/vue/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "moduleResolution": "Node", + "strict": true, + "jsx": "preserve", + "resolveJsonModule": true, + "isolatedModules": true, + "esModuleInterop": true, + "lib": ["ESNext", "DOM"], + "skipLibCheck": true, + "noEmit": true + }, + "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.vue", "farm.config.ts"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3d69ef6159..b9a4d5664a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -77,6 +77,30 @@ importers: '@farmfe/cli': link:../../packages/cli '@farmfe/core': link:../../packages/core + examples/vue: + specifiers: + '@farmfe/cli': ../../packages/cli + '@farmfe/core': ../../packages/core + '@farmfe/js-plugin-vue': workspace:^0.0.0 + vue: ^3.2.45 + dependencies: + vue: 3.2.47 + devDependencies: + '@farmfe/cli': link:../../packages/cli + '@farmfe/core': link:../../packages/core + '@farmfe/js-plugin-vue': link:../../js-plugins/vue + + js-plugins/vue: + specifiers: + '@farmfe/core': workspace:^0.5.2 + '@types/node': ^18.15.3 + '@vue/compiler-sfc': ^3.2.47 + dependencies: + '@vue/compiler-sfc': 3.2.47 + devDependencies: + '@farmfe/core': link:../../packages/core + '@types/node': 18.15.8 + packages/cli: specifiers: '@farmfe/core': workspace:^0.5.0 @@ -176,11 +200,21 @@ packages: '@babel/highlight': 7.18.6 dev: true + /@babel/helper-string-parser/7.19.4: + resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==} + engines: {node: '>=6.9.0'} + dev: false + /@babel/helper-validator-identifier/7.18.6: resolution: {integrity: sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==} engines: {node: '>=6.9.0'} dev: true + /@babel/helper-validator-identifier/7.19.1: + resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} + engines: {node: '>=6.9.0'} + dev: false + /@babel/highlight/7.18.6: resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} engines: {node: '>=6.9.0'} @@ -190,6 +224,14 @@ packages: js-tokens: 4.0.0 dev: true + /@babel/parser/7.21.3: + resolution: {integrity: sha512-lobG0d7aOfQRXh8AyklEAgZGvA4FShxo6xQbUrrT/cNBPUdIDojlokwJsQyCC/eKia7ifqM0yP+2DRZ4WKw2RQ==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.21.3 + dev: false + /@babel/runtime/7.20.13: resolution: {integrity: sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==} engines: {node: '>=6.9.0'} @@ -197,6 +239,15 @@ packages: regenerator-runtime: 0.13.11 dev: true + /@babel/types/7.21.3: + resolution: {integrity: sha512-sBGdETxC+/M4o/zKC0sl6sjWv62WFR/uzxrJ6uYyMLZOUlPnwzw0tKgVHOXxaAd5l2g8pEDM5RZ495GPQI77kg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.19.4 + '@babel/helper-validator-identifier': 7.19.1 + to-fast-properties: 2.0.0 + dev: false + /@bcoe/v8-coverage/0.2.3: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} dev: true @@ -467,10 +518,10 @@ packages: '@commitlint/execute-rule': 17.0.0 '@commitlint/resolve-extends': 17.0.3 '@commitlint/types': 17.0.0 - '@types/node': 18.0.1 + '@types/node': 18.15.8 chalk: 4.1.2 cosmiconfig: 7.0.1 - cosmiconfig-typescript-loader: 2.0.2_6z5ibupqympmu4p4ahawyamnbm + cosmiconfig-typescript-loader: 2.0.2_pr5f2rls7covluxpiz5l35e4ea lodash: 4.17.21 resolve-from: 5.0.0 typescript: 4.9.4 @@ -923,14 +974,14 @@ packages: /@types/accepts/1.3.5: resolution: {integrity: sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==} dependencies: - '@types/node': 18.0.1 + '@types/node': 18.15.8 dev: true /@types/body-parser/1.19.2: resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==} dependencies: '@types/connect': 3.4.35 - '@types/node': 18.11.18 + '@types/node': 18.15.8 dev: true /@types/chai-subset/1.3.3: @@ -946,7 +997,7 @@ packages: /@types/connect/3.4.35: resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} dependencies: - '@types/node': 18.11.18 + '@types/node': 18.15.8 dev: true /@types/content-disposition/0.5.5: @@ -959,13 +1010,13 @@ packages: '@types/connect': 3.4.35 '@types/express': 4.17.13 '@types/keygrip': 1.0.2 - '@types/node': 18.0.1 + '@types/node': 18.15.8 dev: true /@types/express-serve-static-core/4.17.30: resolution: {integrity: sha512-gstzbTWro2/nFed1WXtf+TtrpwxH7Ggs4RLYTLbeVgIkUQOI3WG/JKjgeOU1zXDvezllupjrf8OPIdvTbIaVOQ==} dependencies: - '@types/node': 18.11.18 + '@types/node': 18.15.8 '@types/qs': 6.9.7 '@types/range-parser': 1.2.4 dev: true @@ -1045,7 +1096,7 @@ packages: '@types/http-errors': 1.8.2 '@types/keygrip': 1.0.2 '@types/koa-compose': 3.2.5 - '@types/node': 18.0.1 + '@types/node': 18.15.8 dev: true /@types/lodash.debounce/4.0.7: @@ -1075,7 +1126,7 @@ packages: /@types/node-fetch/2.6.2: resolution: {integrity: sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==} dependencies: - '@types/node': 18.0.1 + '@types/node': 18.15.8 form-data: 3.0.1 dev: true @@ -1091,6 +1142,10 @@ packages: resolution: {integrity: sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==} dev: true + /@types/node/18.15.8: + resolution: {integrity: sha512-kzGNJZ57XEH7RdckxZ7wfRjB9hgZABF+NLgR1B2zogUvV0gmK0/60VYA4yb4oKZckPiiJlmmfpdqTfCN0VRX+Q==} + dev: true + /@types/normalize-package-data/2.4.1: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} dev: true @@ -1137,19 +1192,19 @@ packages: resolution: {integrity: sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==} dependencies: '@types/mime': 3.0.1 - '@types/node': 18.11.18 + '@types/node': 18.15.8 dev: true /@types/through/0.0.30: resolution: {integrity: sha512-FvnCJljyxhPM3gkRgWmxmDZyAQSiBQQWLI0A0VFL0K7W1oRUrPJSqNO0NvTnLkBcotdlp3lKvaT0JrnyRDkzOg==} dependencies: - '@types/node': 18.11.18 + '@types/node': 18.15.8 dev: true /@types/ws/8.5.4: resolution: {integrity: sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg==} dependencies: - '@types/node': 18.11.18 + '@types/node': 18.15.8 dev: true /@typescript-eslint/eslint-plugin/5.30.5_rysf4bry2oqvktl7qw5uk63fhm: @@ -1297,6 +1352,89 @@ packages: - terser dev: true + /@vue/compiler-core/3.2.47: + resolution: {integrity: sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig==} + dependencies: + '@babel/parser': 7.21.3 + '@vue/shared': 3.2.47 + estree-walker: 2.0.2 + source-map: 0.6.1 + dev: false + + /@vue/compiler-dom/3.2.47: + resolution: {integrity: sha512-dBBnEHEPoftUiS03a4ggEig74J2YBZ2UIeyfpcRM2tavgMWo4bsEfgCGsu+uJIL/vax9S+JztH8NmQerUo7shQ==} + dependencies: + '@vue/compiler-core': 3.2.47 + '@vue/shared': 3.2.47 + dev: false + + /@vue/compiler-sfc/3.2.47: + resolution: {integrity: sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ==} + dependencies: + '@babel/parser': 7.21.3 + '@vue/compiler-core': 3.2.47 + '@vue/compiler-dom': 3.2.47 + '@vue/compiler-ssr': 3.2.47 + '@vue/reactivity-transform': 3.2.47 + '@vue/shared': 3.2.47 + estree-walker: 2.0.2 + magic-string: 0.25.9 + postcss: 8.4.21 + source-map: 0.6.1 + dev: false + + /@vue/compiler-ssr/3.2.47: + resolution: {integrity: sha512-wVXC+gszhulcMD8wpxMsqSOpvDZ6xKXSVWkf50Guf/S+28hTAXPDYRTbLQ3EDkOP5Xz/+SY37YiwDquKbJOgZw==} + dependencies: + '@vue/compiler-dom': 3.2.47 + '@vue/shared': 3.2.47 + dev: false + + /@vue/reactivity-transform/3.2.47: + resolution: {integrity: sha512-m8lGXw8rdnPVVIdIFhf0LeQ/ixyHkH5plYuS83yop5n7ggVJU+z5v0zecwEnX7fa7HNLBhh2qngJJkxpwEEmYA==} + dependencies: + '@babel/parser': 7.21.3 + '@vue/compiler-core': 3.2.47 + '@vue/shared': 3.2.47 + estree-walker: 2.0.2 + magic-string: 0.25.9 + dev: false + + /@vue/reactivity/3.2.47: + resolution: {integrity: sha512-7khqQ/75oyyg+N/e+iwV6lpy1f5wq759NdlS1fpAhFXa8VeAIKGgk2E/C4VF59lx5b+Ezs5fpp/5WsRYXQiKxQ==} + dependencies: + '@vue/shared': 3.2.47 + dev: false + + /@vue/runtime-core/3.2.47: + resolution: {integrity: sha512-RZxbLQIRB/K0ev0K9FXhNbBzT32H9iRtYbaXb0ZIz2usLms/D55dJR2t6cIEUn6vyhS3ALNvNthI+Q95C+NOpA==} + dependencies: + '@vue/reactivity': 3.2.47 + '@vue/shared': 3.2.47 + dev: false + + /@vue/runtime-dom/3.2.47: + resolution: {integrity: sha512-ArXrFTjS6TsDei4qwNvgrdmHtD930KgSKGhS5M+j8QxXrDJYLqYw4RRcDy1bz1m1wMmb6j+zGLifdVHtkXA7gA==} + dependencies: + '@vue/runtime-core': 3.2.47 + '@vue/shared': 3.2.47 + csstype: 2.6.21 + dev: false + + /@vue/server-renderer/3.2.47_vue@3.2.47: + resolution: {integrity: sha512-dN9gc1i8EvmP9RCzvneONXsKfBRgqFeFZLurmHOveL7oH6HiFXJw5OGu294n1nHc/HMgTy6LulU/tv5/A7f/LA==} + peerDependencies: + vue: 3.2.47 + dependencies: + '@vue/compiler-ssr': 3.2.47 + '@vue/shared': 3.2.47 + vue: 3.2.47 + dev: false + + /@vue/shared/3.2.47: + resolution: {integrity: sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ==} + dev: false + /JSONStream/1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} hasBin: true @@ -1922,16 +2060,16 @@ packages: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} dev: true - /cosmiconfig-typescript-loader/2.0.2_6z5ibupqympmu4p4ahawyamnbm: + /cosmiconfig-typescript-loader/2.0.2_pr5f2rls7covluxpiz5l35e4ea: resolution: {integrity: sha512-KmE+bMjWMXJbkWCeY4FJX/npHuZPNr9XF9q9CIQ/bpFwi1qHfCmSiKarrCcRa0LO4fWjk93pVoeRtJAkTGcYNw==} engines: {node: '>=12', npm: '>=6'} peerDependencies: '@types/node': '*' typescript: '>=3' dependencies: - '@types/node': 18.0.1 + '@types/node': 18.15.8 cosmiconfig: 7.0.1 - ts-node: 10.8.2_6z5ibupqympmu4p4ahawyamnbm + ts-node: 10.8.2_pr5f2rls7covluxpiz5l35e4ea typescript: 4.9.4 transitivePeerDependencies: - '@swc/core' @@ -2071,6 +2209,10 @@ packages: - encoding dev: true + /csstype/2.6.21: + resolution: {integrity: sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==} + dev: false + /csstype/3.1.0: resolution: {integrity: sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==} dev: true @@ -2883,6 +3025,10 @@ packages: engines: {node: '>=4.0'} dev: true + /estree-walker/2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + dev: false + /esutils/2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} @@ -3977,6 +4123,12 @@ packages: yallist: 4.0.0 dev: true + /magic-string/0.25.9: + resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} + dependencies: + sourcemap-codec: 1.4.8 + dev: false + /make-dir/3.1.0: resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} engines: {node: '>=8'} @@ -4125,7 +4277,6 @@ packages: resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - dev: true /nanospinner/1.1.0: resolution: {integrity: sha512-yFvNYMig4AthKYfHFl1sLj7B2nkHL4lzdig4osvl9/LdGbXwrdFRoqBS98gsEsOakr0yH+r5NZ/1Y9gdVB8trA==} @@ -4398,7 +4549,6 @@ packages: /picocolors/1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} - dev: true /picomatch/2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} @@ -4446,7 +4596,6 @@ packages: nanoid: 3.3.4 picocolors: 1.0.0 source-map-js: 1.0.2 - dev: true /preferred-pm/3.0.3: resolution: {integrity: sha512-+wZgbxNES/KlJs9q40F/1sfOd/j7f1O9JaHcW5Dsn3aUUOZg3L2bjpVUcKV2jvtElYfoTuQiNeMfQJ4kwUAhCQ==} @@ -4847,7 +4996,6 @@ packages: /source-map-js/1.0.2: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} - dev: true /source-map-support/0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} @@ -4859,7 +5007,11 @@ packages: /source-map/0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} - dev: true + + /sourcemap-codec/1.4.8: + resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + deprecated: Please use @jridgewell/sourcemap-codec instead + dev: false /spawndamnit/2.0.0: resolution: {integrity: sha512-j4JKEcncSjFlqIwU5L/rp2N5SIPsdxaRsIv678+TZxZ0SRDJTm8JrxJMjE/XuiEZNEir3S8l0Fa3Ke339WI4qA==} @@ -5073,6 +5225,11 @@ packages: dependencies: os-tmpdir: 1.0.2 + /to-fast-properties/2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + dev: false + /to-regex-range/5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -5093,7 +5250,7 @@ packages: engines: {node: '>=8'} dev: true - /ts-node/10.8.2_6z5ibupqympmu4p4ahawyamnbm: + /ts-node/10.8.2_pr5f2rls7covluxpiz5l35e4ea: resolution: {integrity: sha512-LYdGnoGddf1D6v8REPtIH+5iq/gTDuZqv2/UJUU7tKjuEU8xVZorBM+buCGNjj+pGEud+sOoM4CX3/YzINpENA==} hasBin: true peerDependencies: @@ -5112,7 +5269,7 @@ packages: '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.3 - '@types/node': 18.0.1 + '@types/node': 18.15.8 acorn: 8.7.1 acorn-walk: 8.2.0 arg: 4.1.3 @@ -5455,6 +5612,16 @@ packages: resolution: {integrity: sha512-EcswR2S8bpR7fD0YPeS7r2xXExrScVMxg4MedACaWHEtx9ftCF/qHG1xGkolzTPcEmjTavCQgbVzHUIdTMzFGA==} dev: true + /vue/3.2.47: + resolution: {integrity: sha512-60188y/9Dc9WVrAZeUVSDxRQOZ+z+y5nO2ts9jWXSTkMvayiWxCWOWtBQoYjLeccfXkiiPZWAHcV+WTPhkqJHQ==} + dependencies: + '@vue/compiler-dom': 3.2.47 + '@vue/compiler-sfc': 3.2.47 + '@vue/runtime-dom': 3.2.47 + '@vue/server-renderer': 3.2.47_vue@3.2.47 + '@vue/shared': 3.2.47 + dev: false + /walkdir/0.4.1: resolution: {integrity: sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ==} engines: {node: '>=6.0.0'} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 3cdfe93089..13d6523ccc 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -3,3 +3,4 @@ packages: - examples/* - crates/* - rust-plugins/* + - js-plugins/*