Skip to content

Commit e0813a7

Browse files
committed
fix: improve middleware logic
1 parent 8aebf2a commit e0813a7

File tree

24 files changed

+757
-307
lines changed

24 files changed

+757
-307
lines changed

package.json

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,23 +28,23 @@
2828
"@types/html-minifier-terser": "^6.1.0",
2929
"@types/jsdom": "^16.2.14",
3030
"@types/node": "^17.0.21",
31-
"@typescript-eslint/eslint-plugin": "^5.12.1",
32-
"@typescript-eslint/parser": "^5.12.1",
31+
"@typescript-eslint/eslint-plugin": "^5.14.0",
32+
"@typescript-eslint/parser": "^5.14.0",
3333
"commitizen": "^4.2.4",
3434
"conventional-changelog-cli": "^2.2.2",
3535
"cross-env": "^7.0.3",
36-
"eslint": "^8.9.0",
37-
"eslint-config-prettier": "^8.4.0",
36+
"eslint": "^8.11.0",
37+
"eslint-config-prettier": "^8.5.0",
3838
"eslint-plugin-html": "^6.2.0",
3939
"husky": "^7.0.4",
40-
"lint-staged": "^12.3.4",
40+
"lint-staged": "^12.3.5",
4141
"prettier": "^2.5.1",
4242
"rimraf": "^3.0.2",
43-
"tsup": "^5.11.13",
44-
"typescript": "^4.5.5",
45-
"unbuild": "^0.6.9",
46-
"vite": "^2.8.4",
47-
"vitest": "^0.5.5"
43+
"tsup": "^5.12.1",
44+
"typescript": "^4.6.2",
45+
"unbuild": "^0.7.0",
46+
"vite": "^2.8.6",
47+
"vitest": "^0.6.1"
4848
},
4949
"lint-staged": {
5050
"*": [

packages/core/package.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,28 +42,29 @@
4242
},
4343
"homepage": "https://github.com/vbenjs/vite-plugin-html/tree/master/#readme",
4444
"dependencies": {
45-
"@rollup/pluginutils": "^4.1.2",
45+
"@rollup/pluginutils": "^4.2.0",
4646
"colorette": "^2.0.16",
4747
"connect-history-api-fallback": "^1.6.0",
4848
"consola": "^2.15.3",
4949
"dotenv": "^16.0.0",
50-
"dotenv-expand": "^8.0.1",
50+
"dotenv-expand": "^8.0.2",
5151
"ejs": "^3.1.6",
5252
"fast-glob": "^3.2.11",
5353
"fs-extra": "^10.0.1",
5454
"html-minifier-terser": "^6.1.0",
55-
"node-html-parser": "^5.2.0",
55+
"node-html-parser": "^5.3.3",
5656
"pathe": "^0.2.0"
5757
},
5858
"peerDependencies": {
5959
"vite": ">=2.0.0"
6060
},
6161
"devDependencies": {
62+
"@babel/types": "^7.17.0",
6263
"@types/ejs": "^3.1.0",
6364
"@types/fs-extra": "^9.0.13",
6465
"@types/html-minifier-terser": "^6.1.0",
6566
"@types/node": "^17.0.21",
66-
"typescript": "^4.5.5",
67-
"vite": "^2.8.4"
67+
"typescript": "^4.6.2",
68+
"vite": "^2.8.6"
6869
}
6970
}

packages/core/src/htmlPlugin.ts

Lines changed: 66 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
import type { ResolvedConfig, PluginOption, TransformResult } from 'vite'
1+
import type { ResolvedConfig, PluginOption } from 'vite'
22
import type { InjectOptions, PageOption, Pages, UserOptions } from './typing'
33
import { render } from 'ejs'
4-
import { cleanUrl, isDirEmpty, loadEnv } from './utils'
5-
import { htmlFilter } from './utils/createHtmlFilter'
4+
import { isDirEmpty, loadEnv } from './utils'
65
import { normalizePath } from 'vite'
76
import { parse } from 'node-html-parser'
87
import fs from 'fs-extra'
@@ -50,35 +49,48 @@ export function createPlugin(userOptions: UserOptions = {}): PluginOption {
5049
},
5150

