Skip to content

Commit

Permalink
feat(packages): add @admin-pkg/vite-plugin-http2-proxy
Browse files Browse the repository at this point in the history
  • Loading branch information
buqiyuan committed Apr 6, 2024
1 parent 63721b3 commit f6a8090
Show file tree
Hide file tree
Showing 10 changed files with 652 additions and 308 deletions.
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,4 @@ yarn-error.log*
# auto generate file
types/auto-imports.d.ts
types/components.d.ts

packages/vite-plugin-http2-proxy

8 changes: 4 additions & 4 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
"npm.packageManager": "pnpm",
"editor.tabSize": 2,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"vue.server.maxOldSpaceSize": 4096,
"vue.server.hybridMode": true,
"typescript.tsserver.maxTsServerMemory": 4096,
// "typescript.tsserver.nodePath": "node",
// 保存文件缓慢时,可以考虑开启以下 3 行配置。
// "vue.server.maxOldSpaceSize": 4096,
// "vue.server.hybridMode": true,
// "typescript.tsserver.maxTsServerMemory": 4096,
"files.eol": "\n",
"search.exclude": {
"**/node_modules": true,
Expand Down
11 changes: 6 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,18 @@
},
"devDependencies": {
"@admin-pkg/components": "workspace:*",
"@admin-pkg/vite-plugin-http2-proxy": "workspace:*",
"@admin-pkg/vite-plugin-msw": "workspace:*",
"@admin-pkg/vite-plugin-tinymce-resource": "workspace:*",
"@commitlint/cli": "~19.2.1",
"@commitlint/config-conventional": "~19.1.0",
"@faker-js/faker": "^8.4.1",
"@iconify-json/ant-design": "^1.1.15",
"@iconify-json/ep": "^1.1.15",
"@iconify/json": "^2.2.195",
"@iconify/json": "^2.2.197",
"@types/crypto-js": "^4.2.2",
"@types/lodash-es": "~4.17.12",
"@types/node": "~20.11.16",
"@types/node": "~20.12.4",
"@types/sortablejs": "^1.15.8",
"@typescript-eslint/eslint-plugin": "~7.5.0",
"@typescript-eslint/parser": "~7.5.0",
Expand All @@ -102,7 +103,7 @@
"less": "~4.2.0",
"lint-staged": "~15.2.2",
"msw": "^2.2.13",
"nx": "^18.2.2",
"nx": "^18.2.3",
"postcss": "~8.4.38",
"postcss-html": "~1.6.0",
"postcss-less": "~6.0.0",
Expand All @@ -115,8 +116,8 @@
"stylelint-config-standard": "~36.0.0",
"stylelint-order": "~6.0.4",
"stylelint-prettier": "^5.0.0",
"typescript": "~5.4.3",
"unocss": "^0.58.9",
"typescript": "~5.4.4",
"unocss": "^0.59.0",
"unplugin-vue-components": "~0.26.0",
"vite": "~5.2.8",
"vite-plugin-checker": "~0.6.4",
Expand Down
2 changes: 1 addition & 1 deletion packages/components/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@admin-pkg/components",
"version": "0.0.4",
"version": "0.0.5",
"description": "",
"type": "module",
"module": "./dist/index.es.js",
Expand Down
17 changes: 17 additions & 0 deletions packages/vite-plugin-http2-proxy/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "@admin-pkg/vite-plugin-http2-proxy",
"version": "0.0.1",
"type": "module",
"description": "",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"build": "tsc"
},
"keywords": [],
"author": "",
"license": "MIT",
"dependencies": {
"http2-proxy": "^5.0.53"
}
}
124 changes: 124 additions & 0 deletions packages/vite-plugin-http2-proxy/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import http2Proxy from 'http2-proxy';
import type { Plugin, ProxyOptions } from 'vite';

const error = (message: string): never => {
throw new Error(message);
};

export default (options?: Record<string, ProxyOptions>): Plugin => {
let routes: Record<string, ProxyOptions>;

const configure: Plugin['configureServer'] = ({ middlewares, httpServer }) => {
const proxyOptions = options || routes;
for (const [regexp, serverOptions] of Object.entries(proxyOptions)) {
const { target, rewrite, headers, ws, secure = true } = serverOptions;
if (!target) {
continue;
}

const re = new RegExp(regexp);
const urlObj = new URL(target.toString());

if (!urlObj.pathname.endsWith('/')) {
urlObj.pathname += '/';
}

const protocol = /^(http|ws)s?:$/.test(urlObj.protocol)
? (urlObj.protocol as 'https' | 'http')
: error(`Invalid protocol: ${urlObj.href}`);

const port =
urlObj.port === ''
? { https: 443, http: 80 }[protocol]
: /^\d+$/.test(urlObj.port)
? Number(urlObj.port)
: error(`Invalid port: ${urlObj.href}`);

// TODO unfinished
if (ws && httpServer) {
httpServer?.on('upgrade', (req, socket, head) => {
if (req.url && re.test(req.url)) {
const url = (rewrite?.(req.url) ?? req.url).replace(/^\/+/, '');
const { pathname, search } = new URL(url, urlObj);

http2Proxy.ws(
req,
socket,
head,
{
port: 443,
path: pathname + search,
hostname: urlObj.hostname,
['rejectUnauthorized' as never]: secure,
...serverOptions,
},
(err) => {
if (err) {
console.error('proxy error', err);
socket.destroy();
}
},
);
}
});
} else {
middlewares.use((req, res, next) => {
if (req.url && re.test(req.url)) {
const url = (rewrite?.(req.url) ?? req.url).replace(/^\/+/, '');
const { pathname, search } = new URL(url, urlObj);

http2Proxy.web(
req,
res,
{
protocol,
port,
hostname: urlObj.hostname,
path: pathname + search,
onReq: async (_, options) => {
options.headers = {
...options.headers,
...headers,
};
},
['rejectUnauthorized' as never]: secure,
...serverOptions,
},
(err) => err && next(err),
);
} else {
next();
}
});
}
}
};

return {
name: '@admin-pkg/vite-plugin-http2-proxy',
config: (config) => {
const { server } = config;
routes = Object.entries(server?.proxy ?? {}).reduce(
(prev, [key, value]) => {
if (typeof value === 'string') {
prev[key] = {
target: value,
};
} else {
prev[key] = value;
}
return prev;
},
{} as Record<string, ProxyOptions>,
);

if (server) {
server.proxy = undefined;
}
return config;
},
configureServer: configure,
// @ts-ignore
configurePreviewServer: configure,
};
};
13 changes: 13 additions & 0 deletions packages/vite-plugin-http2-proxy/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"target": "ESNext",
"moduleResolution": "Node",
"module": "ESNext",
"outDir": "dist",
"declaration": true,
"strict": true,
"skipLibCheck": true,
"useUnknownInCatchVariables": false,
"allowSyntheticDefaultImports": true
}
}
Loading

0 comments on commit f6a8090

Please sign in to comment.