diff --git a/lib/dev.js b/lib/dev.js
index a3d67ca..4854dfb 100644
--- a/lib/dev.js
+++ b/lib/dev.js
@@ -3,6 +3,7 @@ import https from 'https'
import fs from 'iofs'
import { join, resolve, dirname } from 'path'
import { parse } from 'url'
+import socket from './ws.js'
import { compileScss, parseJs, compileVue, parseHtml } from './compile-vue.js'
@@ -12,12 +13,15 @@ import { COMMON_HEADERS } from './constants.js'
const noc = Buffer.from('')
const SERVER_OPTIONS = {}
-export default function createServer(root = '', conf = {}) {
+export default async function createServer(root = '', conf = {}) {
const IS_MPA = Object.keys(conf.pages).length > 1
const PORT = conf.devServer.port || 8080
const USE_HTTPS = conf.devServer.https
const DOMAIN = conf.devServer.domain || 'localhost'
- const WEB_SERVER = USE_HTTPS ? https : http
+ const server = (USE_HTTPS ? https : http)
+ .createServer(SERVER_OPTIONS)
+ .listen(PORT)
+
let indexPage = Object.keys(conf.pages)
.map(it => {
let tmp = it + '.html'
@@ -37,29 +41,41 @@ export default function createServer(root = '', conf = {}) {
}
}
- WEB_SERVER.createServer(SERVER_OPTIONS, function (req, res) {
- let pathname = parse(req.url.slice(1)).pathname
- let pageName = '',
- isIndex = false // 是否渲染目录页
- let ext
+ server
+ .on('request', function (req, res) {
+ let pathname = parse(req.url.slice(1)).pathname
+ let pageName = '',
+ isIndex = false // 是否渲染目录页
+ let ext
- if (pathname) {
- pathname = pathname.split('/')
+ if (pathname) {
+ pathname = pathname.split('/')
- if (pathname[0].endsWith('.html')) {
- pageName = pathname.shift()
+ if (pathname[0].endsWith('.html')) {
+ pageName = pathname.shift()
- let tmp = pageName.split('.')
+ let tmp = pageName.split('.')
- ext = tmp.pop()
- pageName = tmp.join('.')
+ ext = tmp.pop()
+ pageName = tmp.join('.')
- currentPage = pageName
- pagesDir = dirname(conf.pages[pageName].entry)
+ currentPage = pageName
+ pagesDir = dirname(conf.pages[pageName].entry)
+ } else {
+ if (currentPage) {
+ ext = pathname.at(-1).split('.').pop()
+ pageName = currentPage
+ } else {
+ pageName = Object.keys(conf.pages).pop()
+ currentPage = pageName
+ pagesDir = dirname(conf.pages[pageName].entry)
+ ext = 'html'
+ }
+ }
+ pathname = pathname.join('/')
} else {
- if (currentPage) {
- ext = pathname.at(-1).split('.').pop()
- pageName = currentPage
+ if (IS_MPA) {
+ isIndex = true
} else {
pageName = Object.keys(conf.pages).pop()
currentPage = pageName
@@ -67,135 +83,124 @@ export default function createServer(root = '', conf = {}) {
ext = 'html'
}
}
- pathname = pathname.join('/')
- } else {
- if (IS_MPA) {
- isIndex = true
- } else {
- pageName = Object.keys(conf.pages).pop()
- currentPage = pageName
- pagesDir = dirname(conf.pages[pageName].entry)
+ // 修正history路由时的访问
+ if (pathname === ext) {
ext = 'html'
}
- }
- // 修正history路由时的访问
- if (pathname === ext) {
- ext = 'html'
- }
- for (let k in COMMON_HEADERS) {
- res.setHeader(k, COMMON_HEADERS[k])
- }
-
- if (isIndex) {
- res.setHeader('content-type', MIME_TYPES.html)
- res.writeHead(200, 'OK')
- res.end('
')
- } else {
- res.setHeader('accept-ranges', 'bytes')
-
- let code = ''
-
- switch (ext) {
- case 'html':
- {
- res.setHeader('content-type', MIME_TYPES.html)
-
- let page = conf.pages[pageName]
- let entry = fs.cat(page.entry).toString()
- let html = fs.cat(join(process.cwd(), 'index.html')).toString()
-
- entry = parseJs(entry, conf.imports, { IS_MPA, currentPage })
-
- code = parseHtml(html, { page, imports: conf.imports, entry })
- }
-
- break
-
- case 'vue':
- {
- let rpath = pathname.replace(/^assets\/js\//, '')
- let file
-
- if (IS_MPA) {
- file = join(pagesDir, rpath)
- } else {
- file = join(root, rpath)
- }
- if (!fs.isfile(file)) {
- file = file.replace(/\.vue$/, '/index.vue')
- }
-
- // console.log('>>>>', file)
- code = compileVue(file, conf.imports, {
- IS_MPA,
- currentPage,
- root,
- pagesDir
- })
- res.setHeader('content-type', MIME_TYPES.js)
- }
- break
-
- case 'scss':
- case 'css':
- {
- let file = join(root, pathname.replace(/^assets\/css\//, ''))
- code = compileScss(file)
- res.setHeader('content-type', MIME_TYPES.css)
- }
- break
-
- case 'js':
- {
- pathname = pathname.replace(/^assets\/js\//, '')
- let file
- if (pathname.startsWith(currentPage)) {
- file = join(pagesDir, pathname)
- } else {
- file = join(root, pathname)
- }
- if (fs.isfile(file)) {
- code = fs.cat(file)
- } else {
- file = file.replace(/\.js$/, '/index.js')
- code = fs.cat(file)
- }
- code = parseJs(code + '', conf.imports, { IS_MPA, currentPage })
- res.setHeader('content-type', MIME_TYPES.js)
- }
-
- break
-
- case 'png':
- case 'jpg':
- case 'jpeg':
- case 'webp':
- case 'gif':
- case 'svg':
- case 'ico':
- case 'bmp':
- res.setHeader('content-type', MIME_TYPES[ext])
- code = fs.cat(join(root, pathname))
- if (code === null) {
- console.error(pathname, '文件不存在')
- res.writeHead(404, 'Not Found')
- res.end('')
- return
- }
- break
-
- default:
- res.setHeader('content-type', MIME_TYPES[ext] || MIME_TYPES.html)
- break
+ for (let k in COMMON_HEADERS) {
+ res.setHeader(k, COMMON_HEADERS[k])
}
- res.setHeader('content-length', Buffer.byteLength(code || noc))
- res.writeHead(200, 'OK')
- res.end(code || noc)
- }
- })
- .listen(PORT)
+ if (isIndex) {
+ res.setHeader('content-type', MIME_TYPES.html)
+ res.writeHead(200, 'OK')
+ res.end('')
+ } else {
+ res.setHeader('accept-ranges', 'bytes')
+
+ let code = ''
+
+ switch (ext) {
+ case 'html':
+ {
+ res.setHeader('content-type', MIME_TYPES.html)
+
+ let page = conf.pages[pageName]
+ let entry = fs.cat(page.entry).toString()
+ let html = fs.cat(join(process.cwd(), 'index.html')).toString()
+
+ entry = parseJs(entry, conf.imports, { IS_MPA, currentPage })
+
+ code = parseHtml(html, { page, imports: conf.imports, entry })
+ }
+
+ break
+
+ case 'vue':
+ {
+ let rpath = pathname.replace(/^assets\/js\//, '')
+ let file
+
+ if (IS_MPA) {
+ file = join(pagesDir, rpath)
+ } else {
+ file = join(root, rpath)
+ }
+ if (!fs.isfile(file)) {
+ file = file.replace(/\.vue$/, '/index.vue')
+ }
+
+ // console.log('>>>>', file)
+ code = compileVue(file, conf.imports, {
+ IS_MPA,
+ currentPage,
+ root,
+ pagesDir
+ })
+ res.setHeader('content-type', MIME_TYPES.js)
+ }
+ break
+
+ case 'scss':
+ case 'css':
+ {
+ let file = join(root, pathname.replace(/^assets\/css\//, ''))
+ code = compileScss(file)
+ res.setHeader('content-type', MIME_TYPES.css)
+ }
+ break
+
+ case 'js':
+ {
+ pathname = pathname.replace(/^assets\/js\//, '')
+ let file
+ if (pathname.startsWith(currentPage)) {
+ file = join(pagesDir, pathname)
+ } else {
+ file = join(root, pathname)
+ }
+ if (fs.isfile(file)) {
+ code = fs.cat(file)
+ } else {
+ file = file.replace(/\.js$/, '/index.js')
+ code = fs.cat(file)
+ }
+ code = parseJs(code + '', conf.imports, { IS_MPA, currentPage })
+ res.setHeader('content-type', MIME_TYPES.js)
+ }
+
+ break
+
+ case 'png':
+ case 'jpg':
+ case 'jpeg':
+ case 'webp':
+ case 'gif':
+ case 'svg':
+ case 'ico':
+ case 'bmp':
+ res.setHeader('content-type', MIME_TYPES[ext])
+ code = fs.cat(join(root, pathname))
+ if (code === null) {
+ console.error(pathname, '文件不存在')
+ res.writeHead(404, 'Not Found')
+ res.end('')
+ return
+ }
+ break
+
+ default:
+ res.setHeader('content-type', MIME_TYPES[ext] || MIME_TYPES.html)
+ break
+ }
+
+ res.setHeader('content-length', Buffer.byteLength(code || noc))
+ res.writeHead(200, 'OK')
+ res.end(code || noc)
+ }
+ })
+
.on('error', err => {
console.log(`${PORT}端口被占用~~~`)
conf.devServer.port = PORT + 1
@@ -216,4 +221,10 @@ export default function createServer(root = '', conf = {}) {
PORT
)
})
+
+ const ws = await socket(server)
+
+ console.log(ws)
+
+ ws.send('hello from vue-live')
}
diff --git a/lib/ws.js b/lib/ws.js
new file mode 100644
index 0000000..0f4826e
--- /dev/null
+++ b/lib/ws.js
@@ -0,0 +1,25 @@
+/**
+ * {}
+ * @author yutent
+ * @date 2023/01/17 17:32:51
+ */
+import { WebSocketServer } from 'ws'
+
+function defer() {
+ var o = {}
+ o.promise = new Promise((resolve, reject) => {
+ o.resolve = resolve
+ o.reject = reject
+ })
+ return o
+}
+
+export default function (server) {
+ var _ = defer()
+ var conn = new WebSocketServer({ server, path: '/ws-vue-live' })
+
+ conn.on('connection', client => {
+ _.resolve(client)
+ })
+ return _.promise
+}
diff --git a/package.json b/package.json
index c7ad3ae..5dabffc 100644
--- a/package.json
+++ b/package.json
@@ -9,6 +9,7 @@
"@bytedo/sass": "^1.54.8",
"chokidar": "^3.5.3",
"esbuild": "^0.15.13",
- "iofs": "^1.5.2"
+ "iofs": "^1.5.2",
+ "ws": "^8.12.0"
}
}