5251
configureServer(server) {
52+
let _pages: { filename: string; template: string }[] = []
53+
const rewrites: { from: RegExp; to: any }[] = []
54+
if (!isMpa(viteConfig)) {
55+
const template = userOptions.template || DEFAULT_TEMPLATE
56+
const filename = DEFAULT_TEMPLATE
57+
_pages.push({
58+
filename,
59+
template,
60+
})
61+
} else {
62+
_pages = pages.map((page) => {
63+
return {
64+
filename: page.filename || DEFAULT_TEMPLATE,
65+
template: page.template || DEFAULT_TEMPLATE,
66+
}
67+
})
68+
}
69+
const proxy = viteConfig.server?.proxy ?? {}
70+
const baseUrl = viteConfig.base ?? '/'
71+
const keys = Object.keys(proxy)
72+
73+
let indexPage: any = null
74+
for (const page of _pages) {
75+
if (page.filename !== 'index.html') {
76+
rewrites.push(createRewire(page.template, page, baseUrl, keys))
77+
} else {
78+
indexPage = page
79+
}
80+
}
81+
82+
// ensure order
83+
if (indexPage) {
84+
rewrites.push(createRewire('', indexPage, baseUrl, keys))
85+
}
86+
5387
server.middlewares.use(
5488
history({
5589
disableDotRule: undefined,
5690
htmlAcceptHeaders: ['text/html', 'application/xhtml+xml'],
91+
rewrites: rewrites,
5792
}),
5893
)
59-
server.middlewares.use(async (req, res, next) => {
60-
const url = cleanUrl(req.url || '')
61-
const base = viteConfig.base
62-
const excludeBaseUrl = url.replace(base, '/')
63-
if (!htmlFilter(url) && excludeBaseUrl !== '/') {
64-
return next()
65-
}
66-
try {
67-
const htmlName =
68-
excludeBaseUrl === '/' ? DEFAULT_TEMPLATE : url.replace('/', '')
69-
70-
const page = getPage(userOptions, htmlName, viteConfig)
71-
72-
let html = await getHtmlInPages(page, viteConfig.root)
73-
74-
if (server.transformIndexHtml) {
75-
html = await server.transformIndexHtml(url, html, req.originalUrl)
76-
}
77-
res.end(html)
78-
} catch (e) {
79-
consola.log(e)
80-
}
81-
})
8294
},
8395

8496
transformIndexHtml: {
@@ -88,6 +100,7 @@ export function createPlugin(userOptions: UserOptions = {}): PluginOption {
88100
const base = viteConfig.base
89101
const excludeBaseUrl = url.replace(base, '/')
90102
const htmlName = path.relative(process.cwd(), excludeBaseUrl)
103+
91104
const page = getPage(userOptions, htmlName, viteConfig)
92105
const { injectOptions = {} } = page
93106
const _html = await renderHtml(html, {
@@ -104,36 +117,6 @@ export function createPlugin(userOptions: UserOptions = {}): PluginOption {
104117
}
105118
},
106119
},
107-
transform(code, id): Promise<TransformResult> | TransformResult {
108-
if (viteConfig.command === 'build' && htmlFilter(id)) {
109-
const htmlName = id
110-
.replace(path.join(process.cwd(), viteConfig.base), '/')
111-
.replace(/\/public/, '')
112-
113-
const page = getPage(userOptions, htmlName, viteConfig)
114-
115-
const { injectOptions = {} } = page
116-
return getHtmlInPages(page, viteConfig.root).then((html) => {
117-
return renderHtml(html, {
118-
injectOptions,
119-
viteConfig,
120-
env,
121-
entry: page.entry || entry,
122-
verbose,
123-
}).then((resultHtml) => {
124-
return {
125-
code: resultHtml,
126-
map: null,
127-
}
128-
})
129-
})
130-
}
131-
132-
return {
133-
code,
134-
map: null,
135-
}
136-
},
137120
async closeBundle() {
138121
const outputDirs: string[] = []
139122

@@ -312,7 +295,7 @@ export function getPageConfig(
312295
}
313296

314297
const page = pages.filter((page) => {
315-
return path.resolve('/' + page.filename) === path.resolve('/' + htmlName)
298+
return path.resolve('/' + page.template) === path.resolve('/' + htmlName)
316299
})?.[0]
317300
return page ?? defaultPageOption ?? undefined
318301
}
@@ -335,3 +318,29 @@ export async function readHtml(path: string) {
335318
}
336319
return await fs.readFile(path).then((buffer) => buffer.toString())
337320
}
321+
322+
function createRewire(
323+
reg: string,
324+
page: any,
325+
baseUrl: string,
326+
proxyUrlKeys: string[],
327+
) {
328+
return {
329+
from: new RegExp(`^/${reg}*`),
330+
to({ parsedUrl }: any) {
331+
const pathname: string = parsedUrl.pathname
332+
333+
const excludeBaseUrl = pathname.replace(baseUrl, '/')
334+
335+
const template = path.resolve(baseUrl, page.template)
336+
337+
if (excludeBaseUrl === '/') {
338+
return template
339+
}
340+
const isApiUrl = proxyUrlKeys.some((item) =>
341+
pathname.startsWith(path.resolve(baseUrl, item)),
342+
)
343+
return isApiUrl ? excludeBaseUrl : template
344+
},
345+
}
346+
}

packages/core/src/utils/index.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,6 @@ export function lookupFile(
6767
}
6868
}
6969

