From 98e7fb6864b166d1d41e7a1d512c115f0cd68660 Mon Sep 17 00:00:00 2001 From: yutent Date: Wed, 1 Feb 2023 10:51:33 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84hmr?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/compile-vue.js | 15 +++++++++++++-- lib/constants.js | 35 +++++++++++++++++++++++++++++++++++ lib/dev.js | 29 +++++++++++++++++++++-------- lib/ws.js | 35 ++++++++++++++--------------------- package.json | 3 ++- 5 files changed, 85 insertions(+), 32 deletions(-) diff --git a/lib/compile-vue.js b/lib/compile-vue.js index 0df2793..2c0d595 100644 --- a/lib/compile-vue.js +++ b/lib/compile-vue.js @@ -7,8 +7,15 @@ import fs from 'iofs' import scss from '@bytedo/sass' import { createHash } from 'crypto' +import Es from 'esbuild' -import { JS_EXP, STYLE_EXP, HTML_EXP, CSS_SHEET_EXP } from './constants.js' +import { + JS_EXP, + STYLE_EXP, + HTML_EXP, + CSS_SHEET_EXP, + HMR_SCRIPT +} from './constants.js' const OPTIONS = { indentType: 'space', @@ -227,7 +234,11 @@ export function parseHtml(html, { page, imports, entry }, isBuild = false) { ` \n${ - isBuild ? '' : ' ' + isBuild + ? '' + : ` ` }` ) .replace('{{title}}', page.title || '') diff --git a/lib/constants.js b/lib/constants.js index f1a275f..76417f0 100644 --- a/lib/constants.js +++ b/lib/constants.js @@ -14,3 +14,38 @@ export const CSS_SHEET_EXP = export const COMMON_HEADERS = { 'Cache-Control': 'no-store' } + +export const HMR_SCRIPT = ` +!(function(){ + var ws = new WebSocket(\`ws://\${location.host}/ws-vue-live\`) + + ws.addEventListener('open', function (r) { + console.log('vue-live hmr ready...') + }) + + ws.addEventListener('message', function (ev) { + var { action, data } = JSON.parse(ev.data) + + switch (action) { + case 'reload': + location.reload() + break + + case 'render': + { + let tmp = [...document.adoptedStyleSheets] + for (let i = -1, it; (it = tmp[++i]); ) { + if (it.path === data.path) { + let stylesheet = new CSSStyleSheet() + stylesheet.path = data.path + stylesheet.replaceSync(data.content) + document.adoptedStyleSheets[i] = stylesheet + break + } + } + } + break + } + }) +})() +` diff --git a/lib/dev.js b/lib/dev.js index d9f18bb..fbfd380 100644 --- a/lib/dev.js +++ b/lib/dev.js @@ -5,6 +5,7 @@ import { join, resolve, dirname } from 'path' import { parse } from 'url' import socket from './ws.js' import chokidar from 'chokidar' +import { red, cyan, blue } from 'kolorist' import { compileScss, parseJs, compileVue, parseHtml } from './compile-vue.js' @@ -134,10 +135,16 @@ export default async function createServer(root = '', conf = {}) { file = join(root, rpath) } if (!fs.isfile(file)) { - file = file.replace(/\.vue$/, '/index.vue') + console.clear() + console.log(cyan(rpath), red(`not found!!!`)) + console.log( + red( + '请正确填写引入的文件路径, vue-live 不再自动补全【%s】\n' + ), + blue('/index.vue') + ) } - // console.log('>>>>', file) code = compileVue(file, conf.imports, { IS_MPA, currentPage, @@ -176,8 +183,14 @@ export default async function createServer(root = '', conf = {}) { if (fs.isfile(file)) { code = fs.cat(file) } else { - file = file.replace(/\.js$/, '/index.js') - code = fs.cat(file) + console.clear() + console.log(cyan(pathname), red(`not found!!!`)) + console.log( + red( + '请正确填写引入的文件路径, vue-live 不再自动补全【%s】\n' + ), + blue('/index.js') + ) } code = parseJs(code + '', conf.imports, { IS_MPA, currentPage }) res.setHeader('content-type', MIME_TYPES.js) @@ -215,7 +228,10 @@ export default async function createServer(root = '', conf = {}) { }) .on('error', err => { - console.log(`${PORT}端口被占用~~~`) + console.log( + red(`${PORT} 端口被占用!!! 尝试使用 ${PORT + 1} 端口...`), + '\n' + ) conf.devServer.port = PORT + 1 createServer(root, conf) }) @@ -255,7 +271,6 @@ export default async function createServer(root = '', conf = {}) { case 'vue': { - // console.log('>>>>', file) let content = compileVue(filePath, conf.imports, { IS_MPA, currentPage, @@ -264,9 +279,7 @@ export default async function createServer(root = '', conf = {}) { CACHE }) let tmp = CACHE[filePath] - // console.log(tmp); if (tmp.changed) { - console.log('需要刷新了') ws.send({ action: 'reload' }) } else { ws.send({ diff --git a/lib/ws.js b/lib/ws.js index a1a6c84..2428a01 100644 --- a/lib/ws.js +++ b/lib/ws.js @@ -1,35 +1,28 @@ /** - * 一个简单到极致的 WebSocket 类 + * 一个简单到发指的 WebSocket 类 * @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 -} - class WebSocket { #ws = null // ws实例 #queue = [] // 消息队列 constructor(server) { - var conn = new WebSocketServer({ server, path: '/ws-vue-live' }) - conn.on('connection', ws => { - this.#ws = ws - // ws.on('message', data => { - // console.log(data + ''); - // }) - while (this.#queue.length) { - let msg = this.#queue.shift() - this.send(msg) - } - }) + if (server.listening) { + let conn = new WebSocketServer({ server, path: '/ws-vue-live' }) + conn.on('connection', ws => { + this.#ws = ws + // ws.on('message', data => { + // console.log(data + ''); + // }) + while (this.#queue.length) { + let msg = this.#queue.shift() + this.send(msg) + } + }) + } } send(msg = {}) { diff --git a/package.json b/package.json index 17f854c..878862e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@bytedo/vue-live", "type": "module", - "version": "0.1.0", + "version": "0.1.1", "bin": { "vue-live": "index.js" }, @@ -10,6 +10,7 @@ "chokidar": "^3.5.3", "esbuild": "^0.15.13", "iofs": "^1.5.2", + "kolorist": "^1.6.0", "ws": "^8.12.0" } }