Commit b8174a96 authored by 郭铭瑶's avatar 郭铭瑶 🤘

依赖更新,eslint重设

parent d08b61fb
{
"root": true,
"parser": "@typescript-eslint/parser",
"extends": ["plugin:vue/vue3-recommended", "plugin:prettier/recommended"],
"parser": "vue-eslint-parser",
"parserOptions": {
"ecmaVersion": 6,
"ecmaVersion": 2020,
"parser": "@typescript-eslint/parser",
"sourceType": "module"
},
"plugins": [
"vue",
"@typescript-eslint"
],
"rules": {
"vue/no-v-model-argument": "off",
"@typescript-eslint/naming-convention": "warn",
"@typescript-eslint/semi": "warn",
"curly": "warn",
......@@ -17,9 +21,10 @@
"semi": "off"
},
"ignorePatterns": [
"node_modules",
"public",
"out",
"dist",
"**/*.d.ts",
"front-view"
"**/*.d.ts"
]
}
module.exports = {
env: {
browser: true,
es2021: true,
},
extends: ['plugin:vue/vue3-recommended', 'plugin:prettier/recommended'],
parserOptions: {
parser: 'babel-eslint',
},
rules: {
'vue/no-multiple-template-root': 'off',
'vue/max-attributes-per-line': 'off',
'vue/html-self-closing': 'off',
'vue/singleline-html-element-content-newline': 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, // 生产环境禁止debugger
'no-console': process.env.NODE_ENV === 'production' ? 2 : 0, // 生产环境禁止console
'no-alert': process.env.NODE_ENV === 'production' ? 2 : 0, // 生产环境禁止alert
'no-shadow-restricted-names': 2, // 禁用关键字及保留字等
'dot-notation': 1, // 尽可能使用 . 来访问对象属性
'no-multi-spaces': 1, // 禁止使用多个空格
'brace-style': 1, // 大括号风格 - one true brace style
'no-var': 1, // 禁用var声明
'no-new-object': 1, // 禁止new Object
'no-array-constructor': 1, // 禁止new Array
'prefer-const': 1, // 要求使用 const 声明那些声明后不再被修改的变量
'prefer-destructuring': 1, // 优先使用数组和对象解构
'no-param-reassign': 1, // 禁止在函数中对函数参数重新赋值
'no-extra-semi': 1, // 禁用不必要的分号
// "no-unused-vars": 1, // 禁止已声明但未使用的变量
// "indent": [1, 2], // 使用2个空格缩进
'no-multiple-empty-lines': [1, { max: 1 }], // 禁止连续出现2个及以上空行
'default-case': 1, // 要求switch语句必须有default分支
'key-spacing': [1, { beforeColon: false, afterColon: true }], // 冒号前不要空格,后需要空格
'comma-spacing': [1, { before: false, after: true }], // 逗号前不要空格,后需要空格
'arrow-spacing': [1, { before: true, after: true }], // 箭头函数中的箭头前后需要留空格
quotes: [1, 'single'], // 字符串使用单引号
semi: [1, 'never'], // 禁止使用分号
},
}
module.exports = {
tabWidth: 2,
useTabs: false,
singleQuote: true,
semi: false,
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -3,23 +3,18 @@
"version": "0.0.0",
"scripts": {
"dev": "vite",
"start": "node node_modules/esbuild/install.js && npm run dev",
"start": "npm run dev",
"build": "vite build"
},
"dependencies": {
"vue": "^3.0.5"
"vue": "^3.1.5"
},
"devDependencies": {
"@vitejs/plugin-vue": "^1.1.5",
"@vue/compiler-sfc": "^3.0.5",
"babel-eslint": "^10.1.0",
"eslint": "^7.17.0",
"eslint-config-prettier": "^7.1.0",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-vue": "^7.4.1",
"prettier": "^2.2.1",
"@vitejs/plugin-vue": "^1.3.0",
"@vue/compiler-sfc": "^3.1.5",
"naive-ui": "^2.15.11",
"stylus": "^0.54.8",
"vite": "^2.1.0"
"vite": "^2.4.4"
},
"description": "插件前端展示页面",
"author": "Guo"
......
import{p as e,a as t,o as a,c as l,r as n,w as s,b as o,d as i,e as c,f as d,g as u,v as r,F as m,h as p,i as v,j as y,k as g,t as b,l as f}from"./vendor.f6a3a0fc.js";const k={name:"MyLoader",displayName:"m-loader",props:{background:{type:String,default:"rgba(0,0,0,0.3)"}}},C=s();e("data-v-6ecfd4d3");const L=o("div",{class:"my-loader"},[o("div",{class:"outer"}),o("div",{class:"middle"}),o("div",{class:"inner"})],-1);t();const h=C(((e,t,s,o,i,c)=>(a(),l("div",{class:"my-loader-mask",style:`background:${s.background}`},[L,n(e.$slots,"default",{},void 0,!0)],4))));k.render=h,k.__scopeId="data-v-6ecfd4d3";const w={name:"Main",components:{Loader:k},setup(){const e=i([{title:"Vue3版大屏",desc:"Vue3.0 + TypeScript + Vite2.0大屏用",url:"gitee:guomingyao/my-view"},{title:"Vue2大屏",desc:"Vue2.0大屏用",url:"gitee:guomingyao/monitor-template"},{title:"Vite App",desc:"Vue3.0 + Vite2.0 普通项目用",url:"gitee:guomingyao/my-vite-app"},{title:"微前端",desc:"微前端父项目模板",url:"gitee:guomingyao/micfrontend-template"}]),t=i(1),a=i(null),l=i(null),n=i(!1),s=i(null),o=i(null),u=e=>{const{command:i,data:c}=e.data;switch(i){case"DIRECTORY":o.value=c.text;break;case"CLOSE_LOADER":n.value=!1,t.value=1,a.value=null,l.value=null,s.value=null,o.value=null}};c((()=>{window.addEventListener("message",u)})),d((()=>{window.removeEventListener("message",u)}));return{step:t,curIndex:a,curData:l,templates:e,filename:s,directory:o,onClick:(e,t)=>{l.value=e,a.value=t},selectDirectory:()=>{vscode.postMessage({command:"SELECT_FOLDER"})},toStep:e=>{t.value=e},submit:()=>{n.value=!0,vscode.postMessage({command:"FETCH_PROJECT",data:{url:l.value.url,filePath:o.value,filename:s.value}})},showLoader:n}}},E=s();e("data-v-2de735e0");const V=o("h2",null,"选择模板",-1),D={class:"wrapper"},S=o("h2",null,"项目配置",-1),_={class:"item"},M={class:"item directory"};t();const x=E(((e,t,n,s,i,c)=>{const d=g("Loader");return a(),l("main",null,[u(o("section",null,[V,o("div",D,[(a(!0),l(m,null,p(s.templates,((e,t)=>(a(),l("div",{key:e.title},[o("div",{class:["inner",{on:s.curIndex===t}],onClick:a=>s.onClick(e,t)},[o("h3",null,b(e.title),1),o("span",null,b(e.desc),1)],10,["onClick"])])))),128))]),o("button",{onClick:t[1]||(t[1]=e=>s.toStep(2)),class:""+(s.curData?"btn":"disable-btn")},"下一步",2)],512),[[r,1===s.step]]),u(o("section",null,[S,o("div",_,[u(o("input",{type:"text","onUpdate:modelValue":t[2]||(t[2]=e=>s.filename=e),title:s.filename,placeholder:"请输入项目名称"},null,8,["title"]),[[v,s.filename]])]),o("div",M,[o("input",{value:s.directory,title:s.directory,type:"text",placeholder:"请选择项目存放路径",readonly:""},null,8,["value","title"]),o("button",{class:"btn",onClick:t[3]||(t[3]=(...e)=>s.selectDirectory&&s.selectDirectory(...e))},"选择")]),o("button",{onClick:t[4]||(t[4]=(...e)=>s.submit&&s.submit(...e)),class:""+(s.filename&&s.directory?"btn":"disable-btn")},"完成",2),o("button",{onClick:t[5]||(t[5]=e=>s.toStep(1)),class:"btn"},"上一步")],512),[[r,2===s.step]]),s.showLoader?(a(),l(d,{key:0})):y("",!0)])}));w.render=x,w.__scopeId="data-v-2de735e0";const I={name:"App",components:{Main:w}};I.render=function(e,t,n,s,o,i){const c=g("Main");return a(),l(c)};f(I).mount("#app");
import{p as e,a as l,o as a,c as t,r as s,b as u,d as n,e as i,f as o,w as d,v,F as c,g as r,h as p,i as m,t as g,j as b}from"./vendor.992b7f08.js";e("data-v-907dd892");const y=u("div",{class:"my-loader"},[u("div",{class:"outer"}),u("div",{class:"middle"}),u("div",{class:"inner"})],-1);l();const k={props:{background:{type:String,default:"rgba(0,0,0,0.3)"}},setup:e=>(l,u)=>(a(),t("div",{class:"my-loader-mask",style:`background:${e.background}`},[y,s(l.$slots,"default",{},void 0,!0)],4)),__scopeId:"data-v-907dd892"};e("data-v-126a51b6");const C=u("h2",null,"选择模板",-1),E={class:"wrapper"},V=u("h2",null,"项目配置",-1),f={class:"item"},h={class:"item directory"};l();const w={setup(e){const l=n([{title:"Vue3版大屏",desc:"Vue3.0 + TypeScript + Vite2.0大屏用",url:"gitee:guomingyao/my-view"},{title:"Vue2大屏",desc:"Vue2.0大屏用",url:"gitee:guomingyao/monitor-template"},{title:"Vite App",desc:"Vue3.0 + Vite2.0 普通项目用",url:"gitee:guomingyao/my-vite-app"},{title:"微前端",desc:"微前端父项目模板",url:"gitee:guomingyao/micfrontend-template"}]),s=n(1),b=n(null),y=n(null),w=n(!1),_=n(null),L=n(null),O=e=>{const{command:l,data:a}=e.data;switch(l){case"DIRECTORY":L.value=a.text;break;case"CLOSE_LOADER":w.value=!1,s.value=1,b.value=null,y.value=null,_.value=null,L.value=null}};i((()=>{window.addEventListener("message",O)})),o((()=>{window.removeEventListener("message",O)}));const R=()=>{vscode.postMessage({command:"SELECT_FOLDER"})},T=e=>{s.value=e},S=()=>{w.value=!0,vscode.postMessage({command:"FETCH_PROJECT",data:{url:y.value.url,filePath:L.value,filename:_.value}})};return(e,n)=>(a(),t("main",null,[d(u("section",null,[C,u("div",E,[(a(!0),t(c,null,r(l.value,((e,l)=>(a(),t("div",{key:e.title},[u("div",{class:["inner",{on:b.value===l}],onClick:a=>((e,l)=>{y.value=e,b.value=l})(e,l)},[u("h3",null,g(e.title),1),u("span",null,g(e.desc),1)],10,["onClick"])])))),128))]),u("button",{onClick:n[1]||(n[1]=e=>T(2)),class:""+(y.value?"btn":"disable-btn")},"下一步",2)],512),[[v,1===s.value]]),d(u("section",null,[V,u("div",f,[d(u("input",{type:"text","onUpdate:modelValue":n[2]||(n[2]=e=>_.value=e),title:_.value,placeholder:"请输入项目名称"},null,8,["title"]),[[p,_.value]])]),u("div",h,[u("input",{value:L.value,title:L.value,type:"text",placeholder:"请选择项目存放路径",readonly:""},null,8,["value","title"]),u("button",{class:"btn",onClick:R},"选择")]),u("button",{onClick:S,class:""+(_.value&&L.value?"btn":"disable-btn")},"完成",2),u("button",{onClick:n[3]||(n[3]=e=>T(1)),class:"btn"},"上一步")],512),[[v,2===s.value]]),w.value?(a(),t(k,{key:0})):m("",!0)]))},__scopeId:"data-v-126a51b6"};b({setup:e=>(e,l)=>(a(),t(w))}).mount("#app");
This diff is collapsed.
This diff is collapsed.
......@@ -6,10 +6,10 @@
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>My Cli</title>
<script type="module" crossorigin src="./assets/index.6ed84c4a.js"></script>
<link rel="modulepreload" href="./assets/vendor.f6a3a0fc.js">
<link rel="stylesheet" href="./assets/index.32d76172.css">
</head>
<script type="module" crossorigin src="./assets/index.f3604d81.js"></script>
<link rel="modulepreload" href="./assets/vendor.992b7f08.js">
<link rel="stylesheet" href="./assets/index.34afb9fb.css">
</head>
<body>
<div id="app"></div>
......
<template>
<Main />
<n-config-provider :theme="darkTheme">
<n-message-provider>
<Main />
<Form />
</n-message-provider>
</n-config-provider>
</template>
<script>
import Main from './components/main.vue'
export default {
name: 'App',
components: { Main },
}
<script setup>
import Main from "@/components/main.vue";
import Form from "@/components/form.vue";
import { darkTheme, NConfigProvider, NMessageProvider } from "naive-ui";
</script>
<style lang="stylus">
......
<template>
<n-form
ref="formRef"
inline
:label-width="80"
:model="formValue"
:rules="rules"
size="small"
>
<n-form-item label="姓名" path="user.name">
<n-input v-model:value="formValue.user.name" placeholder="输入姓名" />
</n-form-item>
<n-form-item label="年龄" path="user.age">
<n-input v-model:value="formValue.user.age" placeholder="输入年龄" />
</n-form-item>
<n-form-item label="电话号码" path="phone">
<n-input v-model:value="formValue.phone" placeholder="电话号码" />
</n-form-item>
<n-form-item>
<n-button attr-type="button" @click="handleValidateClick">验证</n-button>
</n-form-item>
</n-form>
</template>
<script setup>
import { ref } from "vue";
import {
useMessage,
NRadio,
NRadioGroup,
NRadioButton,
NForm,
NFormItem,
NInput,
NButton,
} from "naive-ui";
const formRef = ref(null);
const message = useMessage();
const formValue = ref({
user: {
name: "",
age: "",
},
phone: "",
});
const rules = {
user: {
name: {
required: true,
message: "请输入姓名",
trigger: "blur",
},
age: {
required: true,
message: "请输入年龄",
trigger: ["input", "blur"],
},
},
phone: {
required: true,
message: "请输入电话号码",
trigger: ["input"],
},
};
const handleValidateClick = (e) => {
formRef.value.validate((errors) => {
if (!errors) {
message.success("Valid");
} else {
console.log(errors);
message.error("Invalid");
}
});
};
</script>
......@@ -9,17 +9,13 @@
</div>
</template>
<script>
export default {
name: 'MyLoader',
displayName: 'm-loader',
props: {
background: {
type: String,
default: 'rgba(0,0,0,0.3)',
},
<script setup>
defineProps({
background: {
type: String,
default: "rgba(0,0,0,0.3)",
},
}
});
</script>
<style lang="stylus" scoped>
......
<template>
<main>
<section v-show="step === 1">
<h2>选择模板</h2>
<div class="wrapper">
<div v-for="(item, i) in templates" :key="item.title">
<div class="inner" :class="{on: curIndex === i}" @click="onClick(item, i)">
<h3>{{item.title}}</h3>
<span>{{item.desc}}</span>
<main>
<section v-show="step === 1">
<h2>选择模板</h2>
<div class="wrapper">
<div v-for="(item, i) in templates" :key="item.title">
<div
class="inner"
:class="{ on: curIndex === i }"
@click="onClick(item, i)"
>
<h3>{{ item.title }}</h3>
<span>{{ item.desc }}</span>
</div>
</div>
</div>
</div>
<button @click="toStep(2)" :class="`${curData ? 'btn' : 'disable-btn'}`">下一步</button>
</section>
<section v-show="step === 2">
<h2>项目配置</h2>
<div class="item">
<input type="text" v-model="filename" :title="filename" placeholder="请输入项目名称"/>
</div>
<div class="item directory">
<input :value="directory" :title="directory" type="text" placeholder="请选择项目存放路径" readonly/>
<button class="btn" @click="selectDirectory">选择</button>
</div>
<button @click="submit" :class="`${(filename && directory) ? 'btn' : 'disable-btn'}`">完成</button>
<button @click="toStep(1)" class='btn'>上一步</button>
</section>
<Loader v-if="showLoader" />
</main>
<button :class="`${curData ? 'btn' : 'disable-btn'}`" @click="toStep(2)">
下一步
</button>
</section>
<section v-show="step === 2">
<h2>项目配置</h2>
<div class="item">
<input
v-model="filename"
type="text"
:title="filename"
placeholder="请输入项目名称"
/>
</div>
<div class="item directory">
<input
:value="directory"
:title="directory"
type="text"
placeholder="请选择项目存放路径"
readonly
/>
<button class="btn" @click="selectDirectory">选择</button>
</div>
<button
:class="`${filename && directory ? 'btn' : 'disable-btn'}`"
@click="submit"
>
完成
</button>
<button class="btn" @click="toStep(1)">上一步</button>
</section>
<Loader v-if="showLoader" />
</main>
</template>
<script>
import {onBeforeUnmount, onMounted, ref} from 'vue'
import Loader from './loader.vue'
export default {
name: 'Main',
components: {Loader},
setup() {
const templates = ref([
{
title: 'Vue3版大屏',
desc: 'Vue3.0 + TypeScript + Vite2.0大屏用',
url: 'gitee:guomingyao/my-view',
},
{
title: 'Vue2大屏',
desc: 'Vue2.0大屏用',
url: 'gitee:guomingyao/monitor-template',
},
{
title: 'Vite App',
desc: 'Vue3.0 + Vite2.0 普通项目用',
url: 'gitee:guomingyao/my-vite-app',
},
{
title: '微前端',
desc: '微前端父项目模板',
url: 'gitee:guomingyao/micfrontend-template',
},
])
const step = ref(1)
const curIndex = ref(null)
const curData = ref(null)
const showLoader = ref(false)
const filename = ref(null)
const directory = ref(null)
const onClick = (data, i) => {
curData.value = data
curIndex.value = i
}
const cb = event => {
const {command, data} = event.data
switch (command) {
case 'DIRECTORY':
directory.value = data.text
break;
case 'CLOSE_LOADER':
showLoader.value = false
step.value = 1
curIndex.value = null
curData.value = null
filename.value = null
directory.value = null
break;
default:
break;
}
}
onMounted(() => {
window.addEventListener('message', cb)
})
onBeforeUnmount(() => {
window.removeEventListener('message', cb)
})
const selectDirectory = () => {
vscode.postMessage({
command: 'SELECT_FOLDER',
})
}
const toStep = (val) => {
step.value = val
}
const submit = () => {
showLoader.value = true
vscode.postMessage({
command: 'FETCH_PROJECT',
data: {
url: curData.value.url,
filePath: directory.value,
filename: filename.value,
}
})
}
return {
step,
curIndex,
curData,
templates,
filename,
directory,
onClick,
selectDirectory,
toStep,
submit,
showLoader,
}
<script setup>
import { onBeforeUnmount, onMounted, ref } from "vue";
import Loader from "@/components/loader.vue";
const templates = ref([
{
title: "Vue3版大屏",
desc: "Vue3.0 + TypeScript + Vite2.0大屏用",
url: "gitee:guomingyao/my-view",
},
{
title: "Vue2大屏",
desc: "Vue2.0大屏用",
url: "gitee:guomingyao/monitor-template",
},
{
title: "Vite App",
desc: "Vue3.0 + Vite2.0 普通项目用",
url: "gitee:guomingyao/my-vite-app",
},
{
title: "微前端",
desc: "微前端父项目模板",
url: "gitee:guomingyao/micfrontend-template",
},
]);
const step = ref(1);
const curIndex = ref(null);
const curData = ref(null);
const showLoader = ref(false);
const filename = ref(null);
const directory = ref(null);
const onClick = (data, i) => {
curData.value = data;
curIndex.value = i;
};
const cb = (event) => {
const { command, data } = event.data;
switch (command) {
case "DIRECTORY":
directory.value = data.text;
break;
case "CLOSE_LOADER":
showLoader.value = false;
step.value = 1;
curIndex.value = null;
curData.value = null;
filename.value = null;
directory.value = null;
break;
default:
break;
}
}
};
onMounted(() => {
window.addEventListener("message", cb);
});
onBeforeUnmount(() => {
window.removeEventListener("message", cb);
});
const selectDirectory = () => {
vscode.postMessage({
command: "SELECT_FOLDER",
});
};
const toStep = (val) => {
step.value = val;
};
const submit = () => {
showLoader.value = true;
vscode.postMessage({
command: "FETCH_PROJECT",
data: {
url: curData.value.url,
filePath: directory.value,
filename: filename.value,
},
});
};
</script>
<style lang="stylus" scoped>
......@@ -187,4 +190,4 @@ h2
overflow hidden
white-space nowrap
text-overflow ellipsis
</style>
\ No newline at end of file
</style>
import { createApp } from 'vue'
import App from './App.vue'
import './assets/css/normalize.css'
import './assets/css/style.styl'
import { createApp } from "vue";
import App from "./App.vue";
import "./assets/css/normalize.css";
import "./assets/css/style.styl";
createApp(App).mount('#app')
createApp(App).mount("#app");
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import { resolve } from "path";
// https://vitejs.dev/config/
export default defineConfig({
base: './',
base: "./",
build: {
outDir: resolve(__dirname, './public'),
outDir: resolve(__dirname, "./public"),
},
plugins: [vue()],
resolve: {
alias: {
'@': resolve(__dirname, './src'),
'@images': resolve(__dirname, './src/assets/images'),
"@": resolve(__dirname, "./src"),
"@images": resolve(__dirname, "./src/assets/images"),
},
},
})
});
This diff is collapsed.
......@@ -66,11 +66,16 @@
"@typescript-eslint/eslint-plugin": "^4.26.0",
"@typescript-eslint/parser": "^4.26.0",
"eslint": "^7.27.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^3.4.0",
"eslint-plugin-vue": "^7.14.0",
"glob": "^7.1.7",
"mocha": "^8.4.0",
"prettier": "^2.3.2",
"ts-loader": "^9.2.2",
"typescript": "^4.3.2",
"vscode-test": "^1.5.2",
"vue-eslint-parser": "^7.10.0",
"webpack": "^5.38.1",
"webpack-cli": "^4.7.0"
},
......
// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import * as vscode from 'vscode';
import { getWebViewContent, fetchProject, updatePackageJson } from './util';
import * as vscode from "vscode";
import { getWebViewContent, fetchProject, updatePackageJson } from "./util";
// this method is called when your extension is activated
// your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) {
// Use the console to output diagnostic information (console.log) and errors (console.error)
// This line of code will only be executed once when your extension is activated
// console.log('Congratulations, your extension "my-cli" is now active!');
// Use the console to output diagnostic information (console.log) and errors (console.error)
// This line of code will only be executed once when your extension is activated
// console.log('Congratulations, your extension "my-cli" is now active!');
// The command has been defined in the package.json file
// Now provide the implementation of the command with registerCommand
// The commandId parameter must match the command field in package.json
const disposable = vscode.commands.registerCommand("my-cli.my-cli", () => {
const panel = vscode.window.createWebviewPanel(
"my-cli",
"创建前端项目",
vscode.ViewColumn.One,
{
enableScripts: true,
retainContextWhenHidden: true,
}
);
panel.webview.html = getWebViewContent("../front-view/public/index.html");
panel.webview.onDidReceiveMessage(
async (msg) => {
const { command, data } = msg;
switch (command) {
case "FETCH_PROJECT":
const { url, filePath, filename } = data;
try {
await fetchProject({ url, filePath, filename });
} catch (error) {
panel.webview.postMessage({
command: "CLOSE_LOADER",
});
}
await updatePackageJson(data);
panel.webview.postMessage({
command: "CLOSE_LOADER",
});
break;
case "SELECT_FOLDER":
const folders = await vscode.window.showOpenDialog({
canSelectFolders: true,
canSelectFiles: false,
});
panel.webview.postMessage({
command: "DIRECTORY",
data: {
text: folders?.[0]?.path,
},
});
break;
default:
break;
}
},
undefined,
context.subscriptions
);
});
// The command has been defined in the package.json file
// Now provide the implementation of the command with registerCommand
// The commandId parameter must match the command field in package.json
const disposable = vscode.commands.registerCommand('my-cli.my-cli', () => {
const panel = vscode.window.createWebviewPanel(
'my-cli',
'创建前端项目',
vscode.ViewColumn.One,
{
enableScripts: true,
retainContextWhenHidden: true,
}
);
panel.webview.html = getWebViewContent('../front-view/public/index.html');
panel.webview.onDidReceiveMessage(async msg => {
const {command, data} = msg;
switch (command) {
case 'FETCH_PROJECT':
const {url, filePath, filename} = data;
try {
await fetchProject({url, filePath, filename});
} catch (error) {
panel.webview.postMessage({
command: 'CLOSE_LOADER',
});
}
await updatePackageJson(data);
panel.webview.postMessage({
command: 'CLOSE_LOADER',
});
break;
case 'SELECT_FOLDER':
const folders = await vscode.window.showOpenDialog({
canSelectFolders: true,
canSelectFiles: false
});
panel.webview.postMessage({
command: 'DIRECTORY',
data: {
text: folders?.[0]?.path
}
});
break;
default:
break;
}
}, undefined, context.subscriptions);
});
context.subscriptions.push(disposable);
context.subscriptions.push(disposable);
}
// this method is called when your extension is deactivated
......
import * as vscode from 'vscode';
import path = require('path');
import fs = require('fs');
const download = require('npm-gitee-lw');
import * as vscode from "vscode";
import path = require("path");
import fs = require("fs");
const download = require("npm-gitee-lw");
export const getWebViewContent = (filePath: string) => {
const dirname = path.dirname(filePath);
const resourcePath = path.join(__dirname, dirname);
const filename = path.basename(filePath);
const html = fs.readFileSync(path.join(resourcePath, filename), 'utf-8');
const html = fs.readFileSync(path.join(resourcePath, filename), "utf-8");
// vscode不支持直接加载本地资源,需要替换成其专有路径格式,这里只是简单的将样式和JS的路径替换
return html.replace(/(<link.+?href="|<script.+?src="|<img.+?src=")(.+?)"/g, (m, $1, $2) => {
return $1 + vscode.Uri.file(path.resolve(resourcePath, $2)).with({ scheme: 'vscode-resource' }).toString() + '"';
});
return html.replace(
/(<link.+?href="|<script.+?src="|<img.+?src=")(.+?)"/g,
(m, $1, $2) => {
return (
$1 +
vscode.Uri.file(path.resolve(resourcePath, $2))
.with({ scheme: "vscode-resource" })
.toString() +
'"'
);
}
);
};
export const isDirExist = (path:string) => {
export const isDirExist = (path: string) => {
try {
fs.accessSync(path, fs.constants.R_OK | fs.constants.W_OK);
return true;
......@@ -24,33 +33,47 @@ export const isDirExist = (path:string) => {
};
export interface FileConfig {
url:string
filePath:string
filename: string
url: string;
filePath: string;
filename: string;
}
export const fetchProject = ({url, filePath, filename}: FileConfig):Promise<void> => {
export const fetchProject = ({
url,
filePath,
filename,
}: FileConfig): Promise<void> => {
const projectPath = `${filePath}/${filename}`;
return new Promise((resolve, reject) => {
if (isDirExist(projectPath)) {
vscode.window.showErrorMessage('该路径下已存在同名项目文件夹!');
vscode.window.showErrorMessage("该路径下已存在同名项目文件夹!");
return reject();
}
download(url, projectPath, {clone: true}, async (err:Error) => {
download(url, projectPath, { clone: true }, async (err: Error) => {
if (err) {
vscode.window.showErrorMessage(err.message);
throw new Error(err.message);
}
vscode.window.showInformationMessage(`'${filename}' 项目创建成功!`);
await vscode.commands.executeCommand('vscode.openFolder', vscode.Uri.file(projectPath), true);
await vscode.commands.executeCommand(
"vscode.openFolder",
vscode.Uri.file(projectPath),
true
);
return resolve();
});
});
};
const packageInfo = ({name, path}: {name: string, path: string}):Promise<any> => {
const packageInfo = ({
name,
path,
}: {
name: string;
path: string;
}): Promise<any> => {
return new Promise((resolve, reject) => {
fs.readFile(`${path}/package.json`, 'utf8', (err, data) => {
fs.readFile(`${path}/package.json`, "utf8", (err, data) => {
if (err) {
return reject(err);
}
......@@ -61,15 +84,18 @@ const packageInfo = ({name, path}: {name: string, path: string}):Promise<any> =>
});
};
export const updatePackageJson = async ({filePath, filename}: FileConfig):Promise<void> => {
export const updatePackageJson = async ({
filePath,
filename,
}: FileConfig): Promise<void> => {
const path = `${filePath}/${filename}`;
const data = await packageInfo({path, name: filename});
const data = await packageInfo({ path, name: filename });
return new Promise((resolve, reject) => {
fs.writeFile(`${path}/package.json`, data, 'utf8', err => {
fs.writeFile(`${path}/package.json`, data, "utf8", (err) => {
if (err) {
return reject();
}
return resolve();
});
});
};
\ No newline at end of file
};
//@ts-check
'use strict';
"use strict";
const path = require('path');
const path = require("path");
/**@type {import('webpack').Configuration}*/
const config = {
target: 'node', // vscode extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/
mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production')
target: "node", // vscode extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/
mode: "none", // this leaves the source code as close as possible to the original (when packaging we set this to 'production')
entry: './src/extension.ts', // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/
entry: "./src/extension.ts", // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/
output: {
// the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/
path: path.resolve(__dirname, 'dist'),
filename: 'extension.js',
libraryTarget: 'commonjs2'
path: path.resolve(__dirname, "dist"),
filename: "extension.js",
libraryTarget: "commonjs2",
},
devtool: 'nosources-source-map',
devtool: "nosources-source-map",
externals: {
vscode: 'commonjs vscode' // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/
vscode: "commonjs vscode", // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/
// modules added here also need to be added in the .vsceignore file
},
resolve: {
// support reading TypeScript and JavaScript files, 📖 -> https://github.com/TypeStrong/ts-loader
extensions: ['.ts', '.js']
extensions: [".ts", ".js"],
},
module: {
rules: [
......@@ -32,11 +32,11 @@ const config = {
exclude: /node_modules/,
use: [
{
loader: 'ts-loader'
}
]
}
]
}
loader: "ts-loader",
},
],
},
],
},
};
module.exports = config;
\ No newline at end of file
module.exports = config;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment