@tomjs/vite-plugin-vscode 2.3.1 → 2.4.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 +2 -2
- package/README.zh_CN.md +2 -2
- package/dist/client.global.js +92 -0
- package/dist/index.js +9 -69
- package/dist/index.mjs +22 -74
- package/dist/webview.d.mts +13 -0
- package/dist/webview.d.ts +13 -0
- package/dist/webview.js +165 -0
- package/dist/webview.mjs +165 -0
- package/package.json +26 -7
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
> Use `vue`/`react` to develop [vscode extension webview](https://code.visualstudio.com/api/references/vscode-api#WebviewPanel), supporting `esm` and `cjs`.
|
|
8
8
|
|
|
9
|
-
In development mode, inject the code of [@tomjs/vscode-extension-webview](https://github.com/tomjs/vscode-extension-webview) into `vscode extension code` and `web page code`, use To support `HMR`; during production build, the final generated `index.html` code is injected into `vscode extension code` to reduce the workload.
|
|
9
|
+
In development mode, inject the same code of [@tomjs/vscode-extension-webview](https://github.com/tomjs/vscode-extension-webview) into `vscode extension code` and `web page code`, use To support `HMR`; during production build, the final generated `index.html` code is injected into `vscode extension code` to reduce the workload.
|
|
10
10
|
|
|
11
11
|
## Features
|
|
12
12
|
|
|
@@ -27,7 +27,7 @@ pnpm add @tomjs/vite-plugin-vscode -D
|
|
|
27
27
|
yarn add @tomjs/vite-plugin-vscode -D
|
|
28
28
|
|
|
29
29
|
# npm
|
|
30
|
-
npm i @tomjs/vite-plugin-vscode
|
|
30
|
+
npm i @tomjs/vite-plugin-vscode -D
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
## Usage
|
package/README.zh_CN.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
> 用 `vue`/`react` 来开发 [vscode extension webview](https://code.visualstudio.com/api/references/vscode-api#WebviewPanel) ,支持 `esm` 和 `cjs`。
|
|
8
8
|
|
|
9
|
-
在开发模式时,给 `vscode 扩展代码` 和 `web 页面代码`中注入 [@tomjs/vscode-extension-webview](https://github.com/tomjs/vscode-extension-webview)
|
|
9
|
+
在开发模式时,给 `vscode 扩展代码` 和 `web 页面代码`中注入 [@tomjs/vscode-extension-webview](https://github.com/tomjs/vscode-extension-webview) 相同的代码,用来支持 `HMR`;生产构建时,将最终生成的`index.html` 代码注入到 `vscode 扩展代码` 中,减少工作量。
|
|
10
10
|
|
|
11
11
|
## 特性
|
|
12
12
|
|
|
@@ -27,7 +27,7 @@ pnpm add @tomjs/vite-plugin-vscode -D
|
|
|
27
27
|
yarn add @tomjs/vite-plugin-vscode -D
|
|
28
28
|
|
|
29
29
|
# npm
|
|
30
|
-
npm i @tomjs/vite-plugin-vscode
|
|
30
|
+
npm i @tomjs/vite-plugin-vscode -D
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
## 使用说明
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
(() => {
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
5
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
// src/webview/client.ts
|
|
9
|
+
var require_client = __commonJS({
|
|
10
|
+
"src/webview/client.ts"() {
|
|
11
|
+
if (window.top === window.self) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
var TAG = "[@tomjs:vscode:client] ";
|
|
15
|
+
patchAcquireVsCodeApi();
|
|
16
|
+
function onDomReady(callback) {
|
|
17
|
+
if (document.readyState === "interactive" || document.readyState === "complete") {
|
|
18
|
+
callback();
|
|
19
|
+
} else {
|
|
20
|
+
document.addEventListener("DOMContentLoaded", callback);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function setStateData(data) {
|
|
24
|
+
localStorage.setItem("vscode.state", JSON.stringify(data));
|
|
25
|
+
}
|
|
26
|
+
function getStateData() {
|
|
27
|
+
try {
|
|
28
|
+
const v = localStorage.getItem("vscode.state");
|
|
29
|
+
return v ? JSON.parse(v) : v;
|
|
30
|
+
} catch (e) {
|
|
31
|
+
}
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
function patchInitData(data) {
|
|
35
|
+
const { state, style, body, root } = data;
|
|
36
|
+
setStateData(state);
|
|
37
|
+
document.documentElement.style.cssText = root.cssText;
|
|
38
|
+
document.body.className = body.className;
|
|
39
|
+
Object.keys(body.dataset).forEach((key) => {
|
|
40
|
+
document.body.dataset[key] = body.dataset[key];
|
|
41
|
+
});
|
|
42
|
+
const defaultStyles = document.createElement("style");
|
|
43
|
+
defaultStyles.id = "_defaultStyles";
|
|
44
|
+
defaultStyles.textContent = style;
|
|
45
|
+
document.head.appendChild(defaultStyles);
|
|
46
|
+
}
|
|
47
|
+
function patchAcquireVsCodeApi() {
|
|
48
|
+
class AcquireVsCodeApi {
|
|
49
|
+
postMessage(message) {
|
|
50
|
+
console.log(TAG + " acquireVsCodeApi.postMessage:", message);
|
|
51
|
+
window.parent.postMessage({ type: "[vscode:client]:postMessage", data: message }, "*");
|
|
52
|
+
}
|
|
53
|
+
getState() {
|
|
54
|
+
console.log(TAG + " acquireVsCodeApi.getState");
|
|
55
|
+
return getStateData();
|
|
56
|
+
}
|
|
57
|
+
setState(newState) {
|
|
58
|
+
console.log(TAG + " acquireVsCodeApi.setState:", newState);
|
|
59
|
+
setStateData(newState);
|
|
60
|
+
window.parent.postMessage({ type: "[vscode:client]:setSate", data: newState }, "*");
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
console.log(TAG + "patch acquireVsCodeApi");
|
|
64
|
+
let api;
|
|
65
|
+
window.acquireVsCodeApi = () => {
|
|
66
|
+
if (!api) {
|
|
67
|
+
api = new AcquireVsCodeApi();
|
|
68
|
+
return api;
|
|
69
|
+
} else {
|
|
70
|
+
return api;
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
var INIT_TYPE = "[vscode:extension]:init";
|
|
75
|
+
var GET_STATE_TYPE = "[vscode:extension]:state";
|
|
76
|
+
window.addEventListener("message", (e) => {
|
|
77
|
+
const { type, data } = e.data || {};
|
|
78
|
+
if (!e.origin.startsWith("vscode-webview://") || ![INIT_TYPE, GET_STATE_TYPE].includes(type)) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
onDomReady(function() {
|
|
82
|
+
if (type === INIT_TYPE) {
|
|
83
|
+
patchInitData(data);
|
|
84
|
+
} else if (type === GET_STATE_TYPE) {
|
|
85
|
+
localStorage.setItem("vscode.state", JSON.stringify(data));
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
require_client();
|
|
92
|
+
})();
|
package/dist/index.js
CHANGED
|
@@ -7,11 +7,11 @@ var _lodashclonedeep = require('lodash.clonedeep'); var _lodashclonedeep2 = _int
|
|
|
7
7
|
var _lodashmerge = require('lodash.merge'); var _lodashmerge2 = _interopRequireDefault(_lodashmerge);
|
|
8
8
|
var _nodehtmlparser = require('node-html-parser');
|
|
9
9
|
var _tsup = require('tsup');
|
|
10
|
+
var _node = require('@tomjs/node');
|
|
10
11
|
|
|
11
12
|
// src/constants.ts
|
|
12
13
|
var PLUGIN_NAME = "tomjs:vscode";
|
|
13
14
|
var PACKAGE_NAME = "@tomjs/vite-plugin-vscode";
|
|
14
|
-
var WEBVIEW_PACKAGE_NAME = "@tomjs/vscode-extension-webview";
|
|
15
15
|
var WEBVIEW_METHOD_NAME = "__getWebviewHtml__";
|
|
16
16
|
|
|
17
17
|
// src/logger.ts
|
|
@@ -57,22 +57,6 @@ var createLogger = (tag) => {
|
|
|
57
57
|
};
|
|
58
58
|
|
|
59
59
|
// src/utils.ts
|
|
60
|
-
|
|
61
|
-
var _module = require('module');
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
var _execa = require('execa'); var _execa2 = _interopRequireDefault(_execa);
|
|
65
|
-
function readJson(path3) {
|
|
66
|
-
if (_fs2.default.existsSync(path3)) {
|
|
67
|
-
return JSON.parse(_fs2.default.readFileSync(path3, "utf8"));
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
function emptyPath(dest) {
|
|
71
|
-
if (_fs2.default.existsSync(dest)) {
|
|
72
|
-
_fs2.default.rmSync(dest, { recursive: true });
|
|
73
|
-
}
|
|
74
|
-
_fs2.default.mkdirSync(dest, { recursive: true });
|
|
75
|
-
}
|
|
76
60
|
function resolveHostname(hostname) {
|
|
77
61
|
const loopbackHosts = /* @__PURE__ */ new Set([
|
|
78
62
|
"localhost",
|
|
@@ -92,38 +76,11 @@ function resolveServerUrl(server) {
|
|
|
92
76
|
const options = server.config.server;
|
|
93
77
|
const protocol = options.https ? "https" : "http";
|
|
94
78
|
const devBase = server.config.base;
|
|
95
|
-
const
|
|
96
|
-
const url =
|
|
79
|
+
const path2 = typeof options.open === "string" ? options.open : devBase;
|
|
80
|
+
const url = path2.startsWith("http") ? path2 : `${protocol}://${hostname}:${port}${path2}`;
|
|
97
81
|
return url;
|
|
98
82
|
}
|
|
99
83
|
}
|
|
100
|
-
function getWebviewPnpmPath() {
|
|
101
|
-
try {
|
|
102
|
-
const res = _execa2.default.sync("pnpm", ["list", "--dev", "--depth=1", "--json"], {});
|
|
103
|
-
if (res.stdout) {
|
|
104
|
-
const list = JSON.parse(res.stdout.trim());
|
|
105
|
-
if (list.length === 0) {
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
const self = (list[0].devDependencies || {})[PACKAGE_NAME];
|
|
109
|
-
if (!self) {
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
const dep = self.dependencies[WEBVIEW_PACKAGE_NAME];
|
|
113
|
-
if (dep) {
|
|
114
|
-
return dep.path;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
} catch (e) {
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
function getWebviewNpmPath() {
|
|
121
|
-
const npmPath = _path2.default.join(_process.cwd.call(void 0, ), "node_modules", WEBVIEW_PACKAGE_NAME);
|
|
122
|
-
if (_fs2.default.existsSync(npmPath)) {
|
|
123
|
-
return npmPath;
|
|
124
|
-
}
|
|
125
|
-
return getWebviewPnpmPath();
|
|
126
|
-
}
|
|
127
84
|
|
|
128
85
|
// src/index.ts
|
|
129
86
|
var isDev = process.env.NODE_ENV === "development";
|
|
@@ -133,7 +90,7 @@ function getPkg() {
|
|
|
133
90
|
if (!_fs2.default.existsSync(pkgFile)) {
|
|
134
91
|
throw new Error("Main file is not specified, and no package.json found");
|
|
135
92
|
}
|
|
136
|
-
const pkg =
|
|
93
|
+
const pkg = _node.readJsonSync.call(void 0, pkgFile);
|
|
137
94
|
if (!pkg.main) {
|
|
138
95
|
throw new Error("Main file is not specified, please check package.json");
|
|
139
96
|
}
|
|
@@ -176,9 +133,7 @@ function preMergeOptions(options) {
|
|
|
176
133
|
} else {
|
|
177
134
|
opt.minify ??= true;
|
|
178
135
|
}
|
|
179
|
-
opt.external = ["vscode"
|
|
180
|
-
_nullishCoalesce(opt.external, () => ( []))
|
|
181
|
-
);
|
|
136
|
+
opt.external = ["vscode"].concat(_nullishCoalesce(opt.external, () => ( [])));
|
|
182
137
|
if (!opt.skipNodeModulesBundle) {
|
|
183
138
|
opt.noExternal = Object.keys(pkg.dependencies || {}).concat(
|
|
184
139
|
Object.keys(pkg.peerDependencies || {})
|
|
@@ -198,7 +153,7 @@ var prodCachePkgName = `${PACKAGE_NAME}-inject`;
|
|
|
198
153
|
function genProdWebviewCode(cache, webview) {
|
|
199
154
|
webview = Object.assign({}, webview);
|
|
200
155
|
const prodCacheFolder = _path2.default.join(_process.cwd.call(void 0, ), "node_modules", prodCachePkgName);
|
|
201
|
-
|
|
156
|
+
_node.emptyDirSync.call(void 0, prodCacheFolder);
|
|
202
157
|
const destFile = _path2.default.join(prodCacheFolder, "index.ts");
|
|
203
158
|
function handleHtmlCode(html) {
|
|
204
159
|
const root = _nodehtmlparser.parse.call(void 0, html);
|
|
@@ -297,23 +252,8 @@ function useVSCodePlugin(options) {
|
|
|
297
252
|
};
|
|
298
253
|
};
|
|
299
254
|
let devWebviewClient;
|
|
300
|
-
let devWebviewPath;
|
|
301
255
|
if (opts.webview) {
|
|
302
|
-
|
|
303
|
-
if (devWebviewPath && _os2.default.platform() === "win32") {
|
|
304
|
-
devWebviewPath = devWebviewPath.replaceAll("\\", "/");
|
|
305
|
-
}
|
|
306
|
-
if (!devWebviewPath || !_fs2.default.existsSync(devWebviewPath)) {
|
|
307
|
-
logger.warn(`[${WEBVIEW_PACKAGE_NAME}] is not installed, please install it first!`);
|
|
308
|
-
} else {
|
|
309
|
-
const fileName = "client.global.js";
|
|
310
|
-
const clientFile = _path2.default.join(devWebviewPath, "dist", fileName);
|
|
311
|
-
if (!_fs2.default.existsSync(clientFile)) {
|
|
312
|
-
logger.warn(`[${fileName}] is does not exist, please update the package!`);
|
|
313
|
-
} else {
|
|
314
|
-
devWebviewClient = _fs2.default.readFileSync(clientFile, "utf-8");
|
|
315
|
-
}
|
|
316
|
-
}
|
|
256
|
+
devWebviewClient = _node.readFileSync.call(void 0, _path2.default.join(__dirname, "client.global.js"));
|
|
317
257
|
}
|
|
318
258
|
let buildConfig;
|
|
319
259
|
const prodHtmlCache = {};
|
|
@@ -351,7 +291,7 @@ function useVSCodePlugin(options) {
|
|
|
351
291
|
const file = _fs2.default.readFileSync(args.path, "utf-8");
|
|
352
292
|
if (file.includes(`${webview.name}(`)) {
|
|
353
293
|
return {
|
|
354
|
-
contents: `import ${webview.name} from '${
|
|
294
|
+
contents: `import ${webview.name} from '${PACKAGE_NAME}/webview';
|
|
355
295
|
` + file,
|
|
356
296
|
loader: "ts"
|
|
357
297
|
};
|
|
@@ -376,7 +316,7 @@ function useVSCodePlugin(options) {
|
|
|
376
316
|
});
|
|
377
317
|
},
|
|
378
318
|
transformIndexHtml(html) {
|
|
379
|
-
if (!opts.webview
|
|
319
|
+
if (!opts.webview) {
|
|
380
320
|
return html;
|
|
381
321
|
}
|
|
382
322
|
return html.replace(/<\/title>/i, `</title><script>${devWebviewClient}</script>`);
|
package/dist/index.mjs
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
|
+
// node_modules/.pnpm/tsup@7.2.0_@swc+core@1.3.100_postcss@8.4.32_typescript@5.3.3/node_modules/tsup/assets/esm_shims.js
|
|
2
|
+
import { fileURLToPath } from "url";
|
|
3
|
+
import path from "path";
|
|
4
|
+
var getFilename = () => fileURLToPath(import.meta.url);
|
|
5
|
+
var getDirname = () => path.dirname(getFilename());
|
|
6
|
+
var __dirname = /* @__PURE__ */ getDirname();
|
|
7
|
+
|
|
1
8
|
// src/index.ts
|
|
2
|
-
import
|
|
9
|
+
import fs from "fs";
|
|
3
10
|
import os from "os";
|
|
4
11
|
import path2 from "path";
|
|
5
|
-
import { cwd
|
|
12
|
+
import { cwd } from "process";
|
|
6
13
|
import cloneDeep from "lodash.clonedeep";
|
|
7
14
|
import merge from "lodash.merge";
|
|
8
15
|
import { parse as htmlParser } from "node-html-parser";
|
|
9
16
|
import { build as tsupBuild } from "tsup";
|
|
17
|
+
import { emptyDirSync, readFileSync, readJsonSync } from "@tomjs/node";
|
|
10
18
|
|
|
11
19
|
// src/constants.ts
|
|
12
20
|
var PLUGIN_NAME = "tomjs:vscode";
|
|
13
21
|
var PACKAGE_NAME = "@tomjs/vite-plugin-vscode";
|
|
14
|
-
var WEBVIEW_PACKAGE_NAME = "@tomjs/vscode-extension-webview";
|
|
15
22
|
var WEBVIEW_METHOD_NAME = "__getWebviewHtml__";
|
|
16
23
|
|
|
17
24
|
// src/logger.ts
|
|
@@ -57,21 +64,6 @@ var createLogger = (tag) => {
|
|
|
57
64
|
};
|
|
58
65
|
|
|
59
66
|
// src/utils.ts
|
|
60
|
-
import fs from "fs";
|
|
61
|
-
import path from "path";
|
|
62
|
-
import { cwd } from "process";
|
|
63
|
-
import execa from "execa";
|
|
64
|
-
function readJson(path3) {
|
|
65
|
-
if (fs.existsSync(path3)) {
|
|
66
|
-
return JSON.parse(fs.readFileSync(path3, "utf8"));
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
function emptyPath(dest) {
|
|
70
|
-
if (fs.existsSync(dest)) {
|
|
71
|
-
fs.rmSync(dest, { recursive: true });
|
|
72
|
-
}
|
|
73
|
-
fs.mkdirSync(dest, { recursive: true });
|
|
74
|
-
}
|
|
75
67
|
function resolveHostname(hostname) {
|
|
76
68
|
const loopbackHosts = /* @__PURE__ */ new Set([
|
|
77
69
|
"localhost",
|
|
@@ -96,43 +88,16 @@ function resolveServerUrl(server) {
|
|
|
96
88
|
return url;
|
|
97
89
|
}
|
|
98
90
|
}
|
|
99
|
-
function getWebviewPnpmPath() {
|
|
100
|
-
try {
|
|
101
|
-
const res = execa.sync("pnpm", ["list", "--dev", "--depth=1", "--json"], {});
|
|
102
|
-
if (res.stdout) {
|
|
103
|
-
const list = JSON.parse(res.stdout.trim());
|
|
104
|
-
if (list.length === 0) {
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
const self = (list[0].devDependencies || {})[PACKAGE_NAME];
|
|
108
|
-
if (!self) {
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
const dep = self.dependencies[WEBVIEW_PACKAGE_NAME];
|
|
112
|
-
if (dep) {
|
|
113
|
-
return dep.path;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
} catch {
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
function getWebviewNpmPath() {
|
|
120
|
-
const npmPath = path.join(cwd(), "node_modules", WEBVIEW_PACKAGE_NAME);
|
|
121
|
-
if (fs.existsSync(npmPath)) {
|
|
122
|
-
return npmPath;
|
|
123
|
-
}
|
|
124
|
-
return getWebviewPnpmPath();
|
|
125
|
-
}
|
|
126
91
|
|
|
127
92
|
// src/index.ts
|
|
128
93
|
var isDev = process.env.NODE_ENV === "development";
|
|
129
94
|
var logger = createLogger();
|
|
130
95
|
function getPkg() {
|
|
131
96
|
const pkgFile = path2.resolve(process.cwd(), "package.json");
|
|
132
|
-
if (!
|
|
97
|
+
if (!fs.existsSync(pkgFile)) {
|
|
133
98
|
throw new Error("Main file is not specified, and no package.json found");
|
|
134
99
|
}
|
|
135
|
-
const pkg =
|
|
100
|
+
const pkg = readJsonSync(pkgFile);
|
|
136
101
|
if (!pkg.main) {
|
|
137
102
|
throw new Error("Main file is not specified, please check package.json");
|
|
138
103
|
}
|
|
@@ -175,9 +140,7 @@ function preMergeOptions(options) {
|
|
|
175
140
|
} else {
|
|
176
141
|
opt.minify ??= true;
|
|
177
142
|
}
|
|
178
|
-
opt.external = ["vscode"
|
|
179
|
-
opt.external ?? []
|
|
180
|
-
);
|
|
143
|
+
opt.external = ["vscode"].concat(opt.external ?? []);
|
|
181
144
|
if (!opt.skipNodeModulesBundle) {
|
|
182
145
|
opt.noExternal = Object.keys(pkg.dependencies || {}).concat(
|
|
183
146
|
Object.keys(pkg.peerDependencies || {})
|
|
@@ -196,8 +159,8 @@ function preMergeOptions(options) {
|
|
|
196
159
|
var prodCachePkgName = `${PACKAGE_NAME}-inject`;
|
|
197
160
|
function genProdWebviewCode(cache, webview) {
|
|
198
161
|
webview = Object.assign({}, webview);
|
|
199
|
-
const prodCacheFolder = path2.join(
|
|
200
|
-
|
|
162
|
+
const prodCacheFolder = path2.join(cwd(), "node_modules", prodCachePkgName);
|
|
163
|
+
emptyDirSync(prodCacheFolder);
|
|
201
164
|
const destFile = path2.join(prodCacheFolder, "index.ts");
|
|
202
165
|
function handleHtmlCode(html) {
|
|
203
166
|
const root = htmlParser(html);
|
|
@@ -254,7 +217,7 @@ export default function getWebviewHtml(webview: Webview, context: ExtensionConte
|
|
|
254
217
|
}
|
|
255
218
|
`
|
|
256
219
|
);
|
|
257
|
-
|
|
220
|
+
fs.writeFileSync(destFile, code, { encoding: "utf8" });
|
|
258
221
|
return fixWindowsPath(destFile);
|
|
259
222
|
}
|
|
260
223
|
function fixWindowsPath(webviewPath) {
|
|
@@ -296,23 +259,8 @@ function useVSCodePlugin(options) {
|
|
|
296
259
|
};
|
|
297
260
|
};
|
|
298
261
|
let devWebviewClient;
|
|
299
|
-
let devWebviewPath;
|
|
300
262
|
if (opts.webview) {
|
|
301
|
-
|
|
302
|
-
if (devWebviewPath && os.platform() === "win32") {
|
|
303
|
-
devWebviewPath = devWebviewPath.replaceAll("\\", "/");
|
|
304
|
-
}
|
|
305
|
-
if (!devWebviewPath || !fs2.existsSync(devWebviewPath)) {
|
|
306
|
-
logger.warn(`[${WEBVIEW_PACKAGE_NAME}] is not installed, please install it first!`);
|
|
307
|
-
} else {
|
|
308
|
-
const fileName = "client.global.js";
|
|
309
|
-
const clientFile = path2.join(devWebviewPath, "dist", fileName);
|
|
310
|
-
if (!fs2.existsSync(clientFile)) {
|
|
311
|
-
logger.warn(`[${fileName}] is does not exist, please update the package!`);
|
|
312
|
-
} else {
|
|
313
|
-
devWebviewClient = fs2.readFileSync(clientFile, "utf-8");
|
|
314
|
-
}
|
|
315
|
-
}
|
|
263
|
+
devWebviewClient = readFileSync(path2.join(__dirname, "client.global.js"));
|
|
316
264
|
}
|
|
317
265
|
let buildConfig;
|
|
318
266
|
const prodHtmlCache = {};
|
|
@@ -347,10 +295,10 @@ function useVSCodePlugin(options) {
|
|
|
347
295
|
name: "@tomjs:vscode:inject",
|
|
348
296
|
setup(build) {
|
|
349
297
|
build.onLoad({ filter: /\.ts$/ }, async (args) => {
|
|
350
|
-
const file =
|
|
298
|
+
const file = fs.readFileSync(args.path, "utf-8");
|
|
351
299
|
if (file.includes(`${webview.name}(`)) {
|
|
352
300
|
return {
|
|
353
|
-
contents: `import ${webview.name} from '${
|
|
301
|
+
contents: `import ${webview.name} from '${PACKAGE_NAME}/webview';
|
|
354
302
|
` + file,
|
|
355
303
|
loader: "ts"
|
|
356
304
|
};
|
|
@@ -375,7 +323,7 @@ function useVSCodePlugin(options) {
|
|
|
375
323
|
});
|
|
376
324
|
},
|
|
377
325
|
transformIndexHtml(html) {
|
|
378
|
-
if (!opts.webview
|
|
326
|
+
if (!opts.webview) {
|
|
379
327
|
return html;
|
|
380
328
|
}
|
|
381
329
|
return html.replace(/<\/title>/i, `</title><script>${devWebviewClient}</script>`);
|
|
@@ -405,7 +353,7 @@ function useVSCodePlugin(options) {
|
|
|
405
353
|
if (webview) {
|
|
406
354
|
webviewPath = genProdWebviewCode(prodHtmlCache, webview);
|
|
407
355
|
}
|
|
408
|
-
let outDir = buildConfig.build.outDir.replace(
|
|
356
|
+
let outDir = buildConfig.build.outDir.replace(cwd(), "").replaceAll("\\", "/");
|
|
409
357
|
if (outDir.startsWith("/")) {
|
|
410
358
|
outDir = outDir.substring(1);
|
|
411
359
|
}
|
|
@@ -424,7 +372,7 @@ function useVSCodePlugin(options) {
|
|
|
424
372
|
name: "@tomjs:vscode:inject",
|
|
425
373
|
setup(build) {
|
|
426
374
|
build.onLoad({ filter: /\.ts$/ }, async (args) => {
|
|
427
|
-
const file =
|
|
375
|
+
const file = fs.readFileSync(args.path, "utf-8");
|
|
428
376
|
if (file.includes(`${webview.name}(`)) {
|
|
429
377
|
return {
|
|
430
378
|
contents: `import ${webview.name} from \`${webviewPath}\`;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
interface WebviewHtmlDevOptions {
|
|
2
|
+
/**
|
|
3
|
+
* local server url
|
|
4
|
+
*/
|
|
5
|
+
serverUrl: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
* @param options serverUrl string or object options
|
|
10
|
+
*/
|
|
11
|
+
declare function getHtml(options: string | WebviewHtmlDevOptions): string;
|
|
12
|
+
|
|
13
|
+
export { WebviewHtmlDevOptions, getHtml as default, getHtml };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
interface WebviewHtmlDevOptions {
|
|
2
|
+
/**
|
|
3
|
+
* local server url
|
|
4
|
+
*/
|
|
5
|
+
serverUrl: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
* @param options serverUrl string or object options
|
|
10
|
+
*/
|
|
11
|
+
declare function getHtml(options: string | WebviewHtmlDevOptions): string;
|
|
12
|
+
|
|
13
|
+
export { WebviewHtmlDevOptions, getHtml as default, getHtml };
|
package/dist/webview.js
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/webview/template.html
|
|
2
|
+
var template_default = `<!doctype html>
|
|
3
|
+
<html lang="en">
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8" />
|
|
6
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
8
|
+
<style>
|
|
9
|
+
html,
|
|
10
|
+
body {
|
|
11
|
+
width: 100%;
|
|
12
|
+
height: 100%;
|
|
13
|
+
margin: 0;
|
|
14
|
+
padding: 0;
|
|
15
|
+
overflow: hidden;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
#webview-patch-iframe {
|
|
19
|
+
width: 100%;
|
|
20
|
+
height: 100%;
|
|
21
|
+
border: none;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.outer {
|
|
25
|
+
width: 100%;
|
|
26
|
+
height: 100%;
|
|
27
|
+
overflow: hidden;
|
|
28
|
+
}
|
|
29
|
+
</style>
|
|
30
|
+
|
|
31
|
+
<script type="module" id="webview-patch">
|
|
32
|
+
const TAG = '[@tomjs:vscode:extension] ';
|
|
33
|
+
|
|
34
|
+
function onDomReady(callback) {
|
|
35
|
+
if (document.readyState === 'interactive' || document.readyState === 'complete') {
|
|
36
|
+
callback();
|
|
37
|
+
} else {
|
|
38
|
+
document.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 addListeners(iframe) {
|
|
77
|
+
window.addEventListener('message', function (e) {
|
|
78
|
+
if (e.origin.startsWith('vscode-webview://')) {
|
|
79
|
+
iframe.contentWindow.postMessage(e.data, '*');
|
|
80
|
+
} else if ('{{serverUrl}}'.startsWith(e.origin)) {
|
|
81
|
+
const { type, data } = e.data;
|
|
82
|
+
if (type === '[vscode:client]:postMessage') {
|
|
83
|
+
getApi().postMessage(data);
|
|
84
|
+
} else if (type === '[vscode:client]:getState') {
|
|
85
|
+
iframe.contentWindow.postMessage(
|
|
86
|
+
{
|
|
87
|
+
type: '[vscode:extension]:getState',
|
|
88
|
+
data: getApi().getState(),
|
|
89
|
+
},
|
|
90
|
+
'*',
|
|
91
|
+
);
|
|
92
|
+
} else if (type === '[vscode:client]:setState') {
|
|
93
|
+
getApi().setState(data);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function observeAttributeChanges(element, attributeName, callback) {
|
|
100
|
+
const observer = new MutationObserver(function (mutationsList) {
|
|
101
|
+
for (let mutation of mutationsList) {
|
|
102
|
+
if (mutation.type === 'attributes' && mutation.attributeName === attributeName) {
|
|
103
|
+
callback(mutation.target.getAttribute(attributeName));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
observer.observe(element, { attributes: true });
|
|
108
|
+
return observer;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
onDomReady(function () {
|
|
112
|
+
const iframe = document.getElementById('webview-patch-iframe');
|
|
113
|
+
observeAttributeChanges(document.body, 'class', function (className) {
|
|
114
|
+
sendInitData(iframe);
|
|
115
|
+
});
|
|
116
|
+
iframe.addEventListener('load', function (e) {
|
|
117
|
+
let interval = setInterval(() => {
|
|
118
|
+
try {
|
|
119
|
+
if (document.getElementById('_defaultStyles')) {
|
|
120
|
+
sendInitData(iframe);
|
|
121
|
+
addListeners(iframe);
|
|
122
|
+
clearInterval(interval);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
} catch (e) {
|
|
126
|
+
clearInterval(interval);
|
|
127
|
+
console.error(e);
|
|
128
|
+
}
|
|
129
|
+
}, 10);
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
</script>
|
|
133
|
+
</head>
|
|
134
|
+
|
|
135
|
+
<body>
|
|
136
|
+
<div class="outer">
|
|
137
|
+
<iframe
|
|
138
|
+
id="webview-patch-iframe"
|
|
139
|
+
frameborder="0"
|
|
140
|
+
sandbox="allow-scripts allow-same-origin allow-forms allow-pointer-lock allow-downloads"
|
|
141
|
+
allow="cross-origin-isolated; autoplay; clipboard-read; clipboard-write"
|
|
142
|
+
src="{{serverUrl}}"
|
|
143
|
+
></iframe>
|
|
144
|
+
</div>
|
|
145
|
+
</body>
|
|
146
|
+
</html>
|
|
147
|
+
`;
|
|
148
|
+
|
|
149
|
+
// src/webview/webview.ts
|
|
150
|
+
function getHtml(options) {
|
|
151
|
+
const opts = {
|
|
152
|
+
serverUrl: ""
|
|
153
|
+
};
|
|
154
|
+
if (typeof options === "string") {
|
|
155
|
+
opts.serverUrl = options;
|
|
156
|
+
} else {
|
|
157
|
+
Object.assign(opts, options);
|
|
158
|
+
}
|
|
159
|
+
return template_default.replace(new RegExp("{{serverUrl}}", "g"), opts.serverUrl);
|
|
160
|
+
}
|
|
161
|
+
var webview_default = getHtml;
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
exports.default = webview_default; exports.getHtml = getHtml;
|
package/dist/webview.mjs
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
// src/webview/template.html
|
|
2
|
+
var template_default = `<!doctype html>
|
|
3
|
+
<html lang="en">
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8" />
|
|
6
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
8
|
+
<style>
|
|
9
|
+
html,
|
|
10
|
+
body {
|
|
11
|
+
width: 100%;
|
|
12
|
+
height: 100%;
|
|
13
|
+
margin: 0;
|
|
14
|
+
padding: 0;
|
|
15
|
+
overflow: hidden;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
#webview-patch-iframe {
|
|
19
|
+
width: 100%;
|
|
20
|
+
height: 100%;
|
|
21
|
+
border: none;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.outer {
|
|
25
|
+
width: 100%;
|
|
26
|
+
height: 100%;
|
|
27
|
+
overflow: hidden;
|
|
28
|
+
}
|
|
29
|
+
</style>
|
|
30
|
+
|
|
31
|
+
<script type="module" id="webview-patch">
|
|
32
|
+
const TAG = '[@tomjs:vscode:extension] ';
|
|
33
|
+
|
|
34
|
+
function onDomReady(callback) {
|
|
35
|
+
if (document.readyState === 'interactive' || document.readyState === 'complete') {
|
|
36
|
+
callback();
|
|
37
|
+
} else {
|
|
38
|
+
document.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 addListeners(iframe) {
|
|
77
|
+
window.addEventListener('message', function (e) {
|
|
78
|
+
if (e.origin.startsWith('vscode-webview://')) {
|
|
79
|
+
iframe.contentWindow.postMessage(e.data, '*');
|
|
80
|
+
} else if ('{{serverUrl}}'.startsWith(e.origin)) {
|
|
81
|
+
const { type, data } = e.data;
|
|
82
|
+
if (type === '[vscode:client]:postMessage') {
|
|
83
|
+
getApi().postMessage(data);
|
|
84
|
+
} else if (type === '[vscode:client]:getState') {
|
|
85
|
+
iframe.contentWindow.postMessage(
|
|
86
|
+
{
|
|
87
|
+
type: '[vscode:extension]:getState',
|
|
88
|
+
data: getApi().getState(),
|
|
89
|
+
},
|
|
90
|
+
'*',
|
|
91
|
+
);
|
|
92
|
+
} else if (type === '[vscode:client]:setState') {
|
|
93
|
+
getApi().setState(data);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function observeAttributeChanges(element, attributeName, callback) {
|
|
100
|
+
const observer = new MutationObserver(function (mutationsList) {
|
|
101
|
+
for (let mutation of mutationsList) {
|
|
102
|
+
if (mutation.type === 'attributes' && mutation.attributeName === attributeName) {
|
|
103
|
+
callback(mutation.target.getAttribute(attributeName));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
observer.observe(element, { attributes: true });
|
|
108
|
+
return observer;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
onDomReady(function () {
|
|
112
|
+
const iframe = document.getElementById('webview-patch-iframe');
|
|
113
|
+
observeAttributeChanges(document.body, 'class', function (className) {
|
|
114
|
+
sendInitData(iframe);
|
|
115
|
+
});
|
|
116
|
+
iframe.addEventListener('load', function (e) {
|
|
117
|
+
let interval = setInterval(() => {
|
|
118
|
+
try {
|
|
119
|
+
if (document.getElementById('_defaultStyles')) {
|
|
120
|
+
sendInitData(iframe);
|
|
121
|
+
addListeners(iframe);
|
|
122
|
+
clearInterval(interval);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
} catch (e) {
|
|
126
|
+
clearInterval(interval);
|
|
127
|
+
console.error(e);
|
|
128
|
+
}
|
|
129
|
+
}, 10);
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
</script>
|
|
133
|
+
</head>
|
|
134
|
+
|
|
135
|
+
<body>
|
|
136
|
+
<div class="outer">
|
|
137
|
+
<iframe
|
|
138
|
+
id="webview-patch-iframe"
|
|
139
|
+
frameborder="0"
|
|
140
|
+
sandbox="allow-scripts allow-same-origin allow-forms allow-pointer-lock allow-downloads"
|
|
141
|
+
allow="cross-origin-isolated; autoplay; clipboard-read; clipboard-write"
|
|
142
|
+
src="{{serverUrl}}"
|
|
143
|
+
></iframe>
|
|
144
|
+
</div>
|
|
145
|
+
</body>
|
|
146
|
+
</html>
|
|
147
|
+
`;
|
|
148
|
+
|
|
149
|
+
// src/webview/webview.ts
|
|
150
|
+
function getHtml(options) {
|
|
151
|
+
const opts = {
|
|
152
|
+
serverUrl: ""
|
|
153
|
+
};
|
|
154
|
+
if (typeof options === "string") {
|
|
155
|
+
opts.serverUrl = options;
|
|
156
|
+
} else {
|
|
157
|
+
Object.assign(opts, options);
|
|
158
|
+
}
|
|
159
|
+
return template_default.replace(new RegExp("{{serverUrl}}", "g"), opts.serverUrl);
|
|
160
|
+
}
|
|
161
|
+
var webview_default = getHtml;
|
|
162
|
+
export {
|
|
163
|
+
webview_default as default,
|
|
164
|
+
getHtml
|
|
165
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tomjs/vite-plugin-vscode",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "Use vue/react to develop 'vscode extension webview', supporting esm/cjs",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"vite",
|
|
@@ -23,10 +23,27 @@
|
|
|
23
23
|
"types": "./dist/index.d.ts",
|
|
24
24
|
"exports": {
|
|
25
25
|
".": {
|
|
26
|
-
"require":
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
"require": {
|
|
27
|
+
"default": "./dist/index.js",
|
|
28
|
+
"types": "./dist/index.d.ts"
|
|
29
|
+
},
|
|
30
|
+
"import": {
|
|
31
|
+
"default": "./dist/index.mjs",
|
|
32
|
+
"types": "./dist/index.d.mts"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"./webview": {
|
|
36
|
+
"require": {
|
|
37
|
+
"default": "./dist/webview.js",
|
|
38
|
+
"types": "./dist/webview.d.ts"
|
|
39
|
+
},
|
|
40
|
+
"import": {
|
|
41
|
+
"default": "./dist/webview.mjs",
|
|
42
|
+
"types": "./dist/webview.d.mts"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"./client": "./dist/client.global.js",
|
|
46
|
+
"./env": "./env.d.ts"
|
|
30
47
|
},
|
|
31
48
|
"files": [
|
|
32
49
|
"dist",
|
|
@@ -44,6 +61,7 @@
|
|
|
44
61
|
"url": "git+https://github.com/tomjs/vite-plugin-vscode.git"
|
|
45
62
|
},
|
|
46
63
|
"dependencies": {
|
|
64
|
+
"@tomjs/node": "^2.2.0",
|
|
47
65
|
"@tomjs/vscode-extension-webview": "^1.2.0",
|
|
48
66
|
"dayjs": "^1.11.10",
|
|
49
67
|
"execa": "^5.1.1",
|
|
@@ -78,8 +96,9 @@
|
|
|
78
96
|
"vite": ">=2"
|
|
79
97
|
},
|
|
80
98
|
"scripts": {
|
|
81
|
-
"dev": "tsup --watch",
|
|
82
|
-
"build": "tsup",
|
|
99
|
+
"dev": "pnpm clean && tsup --watch",
|
|
100
|
+
"build": "pnpm clean && tsup",
|
|
101
|
+
"clean": "rimraf ./dist",
|
|
83
102
|
"lint": "run-s lint:eslint lint:stylelint lint:prettier",
|
|
84
103
|
"lint:eslint": "eslint \"{src,scripts,examples}/**/*.ts\" *.{js,cjs,ts} --fix --cache",
|
|
85
104
|
"lint:stylelint": "stylelint \"examples/**/*.{css,scss,less,vue,html}\" --fix --cache",
|