@tomjs/vite-plugin-vscode 5.2.1 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -25
- package/README.zh_CN.md +44 -26
- package/dist/index.d.ts +7 -16
- package/dist/index.js +24 -36
- package/dist/webview.js +18 -188
- package/env-webview.d.ts +38 -0
- package/env.d.ts +21 -25
- package/package.json +6 -10
package/README.md
CHANGED
|
@@ -82,13 +82,15 @@ Setting `recommended` will modify some preset configurations. See [PluginOptions
|
|
|
82
82
|
code snippet, more code see examples
|
|
83
83
|
|
|
84
84
|
```ts
|
|
85
|
+
import { getWebviewHtml } from 'virtual:vscode';
|
|
86
|
+
|
|
85
87
|
const panel = window.createWebviewPanel('showHelloWorld', 'Hello World', ViewColumn.One, {
|
|
86
88
|
enableScripts: true,
|
|
87
89
|
localResourceRoots: [Uri.joinPath(extensionUri, 'dist/webview')],
|
|
88
90
|
});
|
|
89
91
|
|
|
90
92
|
// Vite development mode and production mode inject different webview codes to reduce development work
|
|
91
|
-
panel.webview.html =
|
|
93
|
+
panel.webview.html = getWebviewHtml({
|
|
92
94
|
// vite dev mode
|
|
93
95
|
serverUrl: process.env.VITE_DEV_SERVER_URL,
|
|
94
96
|
// vite prod mode
|
|
@@ -178,7 +180,9 @@ export default defineConfig({
|
|
|
178
180
|
- page one
|
|
179
181
|
|
|
180
182
|
```ts
|
|
181
|
-
|
|
183
|
+
import { getWebviewHtml } from 'virtual:vscode';
|
|
184
|
+
|
|
185
|
+
getWebviewHtml({
|
|
182
186
|
// vite dev mode
|
|
183
187
|
serverUrl: process.env.VITE_DEV_SERVER_URL,
|
|
184
188
|
// vite prod mode
|
|
@@ -190,7 +194,9 @@ __getWebviewHtml__({
|
|
|
190
194
|
- page two
|
|
191
195
|
|
|
192
196
|
```ts
|
|
193
|
-
|
|
197
|
+
import { getWebviewHtml } from 'virtual:vscode';
|
|
198
|
+
|
|
199
|
+
getWebviewHtml({
|
|
194
200
|
// vite dev mode
|
|
195
201
|
serverUrl: `${process.env.VITE_DEV_SERVER_URL}/index2.html`,
|
|
196
202
|
// vite prod mode
|
|
@@ -203,7 +209,9 @@ __getWebviewHtml__({
|
|
|
203
209
|
- A single page uses different parameters to achieve different functions
|
|
204
210
|
|
|
205
211
|
```ts
|
|
206
|
-
|
|
212
|
+
import { getWebviewHtml } from 'virtual:vscode';
|
|
213
|
+
|
|
214
|
+
getWebviewHtml({
|
|
207
215
|
// vite dev mode
|
|
208
216
|
serverUrl: `${process.env.VITE_DEV_SERVER_URL}?id=666`,
|
|
209
217
|
// vite prod mode
|
|
@@ -238,11 +246,6 @@ interface WebviewHtmlOptions {
|
|
|
238
246
|
*/
|
|
239
247
|
injectCode?: string;
|
|
240
248
|
}
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* Gets the html of webview
|
|
244
|
-
*/
|
|
245
|
-
function __getWebviewHtml__(options?: WebviewHtmlOptions): string;
|
|
246
249
|
```
|
|
247
250
|
|
|
248
251
|
### Warning
|
|
@@ -253,10 +256,6 @@ When using the `acquireVsCodeApi().getState()` method of [@types/vscode-webview]
|
|
|
253
256
|
const value = await acquireVsCodeApi().getState();
|
|
254
257
|
```
|
|
255
258
|
|
|
256
|
-
## Documentation
|
|
257
|
-
|
|
258
|
-
- [index.d.ts](https://www.unpkg.com/browse/@tomjs/vite-plugin-vscode/dist/index.d.ts) provided by [unpkg.com](https://www.unpkg.com).
|
|
259
|
-
|
|
260
259
|
## Parameters
|
|
261
260
|
|
|
262
261
|
### PluginOptions
|
|
@@ -275,18 +274,6 @@ The `recommended` option is used to set the default configuration and behavior,
|
|
|
275
274
|
- The output directory is based on the `build.outDir` parameter of `vite`, and outputs `extension` and `src` to `dist/extension` and `dist/webview` respectively.
|
|
276
275
|
- Other behaviors to be implemented
|
|
277
276
|
|
|
278
|
-
#### Webview
|
|
279
|
-
|
|
280
|
-
Inject [@tomjs/vscode-extension-webview](https://github.com/tomjs/vscode-extension-webview) into vscode extension code and web client code, so that `webview` can support `HMR` during the development stage.
|
|
281
|
-
|
|
282
|
-
- vite serve
|
|
283
|
-
- extension: Inject `import __getWebviewHtml__ from '@tomjs/vite-plugin-vscode/webview';` at the top of the file that calls the `__getWebviewHtml__` method
|
|
284
|
-
- web: Add `<script>` tag to index.html and inject `@tomjs/vite-plugin-vscode/client` code
|
|
285
|
-
- vite build
|
|
286
|
-
- extension: Inject `import __getWebviewHtml__ from '@tomjs/vite-plugin-vscode-inject';` at the top of the file that calls the `__getWebviewHtml__` method
|
|
287
|
-
|
|
288
|
-
If is string, will set inject method name. Default is `__getWebviewHtml__`.
|
|
289
|
-
|
|
290
277
|
#### devtools
|
|
291
278
|
|
|
292
279
|
During development, support standalone development tool applications for `react` and `vue`, enabled by default.
|
|
@@ -443,6 +430,38 @@ Open the [examples](./examples) directory, there are `vue` and `react` examples.
|
|
|
443
430
|
|
|
444
431
|
## Important Notes
|
|
445
432
|
|
|
433
|
+
### v6.0.0
|
|
434
|
+
|
|
435
|
+
**Breaking Updates:**
|
|
436
|
+
|
|
437
|
+
Change the global `__getWebviewHtml__` method to a virtual module method called `import { getWebviewHtml } from 'virtual:vscode';`.
|
|
438
|
+
|
|
439
|
+
before:
|
|
440
|
+
|
|
441
|
+
```ts
|
|
442
|
+
__getWebviewHtml__({
|
|
443
|
+
// vite 开发模式
|
|
444
|
+
serverUrl: process.env.VITE_DEV_SERVER_URL,
|
|
445
|
+
// vite 生产模式
|
|
446
|
+
webview,
|
|
447
|
+
context,
|
|
448
|
+
});
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
after:
|
|
452
|
+
|
|
453
|
+
```ts
|
|
454
|
+
import { getWebviewHtml } from 'virtual:vscode';
|
|
455
|
+
|
|
456
|
+
getWebviewHtml({
|
|
457
|
+
// vite 开发模式
|
|
458
|
+
serverUrl: process.env.VITE_DEV_SERVER_URL,
|
|
459
|
+
// vite 生产模式
|
|
460
|
+
webview,
|
|
461
|
+
context,
|
|
462
|
+
});
|
|
463
|
+
```
|
|
464
|
+
|
|
446
465
|
### v5.0.0
|
|
447
466
|
|
|
448
467
|
**Breaking Updates:**
|
package/README.zh_CN.md
CHANGED
|
@@ -82,13 +82,15 @@ npm i @tomjs/vite-plugin-vscode -D
|
|
|
82
82
|
代码片段,更多配置看示例
|
|
83
83
|
|
|
84
84
|
```ts
|
|
85
|
+
import { getWebviewHtml } from 'virtual:vscode';
|
|
86
|
+
|
|
85
87
|
const panel = window.createWebviewPanel('showHelloWorld', 'Hello World', ViewColumn.One, {
|
|
86
88
|
enableScripts: true,
|
|
87
89
|
localResourceRoots: [Uri.joinPath(extensionUri, 'dist/webview')],
|
|
88
90
|
});
|
|
89
91
|
|
|
90
92
|
// vite 开发模式和生产模式注入不同的webview代码,减少开发工作
|
|
91
|
-
panel.webview.html =
|
|
93
|
+
panel.webview.html = getWebviewHtml({
|
|
92
94
|
// vite 开发模式
|
|
93
95
|
serverUrl: process.env.VITE_DEV_SERVER_URL,
|
|
94
96
|
// vite 生产模式
|
|
@@ -177,7 +179,9 @@ export default defineConfig({
|
|
|
177
179
|
- 页面一
|
|
178
180
|
|
|
179
181
|
```ts
|
|
180
|
-
|
|
182
|
+
import { getWebviewHtml } from 'virtual:vscode';
|
|
183
|
+
|
|
184
|
+
getWebviewHtml({
|
|
181
185
|
// vite 开发模式
|
|
182
186
|
serverUrl: process.env.VITE_DEV_SERVER_URL,
|
|
183
187
|
// vite 生产模式
|
|
@@ -189,7 +193,9 @@ __getWebviewHtml__({
|
|
|
189
193
|
- 页面二
|
|
190
194
|
|
|
191
195
|
```ts
|
|
192
|
-
|
|
196
|
+
import { getWebviewHtml } from 'virtual:vscode';
|
|
197
|
+
|
|
198
|
+
getWebviewHtml({
|
|
193
199
|
// vite 开发模式
|
|
194
200
|
serverUrl: `${process.env.VITE_DEV_SERVER_URL}/index2.html`,
|
|
195
201
|
// vite 生产模式
|
|
@@ -202,7 +208,9 @@ __getWebviewHtml__({
|
|
|
202
208
|
- 单个页面通过不同参数来实现不同功能
|
|
203
209
|
|
|
204
210
|
```ts
|
|
205
|
-
|
|
211
|
+
import { getWebviewHtml } from 'virtual:vscode';
|
|
212
|
+
|
|
213
|
+
getWebviewHtml({
|
|
206
214
|
// vite 开发模式
|
|
207
215
|
serverUrl: `${process.env.VITE_DEV_SERVER_URL}?id=666`,
|
|
208
216
|
// vite 生产模式
|
|
@@ -237,11 +245,6 @@ interface WebviewHtmlOptions {
|
|
|
237
245
|
*/
|
|
238
246
|
injectCode?: string;
|
|
239
247
|
}
|
|
240
|
-
|
|
241
|
-
/**
|
|
242
|
-
* 获取webview的html
|
|
243
|
-
*/
|
|
244
|
-
function __getWebviewHtml__(options?: WebviewHtmlOptions): string;
|
|
245
248
|
```
|
|
246
249
|
|
|
247
250
|
### 警告
|
|
@@ -252,10 +255,6 @@ function __getWebviewHtml__(options?: WebviewHtmlOptions): string;
|
|
|
252
255
|
const value = await acquireVsCodeApi().getState();
|
|
253
256
|
```
|
|
254
257
|
|
|
255
|
-
## 文档
|
|
256
|
-
|
|
257
|
-
- [unpkg.com](https://www.unpkg.com/) 提供的 [index.d.ts](https://www.unpkg.com/browse/@tomjs/vite-plugin-vscode/dist/index.d.ts).
|
|
258
|
-
|
|
259
258
|
## 参数
|
|
260
259
|
|
|
261
260
|
### PluginOptions
|
|
@@ -275,18 +274,6 @@ const value = await acquireVsCodeApi().getState();
|
|
|
275
274
|
|
|
276
275
|
- 其他待实现的行为
|
|
277
276
|
|
|
278
|
-
#### Webview
|
|
279
|
-
|
|
280
|
-
在 vscode 扩展代码和 web 客户端代码中注入 [@tomjs/vscode-extension-webview](https://github.com/tomjs/vscode-extension-webview),使 `webview` 在开发阶段能够支持 `HMR`。
|
|
281
|
-
|
|
282
|
-
- vite serve
|
|
283
|
-
- extension: 在调用 `__getWebviewHtml__` 方法的文件顶部注入 `import __getWebviewHtml__ from '@tomjs/vscode-extension-webview';`
|
|
284
|
-
- web: 在 index.html 中添加 `<script>` 标签,注入 `@tomjs/vscode-extension-webview/client` 代码
|
|
285
|
-
- vite build
|
|
286
|
-
- extension: 在调用 `__getWebviewHtml__` 方法的文件顶部注入 `import __getWebviewHtml__ from '@tomjs/vite-plugin-vscode-inject';`
|
|
287
|
-
|
|
288
|
-
如果为字符串,则设置注入方法名,默认为 `__getWebviewHtml__`。
|
|
289
|
-
|
|
290
277
|
#### devtools
|
|
291
278
|
|
|
292
279
|
开发阶段,支持 `react` 和 `vue` 的独立开发工具应用,默认开启。
|
|
@@ -308,7 +295,6 @@ const value = await acquireVsCodeApi().getState();
|
|
|
308
295
|
|
|
309
296
|
| 参数名 | 类型 | 默认值 | 说明 |
|
|
310
297
|
| ------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- |
|
|
311
|
-
| name | `string` | `__getWebviewHtml__` | 注入的方法名 |
|
|
312
298
|
| csp | `string` | `<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src {{cspSource}} 'unsafe-inline'; script-src 'nonce-{{nonce}}' 'unsafe-eval';">` | webview 的 `CSP` |
|
|
313
299
|
|
|
314
300
|
- `{{cspSource}}`: [webview.cspSource](https://code.visualstudio.com/api/references/vscode-api#Webview)
|
|
@@ -447,6 +433,38 @@ pnpm build
|
|
|
447
433
|
|
|
448
434
|
## 重要说明
|
|
449
435
|
|
|
436
|
+
### v6.0.0
|
|
437
|
+
|
|
438
|
+
**破坏性更新:**
|
|
439
|
+
|
|
440
|
+
全局的 `__getWebviewHtml__` 方法改为 `import { getWebviewHtml } from 'virtual:vscode';` 这种虚拟模块方式调用。
|
|
441
|
+
|
|
442
|
+
之前:
|
|
443
|
+
|
|
444
|
+
```ts
|
|
445
|
+
__getWebviewHtml__({
|
|
446
|
+
// vite 开发模式
|
|
447
|
+
serverUrl: process.env.VITE_DEV_SERVER_URL,
|
|
448
|
+
// vite 生产模式
|
|
449
|
+
webview,
|
|
450
|
+
context,
|
|
451
|
+
});
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
之后:
|
|
455
|
+
|
|
456
|
+
```ts
|
|
457
|
+
import { getWebviewHtml } from 'virtual:vscode';
|
|
458
|
+
|
|
459
|
+
getWebviewHtml({
|
|
460
|
+
// vite 开发模式
|
|
461
|
+
serverUrl: process.env.VITE_DEV_SERVER_URL,
|
|
462
|
+
// vite 生产模式
|
|
463
|
+
webview,
|
|
464
|
+
context,
|
|
465
|
+
});
|
|
466
|
+
```
|
|
467
|
+
|
|
450
468
|
### v5.0.0
|
|
451
469
|
|
|
452
470
|
**破坏性更新:**
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { InlineConfig } from "tsdown";
|
|
2
2
|
import { PluginOption } from "vite";
|
|
3
3
|
|
|
4
4
|
//#region src/types.d.ts
|
|
5
5
|
/**
|
|
6
6
|
* vscode extension options. See [tsdown](https://tsdown.dev/) and [Config Options](https://tsdown.dev/reference/config-options) for more information.
|
|
7
7
|
*/
|
|
8
|
-
interface ExtensionOptions extends Omit<
|
|
8
|
+
interface ExtensionOptions extends Omit<InlineConfig, 'entry' | 'format' | 'outDir' | 'watch'> {
|
|
9
9
|
/**
|
|
10
10
|
* The extension entry file.
|
|
11
11
|
* @default "extension/index.ts"
|
|
@@ -27,10 +27,6 @@ interface ExtensionOptions extends Omit<UserConfig, 'entry' | 'format' | 'outDir
|
|
|
27
27
|
* vscode webview options.
|
|
28
28
|
*/
|
|
29
29
|
interface WebviewOption {
|
|
30
|
-
/**
|
|
31
|
-
* The method name to inject. Default is `__getWebviewHtml__`
|
|
32
|
-
*/
|
|
33
|
-
name?: string;
|
|
34
30
|
/**
|
|
35
31
|
* The CSP meta for the webview. Default is `<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src {{cspSource}} 'unsafe-inline'; script-src 'nonce-{{nonce}}' 'unsafe-eval';">`
|
|
36
32
|
*/
|
|
@@ -49,22 +45,17 @@ interface PluginOptions {
|
|
|
49
45
|
*/
|
|
50
46
|
recommended?: boolean;
|
|
51
47
|
/**
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* - vite serve
|
|
55
|
-
* - extension: Inject `import __getWebviewHtml__ from '@tomjs/vite-plugin-vscode/webview';` at the top of the file that calls the `__getWebviewHtml__` method
|
|
56
|
-
* - web: Add `<script>` tag to index.html and inject `@tomjs/vite-plugin-vscode/client` code
|
|
57
|
-
* - vite build
|
|
58
|
-
* - extension: Inject `import __getWebviewHtml__ from '@tomjs/vite-plugin-vscode-inject';` at the top of the file that calls the `__getWebviewHtml__` method
|
|
59
|
-
*
|
|
60
|
-
* If is string, will set inject method name. Default is '__getWebviewHtml__'.
|
|
48
|
+
* During development, inject code into both `vscode extension code` and `web page` code to support `HMR`;
|
|
61
49
|
*
|
|
50
|
+
* During production builds, inject the final generated `index.html` code into the `vscode extension code` to minimize manual effort.
|
|
62
51
|
*
|
|
63
52
|
* @example
|
|
64
53
|
* extension file
|
|
65
54
|
* ```ts
|
|
55
|
+
*import {getWebviewHtml} from 'virtual:vscode';
|
|
56
|
+
*
|
|
66
57
|
*function setupHtml(webview: Webview, context: ExtensionContext) {
|
|
67
|
-
* return
|
|
58
|
+
* return getWebviewHtml({serverUrl:process.env.VITE_DEV_SERVER_URL, webview, context});
|
|
68
59
|
*}
|
|
69
60
|
* ```
|
|
70
61
|
*/
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
3
|
import fs from "node:fs";
|
|
4
|
-
import os from "node:os";
|
|
5
4
|
import { cwd } from "node:process";
|
|
6
|
-
import {
|
|
5
|
+
import { readFileSync, readJsonSync } from "@tomjs/node";
|
|
7
6
|
import { execa } from "execa";
|
|
8
7
|
import merge from "lodash.merge";
|
|
9
8
|
import { parse } from "node-html-parser";
|
|
@@ -19,8 +18,8 @@ const __dirname = /* @__PURE__ */ getDirname();
|
|
|
19
18
|
//#region src/constants.ts
|
|
20
19
|
const PLUGIN_NAME = "tomjs:vscode";
|
|
21
20
|
const ORG_NAME = "@tomjs";
|
|
22
|
-
const
|
|
23
|
-
const
|
|
21
|
+
const VIRTUAL_MODULE_ID = "virtual:vscode";
|
|
22
|
+
const RESOLVED_VIRTUAL_MODULE_ID = `\0${VIRTUAL_MODULE_ID}`;
|
|
24
23
|
|
|
25
24
|
//#endregion
|
|
26
25
|
//#region src/logger.ts
|
|
@@ -92,9 +91,7 @@ function preMergeOptions(options) {
|
|
|
92
91
|
treeshake: !isDev,
|
|
93
92
|
publint: false,
|
|
94
93
|
config: false,
|
|
95
|
-
|
|
96
|
-
return { js: ".js" };
|
|
97
|
-
},
|
|
94
|
+
fixedExtension: false,
|
|
98
95
|
external: ["vscode"]
|
|
99
96
|
}
|
|
100
97
|
}, options);
|
|
@@ -116,19 +113,10 @@ function preMergeOptions(options) {
|
|
|
116
113
|
}
|
|
117
114
|
if (!isDev && !opt.skipNodeModulesBundle && !opt.noExternal) opt.noExternal = Object.keys(pkg.dependencies || {}).concat(Object.keys(pkg.peerDependencies || {}));
|
|
118
115
|
opts.extension = opt;
|
|
119
|
-
if (opts.webview !== false) {
|
|
120
|
-
let name = WEBVIEW_METHOD_NAME;
|
|
121
|
-
if (typeof opts.webview === "string") name = opts.webview ?? WEBVIEW_METHOD_NAME;
|
|
122
|
-
opts.webview = Object.assign({ name }, opts.webview);
|
|
123
|
-
}
|
|
124
116
|
return opts;
|
|
125
117
|
}
|
|
126
|
-
const prodCachePkgName = `${PACKAGE_NAME}-inject`;
|
|
127
118
|
function genProdWebviewCode(cache, webview) {
|
|
128
119
|
webview = Object.assign({}, webview);
|
|
129
|
-
const prodCacheFolder = path.join(cwd(), "node_modules", prodCachePkgName);
|
|
130
|
-
emptyDirSync(prodCacheFolder);
|
|
131
|
-
const destFile = path.join(prodCacheFolder, "index.js");
|
|
132
120
|
function handleHtmlCode(html) {
|
|
133
121
|
const root = parse(html);
|
|
134
122
|
const head = root.querySelector("head");
|
|
@@ -150,7 +138,7 @@ function genProdWebviewCode(cache, webview) {
|
|
|
150
138
|
}
|
|
151
139
|
return root.removeWhitespace().toString();
|
|
152
140
|
}
|
|
153
|
-
|
|
141
|
+
return `import { Uri } from 'vscode';
|
|
154
142
|
|
|
155
143
|
${`const htmlCode = {
|
|
156
144
|
${Object.keys(cache).map((s) => `'${s}': \`${handleHtmlCode(cache[s])}\`,`).join("\n")}
|
|
@@ -177,12 +165,6 @@ export default function getWebviewHtml(options){
|
|
|
177
165
|
return html.replaceAll('{{cspSource}}', webview.cspSource).replaceAll('{{nonce}}', nonce).replaceAll('{{baseUri}}', baseUri);
|
|
178
166
|
}
|
|
179
167
|
`;
|
|
180
|
-
fs.writeFileSync(destFile, code, { encoding: "utf8" });
|
|
181
|
-
return fixWindowsPath(destFile);
|
|
182
|
-
}
|
|
183
|
-
function fixWindowsPath(webviewPath) {
|
|
184
|
-
if (os.platform() === "win32") webviewPath = webviewPath.replaceAll("\\", "/");
|
|
185
|
-
return webviewPath;
|
|
186
168
|
}
|
|
187
169
|
function useVSCodePlugin(options) {
|
|
188
170
|
const opts = preMergeOptions(options);
|
|
@@ -208,8 +190,8 @@ function useVSCodePlugin(options) {
|
|
|
208
190
|
rollupOptions: { output: rollupOutput }
|
|
209
191
|
} };
|
|
210
192
|
};
|
|
211
|
-
let
|
|
212
|
-
|
|
193
|
+
let devWebviewClientCode;
|
|
194
|
+
let devWebviewVirtualCode;
|
|
213
195
|
let resolvedConfig;
|
|
214
196
|
const prodHtmlCache = {};
|
|
215
197
|
let devtoolsFlag = false;
|
|
@@ -221,6 +203,10 @@ function useVSCodePlugin(options) {
|
|
|
221
203
|
},
|
|
222
204
|
configResolved(config) {
|
|
223
205
|
resolvedConfig = config;
|
|
206
|
+
if (opts.webview) {
|
|
207
|
+
devWebviewClientCode = readFileSync(path.join(__dirname, "client.iife.js"));
|
|
208
|
+
devWebviewVirtualCode = readFileSync(path.join(__dirname, "webview.js"));
|
|
209
|
+
}
|
|
224
210
|
},
|
|
225
211
|
configureServer(server) {
|
|
226
212
|
if (!server || !server.httpServer) return;
|
|
@@ -246,10 +232,11 @@ function useVSCodePlugin(options) {
|
|
|
246
232
|
logLevel: logLevel ?? "silent",
|
|
247
233
|
plugins: !webview ? [] : [{
|
|
248
234
|
name: `${ORG_NAME}:vscode:inject`,
|
|
249
|
-
|
|
250
|
-
if (id
|
|
251
|
-
|
|
252
|
-
|
|
235
|
+
resolveId(id) {
|
|
236
|
+
if (id === VIRTUAL_MODULE_ID) return RESOLVED_VIRTUAL_MODULE_ID;
|
|
237
|
+
},
|
|
238
|
+
load(id) {
|
|
239
|
+
if (id === RESOLVED_VIRTUAL_MODULE_ID) return devWebviewVirtualCode;
|
|
253
240
|
}
|
|
254
241
|
}],
|
|
255
242
|
async onSuccess(config, signal) {
|
|
@@ -275,7 +262,7 @@ function useVSCodePlugin(options) {
|
|
|
275
262
|
logger.warn("Only support react-devtools and vue-devtools!");
|
|
276
263
|
}
|
|
277
264
|
}
|
|
278
|
-
return html.replace(/<head>/i, `<head><script>${
|
|
265
|
+
return html.replace(/<head>/i, `<head><script>${devWebviewClientCode}<\/script>`);
|
|
279
266
|
}
|
|
280
267
|
}, {
|
|
281
268
|
name: "@tomjs:vscode",
|
|
@@ -293,9 +280,9 @@ function useVSCodePlugin(options) {
|
|
|
293
280
|
return html;
|
|
294
281
|
},
|
|
295
282
|
closeBundle() {
|
|
296
|
-
let
|
|
283
|
+
let webviewVirtualCode;
|
|
297
284
|
const webview = opts?.webview;
|
|
298
|
-
if (webview)
|
|
285
|
+
if (webview) webviewVirtualCode = genProdWebviewCode(prodHtmlCache, webview);
|
|
299
286
|
let outDir = resolvedConfig.build.outDir.replace(cwd(), "").replaceAll("\\", "/");
|
|
300
287
|
if (outDir.startsWith("/")) outDir = outDir.substring(1);
|
|
301
288
|
const env = {
|
|
@@ -309,10 +296,11 @@ function useVSCodePlugin(options) {
|
|
|
309
296
|
logLevel: logLevel ?? "silent",
|
|
310
297
|
plugins: !webview ? [] : [{
|
|
311
298
|
name: `${ORG_NAME}:vscode:inject`,
|
|
312
|
-
|
|
313
|
-
if (id
|
|
314
|
-
|
|
315
|
-
|
|
299
|
+
resolveId(id) {
|
|
300
|
+
if (id === VIRTUAL_MODULE_ID) return RESOLVED_VIRTUAL_MODULE_ID;
|
|
301
|
+
},
|
|
302
|
+
load(id) {
|
|
303
|
+
if (id === RESOLVED_VIRTUAL_MODULE_ID) return webviewVirtualCode;
|
|
316
304
|
}
|
|
317
305
|
}],
|
|
318
306
|
async onSuccess(config, signal) {
|
package/dist/webview.js
CHANGED
|
@@ -1,188 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
<html lang
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
height: 100%;
|
|
20
|
-
border: none;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
.outer {
|
|
24
|
-
width: 100%;
|
|
25
|
-
height: 100%;
|
|
26
|
-
overflow: hidden;
|
|
27
|
-
}
|
|
28
|
-
</style>
|
|
29
|
-
|
|
30
|
-
<script type="module" id="webview-patch">
|
|
31
|
-
const TAG = '[@tomjs:vscode:extension] ';
|
|
32
|
-
|
|
33
|
-
function onDomReady(callback, doc) {
|
|
34
|
-
const _doc = doc || document;
|
|
35
|
-
if (_doc.readyState === 'interactive' || _doc.readyState === 'complete') {
|
|
36
|
-
callback();
|
|
37
|
-
} else {
|
|
38
|
-
_doc.addEventListener('DOMContentLoaded', callback);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
let vsCodeApi;
|
|
43
|
-
|
|
44
|
-
function getApi() {
|
|
45
|
-
if (vsCodeApi) return vsCodeApi;
|
|
46
|
-
return (vsCodeApi = acquireVsCodeApi());
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function sendInitData(iframe) {
|
|
50
|
-
console.log(TAG + 'init data');
|
|
51
|
-
const dataset = {};
|
|
52
|
-
Object.keys(document.body.dataset).forEach((key) => {
|
|
53
|
-
dataset[key] = document.body.dataset[key];
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
iframe.contentWindow.postMessage(
|
|
57
|
-
{
|
|
58
|
-
type: '[vscode:extension]:init',
|
|
59
|
-
data: {
|
|
60
|
-
state: getApi().getState(),
|
|
61
|
-
style: document.getElementById('_defaultStyles').innerHTML,
|
|
62
|
-
root: {
|
|
63
|
-
cssText: document.documentElement.style.cssText,
|
|
64
|
-
},
|
|
65
|
-
body: {
|
|
66
|
-
dataset: dataset,
|
|
67
|
-
className: document.body.className,
|
|
68
|
-
role: document.body.getAttribute('role'),
|
|
69
|
-
},
|
|
70
|
-
},
|
|
71
|
-
},
|
|
72
|
-
'*',
|
|
73
|
-
);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function observeAttributeChanges(element, attributeName, callback) {
|
|
77
|
-
const observer = new MutationObserver(function (mutationsList) {
|
|
78
|
-
for (let mutation of mutationsList) {
|
|
79
|
-
if (mutation.type === 'attributes' && mutation.attributeName === attributeName) {
|
|
80
|
-
callback(mutation.target.getAttribute(attributeName));
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
observer.observe(element, { attributes: true });
|
|
85
|
-
return observer;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// message handler
|
|
89
|
-
let iframeLoaded = false;
|
|
90
|
-
const cacheMessages = [];
|
|
91
|
-
|
|
92
|
-
function handleMessage(e) {
|
|
93
|
-
const iframe = document.getElementById('webview-patch-iframe');
|
|
94
|
-
if (!iframeLoaded || !iframe) {
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
if (e.origin.startsWith('vscode-webview://')) {
|
|
98
|
-
iframe.contentWindow.postMessage(e.data, '*');
|
|
99
|
-
} else if ('{{serverUrl}}'.startsWith(e.origin)) {
|
|
100
|
-
const { type, data } = e.data;
|
|
101
|
-
console.log(TAG + ' received:', e.data);
|
|
102
|
-
if (type === '[vscode:client]:postMessage') {
|
|
103
|
-
getApi().postMessage(data);
|
|
104
|
-
} else if (type === '[vscode:client]:commands') {
|
|
105
|
-
if (data === 'F1') {
|
|
106
|
-
window.dispatchEvent(
|
|
107
|
-
new KeyboardEvent('keydown', {
|
|
108
|
-
key: 'F1',
|
|
109
|
-
keyCode: 112,
|
|
110
|
-
code: 'F1',
|
|
111
|
-
}),
|
|
112
|
-
);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
window.addEventListener('message', function (event) {
|
|
119
|
-
if (event.origin.startsWith('vscode-webview://')) {
|
|
120
|
-
cacheMessages.push(event);
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
handleMessage(event);
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
let isCacheWorking = false;
|
|
127
|
-
setInterval(() => {
|
|
128
|
-
if (isCacheWorking) {
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
isCacheWorking = true;
|
|
133
|
-
if (iframeLoaded) {
|
|
134
|
-
let event = cacheMessages.shift();
|
|
135
|
-
while (event) {
|
|
136
|
-
handleMessage(event);
|
|
137
|
-
event = cacheMessages.shift();
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
isCacheWorking = false;
|
|
141
|
-
}, 50);
|
|
142
|
-
|
|
143
|
-
onDomReady(function () {
|
|
144
|
-
/** @type {HTMLIFrameElement} */
|
|
145
|
-
const iframe = document.getElementById('webview-patch-iframe');
|
|
146
|
-
observeAttributeChanges(document.body, 'class', function (className) {
|
|
147
|
-
sendInitData(iframe);
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
onDomReady(function () {
|
|
151
|
-
iframeLoaded = true;
|
|
152
|
-
sendInitData(iframe);
|
|
153
|
-
}, iframe.contentDocument);
|
|
154
|
-
|
|
155
|
-
iframe.addEventListener('load', function (e) {
|
|
156
|
-
iframeLoaded = true;
|
|
157
|
-
|
|
158
|
-
let interval = setInterval(() => {
|
|
159
|
-
try {
|
|
160
|
-
if (document.getElementById('_defaultStyles')) {
|
|
161
|
-
sendInitData(iframe);
|
|
162
|
-
// addListeners(iframe);
|
|
163
|
-
clearInterval(interval);
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
} catch (e) {
|
|
167
|
-
clearInterval(interval);
|
|
168
|
-
console.error(e);
|
|
169
|
-
}
|
|
170
|
-
}, 10);
|
|
171
|
-
});
|
|
172
|
-
});
|
|
173
|
-
<\/script>
|
|
174
|
-
</head>
|
|
175
|
-
|
|
176
|
-
<body>
|
|
177
|
-
<div class="outer">
|
|
178
|
-
<iframe
|
|
179
|
-
id="webview-patch-iframe"
|
|
180
|
-
frameborder="0"
|
|
181
|
-
sandbox="allow-scripts allow-same-origin allow-forms allow-pointer-lock allow-downloads"
|
|
182
|
-
allow="cross-origin-isolated; autoplay; clipboard-read; clipboard-write"
|
|
183
|
-
src="{{serverUrl}}"
|
|
184
|
-
></iframe>
|
|
185
|
-
</div>
|
|
186
|
-
</body>
|
|
187
|
-
</html>
|
|
188
|
-
`;function t(t){let n={serverUrl:``};return Object.assign(n,t),e.replace(/\{\{serverUrl\}\}/g,n.serverUrl)}var n=t;export{n as default,t as getWebviewHtml};
|
|
1
|
+
//#region src/webview/template.html
|
|
2
|
+
var template_default = "<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <style>\n html,\n body {\n width: 100%;\n height: 100%;\n margin: 0;\n padding: 0;\n overflow: hidden;\n }\n\n #webview-patch-iframe {\n width: 100%;\n height: 100%;\n border: none;\n }\n\n .outer {\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n </style>\n\n <script type=\"module\" id=\"webview-patch\">\n const TAG = '[@tomjs:vscode:extension] ';\n\n function onDomReady(callback, doc) {\n const _doc = doc || document;\n if (_doc.readyState === 'interactive' || _doc.readyState === 'complete') {\n callback();\n } else {\n _doc.addEventListener('DOMContentLoaded', callback);\n }\n }\n\n let vsCodeApi;\n\n function getApi() {\n if (vsCodeApi) return vsCodeApi;\n return (vsCodeApi = acquireVsCodeApi());\n }\n\n function sendInitData(iframe) {\n console.log(TAG + 'init data');\n const dataset = {};\n Object.keys(document.body.dataset).forEach((key) => {\n dataset[key] = document.body.dataset[key];\n });\n\n iframe.contentWindow.postMessage(\n {\n type: '[vscode:extension]:init',\n data: {\n state: getApi().getState(),\n style: document.getElementById('_defaultStyles').innerHTML,\n root: {\n cssText: document.documentElement.style.cssText,\n },\n body: {\n dataset: dataset,\n className: document.body.className,\n role: document.body.getAttribute('role'),\n },\n },\n },\n '*',\n );\n }\n\n function observeAttributeChanges(element, attributeName, callback) {\n const observer = new MutationObserver(function (mutationsList) {\n for (let mutation of mutationsList) {\n if (mutation.type === 'attributes' && mutation.attributeName === attributeName) {\n callback(mutation.target.getAttribute(attributeName));\n }\n }\n });\n observer.observe(element, { attributes: true });\n return observer;\n }\n\n // message handler\n let iframeLoaded = false;\n const cacheMessages = [];\n\n function handleMessage(e) {\n const iframe = document.getElementById('webview-patch-iframe');\n if (!iframeLoaded || !iframe) {\n return;\n }\n if (e.origin.startsWith('vscode-webview://')) {\n iframe.contentWindow.postMessage(e.data, '*');\n } else if ('{{serverUrl}}'.startsWith(e.origin)) {\n const { type, data } = e.data;\n console.log(TAG + ' received:', e.data);\n if (type === '[vscode:client]:postMessage') {\n getApi().postMessage(data);\n } else if (type === '[vscode:client]:commands') {\n if (data === 'F1') {\n window.dispatchEvent(\n new KeyboardEvent('keydown', {\n key: 'F1',\n keyCode: 112,\n code: 'F1',\n }),\n );\n }\n }\n }\n }\n\n window.addEventListener('message', function (event) {\n if (event.origin.startsWith('vscode-webview://')) {\n cacheMessages.push(event);\n return;\n }\n handleMessage(event);\n });\n\n let isCacheWorking = false;\n setInterval(() => {\n if (isCacheWorking) {\n return;\n }\n\n isCacheWorking = true;\n if (iframeLoaded) {\n let event = cacheMessages.shift();\n while (event) {\n handleMessage(event);\n event = cacheMessages.shift();\n }\n }\n isCacheWorking = false;\n }, 50);\n\n onDomReady(function () {\n /** @type {HTMLIFrameElement} */\n const iframe = document.getElementById('webview-patch-iframe');\n observeAttributeChanges(document.body, 'class', function (className) {\n sendInitData(iframe);\n });\n\n onDomReady(function () {\n iframeLoaded = true;\n sendInitData(iframe);\n }, iframe.contentDocument);\n\n iframe.addEventListener('load', function (e) {\n iframeLoaded = true;\n\n let interval = setInterval(() => {\n try {\n if (document.getElementById('_defaultStyles')) {\n sendInitData(iframe);\n // addListeners(iframe);\n clearInterval(interval);\n return;\n }\n } catch (e) {\n clearInterval(interval);\n console.error(e);\n }\n }, 10);\n });\n });\n <\/script>\n </head>\n\n <body>\n <div class=\"outer\">\n <iframe\n id=\"webview-patch-iframe\"\n frameborder=\"0\"\n sandbox=\"allow-scripts allow-same-origin allow-forms allow-pointer-lock allow-downloads\"\n allow=\"cross-origin-isolated; autoplay; clipboard-read; clipboard-write\"\n src=\"{{serverUrl}}\"\n ></iframe>\n </div>\n </body>\n</html>\n";
|
|
3
|
+
|
|
4
|
+
//#endregion
|
|
5
|
+
//#region src/webview/webview.ts
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
* @param options serverUrl string or object options
|
|
9
|
+
*/
|
|
10
|
+
function getWebviewHtml(options) {
|
|
11
|
+
const opts = { serverUrl: "" };
|
|
12
|
+
Object.assign(opts, options);
|
|
13
|
+
return template_default.replace(/\{\{serverUrl\}\}/g, opts.serverUrl);
|
|
14
|
+
}
|
|
15
|
+
var webview_default = getWebviewHtml;
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
export { webview_default as default, getWebviewHtml };
|
package/env-webview.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inject some methods such as `getWebviewHtml`
|
|
3
|
+
*/
|
|
4
|
+
declare module 'virtual:vscode' {
|
|
5
|
+
import type { ExtensionContext, Webview } from 'vscode';
|
|
6
|
+
|
|
7
|
+
export interface WebviewHtmlOptions {
|
|
8
|
+
/**
|
|
9
|
+
* `[vite serve]` The url of the vite dev server. Please use `process.env.VITE_DEV_SERVER_URL`
|
|
10
|
+
*/
|
|
11
|
+
serverUrl?: string;
|
|
12
|
+
/**
|
|
13
|
+
* `[vite build]` The Webview instance of the extension.
|
|
14
|
+
*/
|
|
15
|
+
webview: Webview;
|
|
16
|
+
/**
|
|
17
|
+
* `[vite build]` The ExtensionContext instance of the extension.
|
|
18
|
+
*/
|
|
19
|
+
context: ExtensionContext;
|
|
20
|
+
/**
|
|
21
|
+
* `[vite build]` vite build.rollupOptions.input name. Default is `index`.
|
|
22
|
+
*/
|
|
23
|
+
inputName?: string;
|
|
24
|
+
/**
|
|
25
|
+
* `[vite build]` Inject code into the afterbegin of the head element.
|
|
26
|
+
*/
|
|
27
|
+
injectCode?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Get the html of the webview.
|
|
32
|
+
*
|
|
33
|
+
* @param options
|
|
34
|
+
*/
|
|
35
|
+
export const getWebviewHtml: (options?: WebviewHtmlOptions) => string;
|
|
36
|
+
|
|
37
|
+
export default getWebviewHtml;
|
|
38
|
+
}
|
package/env.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
/// <reference types="./env-webview.d.ts" />
|
|
2
|
+
import type { WebviewHtmlOptions } from 'virtual:vscode';
|
|
3
|
+
|
|
2
4
|
// Make this a module
|
|
3
5
|
export {};
|
|
4
6
|
declare global {
|
|
@@ -24,31 +26,25 @@ declare global {
|
|
|
24
26
|
}
|
|
25
27
|
}
|
|
26
28
|
|
|
27
|
-
interface WebviewHtmlOptions {
|
|
28
|
-
/**
|
|
29
|
-
* `[vite serve]` The url of the vite dev server. Please use `process.env.VITE_DEV_SERVER_URL`
|
|
30
|
-
*/
|
|
31
|
-
serverUrl?: string;
|
|
32
|
-
/**
|
|
33
|
-
* `[vite build]` The Webview instance of the extension.
|
|
34
|
-
*/
|
|
35
|
-
webview: Webview;
|
|
36
|
-
/**
|
|
37
|
-
* `[vite build]` The ExtensionContext instance of the extension.
|
|
38
|
-
*/
|
|
39
|
-
context: ExtensionContext;
|
|
40
|
-
/**
|
|
41
|
-
* `[vite build]` vite build.rollupOptions.input name. Default is `index`.
|
|
42
|
-
*/
|
|
43
|
-
inputName?: string;
|
|
44
|
-
/**
|
|
45
|
-
* `[vite build]` Inject code into the afterbegin of the head element.
|
|
46
|
-
*/
|
|
47
|
-
injectCode?: string;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
29
|
/**
|
|
51
|
-
* Gets the html of webview
|
|
30
|
+
* Gets the html of webview. It's deprecated. Please use `import { getWebviewHtml } from 'virtual:vscode';`.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* import type { ExtensionContext, Webview } from 'vscode';
|
|
34
|
+
* import { getWebviewHtml } from 'virtual:vscode';
|
|
35
|
+
* import { window } from 'vscode';
|
|
36
|
+
*
|
|
37
|
+
* export class WebviewHelper {
|
|
38
|
+
* public static setupHtml(webview: Webview, context: ExtensionContext) {
|
|
39
|
+
* return getWebviewHtml({
|
|
40
|
+
* serverUrl: process.env.VITE_DEV_SERVER_URL,
|
|
41
|
+
* webview,
|
|
42
|
+
* context,
|
|
43
|
+
* injectCode: `<script>window.__FLAG1__=666;window.__FLAG2__=888;</script>`,
|
|
44
|
+
* });
|
|
45
|
+
* }
|
|
46
|
+
*
|
|
47
|
+
* @deprecated
|
|
52
48
|
*/
|
|
53
49
|
function __getWebviewHtml__(options?: WebviewHtmlOptions): string;
|
|
54
50
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tomjs/vite-plugin-vscode",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "6.0.0",
|
|
5
5
|
"description": "Use vue/react to develop 'vscode extension webview', supporting esm/cjs",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Tom Gao",
|
|
@@ -21,8 +21,7 @@
|
|
|
21
21
|
"extension",
|
|
22
22
|
"webview",
|
|
23
23
|
"esm",
|
|
24
|
-
"cjs"
|
|
25
|
-
"mjs"
|
|
24
|
+
"cjs"
|
|
26
25
|
],
|
|
27
26
|
"exports": {
|
|
28
27
|
".": "./dist/index.js",
|
|
@@ -33,8 +32,8 @@
|
|
|
33
32
|
"module": "./dist/index.js",
|
|
34
33
|
"types": "./dist/index.d.ts",
|
|
35
34
|
"files": [
|
|
36
|
-
"
|
|
37
|
-
"
|
|
35
|
+
"*.d.ts",
|
|
36
|
+
"dist"
|
|
38
37
|
],
|
|
39
38
|
"engines": {
|
|
40
39
|
"node": ">=18.19"
|
|
@@ -44,27 +43,24 @@
|
|
|
44
43
|
"registry": "https://registry.npmjs.org/"
|
|
45
44
|
},
|
|
46
45
|
"peerDependencies": {
|
|
46
|
+
"@types/vscode": "^1.56.0",
|
|
47
47
|
"vite": ">=2"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
50
|
"@tomjs/logger": "^1.4.0",
|
|
51
51
|
"@tomjs/node": "^2.2.3",
|
|
52
|
-
"dayjs": "^1.11.19",
|
|
53
52
|
"execa": "^9.6.1",
|
|
54
|
-
"kolorist": "^1.8.0",
|
|
55
|
-
"lodash.clonedeep": "^4.5.0",
|
|
56
53
|
"lodash.merge": "^4.6.2",
|
|
57
54
|
"node-html-parser": "^7.0.1",
|
|
58
55
|
"tsdown": "~0.18.3"
|
|
59
56
|
},
|
|
60
57
|
"devDependencies": {
|
|
61
|
-
"@antfu/eslint-config": "^6.7.
|
|
58
|
+
"@antfu/eslint-config": "^6.7.3",
|
|
62
59
|
"@commitlint/cli": "^20.2.0",
|
|
63
60
|
"@tomjs/commitlint": "^5.0.0",
|
|
64
61
|
"@tomjs/eslint": "^6.0.0",
|
|
65
62
|
"@tomjs/stylelint": "^7.0.0",
|
|
66
63
|
"@tomjs/tsconfig": "^2.2.0",
|
|
67
|
-
"@types/lodash.clonedeep": "^4.5.9",
|
|
68
64
|
"@types/lodash.merge": "^4.6.9",
|
|
69
65
|
"@types/node": "^20.19.27",
|
|
70
66
|
"@vitejs/plugin-vue": "^6.0.3",
|