@tomjs/vite-plugin-vscode 1.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/LICENSE +21 -0
- package/README.md +283 -0
- package/README.zh_CN.md +282 -0
- package/dist/index.d.mts +74 -0
- package/dist/index.d.ts +74 -0
- package/dist/index.js +261 -0
- package/dist/index.mjs +260 -0
- package/package.json +84 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023-PRESENT Tom Gao<tom@tomgao.cc>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
# @tomjs/vite-plugin-vscode
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@tomjs/vite-plugin-vscode)   [](https://www.paka.dev/npm/@tomjs/vite-plugin-vscode)
|
|
4
|
+
|
|
5
|
+
**English** | [中文](./README.zh_CN.md)
|
|
6
|
+
|
|
7
|
+
> The [vite](https://cn.vitejs.dev/) plugin for [vscode extension](https://code.visualstudio.com/api), supports `esm` and `cjs`.
|
|
8
|
+
|
|
9
|
+
Inject [@tomjs/vscode-extension-webview](https://github.com/tomgao365/vscode-extension-webview) into vscode extension code and web client code, so that webview can support HMR during the development stage.
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- Fast build `extension` with [tsup](https://github.com/egoist/tsup)
|
|
14
|
+
- Little configuration, focus on business
|
|
15
|
+
- Support `esm` and `cjs`
|
|
16
|
+
- Support webview `HMR`
|
|
17
|
+
- Support `vue` and `react` and other [frameworks](https://vitejs.dev/guide/#trying-vite-online) supported by `vite`
|
|
18
|
+
|
|
19
|
+
## Install
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# pnpm
|
|
23
|
+
pnpm add @tomjs/vite-plugin-vscode -D
|
|
24
|
+
|
|
25
|
+
# yarn
|
|
26
|
+
yarn add @tomjs/vite-plugin-vscode -D
|
|
27
|
+
|
|
28
|
+
# npm
|
|
29
|
+
npm i @tomjs/vite-plugin-vscode --save-dev
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Usage
|
|
33
|
+
|
|
34
|
+
### Recommended Agreement
|
|
35
|
+
|
|
36
|
+
#### Directory Structure
|
|
37
|
+
|
|
38
|
+
- Recommend `extension` and page `src` code directory structure
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
|--extension // extension code
|
|
42
|
+
| |--index.ts
|
|
43
|
+
|--src // front-end code
|
|
44
|
+
| |--App.vue
|
|
45
|
+
| |--main.ts
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
- Zero configuration, default dist output directory
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
|--dist
|
|
52
|
+
| |--extension
|
|
53
|
+
| | |--index.js
|
|
54
|
+
| | |--index.js.map
|
|
55
|
+
| |--webview
|
|
56
|
+
| | |--index.html
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
#### Default configuration and behavior
|
|
60
|
+
|
|
61
|
+
See [PluginOptions](#pluginoptions) and `recommended` parameter descriptions in detail
|
|
62
|
+
|
|
63
|
+
### extension
|
|
64
|
+
|
|
65
|
+
code snippet, more code see examples
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
const panel = window.createWebviewPanel('showHelloWorld', 'Hello World', ViewColumn.One, {
|
|
69
|
+
enableScripts: true,
|
|
70
|
+
localResourceRoots: [Uri.joinPath(extensionUri, 'dist/webview')],
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
private _getWebviewContent(webview: Webview, extensionUri: Uri) {
|
|
76
|
+
// The CSS file from the Vue build output
|
|
77
|
+
const stylesUri = getUri(webview, extensionUri, ['dist', 'webview', 'assets', 'index.css']);
|
|
78
|
+
// The JS file from the Vue build output
|
|
79
|
+
const scriptUri = getUri(webview, extensionUri, ['dist', 'webview', 'assets', 'index.js']);
|
|
80
|
+
|
|
81
|
+
const nonce = uuid();
|
|
82
|
+
|
|
83
|
+
if (process.env.VITE_DEV_SERVER_URL) {
|
|
84
|
+
// @ts-ignore
|
|
85
|
+
return __getWebviewHtml({ serverUrl: process.env.VITE_DEV_SERVER_URL });
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Tip: Install the es6-string-html VS Code extension to enable code highlighting below
|
|
89
|
+
return /*html*/ `
|
|
90
|
+
<!doctype html>
|
|
91
|
+
<html lang="en">
|
|
92
|
+
<head>
|
|
93
|
+
<meta charset="UTF-8" />
|
|
94
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
95
|
+
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src ${webview.cspSource}; script-src 'nonce-${nonce}';">
|
|
96
|
+
<script type="module" crossorigin nonce="${nonce}" src="${scriptUri}"></script>
|
|
97
|
+
<link rel="stylesheet" crossorigin href="${stylesUri}">
|
|
98
|
+
<title>Hello World</title>
|
|
99
|
+
</head>
|
|
100
|
+
<body>
|
|
101
|
+
<div id="app"></div>
|
|
102
|
+
</body>
|
|
103
|
+
</html>
|
|
104
|
+
`;
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
- `package.json`
|
|
109
|
+
|
|
110
|
+
```json
|
|
111
|
+
{
|
|
112
|
+
"main": "dist/extension/index.js"
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### vue
|
|
117
|
+
|
|
118
|
+
- `vite.config.ts`
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
import { defineConfig } from 'vite';
|
|
122
|
+
import vscode from '@tomjs/vite-plugin-vscode';
|
|
123
|
+
import vue from '@vitejs/plugin-vue';
|
|
124
|
+
|
|
125
|
+
// https://vitejs.dev/config/
|
|
126
|
+
export default defineConfig({
|
|
127
|
+
plugins: [
|
|
128
|
+
vue({
|
|
129
|
+
template: {
|
|
130
|
+
compilerOptions: {
|
|
131
|
+
isCustomElement: (tag: string) => tag.startsWith('vscode-'),
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
}),
|
|
135
|
+
vscode(),
|
|
136
|
+
],
|
|
137
|
+
build: {
|
|
138
|
+
rollupOptions: {
|
|
139
|
+
output: {
|
|
140
|
+
entryFileNames: `assets/[name].js`,
|
|
141
|
+
chunkFileNames: `assets/[name].js`,
|
|
142
|
+
assetFileNames: `assets/[name].[ext]`,
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### react
|
|
150
|
+
|
|
151
|
+
- `vite.config.ts`
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
import { defineConfig } from 'vite';
|
|
155
|
+
import vscode from '@tomjs/vite-plugin-vscode';
|
|
156
|
+
import react from '@vitejs/plugin-react-swc';
|
|
157
|
+
|
|
158
|
+
// https://vitejs.dev/config/
|
|
159
|
+
export default defineConfig({
|
|
160
|
+
plugins: [react(), vscode()],
|
|
161
|
+
build: {
|
|
162
|
+
rollupOptions: {
|
|
163
|
+
output: {
|
|
164
|
+
entryFileNames: `assets/[name].js`,
|
|
165
|
+
chunkFileNames: `assets/[name].js`,
|
|
166
|
+
assetFileNames: `assets/[name].[ext]`,
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
});
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Documentation
|
|
174
|
+
|
|
175
|
+
- [API Documentation](https://paka.dev/npm/@tomjs/vite-plugin-vscode) provided by [paka.dev](https://paka.dev).
|
|
176
|
+
- [index.d.ts](https://www.unpkg.com/browse/@tomjs/vite-plugin-vscode/dist/index.d.ts) provided by [unpkg.com](https://www.unpkg.com).
|
|
177
|
+
|
|
178
|
+
## Parameters
|
|
179
|
+
|
|
180
|
+
### PluginOptions
|
|
181
|
+
|
|
182
|
+
| Property | Type | Default | Description |
|
|
183
|
+
| --- | --- | --- | --- |
|
|
184
|
+
| recommended | `boolean` | `true` | This option is intended to provide recommended default parameters and behavior. |
|
|
185
|
+
| extension | [ExtensionOptions](#ExtensionOptions) | | Configuration options for the vscode extension. |
|
|
186
|
+
| webview | `boolean` | `false` | Inject [@tomjs/vscode-extension-webview](https://github.com/tomgao365/vscode-extension-webview) into vscode extension code and web client code, so that webview can support HMR during the development stage. |
|
|
187
|
+
|
|
188
|
+
**Notice**
|
|
189
|
+
|
|
190
|
+
The `recommended` option is used to set the default configuration and behavior, which can be used with almost zero configuration. The default is `true`. If you want to customize the configuration, set it to `false`. The following default prerequisites are to use the recommended [project structure](#directory-structure).
|
|
191
|
+
|
|
192
|
+
- The output directory is based on the `build.outDir` parameter of `vite`, and outputs `extension` and `src` to `dist/extension` and `dist/webview` respectively.
|
|
193
|
+
- Other behaviors to be implemented
|
|
194
|
+
|
|
195
|
+
### ExtensionOptions
|
|
196
|
+
|
|
197
|
+
Based on [Options](https://paka.dev/npm/tsup) of [tsup](https://tsup.egoist.dev/), some default values are added for ease of use.
|
|
198
|
+
|
|
199
|
+
| Property | Type | Default | Description |
|
|
200
|
+
| --- | --- | --- | --- |
|
|
201
|
+
| entry | `string` | `extension/index.ts` | The vscode extension entry file. |
|
|
202
|
+
| outDir | `string` | `dist-extension/main` | The output directory for the vscode extension file |
|
|
203
|
+
| onSuccess | `() => Promise<void \| undefined \| (() => void \| Promise<void>)>` | `undefined` | A function that will be executed after the build succeeds. |
|
|
204
|
+
|
|
205
|
+
### Additional Information
|
|
206
|
+
|
|
207
|
+
- Default values for `extension` when the relevant parameters are not configured
|
|
208
|
+
|
|
209
|
+
| Parameter | Development Mode Default | Production Mode Default |
|
|
210
|
+
| --------- | ------------------------ | ----------------------- |
|
|
211
|
+
| sourcemap | `true` | `false` |
|
|
212
|
+
| minify | `false` | `true` |
|
|
213
|
+
|
|
214
|
+
## Environment Variables
|
|
215
|
+
|
|
216
|
+
### Vite plugin variables
|
|
217
|
+
|
|
218
|
+
`vscode extension` use.
|
|
219
|
+
|
|
220
|
+
| Variable | Description |
|
|
221
|
+
| --------------------- | -------------------------- |
|
|
222
|
+
| `VITE_DEV_SERVER_URL` | The url of the dev server. |
|
|
223
|
+
|
|
224
|
+
## Debug
|
|
225
|
+
|
|
226
|
+
Run `Run Extension` through `vscode` to debug. For debugging tools, refer to [Official Documentation](https://code.visualstudio.com/docs/editor/debugging)
|
|
227
|
+
|
|
228
|
+
`launch.json` is configured as follows:
|
|
229
|
+
|
|
230
|
+
```json
|
|
231
|
+
{
|
|
232
|
+
"version": "0.2.0",
|
|
233
|
+
"configurations": [
|
|
234
|
+
{
|
|
235
|
+
"name": "Run Extension",
|
|
236
|
+
"type": "extensionHost",
|
|
237
|
+
"request": "launch",
|
|
238
|
+
"args": ["--extensionDevelopmentPath=${workspaceFolder}"],
|
|
239
|
+
"outFiles": ["${workspaceFolder}/dist/extension/*.js"],
|
|
240
|
+
"preLaunchTask": "${defaultBuildTask}"
|
|
241
|
+
}
|
|
242
|
+
]
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
`tasks.json` is configured as follows:
|
|
247
|
+
|
|
248
|
+
```json
|
|
249
|
+
{
|
|
250
|
+
"version": "2.0.0",
|
|
251
|
+
"tasks": [
|
|
252
|
+
{
|
|
253
|
+
"type": "npm",
|
|
254
|
+
"script": "dev",
|
|
255
|
+
"problemMatcher": {
|
|
256
|
+
"owner": "typescript",
|
|
257
|
+
"fileLocation": "relative",
|
|
258
|
+
"pattern": {
|
|
259
|
+
"regexp": "^([a-zA-Z]\\:/?([\\w\\-]/?)+\\.\\w+):(\\d+):(\\d+): (ERROR|WARNING)\\: (.*)$",
|
|
260
|
+
"file": 1,
|
|
261
|
+
"line": 3,
|
|
262
|
+
"column": 4,
|
|
263
|
+
"code": 5,
|
|
264
|
+
"message": 6
|
|
265
|
+
},
|
|
266
|
+
"background": {
|
|
267
|
+
"activeOnStart": true,
|
|
268
|
+
"beginsPattern": "^.*extension build start*$",
|
|
269
|
+
"endsPattern": "^.*extension (build|rebuild) success.*$"
|
|
270
|
+
}
|
|
271
|
+
},
|
|
272
|
+
"isBackground": true,
|
|
273
|
+
"presentation": {
|
|
274
|
+
"reveal": "never"
|
|
275
|
+
},
|
|
276
|
+
"group": {
|
|
277
|
+
"kind": "build",
|
|
278
|
+
"isDefault": true
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
]
|
|
282
|
+
}
|
|
283
|
+
```
|
package/README.zh_CN.md
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
# @tomjs/vite-plugin-vscode
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@tomjs/vite-plugin-vscode)   [](https://www.paka.dev/npm/@tomjs/vite-plugin-vscode)
|
|
4
|
+
|
|
5
|
+
[English](./README.md) | **中文**
|
|
6
|
+
|
|
7
|
+
> [vscode extension](https://code.visualstudio.com/api) 的 [vite](https://cn.vitejs.dev/) 插件,支持 `esm` 和 `cjs`。
|
|
8
|
+
|
|
9
|
+
给 vscode 扩展代码和 web 客户端代码中注入 [@tomjs/vscode-extension-webview](https://github.com/tomgao365/vscode-extension-webview),可以让 webview 在开发阶段支持 `HMR`
|
|
10
|
+
|
|
11
|
+
## 特性
|
|
12
|
+
|
|
13
|
+
- 使用 [tsup](https://github.com/egoist/tsup) 快速构建 `main` 和 `preload`
|
|
14
|
+
- 配置简单,专注业务
|
|
15
|
+
- 支持 `esm`和 `cjs`
|
|
16
|
+
- 支持 webview `HMR`
|
|
17
|
+
- 支持 `vue` 和 `react` 等其他 `vite` 支持的[框架](https://cn.vitejs.dev/guide/#trying-vite-online)
|
|
18
|
+
|
|
19
|
+
## 安装
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# pnpm
|
|
23
|
+
pnpm add @tomjs/vite-plugin-vscode -D
|
|
24
|
+
|
|
25
|
+
# yarn
|
|
26
|
+
yarn add @tomjs/vite-plugin-vscode -D
|
|
27
|
+
|
|
28
|
+
# npm
|
|
29
|
+
npm i @tomjs/vite-plugin-vscode --save-dev
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## 使用说明
|
|
33
|
+
|
|
34
|
+
### 推荐约定
|
|
35
|
+
|
|
36
|
+
#### 目录结构
|
|
37
|
+
|
|
38
|
+
- 推荐 `extension` 和 页面 `src` 代码目录结构
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
|--extension // extension code
|
|
42
|
+
| |--index.ts
|
|
43
|
+
|--src // front-end code
|
|
44
|
+
| |--App.vue
|
|
45
|
+
| |--main.ts
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
- 零配置,默认 dist 输出目录
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
|--dist
|
|
52
|
+
| |--extension
|
|
53
|
+
| | |--index.js
|
|
54
|
+
| | |--index.js.map
|
|
55
|
+
| |--webview
|
|
56
|
+
| | |--index.html
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
#### 默认配置和行为
|
|
60
|
+
|
|
61
|
+
详细查看 [PluginOptions](#pluginoptions) 和 `recommended` 参数说明
|
|
62
|
+
|
|
63
|
+
### extension
|
|
64
|
+
|
|
65
|
+
代码片段,更多配置看示例
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
const panel = window.createWebviewPanel('showHelloWorld', 'Hello World', ViewColumn.One, {
|
|
69
|
+
enableScripts: true,
|
|
70
|
+
localResourceRoots: [Uri.joinPath(extensionUri, 'dist/webview')],
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
private _getWebviewContent(webview: Webview, extensionUri: Uri) {
|
|
76
|
+
// The CSS file from the Vue build output
|
|
77
|
+
const stylesUri = getUri(webview, extensionUri, ['dist', 'webview', 'assets', 'index.css']);
|
|
78
|
+
// The JS file from the Vue build output
|
|
79
|
+
const scriptUri = getUri(webview, extensionUri, ['dist', 'webview', 'assets', 'index.js']);
|
|
80
|
+
|
|
81
|
+
const nonce = uuid();
|
|
82
|
+
|
|
83
|
+
if (process.env.VITE_DEV_SERVER_URL) {
|
|
84
|
+
// @ts-ignore
|
|
85
|
+
return __getWebviewHtml({ serverUrl: process.env.VITE_DEV_SERVER_URL });
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Tip: Install the es6-string-html VS Code extension to enable code highlighting below
|
|
89
|
+
return /*html*/ `
|
|
90
|
+
<!doctype html>
|
|
91
|
+
<html lang="en">
|
|
92
|
+
<head>
|
|
93
|
+
<meta charset="UTF-8" />
|
|
94
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
95
|
+
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src ${webview.cspSource}; script-src 'nonce-${nonce}';">
|
|
96
|
+
<script type="module" crossorigin nonce="${nonce}" src="${scriptUri}"></script>
|
|
97
|
+
<link rel="stylesheet" crossorigin href="${stylesUri}">
|
|
98
|
+
<title>Hello World</title>
|
|
99
|
+
</head>
|
|
100
|
+
<body>
|
|
101
|
+
<div id="app"></div>
|
|
102
|
+
</body>
|
|
103
|
+
</html>
|
|
104
|
+
`;
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
- `package.json`
|
|
109
|
+
|
|
110
|
+
```json
|
|
111
|
+
{
|
|
112
|
+
"main": "dist/extension/index.js"
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### vue
|
|
117
|
+
|
|
118
|
+
- `vite.config.ts`
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
import { defineConfig } from 'vite';
|
|
122
|
+
import vscode from '@tomjs/vite-plugin-vscode';
|
|
123
|
+
import vue from '@vitejs/plugin-vue';
|
|
124
|
+
|
|
125
|
+
// https://vitejs.dev/config/
|
|
126
|
+
export default defineConfig({
|
|
127
|
+
plugins: [
|
|
128
|
+
vue({
|
|
129
|
+
template: {
|
|
130
|
+
compilerOptions: {
|
|
131
|
+
isCustomElement: (tag: string) => tag.startsWith('vscode-'),
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
}),
|
|
135
|
+
vscode(),
|
|
136
|
+
],
|
|
137
|
+
build: {
|
|
138
|
+
rollupOptions: {
|
|
139
|
+
output: {
|
|
140
|
+
entryFileNames: `assets/[name].js`,
|
|
141
|
+
chunkFileNames: `assets/[name].js`,
|
|
142
|
+
assetFileNames: `assets/[name].[ext]`,
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### react
|
|
150
|
+
|
|
151
|
+
- `vite.config.ts`
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
import { defineConfig } from 'vite';
|
|
155
|
+
import vscode from '@tomjs/vite-plugin-vscode';
|
|
156
|
+
import react from '@vitejs/plugin-react-swc';
|
|
157
|
+
|
|
158
|
+
// https://vitejs.dev/config/
|
|
159
|
+
export default defineConfig({
|
|
160
|
+
plugins: [react(), vscode()],
|
|
161
|
+
build: {
|
|
162
|
+
rollupOptions: {
|
|
163
|
+
output: {
|
|
164
|
+
entryFileNames: `assets/[name].js`,
|
|
165
|
+
chunkFileNames: `assets/[name].js`,
|
|
166
|
+
assetFileNames: `assets/[name].[ext]`,
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
});
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## 文档
|
|
174
|
+
|
|
175
|
+
- [paka.dev](https://paka.dev) 提供的 [API文档](https://paka.dev/npm/@tomjs/vite-plugin-vscode).
|
|
176
|
+
- [unpkg.com](https://www.unpkg.com/) 提供的 [index.d.ts](https://www.unpkg.com/browse/@tomjs/vite-plugin-vscode/dist/index.d.ts).
|
|
177
|
+
|
|
178
|
+
## 参数
|
|
179
|
+
|
|
180
|
+
### PluginOptions
|
|
181
|
+
|
|
182
|
+
| 参数名 | 类型 | 默认值 | 说明 |
|
|
183
|
+
| --- | --- | --- | --- |
|
|
184
|
+
| recommended | `boolean` | `true` | 这个选项是为了提供推荐的默认参数和行为 |
|
|
185
|
+
| extension | [ExtensionOptions](#ExtensionOptions) | | vscode extension 可选配置 |
|
|
186
|
+
| webview | `boolean` | `false` | 在vscode扩展代码和Web客户端代码中注入[@tomjs/vscode-extension-webview](https://github.com/tomgao365/vscode-extension-webview),以便webview在开发阶段可以支持HMR。 |
|
|
187
|
+
|
|
188
|
+
**Notice**
|
|
189
|
+
|
|
190
|
+
`recommended` 选项用于设置默认配置和行为,几乎可以达到零配置使用,默认为 `true` 。如果你要自定义配置,请设置它为`false`。以下默认的前提条件是使用推荐的 [项目结构](#目录结构)。
|
|
191
|
+
|
|
192
|
+
- 输出目录根据 `vite` 的 `build.outDir` 参数, 将 `extension`、`src` 分别输出到 `dist/extension`、`dist/webview`
|
|
193
|
+
|
|
194
|
+
- 其他待实现的行为
|
|
195
|
+
|
|
196
|
+
### ExtensionOptions
|
|
197
|
+
|
|
198
|
+
继承自 [tsup](https://tsup.egoist.dev/) 的 [Options](https://paka.dev/npm/tsup),添加了一些默认值,方便使用。
|
|
199
|
+
|
|
200
|
+
| 参数名 | 类型 | 默认值 | 说明 |
|
|
201
|
+
| --- | --- | --- | --- |
|
|
202
|
+
| entry | `string` | `extension/index.ts` | 入口文件 |
|
|
203
|
+
| outDir | `string` | `dist-extension/main` | 输出文件夹 |
|
|
204
|
+
| onSuccess | `() => Promise<void \| undefined \| (() => void \| Promise<void>)>` | `undefined` | 构建成功后运行的回调函数 |
|
|
205
|
+
|
|
206
|
+
### 补充说明
|
|
207
|
+
|
|
208
|
+
- `extension` 未配置相关参数时的默认值
|
|
209
|
+
|
|
210
|
+
| 参数 | 开发模式默认值 | 生产模式默认值 |
|
|
211
|
+
| --------- | -------------- | -------------- |
|
|
212
|
+
| sourcemap | `true` | `false` |
|
|
213
|
+
| minify | `false` | `true` |
|
|
214
|
+
|
|
215
|
+
## 环境变量
|
|
216
|
+
|
|
217
|
+
`vscode extension` 使用
|
|
218
|
+
|
|
219
|
+
| 变量 | 描述 |
|
|
220
|
+
| --------------------- | --------------------- |
|
|
221
|
+
| `VITE_DEV_SERVER_URL` | Vite 开发服务器的 URL |
|
|
222
|
+
|
|
223
|
+
## Debug
|
|
224
|
+
|
|
225
|
+
通过 `vscode` 运行 `Debug Extension` 调试,调试工具参考 [官方文档](https://code.visualstudio.com/docs/editor/debugging)
|
|
226
|
+
|
|
227
|
+
`launch.json` 配置如下:
|
|
228
|
+
|
|
229
|
+
```json
|
|
230
|
+
{
|
|
231
|
+
"version": "0.2.0",
|
|
232
|
+
"configurations": [
|
|
233
|
+
{
|
|
234
|
+
"name": "Run Extension",
|
|
235
|
+
"type": "extensionHost",
|
|
236
|
+
"request": "launch",
|
|
237
|
+
"args": ["--extensionDevelopmentPath=${workspaceFolder}"],
|
|
238
|
+
"outFiles": ["${workspaceFolder}/dist/extension/*.js"],
|
|
239
|
+
"preLaunchTask": "${defaultBuildTask}"
|
|
240
|
+
}
|
|
241
|
+
]
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
`tasks.json` 配置如下:
|
|
246
|
+
|
|
247
|
+
```json
|
|
248
|
+
{
|
|
249
|
+
"version": "2.0.0",
|
|
250
|
+
"tasks": [
|
|
251
|
+
{
|
|
252
|
+
"type": "npm",
|
|
253
|
+
"script": "dev",
|
|
254
|
+
"problemMatcher": {
|
|
255
|
+
"owner": "typescript",
|
|
256
|
+
"fileLocation": "relative",
|
|
257
|
+
"pattern": {
|
|
258
|
+
"regexp": "^([a-zA-Z]\\:/?([\\w\\-]/?)+\\.\\w+):(\\d+):(\\d+): (ERROR|WARNING)\\: (.*)$",
|
|
259
|
+
"file": 1,
|
|
260
|
+
"line": 3,
|
|
261
|
+
"column": 4,
|
|
262
|
+
"code": 5,
|
|
263
|
+
"message": 6
|
|
264
|
+
},
|
|
265
|
+
"background": {
|
|
266
|
+
"activeOnStart": true,
|
|
267
|
+
"beginsPattern": "^.*extension build start*$",
|
|
268
|
+
"endsPattern": "^.*extension (build|rebuild) success.*$"
|
|
269
|
+
}
|
|
270
|
+
},
|
|
271
|
+
"isBackground": true,
|
|
272
|
+
"presentation": {
|
|
273
|
+
"reveal": "never"
|
|
274
|
+
},
|
|
275
|
+
"group": {
|
|
276
|
+
"kind": "build",
|
|
277
|
+
"isDefault": true
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
]
|
|
281
|
+
}
|
|
282
|
+
```
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
import { Options } from 'tsup';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* vscode extension options. See [tsup](https://tsup.egoist.dev/) and [API Doc](https://paka.dev/npm/tsup) for more information.
|
|
6
|
+
*/
|
|
7
|
+
interface ExtensionOptions extends Omit<Options, 'entry' | 'format' | 'outDir' | 'watch' | 'onSuccess'> {
|
|
8
|
+
/**
|
|
9
|
+
* The extension entry file.
|
|
10
|
+
* @default "extension/index.ts"
|
|
11
|
+
*/
|
|
12
|
+
entry?: string;
|
|
13
|
+
/**
|
|
14
|
+
* The output directory for the extension files. Default is `dist-extension`.
|
|
15
|
+
* @default "dist-extension"
|
|
16
|
+
*/
|
|
17
|
+
outDir?: string;
|
|
18
|
+
/**
|
|
19
|
+
* The bundle format. Currently only supports cjs.
|
|
20
|
+
*/
|
|
21
|
+
format?: 'cjs';
|
|
22
|
+
/**
|
|
23
|
+
* A function that will be executed after the build succeeds.
|
|
24
|
+
*/
|
|
25
|
+
onSuccess?: () => Promise<void | undefined | (() => void | Promise<void>)>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* vite plugin options.
|
|
29
|
+
*/
|
|
30
|
+
interface PluginOptions {
|
|
31
|
+
/**
|
|
32
|
+
* Recommended switch. Default is true.
|
|
33
|
+
* if true, will have the following default behavior:
|
|
34
|
+
* * will change the extension/webview outDir to be parallel outDir;
|
|
35
|
+
* eg. if vite build.outDir is 'dist', will change extension/webview to 'dist/extension' and 'dist/webview'
|
|
36
|
+
* @default true
|
|
37
|
+
*/
|
|
38
|
+
recommended?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Inject [@tomjs/vscode-extension-webview](https://github.com/tomgao365/vscode-extension-webview) into vscode extension code and web client code, so that webview can support HMR during the development stage.
|
|
41
|
+
*
|
|
42
|
+
* * extension: Inject `import getDevWebviewHtml from '@tomjs/vscode-extension-webview';` above the file that calls the `getDevWebviewHtml` method
|
|
43
|
+
* * web: Add `<script>` tag to index.html and inject `@tomjs/vscode-extension-webview/client` code
|
|
44
|
+
*
|
|
45
|
+
* If is string, will set inject method name. Default is 'getDevWebviewHtml'.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* extension file
|
|
49
|
+
* ```ts
|
|
50
|
+
* if(process.env.VITE_DEV_SERVER_URL){
|
|
51
|
+
* webview.html = getDevWebviewHtml(process.env.VITE_DEV_SERVER_URL)
|
|
52
|
+
* } else {
|
|
53
|
+
* webview.html = `<html></html>`
|
|
54
|
+
* }
|
|
55
|
+
* ```
|
|
56
|
+
* webview client
|
|
57
|
+
* ```html
|
|
58
|
+
* <html>
|
|
59
|
+
* <head>
|
|
60
|
+
* <script>inject code</script>
|
|
61
|
+
* </head>
|
|
62
|
+
* </html>
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
webview?: boolean | string;
|
|
66
|
+
/**
|
|
67
|
+
* extension vite config.
|
|
68
|
+
*/
|
|
69
|
+
extension?: ExtensionOptions;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
declare function useVSCodePlugin(options?: PluginOptions): Plugin[];
|
|
73
|
+
|
|
74
|
+
export { useVSCodePlugin as default, useVSCodePlugin };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
import { Options } from 'tsup';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* vscode extension options. See [tsup](https://tsup.egoist.dev/) and [API Doc](https://paka.dev/npm/tsup) for more information.
|
|
6
|
+
*/
|
|
7
|
+
interface ExtensionOptions extends Omit<Options, 'entry' | 'format' | 'outDir' | 'watch' | 'onSuccess'> {
|
|
8
|
+
/**
|
|
9
|
+
* The extension entry file.
|
|
10
|
+
* @default "extension/index.ts"
|
|
11
|
+
*/
|
|
12
|
+
entry?: string;
|
|
13
|
+
/**
|
|
14
|
+
* The output directory for the extension files. Default is `dist-extension`.
|
|
15
|
+
* @default "dist-extension"
|
|
16
|
+
*/
|
|
17
|
+
outDir?: string;
|
|
18
|
+
/**
|
|
19
|
+
* The bundle format. Currently only supports cjs.
|
|
20
|
+
*/
|
|
21
|
+
format?: 'cjs';
|
|
22
|
+
/**
|
|
23
|
+
* A function that will be executed after the build succeeds.
|
|
24
|
+
*/
|
|
25
|
+
onSuccess?: () => Promise<void | undefined | (() => void | Promise<void>)>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* vite plugin options.
|
|
29
|
+
*/
|
|
30
|
+
interface PluginOptions {
|
|
31
|
+
/**
|
|
32
|
+
* Recommended switch. Default is true.
|
|
33
|
+
* if true, will have the following default behavior:
|
|
34
|
+
* * will change the extension/webview outDir to be parallel outDir;
|
|
35
|
+
* eg. if vite build.outDir is 'dist', will change extension/webview to 'dist/extension' and 'dist/webview'
|
|
36
|
+
* @default true
|
|
37
|
+
*/
|
|
38
|
+
recommended?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Inject [@tomjs/vscode-extension-webview](https://github.com/tomgao365/vscode-extension-webview) into vscode extension code and web client code, so that webview can support HMR during the development stage.
|
|
41
|
+
*
|
|
42
|
+
* * extension: Inject `import getDevWebviewHtml from '@tomjs/vscode-extension-webview';` above the file that calls the `getDevWebviewHtml` method
|
|
43
|
+
* * web: Add `<script>` tag to index.html and inject `@tomjs/vscode-extension-webview/client` code
|
|
44
|
+
*
|
|
45
|
+
* If is string, will set inject method name. Default is 'getDevWebviewHtml'.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* extension file
|
|
49
|
+
* ```ts
|
|
50
|
+
* if(process.env.VITE_DEV_SERVER_URL){
|
|
51
|
+
* webview.html = getDevWebviewHtml(process.env.VITE_DEV_SERVER_URL)
|
|
52
|
+
* } else {
|
|
53
|
+
* webview.html = `<html></html>`
|
|
54
|
+
* }
|
|
55
|
+
* ```
|
|
56
|
+
* webview client
|
|
57
|
+
* ```html
|
|
58
|
+
* <html>
|
|
59
|
+
* <head>
|
|
60
|
+
* <script>inject code</script>
|
|
61
|
+
* </head>
|
|
62
|
+
* </html>
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
webview?: boolean | string;
|
|
66
|
+
/**
|
|
67
|
+
* extension vite config.
|
|
68
|
+
*/
|
|
69
|
+
extension?: ExtensionOptions;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
declare function useVSCodePlugin(options?: PluginOptions): Plugin[];
|
|
73
|
+
|
|
74
|
+
export { useVSCodePlugin as default, useVSCodePlugin };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }// src/index.ts
|
|
2
|
+
var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs);
|
|
3
|
+
var _path = require('path'); var _path2 = _interopRequireDefault(_path);
|
|
4
|
+
var _process = require('process');
|
|
5
|
+
var _lodashclonedeep = require('lodash.clonedeep'); var _lodashclonedeep2 = _interopRequireDefault(_lodashclonedeep);
|
|
6
|
+
var _lodashmerge = require('lodash.merge'); var _lodashmerge2 = _interopRequireDefault(_lodashmerge);
|
|
7
|
+
var _tsup = require('tsup');
|
|
8
|
+
|
|
9
|
+
// src/constants.ts
|
|
10
|
+
var PLUGIN_NAME = "@tomjs:vscode";
|
|
11
|
+
var WEBVIEW_PACKAGE_NAME = "@tomjs/vscode-extension-webview";
|
|
12
|
+
var WEBVIEW_METHOD_NAME = "__getWebviewHtml";
|
|
13
|
+
|
|
14
|
+
// src/logger.ts
|
|
15
|
+
var _dayjs = require('dayjs'); var _dayjs2 = _interopRequireDefault(_dayjs);
|
|
16
|
+
var _kolorist = require('kolorist');
|
|
17
|
+
var Logger = class {
|
|
18
|
+
constructor(tag, withTime) {
|
|
19
|
+
this.tag = PLUGIN_NAME;
|
|
20
|
+
this.withTime = true;
|
|
21
|
+
this.tag = `[${tag}]`;
|
|
22
|
+
this.withTime = _nullishCoalesce(withTime, () => ( true));
|
|
23
|
+
}
|
|
24
|
+
getTime() {
|
|
25
|
+
return `${this.withTime ? _dayjs2.default.call(void 0, ).format("HH:mm:ss") : ""} `;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* 调试
|
|
29
|
+
*/
|
|
30
|
+
debug(msg, ...rest) {
|
|
31
|
+
console.log(`${this.getTime()}${_kolorist.gray.call(void 0, this.tag)}`, msg, ...rest);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* 调试日志 等同 debug
|
|
35
|
+
*/
|
|
36
|
+
log(msg, ...rest) {
|
|
37
|
+
this.debug(msg, ...rest);
|
|
38
|
+
}
|
|
39
|
+
info(msg, ...rest) {
|
|
40
|
+
console.log(`${this.getTime()}${_kolorist.blue.call(void 0, this.tag)}`, msg, ...rest);
|
|
41
|
+
}
|
|
42
|
+
warn(msg, ...rest) {
|
|
43
|
+
console.log(`${this.getTime()}${_kolorist.yellow.call(void 0, this.tag)}`, msg, ...rest);
|
|
44
|
+
}
|
|
45
|
+
error(msg, ...rest) {
|
|
46
|
+
console.log(`${this.getTime()}${_kolorist.red.call(void 0, this.tag)}`, msg, ...rest);
|
|
47
|
+
}
|
|
48
|
+
success(msg, ...rest) {
|
|
49
|
+
console.log(`${this.getTime()}${_kolorist.green.call(void 0, this.tag)}`, msg, ...rest);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
var createLogger = (tag) => {
|
|
53
|
+
return new Logger(tag || PLUGIN_NAME, true);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// src/utils.ts
|
|
57
|
+
|
|
58
|
+
var _module = require('module');
|
|
59
|
+
function readJson(path2) {
|
|
60
|
+
if (_fs2.default.existsSync(path2)) {
|
|
61
|
+
return JSON.parse(_fs2.default.readFileSync(path2, "utf8"));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function resolveHostname(hostname) {
|
|
65
|
+
const loopbackHosts = /* @__PURE__ */ new Set([
|
|
66
|
+
"localhost",
|
|
67
|
+
"127.0.0.1",
|
|
68
|
+
"::1",
|
|
69
|
+
"0000:0000:0000:0000:0000:0000:0000:0001"
|
|
70
|
+
]);
|
|
71
|
+
const wildcardHosts = /* @__PURE__ */ new Set(["0.0.0.0", "::", "0000:0000:0000:0000:0000:0000:0000:0000"]);
|
|
72
|
+
return loopbackHosts.has(hostname) || wildcardHosts.has(hostname) ? "localhost" : hostname;
|
|
73
|
+
}
|
|
74
|
+
function resolveServerUrl(server) {
|
|
75
|
+
const addressInfo = server.httpServer.address();
|
|
76
|
+
const isAddressInfo = (x) => x == null ? void 0 : x.address;
|
|
77
|
+
if (isAddressInfo(addressInfo)) {
|
|
78
|
+
const { address, port } = addressInfo;
|
|
79
|
+
const hostname = resolveHostname(address);
|
|
80
|
+
const options = server.config.server;
|
|
81
|
+
const protocol = options.https ? "https" : "http";
|
|
82
|
+
const devBase = server.config.base;
|
|
83
|
+
const path2 = typeof options.open === "string" ? options.open : devBase;
|
|
84
|
+
const url = path2.startsWith("http") ? path2 : `${protocol}://${hostname}:${port}${path2}`;
|
|
85
|
+
return url;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// src/index.ts
|
|
90
|
+
var isDev = process.env.NODE_ENV === "development";
|
|
91
|
+
var logger = createLogger();
|
|
92
|
+
function getPkg() {
|
|
93
|
+
const pkgFile = _path2.default.resolve(process.cwd(), "package.json");
|
|
94
|
+
if (!_fs2.default.existsSync(pkgFile)) {
|
|
95
|
+
throw new Error("Main file is not specified, and no package.json found");
|
|
96
|
+
}
|
|
97
|
+
const pkg = readJson(pkgFile);
|
|
98
|
+
if (!pkg.main) {
|
|
99
|
+
throw new Error("Main file is not specified, please check package.json");
|
|
100
|
+
}
|
|
101
|
+
return pkg;
|
|
102
|
+
}
|
|
103
|
+
function preMergeOptions(options) {
|
|
104
|
+
getPkg();
|
|
105
|
+
const opts = _lodashmerge2.default.call(void 0,
|
|
106
|
+
{
|
|
107
|
+
webview: true,
|
|
108
|
+
recommended: true,
|
|
109
|
+
debug: false,
|
|
110
|
+
extension: {
|
|
111
|
+
entry: "extension/index.ts",
|
|
112
|
+
outDir: "dist-extension",
|
|
113
|
+
target: ["es2019", "node14"],
|
|
114
|
+
format: "cjs",
|
|
115
|
+
clean: true,
|
|
116
|
+
dts: false,
|
|
117
|
+
treeshake: !!isDev,
|
|
118
|
+
outExtension() {
|
|
119
|
+
return { js: ".js" };
|
|
120
|
+
},
|
|
121
|
+
external: ["vscode"]
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
_lodashclonedeep2.default.call(void 0, options)
|
|
125
|
+
);
|
|
126
|
+
const opt = opts.extension || {};
|
|
127
|
+
["entry", "format"].forEach((prop) => {
|
|
128
|
+
const value = opt[prop];
|
|
129
|
+
if (!Array.isArray(value) && value) {
|
|
130
|
+
opt[prop] = [value];
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
if (isDev) {
|
|
134
|
+
opt.sourcemap = _nullishCoalesce(opt.sourcemap, () => ( true));
|
|
135
|
+
} else {
|
|
136
|
+
opt.minify ??= true;
|
|
137
|
+
}
|
|
138
|
+
opt.external = ["vscode", WEBVIEW_PACKAGE_NAME].concat(
|
|
139
|
+
_nullishCoalesce(opt.external, () => ( []))
|
|
140
|
+
);
|
|
141
|
+
opts.extension = opt;
|
|
142
|
+
if (opts.webview === true) {
|
|
143
|
+
opts.webview = WEBVIEW_METHOD_NAME;
|
|
144
|
+
}
|
|
145
|
+
opts.webview = _nullishCoalesce(opts.webview, () => ( WEBVIEW_METHOD_NAME));
|
|
146
|
+
return opts;
|
|
147
|
+
}
|
|
148
|
+
function useVSCodePlugin(options) {
|
|
149
|
+
const opts = preMergeOptions(options);
|
|
150
|
+
const handleConfig = (config) => {
|
|
151
|
+
var _a, _b;
|
|
152
|
+
let outDir = ((_a = config == null ? void 0 : config.build) == null ? void 0 : _a.outDir) || "dist";
|
|
153
|
+
opts.extension ??= {};
|
|
154
|
+
if (opts.recommended) {
|
|
155
|
+
opts.extension.outDir = _path2.default.resolve(outDir, "extension");
|
|
156
|
+
outDir = _path2.default.resolve(outDir, "webview");
|
|
157
|
+
}
|
|
158
|
+
return {
|
|
159
|
+
build: {
|
|
160
|
+
outDir,
|
|
161
|
+
sourcemap: isDev ? true : (_b = config == null ? void 0 : config.build) == null ? void 0 : _b.sourcemap
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
};
|
|
165
|
+
let webviewClient;
|
|
166
|
+
let webviewNpmPath;
|
|
167
|
+
if (opts.webview) {
|
|
168
|
+
webviewNpmPath = _path2.default.join(_process.cwd.call(void 0, ), "node_modules", WEBVIEW_PACKAGE_NAME, "/dist");
|
|
169
|
+
if (!_fs2.default.existsSync(webviewNpmPath)) {
|
|
170
|
+
logger.warn(`[${WEBVIEW_PACKAGE_NAME}] is not installed, please install it first!`);
|
|
171
|
+
} else {
|
|
172
|
+
const fileName = "client.global.js";
|
|
173
|
+
const clientFile = _path2.default.join(webviewNpmPath, fileName);
|
|
174
|
+
if (!_fs2.default.existsSync(clientFile)) {
|
|
175
|
+
logger.warn(`[${fileName}] is does not exist, please update the package!`);
|
|
176
|
+
} else {
|
|
177
|
+
webviewClient = _fs2.default.readFileSync(clientFile, "utf-8");
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return [
|
|
182
|
+
{
|
|
183
|
+
name: "@tomjs:vscode",
|
|
184
|
+
apply: "serve",
|
|
185
|
+
config(config) {
|
|
186
|
+
return handleConfig(config);
|
|
187
|
+
},
|
|
188
|
+
configureServer(server) {
|
|
189
|
+
var _a;
|
|
190
|
+
if (!server || !server.httpServer) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
(_a = server.httpServer) == null ? void 0 : _a.once("listening", async () => {
|
|
194
|
+
const env = {
|
|
195
|
+
NODE_ENV: server.config.mode || "development",
|
|
196
|
+
VITE_DEV_SERVER_URL: resolveServerUrl(server)
|
|
197
|
+
};
|
|
198
|
+
logger.info("extension build start");
|
|
199
|
+
let buildCount = 0;
|
|
200
|
+
const { onSuccess: _onSuccess, ...tsupOptions } = opts.extension || {};
|
|
201
|
+
await _tsup.build.call(void 0,
|
|
202
|
+
_lodashmerge2.default.call(void 0, tsupOptions, {
|
|
203
|
+
watch: true,
|
|
204
|
+
env,
|
|
205
|
+
silent: true,
|
|
206
|
+
esbuildPlugins: [
|
|
207
|
+
{
|
|
208
|
+
name: "@tomjs:vscode:inject",
|
|
209
|
+
setup(build) {
|
|
210
|
+
build.onLoad({ filter: /\.ts$/ }, async (args) => {
|
|
211
|
+
const file = _fs2.default.readFileSync(args.path, "utf-8");
|
|
212
|
+
if (file.includes(`${opts.webview}(`)) {
|
|
213
|
+
return {
|
|
214
|
+
contents: `import ${opts.webview} from '@tomjs/vscode-extension-webview';
|
|
215
|
+
` + file,
|
|
216
|
+
loader: "ts"
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
return {};
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
],
|
|
224
|
+
async onSuccess() {
|
|
225
|
+
if (typeof _onSuccess === "function") {
|
|
226
|
+
await _onSuccess();
|
|
227
|
+
}
|
|
228
|
+
if (buildCount++ > 1) {
|
|
229
|
+
logger.info("extension rebuild success");
|
|
230
|
+
} else {
|
|
231
|
+
logger.info("extension build success");
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
})
|
|
235
|
+
);
|
|
236
|
+
});
|
|
237
|
+
},
|
|
238
|
+
transformIndexHtml(html) {
|
|
239
|
+
if (!opts.webview || !webviewClient) {
|
|
240
|
+
return html;
|
|
241
|
+
}
|
|
242
|
+
return html.replace(/<\/title>/i, `</title><script>${webviewClient}</script>`);
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
name: "@tomjs:vscode",
|
|
247
|
+
apply: "build",
|
|
248
|
+
config(config) {
|
|
249
|
+
return handleConfig(config);
|
|
250
|
+
},
|
|
251
|
+
closeBundle() {
|
|
252
|
+
_tsup.build.call(void 0, opts.extension);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
];
|
|
256
|
+
}
|
|
257
|
+
var src_default = useVSCodePlugin;
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
exports.default = src_default; exports.useVSCodePlugin = useVSCodePlugin;
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import fs2 from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { cwd } from "process";
|
|
5
|
+
import cloneDeep from "lodash.clonedeep";
|
|
6
|
+
import merge from "lodash.merge";
|
|
7
|
+
import { build as tsupBuild } from "tsup";
|
|
8
|
+
|
|
9
|
+
// src/constants.ts
|
|
10
|
+
var PLUGIN_NAME = "@tomjs:vscode";
|
|
11
|
+
var WEBVIEW_PACKAGE_NAME = "@tomjs/vscode-extension-webview";
|
|
12
|
+
var WEBVIEW_METHOD_NAME = "__getWebviewHtml";
|
|
13
|
+
|
|
14
|
+
// src/logger.ts
|
|
15
|
+
import dayjs from "dayjs";
|
|
16
|
+
import { blue, gray, green, red, yellow } from "kolorist";
|
|
17
|
+
var Logger = class {
|
|
18
|
+
constructor(tag, withTime) {
|
|
19
|
+
this.tag = PLUGIN_NAME;
|
|
20
|
+
this.withTime = true;
|
|
21
|
+
this.tag = `[${tag}]`;
|
|
22
|
+
this.withTime = withTime ?? true;
|
|
23
|
+
}
|
|
24
|
+
getTime() {
|
|
25
|
+
return `${this.withTime ? dayjs().format("HH:mm:ss") : ""} `;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* 调试
|
|
29
|
+
*/
|
|
30
|
+
debug(msg, ...rest) {
|
|
31
|
+
console.log(`${this.getTime()}${gray(this.tag)}`, msg, ...rest);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* 调试日志 等同 debug
|
|
35
|
+
*/
|
|
36
|
+
log(msg, ...rest) {
|
|
37
|
+
this.debug(msg, ...rest);
|
|
38
|
+
}
|
|
39
|
+
info(msg, ...rest) {
|
|
40
|
+
console.log(`${this.getTime()}${blue(this.tag)}`, msg, ...rest);
|
|
41
|
+
}
|
|
42
|
+
warn(msg, ...rest) {
|
|
43
|
+
console.log(`${this.getTime()}${yellow(this.tag)}`, msg, ...rest);
|
|
44
|
+
}
|
|
45
|
+
error(msg, ...rest) {
|
|
46
|
+
console.log(`${this.getTime()}${red(this.tag)}`, msg, ...rest);
|
|
47
|
+
}
|
|
48
|
+
success(msg, ...rest) {
|
|
49
|
+
console.log(`${this.getTime()}${green(this.tag)}`, msg, ...rest);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
var createLogger = (tag) => {
|
|
53
|
+
return new Logger(tag || PLUGIN_NAME, true);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// src/utils.ts
|
|
57
|
+
import fs from "fs";
|
|
58
|
+
function readJson(path2) {
|
|
59
|
+
if (fs.existsSync(path2)) {
|
|
60
|
+
return JSON.parse(fs.readFileSync(path2, "utf8"));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function resolveHostname(hostname) {
|
|
64
|
+
const loopbackHosts = /* @__PURE__ */ new Set([
|
|
65
|
+
"localhost",
|
|
66
|
+
"127.0.0.1",
|
|
67
|
+
"::1",
|
|
68
|
+
"0000:0000:0000:0000:0000:0000:0000:0001"
|
|
69
|
+
]);
|
|
70
|
+
const wildcardHosts = /* @__PURE__ */ new Set(["0.0.0.0", "::", "0000:0000:0000:0000:0000:0000:0000:0000"]);
|
|
71
|
+
return loopbackHosts.has(hostname) || wildcardHosts.has(hostname) ? "localhost" : hostname;
|
|
72
|
+
}
|
|
73
|
+
function resolveServerUrl(server) {
|
|
74
|
+
const addressInfo = server.httpServer.address();
|
|
75
|
+
const isAddressInfo = (x) => x == null ? void 0 : x.address;
|
|
76
|
+
if (isAddressInfo(addressInfo)) {
|
|
77
|
+
const { address, port } = addressInfo;
|
|
78
|
+
const hostname = resolveHostname(address);
|
|
79
|
+
const options = server.config.server;
|
|
80
|
+
const protocol = options.https ? "https" : "http";
|
|
81
|
+
const devBase = server.config.base;
|
|
82
|
+
const path2 = typeof options.open === "string" ? options.open : devBase;
|
|
83
|
+
const url = path2.startsWith("http") ? path2 : `${protocol}://${hostname}:${port}${path2}`;
|
|
84
|
+
return url;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// src/index.ts
|
|
89
|
+
var isDev = process.env.NODE_ENV === "development";
|
|
90
|
+
var logger = createLogger();
|
|
91
|
+
function getPkg() {
|
|
92
|
+
const pkgFile = path.resolve(process.cwd(), "package.json");
|
|
93
|
+
if (!fs2.existsSync(pkgFile)) {
|
|
94
|
+
throw new Error("Main file is not specified, and no package.json found");
|
|
95
|
+
}
|
|
96
|
+
const pkg = readJson(pkgFile);
|
|
97
|
+
if (!pkg.main) {
|
|
98
|
+
throw new Error("Main file is not specified, please check package.json");
|
|
99
|
+
}
|
|
100
|
+
return pkg;
|
|
101
|
+
}
|
|
102
|
+
function preMergeOptions(options) {
|
|
103
|
+
getPkg();
|
|
104
|
+
const opts = merge(
|
|
105
|
+
{
|
|
106
|
+
webview: true,
|
|
107
|
+
recommended: true,
|
|
108
|
+
debug: false,
|
|
109
|
+
extension: {
|
|
110
|
+
entry: "extension/index.ts",
|
|
111
|
+
outDir: "dist-extension",
|
|
112
|
+
target: ["es2019", "node14"],
|
|
113
|
+
format: "cjs",
|
|
114
|
+
clean: true,
|
|
115
|
+
dts: false,
|
|
116
|
+
treeshake: !!isDev,
|
|
117
|
+
outExtension() {
|
|
118
|
+
return { js: ".js" };
|
|
119
|
+
},
|
|
120
|
+
external: ["vscode"]
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
cloneDeep(options)
|
|
124
|
+
);
|
|
125
|
+
const opt = opts.extension || {};
|
|
126
|
+
["entry", "format"].forEach((prop) => {
|
|
127
|
+
const value = opt[prop];
|
|
128
|
+
if (!Array.isArray(value) && value) {
|
|
129
|
+
opt[prop] = [value];
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
if (isDev) {
|
|
133
|
+
opt.sourcemap = opt.sourcemap ?? true;
|
|
134
|
+
} else {
|
|
135
|
+
opt.minify ??= true;
|
|
136
|
+
}
|
|
137
|
+
opt.external = ["vscode", WEBVIEW_PACKAGE_NAME].concat(
|
|
138
|
+
opt.external ?? []
|
|
139
|
+
);
|
|
140
|
+
opts.extension = opt;
|
|
141
|
+
if (opts.webview === true) {
|
|
142
|
+
opts.webview = WEBVIEW_METHOD_NAME;
|
|
143
|
+
}
|
|
144
|
+
opts.webview = opts.webview ?? WEBVIEW_METHOD_NAME;
|
|
145
|
+
return opts;
|
|
146
|
+
}
|
|
147
|
+
function useVSCodePlugin(options) {
|
|
148
|
+
const opts = preMergeOptions(options);
|
|
149
|
+
const handleConfig = (config) => {
|
|
150
|
+
var _a, _b;
|
|
151
|
+
let outDir = ((_a = config == null ? void 0 : config.build) == null ? void 0 : _a.outDir) || "dist";
|
|
152
|
+
opts.extension ??= {};
|
|
153
|
+
if (opts.recommended) {
|
|
154
|
+
opts.extension.outDir = path.resolve(outDir, "extension");
|
|
155
|
+
outDir = path.resolve(outDir, "webview");
|
|
156
|
+
}
|
|
157
|
+
return {
|
|
158
|
+
build: {
|
|
159
|
+
outDir,
|
|
160
|
+
sourcemap: isDev ? true : (_b = config == null ? void 0 : config.build) == null ? void 0 : _b.sourcemap
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
};
|
|
164
|
+
let webviewClient;
|
|
165
|
+
let webviewNpmPath;
|
|
166
|
+
if (opts.webview) {
|
|
167
|
+
webviewNpmPath = path.join(cwd(), "node_modules", WEBVIEW_PACKAGE_NAME, "/dist");
|
|
168
|
+
if (!fs2.existsSync(webviewNpmPath)) {
|
|
169
|
+
logger.warn(`[${WEBVIEW_PACKAGE_NAME}] is not installed, please install it first!`);
|
|
170
|
+
} else {
|
|
171
|
+
const fileName = "client.global.js";
|
|
172
|
+
const clientFile = path.join(webviewNpmPath, fileName);
|
|
173
|
+
if (!fs2.existsSync(clientFile)) {
|
|
174
|
+
logger.warn(`[${fileName}] is does not exist, please update the package!`);
|
|
175
|
+
} else {
|
|
176
|
+
webviewClient = fs2.readFileSync(clientFile, "utf-8");
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return [
|
|
181
|
+
{
|
|
182
|
+
name: "@tomjs:vscode",
|
|
183
|
+
apply: "serve",
|
|
184
|
+
config(config) {
|
|
185
|
+
return handleConfig(config);
|
|
186
|
+
},
|
|
187
|
+
configureServer(server) {
|
|
188
|
+
var _a;
|
|
189
|
+
if (!server || !server.httpServer) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
(_a = server.httpServer) == null ? void 0 : _a.once("listening", async () => {
|
|
193
|
+
const env = {
|
|
194
|
+
NODE_ENV: server.config.mode || "development",
|
|
195
|
+
VITE_DEV_SERVER_URL: resolveServerUrl(server)
|
|
196
|
+
};
|
|
197
|
+
logger.info("extension build start");
|
|
198
|
+
let buildCount = 0;
|
|
199
|
+
const { onSuccess: _onSuccess, ...tsupOptions } = opts.extension || {};
|
|
200
|
+
await tsupBuild(
|
|
201
|
+
merge(tsupOptions, {
|
|
202
|
+
watch: true,
|
|
203
|
+
env,
|
|
204
|
+
silent: true,
|
|
205
|
+
esbuildPlugins: [
|
|
206
|
+
{
|
|
207
|
+
name: "@tomjs:vscode:inject",
|
|
208
|
+
setup(build) {
|
|
209
|
+
build.onLoad({ filter: /\.ts$/ }, async (args) => {
|
|
210
|
+
const file = fs2.readFileSync(args.path, "utf-8");
|
|
211
|
+
if (file.includes(`${opts.webview}(`)) {
|
|
212
|
+
return {
|
|
213
|
+
contents: `import ${opts.webview} from '@tomjs/vscode-extension-webview';
|
|
214
|
+
` + file,
|
|
215
|
+
loader: "ts"
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
return {};
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
],
|
|
223
|
+
async onSuccess() {
|
|
224
|
+
if (typeof _onSuccess === "function") {
|
|
225
|
+
await _onSuccess();
|
|
226
|
+
}
|
|
227
|
+
if (buildCount++ > 1) {
|
|
228
|
+
logger.info("extension rebuild success");
|
|
229
|
+
} else {
|
|
230
|
+
logger.info("extension build success");
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
})
|
|
234
|
+
);
|
|
235
|
+
});
|
|
236
|
+
},
|
|
237
|
+
transformIndexHtml(html) {
|
|
238
|
+
if (!opts.webview || !webviewClient) {
|
|
239
|
+
return html;
|
|
240
|
+
}
|
|
241
|
+
return html.replace(/<\/title>/i, `</title><script>${webviewClient}</script>`);
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
name: "@tomjs:vscode",
|
|
246
|
+
apply: "build",
|
|
247
|
+
config(config) {
|
|
248
|
+
return handleConfig(config);
|
|
249
|
+
},
|
|
250
|
+
closeBundle() {
|
|
251
|
+
tsupBuild(opts.extension);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
];
|
|
255
|
+
}
|
|
256
|
+
var src_default = useVSCodePlugin;
|
|
257
|
+
export {
|
|
258
|
+
src_default as default,
|
|
259
|
+
useVSCodePlugin
|
|
260
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tomjs/vite-plugin-vscode",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "The vite plugin for vscode extension, supports esm and cjs.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"vite",
|
|
7
|
+
"plugin",
|
|
8
|
+
"vscode",
|
|
9
|
+
"extension",
|
|
10
|
+
"webview",
|
|
11
|
+
"esm",
|
|
12
|
+
"cjs"
|
|
13
|
+
],
|
|
14
|
+
"author": {
|
|
15
|
+
"name": "Tom Gao",
|
|
16
|
+
"email": "tom@tomgao.cc"
|
|
17
|
+
},
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"main": "./dist/index.js",
|
|
20
|
+
"module": "./dist/index.mjs",
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"require": "./dist/index.js",
|
|
25
|
+
"import": "./dist/index.mjs",
|
|
26
|
+
"types": "./dist/index.d.ts"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"dist"
|
|
31
|
+
],
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=16"
|
|
34
|
+
},
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public",
|
|
37
|
+
"registry": "https://registry.npmjs.org/"
|
|
38
|
+
},
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "git+https://github.com/tomgao365/vite-plugin-vscode.git"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"@tomjs/vscode-extension-webview": "^1.0.1",
|
|
45
|
+
"dayjs": "^1.11.10",
|
|
46
|
+
"kolorist": "^1.8.0",
|
|
47
|
+
"lodash.clonedeep": "^4.5.0",
|
|
48
|
+
"lodash.merge": "^4.6.2",
|
|
49
|
+
"tsup": "7.2.0"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@commitlint/cli": "^18.4.3",
|
|
53
|
+
"@tomjs/commitlint": "^2.0.8",
|
|
54
|
+
"@tomjs/eslint": "^1.1.4",
|
|
55
|
+
"@tomjs/prettier": "^1.0.9",
|
|
56
|
+
"@tomjs/stylelint": "^2.0.2",
|
|
57
|
+
"@tomjs/tsconfig": "^1.1.5",
|
|
58
|
+
"@types/lodash.clonedeep": "^4.5.9",
|
|
59
|
+
"@types/lodash.merge": "^4.6.9",
|
|
60
|
+
"@types/node": "^18.19.3",
|
|
61
|
+
"cross-env": "^7.0.3",
|
|
62
|
+
"eslint": "^8.56.0",
|
|
63
|
+
"husky": "^8.0.3",
|
|
64
|
+
"lint-staged": "^15.2.0",
|
|
65
|
+
"np": "^9.2.0",
|
|
66
|
+
"npm-run-all": "^4.1.5",
|
|
67
|
+
"prettier": "^3.1.1",
|
|
68
|
+
"rimraf": "^5.0.5",
|
|
69
|
+
"stylelint": "^16.0.2",
|
|
70
|
+
"tsx": "^4.6.2",
|
|
71
|
+
"typescript": "~5.3.3"
|
|
72
|
+
},
|
|
73
|
+
"peerDependencies": {
|
|
74
|
+
"vite": ">=2"
|
|
75
|
+
},
|
|
76
|
+
"scripts": {
|
|
77
|
+
"dev": "tsup --watch",
|
|
78
|
+
"build": "tsup",
|
|
79
|
+
"lint": "run-s lint:eslint lint:stylelint lint:prettier",
|
|
80
|
+
"lint:eslint": "eslint \"{src,scripts,examples}/**/*.ts\" *.{js,cjs,ts} --fix --cache",
|
|
81
|
+
"lint:stylelint": "stylelint \"examples/**/*.{css,scss,less,vue,html}\" --fix --cache",
|
|
82
|
+
"lint:prettier": "prettier --write ."
|
|
83
|
+
}
|
|
84
|
+
}
|