70-
export function cleanUrl(url: string): string {
71-
const queryRE = /\?.*$/s
72-
const hashRE = /#.*$/s
73-
return url.replace(hashRE, '').replace(queryRE, '')
74-
}
75-
7670
export async function isDirEmpty(dir: string) {
7771
return fse.readdir(dir).then((files) => {
7872
return files.length === 0
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="icon" href="/favicon.ico" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>test-<%- title %></title>
8+
</head>
9+
10+
<body>
11+
<div><%- ENV %></div>
12+
<div><%- NODE_ENV %></div>
13+
<div id="app"></div>
14+
basic-html
15+
<script type="module" src="/src/main.ts"></script>
16+
<%- injectScript %>
17+
</body>
18+
</html>

packages/playground/basic/package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@
66
"build": "vite build"
77
},
88
"dependencies": {
9+
"axios": "^0.26.1",
910
"vite-plugin-html": "workspace:*",
1011
"vue": "^3.2.31",
11-
"vue-router": "^4.0.12"
12+
"vue-router": "^4.0.14"
1213
},
1314
"devDependencies": {
14-
"@vitejs/plugin-vue": "^2.2.2",
15+
"@vitejs/plugin-vue": "^2.2.4",
1516
"@vue/compiler-sfc": "^3.2.31",
16-
"vite": "^2.8.4"
17+
"vite": "^2.8.6"
1718
}
1819
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
const http = require('http')
2+
const url = require('url')
3+
4+
const port = 8080
5+
6+
const server = http.createServer((req, res) => {
7+
const urlObject = url.parse(req.url)
8+
const { pathname } = urlObject
9+
10+
// api开头的是API请求
11+
if (pathname.startsWith('/api')) {
12+
// 再判断路由
13+
if (pathname === '/api/users') {
14+
// 获取HTTP动词
15+
const method = req.method
16+
if (method === 'GET') {
17+
// 写一个假数据
18+
const resData = [
19+
{
20+
id: 1,
21+
name: '小明',
22+
age: 18,
23+
},
24+
{
25+
id: 2,
26+
name: '小红',
27+
age: 19,
28+
},
29+
]
30+
res.setHeader('Content-Type', 'application/json')
31+
res.end(JSON.stringify(resData))
32+
return
33+
}
34+
}
35+
}
36+
res.statusCode = 200
37+
res.setHeader('Content-Type', 'text/plain')
38+
res.end('Hello World')
39+
})
40+
41+
server.listen(port, () => {
42+
console.log(`Server is running on http://127.0.0.1:${port}/`)
43+
})

packages/playground/basic/src/main.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { createApp } from 'vue'
22
import App from './App.vue'
33
import { createRouter, createWebHashHistory } from 'vue-router'
4+
// import { createRouter, createWebHistory } from 'vue-router'
5+
import axios from 'axios'
46

57
const router = createRouter({
68
history: createWebHashHistory(),
@@ -11,4 +13,9 @@ const router = createRouter({
1113
},
1214
],
1315
})
16+
1417
createApp(App).use(router).mount('#app')
18+
19+
axios.get('/api/users').then((res) => {
20+
console.log(res)
21+
})

packages/playground/basic/vite.config.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ import vue from '@vitejs/plugin-vue'
33
import { createHtmlPlugin } from 'vite-plugin-html'
44

55
export default defineConfig({
6+
// base: '/aaa/',
7+
server: {
8+
proxy: {
9+
'/api': 'http://localhost:8080',
10+
},
11+
},
612
plugins: [
713
vue(),
814
createHtmlPlugin({

packages/playground/custom-entry/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88
"dependencies": {
99
"vite-plugin-html": "workspace:*",
1010
"vue": "^3.2.31",
11-
"vue-router": "^4.0.12"
11+
"vue-router": "^4.0.14"
1212
},
1313
"devDependencies": {
14-
"@vitejs/plugin-vue": "^2.2.2",
14+
"@vitejs/plugin-vue": "^2.2.4",
1515
"@vue/compiler-sfc": "^3.2.31",
16-
"vite": "^2.8.4"
16+
"vite": "^2.8.6"
1717
}
1818
}

0 commit comments

Comments
 (0)