Skip to content

Commit

Permalink
feat: copy the code of @tomjs/vscode-extension-webview to the current…
Browse files Browse the repository at this point in the history
… project to solve dependency issues #7
  • Loading branch information
tomgao365 committed Jun 17, 2024
1 parent 9405788 commit aad58f2
Show file tree
Hide file tree
Showing 14 changed files with 367 additions and 153 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

> Use `vue`/`react` to develop [vscode extension webview](https://code.visualstudio.com/api/references/vscode-api#WebviewPanel), supporting `esm` and `cjs`.
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.
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.

## Features

Expand All @@ -27,7 +27,7 @@ pnpm add @tomjs/vite-plugin-vscode -D
yarn add @tomjs/vite-plugin-vscode -D

# npm
npm i @tomjs/vite-plugin-vscode --save-dev
npm i @tomjs/vite-plugin-vscode -D
```

## Usage
Expand Down
4 changes: 2 additions & 2 deletions README.zh_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

> `vue`/`react` 来开发 [vscode extension webview](https://code.visualstudio.com/api/references/vscode-api#WebviewPanel) ,支持 `esm``cjs`
在开发模式时,给 `vscode 扩展代码``web 页面代码`中注入 [@tomjs/vscode-extension-webview](https://github.com/tomjs/vscode-extension-webview) 的代码,用来支持 `HMR`;生产构建时,将最终生成的`index.html` 代码注入到 `vscode 扩展代码` 中,减少工作量。
在开发模式时,给 `vscode 扩展代码``web 页面代码`中注入 [@tomjs/vscode-extension-webview](https://github.com/tomjs/vscode-extension-webview) 相同的代码,用来支持 `HMR`;生产构建时,将最终生成的`index.html` 代码注入到 `vscode 扩展代码` 中,减少工作量。

## 特性

Expand All @@ -27,7 +27,7 @@ pnpm add @tomjs/vite-plugin-vscode -D
yarn add @tomjs/vite-plugin-vscode -D

# npm
npm i @tomjs/vite-plugin-vscode --save-dev
npm i @tomjs/vite-plugin-vscode -D
```

## 使用说明
Expand Down
30 changes: 24 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,26 @@
"types": "./dist/index.d.ts",
"exports": {
".": {
"require": "./dist/index.js",
"import": "./dist/index.mjs",
"types": "./dist/index.d.ts"
}
"require": {
"default": "./dist/index.js",
"types": "./dist/index.d.ts"
},
"import": {
"default": "./dist/index.mjs",
"types": "./dist/index.d.mts"
}
},
"./webview": {
"require": {
"default": "./dist/webview.js",
"types": "./dist/webview.d.ts"
},
"import": {
"default": "./dist/webview.mjs",
"types": "./dist/webview.d.mts"
}
},
"./client": "./dist/client.global.js"
},
"files": [
"dist",
Expand All @@ -45,15 +61,17 @@
"url": "git+https://github.com/tomjs/vite-plugin-vscode.git"
},
"scripts": {
"dev": "tsup --watch",
"build": "tsup",
"dev": "pnpm clean && tsup --watch",
"build": "pnpm clean && tsup",
"clean": "rimraf ./dist",
"lint": "run-s lint:eslint lint:stylelint lint:prettier",
"lint:eslint": "eslint \"{src,scripts,examples}/**/*.ts\" *.{js,cjs,ts} --fix --cache",
"lint:stylelint": "stylelint \"examples/**/*.{css,scss,less,vue,html}\" --fix --cache",
"lint:prettier": "prettier --write .",
"prepare": "husky install"
},
"dependencies": {
"@tomjs/node": "^2.2.0",
"@tomjs/vscode-extension-webview": "^1.2.0",
"dayjs": "^1.11.10",
"execa": "^5.1.1",
Expand Down
9 changes: 9 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export const PLUGIN_NAME = 'tomjs:vscode';
export const ORG_NAME = '@tomjs';
export const PACKAGE_NAME = '@tomjs/vite-plugin-vscode';
export const WEBVIEW_PACKAGE_NAME = '@tomjs/vscode-extension-webview';
export const WEBVIEW_METHOD_NAME = '__getWebviewHtml__';
36 changes: 10 additions & 26 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import cloneDeep from 'lodash.clonedeep';
import merge from 'lodash.merge';
import { parse as htmlParser } from 'node-html-parser';
import { build as tsupBuild, type Options as TsupOptions } from 'tsup';
import { PACKAGE_NAME, WEBVIEW_METHOD_NAME, WEBVIEW_PACKAGE_NAME } from './constants';
import { emptyDirSync, readFileSync, readJsonSync } from '@tomjs/node';
import { PACKAGE_NAME, WEBVIEW_METHOD_NAME } from './constants';
import { createLogger } from './logger';
import { emptyPath, getWebviewNpmPath, readJson, resolveServerUrl } from './utils';
import { resolveServerUrl } from './utils';

const isDev = process.env.NODE_ENV === 'development';
const logger = createLogger();
Expand All @@ -21,7 +22,7 @@ function getPkg() {
throw new Error('Main file is not specified, and no package.json found');
}

const pkg = readJson(pkgFile);
const pkg = readJsonSync(pkgFile);
if (!pkg.main) {
throw new Error('Main file is not specified, please check package.json');
}
Expand Down Expand Up @@ -69,9 +70,7 @@ function preMergeOptions(options?: PluginOptions): PluginOptions {
opt.minify ??= true;
}

opt.external = (['vscode', WEBVIEW_PACKAGE_NAME] as (string | RegExp)[]).concat(
opt.external ?? [],
);
opt.external = (['vscode'] as (string | RegExp)[]).concat(opt.external ?? []);

if (!opt.skipNodeModulesBundle) {
opt.noExternal = Object.keys(pkg.dependencies || {}).concat(
Expand All @@ -97,7 +96,7 @@ function genProdWebviewCode(cache: Record<string, string>, webview?: WebviewOpti
webview = Object.assign({}, webview);

const prodCacheFolder = path.join(cwd(), 'node_modules', prodCachePkgName);
emptyPath(prodCacheFolder);
emptyDirSync(prodCacheFolder);
const destFile = path.join(prodCacheFolder, 'index.ts');

function handleHtmlCode(html: string) {
Expand Down Expand Up @@ -210,24 +209,8 @@ export function useVSCodePlugin(options?: PluginOptions): Plugin[] {
};

let devWebviewClient: string;
let devWebviewPath: string | undefined;
if (opts.webview) {
devWebviewPath = getWebviewNpmPath();
if (devWebviewPath && os.platform() === 'win32') {
devWebviewPath = devWebviewPath.replaceAll('\\', '/');
}

if (!devWebviewPath || !fs.existsSync(devWebviewPath)) {
logger.warn(`[${WEBVIEW_PACKAGE_NAME}] is not installed, please install it first!`);
} else {
const fileName = 'client.global.js';
const clientFile = path.join(devWebviewPath, 'dist', fileName);
if (!fs.existsSync(clientFile)) {
logger.warn(`[${fileName}] is does not exist, please update the package!`);
} else {
devWebviewClient = fs.readFileSync(clientFile, 'utf-8');
}
}
devWebviewClient = readFileSync(path.join(__dirname, 'client.global.js'));
}

let buildConfig: ResolvedConfig;
Expand Down Expand Up @@ -273,7 +256,8 @@ export function useVSCodePlugin(options?: PluginOptions): Plugin[] {
const file = fs.readFileSync(args.path, 'utf-8');
if (file.includes(`${webview.name}(`)) {
return {
contents: `import ${webview.name} from '${devWebviewPath}';\n` + file,
contents:
`import ${webview.name} from '${PACKAGE_NAME}/webview';\n` + file,
loader: 'ts',
};
}
Expand All @@ -299,7 +283,7 @@ export function useVSCodePlugin(options?: PluginOptions): Plugin[] {
});
},
transformIndexHtml(html) {
if (!opts.webview || !devWebviewClient) {
if (!opts.webview) {
return html;
}

Expand Down
105 changes: 0 additions & 105 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,78 +1,5 @@
import type { AddressInfo } from 'node:net';
import type { ViteDevServer } from 'vite';
import fs from 'node:fs';
import { builtinModules } from 'node:module';
import path from 'node:path';
import { cwd } from 'node:process';
import execa from 'execa';
import { PACKAGE_NAME, WEBVIEW_PACKAGE_NAME } from './constants';

export function readJson(path: string) {
if (fs.existsSync(path)) {
return JSON.parse(fs.readFileSync(path, 'utf8'));
}
}
export function writeJson(path: string, data: any) {
fs.writeFileSync(path, JSON.stringify(data, null, 2), 'utf8');
}

export function emptyPath(dest: string) {
if (fs.existsSync(dest)) {
fs.rmSync(dest, { recursive: true });
}
fs.mkdirSync(dest, { recursive: true });
}

export const getNodeExternal = (externals?: (string | RegExp)[]) => {
const modules: (string | RegExp)[] = builtinModules.filter(
x => !/^_|^(internal|v8|node-inspect|fsevents)\/|\//.test(x),
);

const external = Array.isArray(externals) ? externals : [];
return [
...new Set(modules.concat(modules.map(s => `node:${s}`)).concat(['vscode', ...external])),
];
};

export function hasArrayValue(value: any) {
return Array.isArray(value) && value.length > 0;
}

export function mergeExternal(
modules: string[],
noExternals?: (string | RegExp)[],
externals?: (string | RegExp)[],
) {
if (!Array.isArray(modules) || modules.length === 0) {
return modules;
}
let list = [...modules];
if (Array.isArray(noExternals) && noExternals.length > 0) {
list = list.filter(x => !noExternals.includes(x));
}

if (Array.isArray(externals) && externals.length > 0) {
list = list.filter(x => externals.includes(x));
}

return list;
}

export function getBooleanValue(value?: string) {
if (typeof value !== 'string' || value.trim() === '') {
return;
}

if (['true', 'false'].includes(value)) {
return value === 'true';
}

if (['1', '0'].includes(value)) {
return value === '1';
}

return;
}

/**
* @see https://github.com/vitejs/vite/blob/v4.0.1/packages/vite/src/node/constants.ts#L137-L147
Expand Down Expand Up @@ -107,35 +34,3 @@ export function resolveServerUrl(server: ViteDevServer) {
return url;
}
}

function getWebviewPnpmPath() {
try {
const res = execa.sync('pnpm', ['list', '--dev', '--depth=1', '--json'], {});
if (res.stdout) {
const list = JSON.parse(res.stdout.trim());
if (list.length === 0) {
return;
}
const self = (list[0].devDependencies || {})[PACKAGE_NAME];
if (!self) {
return;
}

const dep = self.dependencies[WEBVIEW_PACKAGE_NAME];
if (dep) {
return dep.path;
}
}
} catch {}
}

export function getWebviewNpmPath() {
const npmPath = path.join(cwd(), 'node_modules', WEBVIEW_PACKAGE_NAME);

if (fs.existsSync(npmPath)) {
return npmPath;
}

// Temporary solution
return getWebviewPnpmPath();
}
Loading

0 comments on commit aad58f2

Please sign in to comment.