refactor types

This commit is contained in:
Evan You 2020-04-20 23:08:38 -04:00
parent 93286b9f2b
commit f4382f1db9
6 changed files with 93 additions and 84 deletions

15
README.md Normal file
View File

@ -0,0 +1,15 @@
# vue-dev-server
```bash
npx -p @vue/dev-server vds
```
## How It Works
Imports are requested by the browser as native ES module imports - there's no bundling.
The server intercepts requests to *.vue files, compiles them on the fly, and sends them back as JavaScript.
For libraries that provide ES modules builds that work in browsers, just directly import them from a CDN.
Imports to npm packages inside .js files (package name only) are re-written on the fly to point to locally installed files. Currently, only vue is supported as a special case. Other packages will likely need to be transformed to be exposed as a native browser-targeting ES module.

View File

@ -35,7 +35,7 @@
},
"dependencies": {
"@babel/parser": "^7.9.4",
"@vue/compiler-sfc": "^3.0.0-beta.2",
"@vue/compiler-sfc": "^3.0.0-beta.3",
"chokidar": "^3.3.1",
"magic-string": "^0.25.7",
"minimist": "^1.2.5",

View File

@ -2,13 +2,16 @@ import url from 'url'
import path from 'path'
import { promises as fs } from 'fs'
import { IncomingMessage, ServerResponse } from 'http'
import { parse, compileTemplate } from '@vue/compiler-sfc'
import { parse, compileTemplate, SFCDescriptor } from '@vue/compiler-sfc'
import { sendJS } from './utils'
import { rewrite } from './moduleRewriter'
const cache = new Map()
export async function parseSFC(filename: string, saveCache = false) {
export async function parseSFC(
filename: string,
saveCache = false
): Promise<[SFCDescriptor, SFCDescriptor | undefined] | []> {
let content: string
try {
content = await fs.readFile(filename, 'utf-8')
@ -36,8 +39,9 @@ export async function vueMiddleware(
res: ServerResponse
) {
const parsed = url.parse(req.url!, true)
const pathname = parsed.pathname!
const query = parsed.query
const filename = path.join(cwd, parsed.pathname!.slice(1))
const filename = path.join(cwd, pathname.slice(1))
const [descriptor] = await parseSFC(
filename,
true /* save last accessed descriptor on the client */
@ -47,49 +51,62 @@ export async function vueMiddleware(
return res.end()
}
if (!query.type) {
// inject hmr client
let code = `import "/__hmrClient"\n`
if (descriptor.script) {
code += rewrite(
descriptor.script.content,
true /* rewrite default export to `script` */
)
} else {
code += `const __script = {}; export default __script`
}
if (descriptor.template) {
code += `\nimport { render as __render } from ${JSON.stringify(
parsed.pathname + `?type=template${query.t ? `&t=${query.t}` : ``}`
)}`
code += `\n__script.render = __render`
}
if (descriptor.style) {
// TODO
}
code += `\n__script.__hmrId = ${JSON.stringify(parsed.pathname)}`
return sendJS(res, code)
return compileSFCMain(res, descriptor, pathname, query.t as string)
}
if (query.type === 'template') {
const { code, errors } = compileTemplate({
source: descriptor.template.content,
filename,
compilerOptions: {
// TODO infer proper Vue path
runtimeModuleName: '/__modules/vue'
}
})
if (errors) {
// TODO
}
return sendJS(res, code)
return compileSFCTemplate(res, descriptor, filename)
}
if (query.type === 'style') {
// TODO
return
}
// TODO custom blocks
}
function compileSFCMain(
res: ServerResponse,
descriptor: SFCDescriptor,
pathname: string,
timestamp: string | undefined
) {
// inject hmr client
let code = `import "/__hmrClient"\n`
if (descriptor.script) {
code += rewrite(
descriptor.script.content,
true /* rewrite default export to `script` */
)
} else {
code += `const __script = {}; export default __script`
}
if (descriptor.template) {
code += `\nimport { render as __render } from ${JSON.stringify(
pathname + `?type=template${timestamp ? `&t=${timestamp}` : ``}`
)}`
code += `\n__script.render = __render`
}
if (descriptor.styles) {
// TODO
}
code += `\n__script.__hmrId = ${JSON.stringify(pathname)}`
sendJS(res, code)
}
function compileSFCTemplate(
res: ServerResponse,
descriptor: SFCDescriptor,
filename: string
) {
const { code, errors } = compileTemplate({
source: descriptor.template!.content,
filename,
compilerOptions: {
runtimeModuleName: '/__modules/vue'
}
})
if (errors) {
// TODO
}
sendJS(res, code)
}

View File

@ -21,7 +21,7 @@ export function createFileWatcher(
if (file.endsWith('.vue')) {
// check which part of the file changed
const [descriptor, prevDescriptor] = await parseSFC(file)
if (!prevDescriptor) {
if (!descriptor || !prevDescriptor) {
// the file has never been accessed yet
return
}

View File

@ -24,11 +24,12 @@ beforeAll(async () => {
})
afterAll(async () => {
await browser.close()
await fs.rmdir(tempDir, { recursive: true })
server.kill('SIGTERM', {
forceKillAfterTimeout: 2000
})
if (browser) await browser.close()
if (server)
server.kill('SIGTERM', {
forceKillAfterTimeout: 2000
})
})
test('test', async () => {

View File

@ -579,17 +579,6 @@
dependencies:
"@types/node" "*"
"@vue/compiler-core@3.0.0-beta.2":
version "3.0.0-beta.2"
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.0.0-beta.2.tgz#ac8f14856cd874cb22d89181e8c3bddf810b8261"
integrity sha512-/c3ePWU9T7xwn0J/YRlxCxnxqphNVlcXisnI6aMoK3pjvQFXOMD6tfrHUtepCrQLNdKlhxNjqe3Q625Z64Z0kQ==
dependencies:
"@babel/parser" "^7.8.6"
"@babel/types" "^7.8.6"
"@vue/shared" "3.0.0-beta.2"
estree-walker "^0.8.1"
source-map "^0.6.1"
"@vue/compiler-core@3.0.0-beta.3":
version "3.0.0-beta.3"
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.0.0-beta.3.tgz#e9cbd695d6bc07e475b80c5e47ae9261475582dd"
@ -601,14 +590,6 @@
estree-walker "^0.8.1"
source-map "^0.6.1"
"@vue/compiler-dom@3.0.0-beta.2":
version "3.0.0-beta.2"
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.0.0-beta.2.tgz#344263f4e50258496bfdbd01a9a85a7b842e96de"
integrity sha512-VZwvnsWPoi0/MR5CF5p5VhRGk3AkM9MQYt/pMaXDmbl09kWKVjQZubCRvpzuyjjm1QnV1yrSaqTZWDAIYbKYtw==
dependencies:
"@vue/compiler-core" "3.0.0-beta.2"
"@vue/shared" "3.0.0-beta.2"
"@vue/compiler-dom@3.0.0-beta.3":
version "3.0.0-beta.3"
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.0.0-beta.3.tgz#089d9ede865576a1b5bcf5d3272d546e04460f90"
@ -617,15 +598,15 @@
"@vue/compiler-core" "3.0.0-beta.3"
"@vue/shared" "3.0.0-beta.3"
"@vue/compiler-sfc@^3.0.0-beta.2":
version "3.0.0-beta.2"
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.0.0-beta.2.tgz#610697d29e067165d5e2ccf81bdd238399b6d156"
integrity sha512-v3zQ8fR+Oc8U/WZFmJY641b05ayP1cdngZMn8PUgPecRwjQkdR/k9ikCMZpsrWtoS4am0e3PHyCt/BBZCxA4nA==
"@vue/compiler-sfc@^3.0.0-beta.3":
version "3.0.0-beta.3"
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.0.0-beta.3.tgz#c3d2d0a7fa606b246bb875a5fa6f7b19a03d0b09"
integrity sha512-R8gfZX5fm43dig/cKf0jOKOIhKXIZibf4ycF+yjbNGzHfA2lgVbBGOp/4dYxe9l7ajCBqGTgHkAHwXTeorKKYA==
dependencies:
"@vue/compiler-core" "3.0.0-beta.2"
"@vue/compiler-dom" "3.0.0-beta.2"
"@vue/compiler-ssr" "3.0.0-beta.2"
"@vue/shared" "3.0.0-beta.2"
"@vue/compiler-core" "3.0.0-beta.3"
"@vue/compiler-dom" "3.0.0-beta.3"
"@vue/compiler-ssr" "3.0.0-beta.3"
"@vue/shared" "3.0.0-beta.3"
consolidate "^0.15.1"
hash-sum "^2.0.0"
lru-cache "^5.1.1"
@ -634,13 +615,13 @@
postcss-selector-parser "^6.0.2"
source-map "^0.6.1"
"@vue/compiler-ssr@3.0.0-beta.2":
version "3.0.0-beta.2"
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.0.0-beta.2.tgz#05c965d8f5a6362928959d4f8a7b75b07cf68c45"
integrity sha512-+g0u8Zgns3uR6E3338yCGBz927mOdzzsCFxBKTS6O2WRXhUZ1vcRerigruRRF+LDiWtFm2txsjj70CcMqF4D/w==
"@vue/compiler-ssr@3.0.0-beta.3":
version "3.0.0-beta.3"
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.0.0-beta.3.tgz#b9e0be53bf302640bf0edc6faea7f94ac96c503a"
integrity sha512-X2Rh+y9pZPIM9WnzlOxyuLhQPvk5VmGjrwKG/YPDvS0F1cCLN8jANercm3IIQvR6NZ6aMjUwytohaTeUCzFoEw==
dependencies:
"@vue/compiler-dom" "3.0.0-beta.2"
"@vue/shared" "3.0.0-beta.2"
"@vue/compiler-dom" "3.0.0-beta.3"
"@vue/shared" "3.0.0-beta.3"
"@vue/reactivity@3.0.0-beta.3":
version "3.0.0-beta.3"
@ -666,11 +647,6 @@
"@vue/shared" "3.0.0-beta.3"
csstype "^2.6.8"
"@vue/shared@3.0.0-beta.2":
version "3.0.0-beta.2"
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.0.0-beta.2.tgz#6659413868b0ba0b96260cbf3c9ed99f2d0f90ef"
integrity sha512-ED5oa+ZOcjAJkWEzL0zFZ4QG89L23DrW9LBBGT6YBUhBmOsf9BKii2JIBfdxWYwRkjAhbHffQH0mc6rI2famug==
"@vue/shared@3.0.0-beta.3":
version "3.0.0-beta.3"
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.0.0-beta.3.tgz#783e98475757c9e2c58cb804cce2cd9dd328f4b8"