mirror of
https://github.com/vitejs/vite.git
synced 2024-11-22 07:09:05 +00:00
refactor: use async fs + expose createServer API
This commit is contained in:
parent
33488fe7e6
commit
bfb4b911ae
@ -1,2 +1,5 @@
|
||||
#!/usr/bin/env node
|
||||
require('../lib/server')
|
||||
const { createServer } = require('../lib/server')
|
||||
|
||||
// TODO pass cli args
|
||||
createServer()
|
||||
|
@ -8,12 +8,12 @@ exports.createFileWatcher = (notify) => {
|
||||
ignored: [/node_modules/]
|
||||
})
|
||||
|
||||
fileWatcher.on('change', (file) => {
|
||||
fileWatcher.on('change', async (file) => {
|
||||
const resourcePath = '/' + path.relative(process.cwd(), file)
|
||||
|
||||
if (file.endsWith('.vue')) {
|
||||
// check which part of the file changed
|
||||
const [descriptor, prevDescriptor] = parseSFC(file)
|
||||
const [descriptor, prevDescriptor] = await parseSFC(file)
|
||||
if (!prevDescriptor) {
|
||||
// the file has never been accessed yet
|
||||
return
|
||||
|
@ -1,23 +1,24 @@
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const { sendJS } = require('./utils')
|
||||
const resolve = require('resolve-cwd')
|
||||
const { sendJSStream } = require('./utils')
|
||||
|
||||
exports.moduleMiddleware = (id, res) => {
|
||||
let modulePath
|
||||
// try node resolve first
|
||||
// TODO support custom imports map e.g. for snowpack web_modules
|
||||
|
||||
// fallback to node resolve
|
||||
try {
|
||||
modulePath = require.resolve(id)
|
||||
modulePath = resolve(id)
|
||||
if (id === 'vue') {
|
||||
modulePath = path.join(
|
||||
path.dirname(modulePath),
|
||||
'dist/vue.runtime.esm-browser.js'
|
||||
)
|
||||
}
|
||||
} catch (e) {
|
||||
res.setStatus(404)
|
||||
res.end()
|
||||
}
|
||||
|
||||
// TODO resolve snowpack web_modules
|
||||
|
||||
if (id === 'vue') {
|
||||
// modulePath = path.relative(modulePath, 'dist/vue.runtime.esm-browser.js')
|
||||
modulePath = path.resolve(__dirname, 'vue.js')
|
||||
}
|
||||
|
||||
sendJS(res, fs.readFileSync(modulePath))
|
||||
sendJSStream(res, modulePath)
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
const fs = require('fs')
|
||||
const fs = require('fs').promises
|
||||
const { parse } = require('@vue/compiler-sfc')
|
||||
|
||||
const cache = new Map()
|
||||
|
||||
exports.parseSFC = (filename, saveCache = false) => {
|
||||
const content = fs.readFileSync(filename, 'utf-8')
|
||||
exports.parseSFC = async (filename, saveCache = false) => {
|
||||
const content = await fs.readFile(filename, 'utf-8')
|
||||
const { descriptor, errors } = parse(content, {
|
||||
filename
|
||||
})
|
||||
|
101
lib/server.js
101
lib/server.js
@ -1,4 +1,4 @@
|
||||
const fs = require('fs')
|
||||
const fs = require('fs').promises
|
||||
const path = require('path')
|
||||
const http = require('http')
|
||||
const url = require('url')
|
||||
@ -10,44 +10,77 @@ const { createFileWatcher } = require('./hmrWatcher')
|
||||
const { sendJS } = require('./utils')
|
||||
const { rewrite } = require('./moduleRewriter')
|
||||
|
||||
const hmrClientCode = fs.readFileSync(path.resolve(__dirname, './hmrClient.js'))
|
||||
exports.createServer = async ({ port = 3000 } = {}) => {
|
||||
const hmrClientCode = await fs.readFile(
|
||||
path.resolve(__dirname, './hmrClient.js')
|
||||
)
|
||||
|
||||
const server = http.createServer((req, res) => {
|
||||
const pathname = url.parse(req.url).pathname
|
||||
if (pathname === '/__hmrClient') {
|
||||
return sendJS(res, hmrClientCode)
|
||||
} else if (pathname.startsWith('/__modules/')) {
|
||||
return moduleMiddleware(pathname.replace('/__modules/', ''), res)
|
||||
} else if (pathname.endsWith('.vue')) {
|
||||
return vue(req, res)
|
||||
} else if (pathname.endsWith('.js')) {
|
||||
const filename = path.join(process.cwd(), pathname.slice(1))
|
||||
if (fs.existsSync(filename)) {
|
||||
const content = rewrite(fs.readFileSync(filename, 'utf-8'))
|
||||
return sendJS(res, content)
|
||||
const server = http.createServer(async (req, res) => {
|
||||
const pathname = url.parse(req.url).pathname
|
||||
if (pathname === '/__hmrClient') {
|
||||
return sendJS(res, await hmrClientCode)
|
||||
} else if (pathname.startsWith('/__modules/')) {
|
||||
return moduleMiddleware(pathname.replace('/__modules/', ''), res)
|
||||
} else if (pathname.endsWith('.vue')) {
|
||||
return vue(req, res)
|
||||
} else if (pathname.endsWith('.js')) {
|
||||
const filename = path.join(process.cwd(), pathname.slice(1))
|
||||
try {
|
||||
const content = await fs.readFile(filename, 'utf-8')
|
||||
return sendJS(res, rewrite(content))
|
||||
} catch (e) {
|
||||
if (e.code === 'ENOENT') {
|
||||
// fallthrough to serve-handler
|
||||
} else {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
serve(req, res, {
|
||||
rewrites: [{ source: '**', destination: '/index.html' }]
|
||||
serve(req, res, {
|
||||
rewrites: [{ source: '**', destination: '/index.html' }]
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
const wss = new ws.Server({ server })
|
||||
const sockets = new Set()
|
||||
wss.on('connection', (socket) => {
|
||||
sockets.add(socket)
|
||||
socket.send(JSON.stringify({ type: 'connected' }))
|
||||
socket.on('close', () => {
|
||||
sockets.delete(socket)
|
||||
const wss = new ws.Server({ server })
|
||||
const sockets = new Set()
|
||||
|
||||
wss.on('connection', (socket) => {
|
||||
sockets.add(socket)
|
||||
socket.send(JSON.stringify({ type: 'connected' }))
|
||||
socket.on('close', () => {
|
||||
sockets.delete(socket)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
createFileWatcher((payload) =>
|
||||
sockets.forEach((s) => s.send(JSON.stringify(payload)))
|
||||
)
|
||||
wss.on('error', (e) => {
|
||||
if (e.code !== 'EADDRINUSE') {
|
||||
console.error(e)
|
||||
}
|
||||
})
|
||||
|
||||
// TODO customized port
|
||||
server.listen(3000, () => {
|
||||
console.log('Running at http://localhost:3000')
|
||||
})
|
||||
createFileWatcher((payload) =>
|
||||
sockets.forEach((s) => s.send(JSON.stringify(payload)))
|
||||
)
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
server.on('error', (e) => {
|
||||
if (e.code === 'EADDRINUSE') {
|
||||
console.log(`port ${port} is in use, trying another one...`)
|
||||
setTimeout(() => {
|
||||
server.close()
|
||||
server.listen(++port)
|
||||
}, 100)
|
||||
} else {
|
||||
console.error(e)
|
||||
}
|
||||
})
|
||||
|
||||
server.on('listening', () => {
|
||||
console.log(`Running at http://localhost:${port}`)
|
||||
resolve()
|
||||
})
|
||||
|
||||
server.listen(port)
|
||||
})
|
||||
}
|
||||
|
14
lib/utils.js
14
lib/utils.js
@ -1,3 +1,5 @@
|
||||
const fs = require('fs')
|
||||
|
||||
function send(res, source, mime) {
|
||||
res.setHeader('Content-Type', mime)
|
||||
res.end(source)
|
||||
@ -7,5 +9,17 @@ function sendJS(res, source) {
|
||||
send(res, source, 'application/javascript')
|
||||
}
|
||||
|
||||
function sendJSStream(res, file) {
|
||||
res.setHeader('Content-Type', 'application/javascript')
|
||||
const stream = fs.createReadStream(file)
|
||||
stream.on('open', () => {
|
||||
stream.pipe(res)
|
||||
})
|
||||
stream.on('error', (err) => {
|
||||
res.end(err)
|
||||
})
|
||||
}
|
||||
|
||||
exports.send = send
|
||||
exports.sendJS = sendJS
|
||||
exports.sendJSStream = sendJSStream
|
||||
|
7459
lib/vue.js
7459
lib/vue.js
File diff suppressed because it is too large
Load Diff
@ -7,11 +7,11 @@ const { compileTemplate } = require('@vue/compiler-sfc')
|
||||
const { read, sendJS } = require('./utils')
|
||||
const { rewrite } = require('./moduleRewriter')
|
||||
|
||||
module.exports = (req, res) => {
|
||||
module.exports = async (req, res) => {
|
||||
const parsed = url.parse(req.url, true)
|
||||
const query = parsed.query
|
||||
const filename = path.join(process.cwd(), parsed.pathname.slice(1))
|
||||
const [descriptor] = parseSFC(
|
||||
const [descriptor] = await parseSFC(
|
||||
filename,
|
||||
true /* save last accessed descriptor on the client */
|
||||
)
|
||||
|
@ -4,13 +4,15 @@
|
||||
"bin": {
|
||||
"vds": "bin/vds.js"
|
||||
},
|
||||
"main": "lib/server.js",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.9.4",
|
||||
"@vue/compiler-sfc": "^3.0.0-beta.2",
|
||||
"chokidar": "^3.3.1",
|
||||
"magic-string": "^0.25.7",
|
||||
"resolve-cwd": "^3.0.0",
|
||||
"serve-handler": "^6.1.2",
|
||||
"vue": "^3.0.0-beta.2",
|
||||
"vue": "^3.0.0-beta.3",
|
||||
"ws": "^7.2.3"
|
||||
}
|
||||
}
|
||||
|
84
yarn.lock
84
yarn.lock
@ -32,6 +32,17 @@
|
||||
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"
|
||||
integrity sha512-r8AFbzQN3IuLbOEKa8y4EDYrbrBUiHh3kX3UHw3YDfBPDG2NryeAMtonden3Nvs7i3QFTCPzrWRfb/bjWqgAzQ==
|
||||
dependencies:
|
||||
"@babel/parser" "^7.8.6"
|
||||
"@babel/types" "^7.8.6"
|
||||
"@vue/shared" "3.0.0-beta.3"
|
||||
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"
|
||||
@ -40,6 +51,14 @@
|
||||
"@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"
|
||||
integrity sha512-1WimkkPN13ySLAlJl61WSo7xFeC3D8Nqkz35YIZIgksOOIr6W/Q3NfDxfM6bG5nTBWBmgb995oDZ8NNgq2frSg==
|
||||
dependencies:
|
||||
"@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"
|
||||
@ -65,28 +84,28 @@
|
||||
"@vue/compiler-dom" "3.0.0-beta.2"
|
||||
"@vue/shared" "3.0.0-beta.2"
|
||||
|
||||
"@vue/reactivity@3.0.0-beta.2":
|
||||
version "3.0.0-beta.2"
|
||||
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.0.0-beta.2.tgz#216922e264dc447a508f756374c09fb26a7cbe1c"
|
||||
integrity sha512-vAYHiBmpHfLAJulssTTTlvdHtyyKeOCG3qCu/TxDhu3NFHEfrt4eytR2atR6EbpTb853/QKcoW3k6L6g/znxAw==
|
||||
"@vue/reactivity@3.0.0-beta.3":
|
||||
version "3.0.0-beta.3"
|
||||
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.0.0-beta.3.tgz#256dd1633179dc4474c222a28511c043e25c4b22"
|
||||
integrity sha512-/QU5sDJkIlTqDd+T3gMZXgchslW8o0hPtyVxphGUjdUGdsXnXjEagDIHDsi35qOJnjfZ8dwq/L1IfVQJ9TENaA==
|
||||
dependencies:
|
||||
"@vue/shared" "3.0.0-beta.2"
|
||||
"@vue/shared" "3.0.0-beta.3"
|
||||
|
||||
"@vue/runtime-core@3.0.0-beta.2":
|
||||
version "3.0.0-beta.2"
|
||||
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.0.0-beta.2.tgz#0413292d8746c532527dbcdbfcbc56be312f05ad"
|
||||
integrity sha512-tcxNNV7y+H2046F79iw90OdwyxvMEqJ5iOQTsOvfVf2hBNrCWPG1tAU+kywFBlBY4I26k7XB/Q1ZdHb2q8YLaA==
|
||||
"@vue/runtime-core@3.0.0-beta.3":
|
||||
version "3.0.0-beta.3"
|
||||
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.0.0-beta.3.tgz#8e665381ca517a721198bc189b2db3deab5050e5"
|
||||
integrity sha512-GHIlKNlJW0sdlro6ouu7Sy34M4I8FAfn6V02RdUwbPwJJc1VICoejnSS1i88i6riGMgNtRhmxW1NDNPCTY1/vQ==
|
||||
dependencies:
|
||||
"@vue/reactivity" "3.0.0-beta.2"
|
||||
"@vue/shared" "3.0.0-beta.2"
|
||||
"@vue/reactivity" "3.0.0-beta.3"
|
||||
"@vue/shared" "3.0.0-beta.3"
|
||||
|
||||
"@vue/runtime-dom@3.0.0-beta.2":
|
||||
version "3.0.0-beta.2"
|
||||
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.0.0-beta.2.tgz#957a59ecfcdf54619e4d40d2e2967587ea58728d"
|
||||
integrity sha512-swWm7fa3JKEGE0KYVevYqaBTSGxx/bmlwJTbJcnnNgdZZGtWUQsUzXCk6JKRuoYjy+iU0ONcHidEhpwdazH9Aw==
|
||||
"@vue/runtime-dom@3.0.0-beta.3":
|
||||
version "3.0.0-beta.3"
|
||||
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.0.0-beta.3.tgz#9bd2cd70edbf47578c2bc134e235e8586adadef6"
|
||||
integrity sha512-2CbmDjAGYV4BStukAdByXpK2lQC8svk5oSsG/1rWSdXcDH/gpkCmQocaBahzyRBwX9pVEK4RwRBX4CiNbYjVVg==
|
||||
dependencies:
|
||||
"@vue/runtime-core" "3.0.0-beta.2"
|
||||
"@vue/shared" "3.0.0-beta.2"
|
||||
"@vue/runtime-core" "3.0.0-beta.3"
|
||||
"@vue/shared" "3.0.0-beta.3"
|
||||
csstype "^2.6.8"
|
||||
|
||||
"@vue/shared@3.0.0-beta.2":
|
||||
@ -94,6 +113,11 @@
|
||||
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"
|
||||
integrity sha512-NSiCty9fUjn+JuGtBCnlxqB+9jq4S/W6lGREMz/2cQZchIETu16fBxvQukljVmtbChAjrw/JTOb8HzTrDAhLlQ==
|
||||
|
||||
ansi-styles@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
|
||||
@ -382,6 +406,18 @@ readdirp@~3.3.0:
|
||||
dependencies:
|
||||
picomatch "^2.0.7"
|
||||
|
||||
resolve-cwd@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d"
|
||||
integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==
|
||||
dependencies:
|
||||
resolve-from "^5.0.0"
|
||||
|
||||
resolve-from@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69"
|
||||
integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
|
||||
|
||||
serve-handler@^6.1.2:
|
||||
version "6.1.2"
|
||||
resolved "https://registry.yarnpkg.com/serve-handler/-/serve-handler-6.1.2.tgz#f05b0421a313fff2d257838cba00cbcc512cd2b6"
|
||||
@ -437,14 +473,14 @@ uniq@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff"
|
||||
integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=
|
||||
|
||||
vue@^3.0.0-beta.2:
|
||||
version "3.0.0-beta.2"
|
||||
resolved "https://registry.yarnpkg.com/vue/-/vue-3.0.0-beta.2.tgz#f808b498d10cbebe4007738aa2130bd0802f393d"
|
||||
integrity sha512-/HYhK9i8PWM0fL38YflFK/vY1ots+JyNI2GZa8VtDqj4jD3+2UZ0CH0kjmw9YTmRtHdsU65CXGkVuA3EMV3mXQ==
|
||||
vue@^3.0.0-beta.3:
|
||||
version "3.0.0-beta.3"
|
||||
resolved "https://registry.yarnpkg.com/vue/-/vue-3.0.0-beta.3.tgz#c81e3fa9b414e9129ff1dcd13fbf4f7d3ec3bbdf"
|
||||
integrity sha512-5DBah04o/0MNVLFg8BwB5cP3prU6HA/vxXVcUT7E+uvwY6EiJsRKtyZ71m294bKV5ZZkYzzJjLtZrjYGR2tW7g==
|
||||
dependencies:
|
||||
"@vue/compiler-dom" "3.0.0-beta.2"
|
||||
"@vue/runtime-dom" "3.0.0-beta.2"
|
||||
"@vue/shared" "3.0.0-beta.2"
|
||||
"@vue/compiler-dom" "3.0.0-beta.3"
|
||||
"@vue/runtime-dom" "3.0.0-beta.3"
|
||||
"@vue/shared" "3.0.0-beta.3"
|
||||
|
||||
ws@^7.2.3:
|
||||
version "7.2.3"
|
||||
|
Loading…
Reference in New Issue
Block a user