完善hmr
parent
100e000609
commit
98e7fb6864
|
@ -7,8 +7,15 @@
|
||||||
import fs from 'iofs'
|
import fs from 'iofs'
|
||||||
import scss from '@bytedo/sass'
|
import scss from '@bytedo/sass'
|
||||||
import { createHash } from 'crypto'
|
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 = {
|
const OPTIONS = {
|
||||||
indentType: 'space',
|
indentType: 'space',
|
||||||
|
@ -227,7 +234,11 @@ export function parseHtml(html, { page, imports, entry }, isBuild = false) {
|
||||||
` <script>window.process = {env: {NODE_ENV: '${
|
` <script>window.process = {env: {NODE_ENV: '${
|
||||||
isBuild ? 'production' : 'development'
|
isBuild ? 'production' : 'development'
|
||||||
}'}}</script>\n${
|
}'}}</script>\n${
|
||||||
isBuild ? '' : ' <script src="/assets/ws.js"></script>'
|
isBuild
|
||||||
|
? ''
|
||||||
|
: ` <script>${
|
||||||
|
Es.transformSync(HMR_SCRIPT, { minify: true }).code
|
||||||
|
}</script>`
|
||||||
}</head>`
|
}</head>`
|
||||||
)
|
)
|
||||||
.replace('{{title}}', page.title || '')
|
.replace('{{title}}', page.title || '')
|
||||||
|
|
|
@ -14,3 +14,38 @@ export const CSS_SHEET_EXP =
|
||||||
export const COMMON_HEADERS = {
|
export const COMMON_HEADERS = {
|
||||||
'Cache-Control': 'no-store'
|
'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
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})()
|
||||||
|
`
|
||||||
|
|
29
lib/dev.js
29
lib/dev.js
|
@ -5,6 +5,7 @@ import { join, resolve, dirname } from 'path'
|
||||||
import { parse } from 'url'
|
import { parse } from 'url'
|
||||||
import socket from './ws.js'
|
import socket from './ws.js'
|
||||||
import chokidar from 'chokidar'
|
import chokidar from 'chokidar'
|
||||||
|
import { red, cyan, blue } from 'kolorist'
|
||||||
|
|
||||||
import { compileScss, parseJs, compileVue, parseHtml } from './compile-vue.js'
|
import { compileScss, parseJs, compileVue, parseHtml } from './compile-vue.js'
|
||||||
|
|
||||||
|
@ -134,10 +135,16 @@ export default async function createServer(root = '', conf = {}) {
|
||||||
file = join(root, rpath)
|
file = join(root, rpath)
|
||||||
}
|
}
|
||||||
if (!fs.isfile(file)) {
|
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, {
|
code = compileVue(file, conf.imports, {
|
||||||
IS_MPA,
|
IS_MPA,
|
||||||
currentPage,
|
currentPage,
|
||||||
|
@ -176,8 +183,14 @@ export default async function createServer(root = '', conf = {}) {
|
||||||
if (fs.isfile(file)) {
|
if (fs.isfile(file)) {
|
||||||
code = fs.cat(file)
|
code = fs.cat(file)
|
||||||
} else {
|
} else {
|
||||||
file = file.replace(/\.js$/, '/index.js')
|
console.clear()
|
||||||
code = fs.cat(file)
|
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 })
|
code = parseJs(code + '', conf.imports, { IS_MPA, currentPage })
|
||||||
res.setHeader('content-type', MIME_TYPES.js)
|
res.setHeader('content-type', MIME_TYPES.js)
|
||||||
|
@ -215,7 +228,10 @@ export default async function createServer(root = '', conf = {}) {
|
||||||
})
|
})
|
||||||
|
|
||||||
.on('error', err => {
|
.on('error', err => {
|
||||||
console.log(`${PORT}端口被占用~~~`)
|
console.log(
|
||||||
|
red(`${PORT} 端口被占用!!! 尝试使用 ${PORT + 1} 端口...`),
|
||||||
|
'\n'
|
||||||
|
)
|
||||||
conf.devServer.port = PORT + 1
|
conf.devServer.port = PORT + 1
|
||||||
createServer(root, conf)
|
createServer(root, conf)
|
||||||
})
|
})
|
||||||
|
@ -255,7 +271,6 @@ export default async function createServer(root = '', conf = {}) {
|
||||||
|
|
||||||
case 'vue':
|
case 'vue':
|
||||||
{
|
{
|
||||||
// console.log('>>>>', file)
|
|
||||||
let content = compileVue(filePath, conf.imports, {
|
let content = compileVue(filePath, conf.imports, {
|
||||||
IS_MPA,
|
IS_MPA,
|
||||||
currentPage,
|
currentPage,
|
||||||
|
@ -264,9 +279,7 @@ export default async function createServer(root = '', conf = {}) {
|
||||||
CACHE
|
CACHE
|
||||||
})
|
})
|
||||||
let tmp = CACHE[filePath]
|
let tmp = CACHE[filePath]
|
||||||
// console.log(tmp);
|
|
||||||
if (tmp.changed) {
|
if (tmp.changed) {
|
||||||
console.log('需要刷新了')
|
|
||||||
ws.send({ action: 'reload' })
|
ws.send({ action: 'reload' })
|
||||||
} else {
|
} else {
|
||||||
ws.send({
|
ws.send({
|
||||||
|
|
35
lib/ws.js
35
lib/ws.js
|
@ -1,35 +1,28 @@
|
||||||
/**
|
/**
|
||||||
* 一个简单到极致的 WebSocket 类
|
* 一个简单到发指的 WebSocket 类
|
||||||
* @author yutent<yutent.io@gmail.com>
|
* @author yutent<yutent.io@gmail.com>
|
||||||
* @date 2023/01/17 17:32:51
|
* @date 2023/01/17 17:32:51
|
||||||
*/
|
*/
|
||||||
import { WebSocketServer } from 'ws'
|
import { WebSocketServer } from 'ws'
|
||||||
|
|
||||||
function defer() {
|
|
||||||
var o = {}
|
|
||||||
o.promise = new Promise((resolve, reject) => {
|
|
||||||
o.resolve = resolve
|
|
||||||
o.reject = reject
|
|
||||||
})
|
|
||||||
return o
|
|
||||||
}
|
|
||||||
|
|
||||||
class WebSocket {
|
class WebSocket {
|
||||||
#ws = null // ws实例
|
#ws = null // ws实例
|
||||||
#queue = [] // 消息队列
|
#queue = [] // 消息队列
|
||||||
|
|
||||||
constructor(server) {
|
constructor(server) {
|
||||||
var conn = new WebSocketServer({ server, path: '/ws-vue-live' })
|
if (server.listening) {
|
||||||
conn.on('connection', ws => {
|
let conn = new WebSocketServer({ server, path: '/ws-vue-live' })
|
||||||
this.#ws = ws
|
conn.on('connection', ws => {
|
||||||
// ws.on('message', data => {
|
this.#ws = ws
|
||||||
// console.log(data + '');
|
// ws.on('message', data => {
|
||||||
// })
|
// console.log(data + '');
|
||||||
while (this.#queue.length) {
|
// })
|
||||||
let msg = this.#queue.shift()
|
while (this.#queue.length) {
|
||||||
this.send(msg)
|
let msg = this.#queue.shift()
|
||||||
}
|
this.send(msg)
|
||||||
})
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
send(msg = {}) {
|
send(msg = {}) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@bytedo/vue-live",
|
"name": "@bytedo/vue-live",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "0.1.0",
|
"version": "0.1.1",
|
||||||
"bin": {
|
"bin": {
|
||||||
"vue-live": "index.js"
|
"vue-live": "index.js"
|
||||||
},
|
},
|
||||||
|
@ -10,6 +10,7 @@
|
||||||
"chokidar": "^3.5.3",
|
"chokidar": "^3.5.3",
|
||||||
"esbuild": "^0.15.13",
|
"esbuild": "^0.15.13",
|
||||||
"iofs": "^1.5.2",
|
"iofs": "^1.5.2",
|
||||||
|
"kolorist": "^1.6.0",
|
||||||
"ws": "^8.12.0"
|
"ws": "^8.12.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue