完成多线程编译, 修复静态文件复制路径

threads
yutent 2023-06-16 12:11:43 +08:00
parent 82c8686bfb
commit cca39d9156
5 changed files with 30 additions and 46 deletions

View File

@ -11,7 +11,7 @@ import { compileScss, parseJs, compileVue, parseHtml } from './compile-vue.js'
const template = fs.cat(join(process.cwd(), 'index.html')).toString() const template = fs.cat(join(process.cwd(), 'index.html')).toString()
export function compileFiles( export async function compileFiles(
currentPage, currentPage,
page, page,
files, files,
@ -47,7 +47,7 @@ export function compileFiles(
{ {
let code = compileVue(it.path, imports, options) let code = compileVue(it.path, imports, options)
Es.transform(code, { minify: true }).then(r => { await Es.transform(code, { minify: true }).then(r => {
fs.echo( fs.echo(
r.code, r.code,
join(dist, 'assets/', pageDir, it.name.replace(/\.vue$/, '.js')) join(dist, 'assets/', pageDir, it.name.replace(/\.vue$/, '.js'))
@ -62,7 +62,7 @@ export function compileFiles(
code = parseJs(code + '', imports, options) code = parseJs(code + '', imports, options)
Es.transform(code, { minify: true }).then(r => { await Es.transform(code, { minify: true }).then(r => {
fs.echo(r.code, join(dist, 'assets/', pageDir, it.name)) fs.echo(r.code, join(dist, 'assets/', pageDir, it.name))
}) })
} }
@ -71,7 +71,12 @@ export function compileFiles(
case '.scss': case '.scss':
case '.css': case '.css':
{ {
let target = join(dist, 'assets/', it.name.replace(/\.scss$/, '.css')) let target = join(
dist,
'assets/',
pageDir,
it.name.replace(/\.scss$/, '.css')
)
if (it.ext === '.css') { if (it.ext === '.css') {
fs.cp(it.path, target) fs.cp(it.path, target)
} else { } else {
@ -82,7 +87,7 @@ export function compileFiles(
break break
default: default:
fs.cp(it.path, join(dist, it.name)) fs.cp(it.path, join(dist, 'assets/', pageDir, it.name))
break break
} }
} }

View File

@ -1,10 +1,8 @@
import { join, dirname, parse, normalize } from 'node:path' import { join, dirname, parse, normalize } from 'node:path'
import { Worker } from 'node:worker_threads' import { Worker, parentPort } from 'node:worker_threads'
import os from 'node:os' import os from 'node:os'
import fs from 'iofs' import fs from 'iofs'
import { isCustomElement } from './utils.js'
const IS_WIN = process.platform === 'win32' const IS_WIN = process.platform === 'win32'
const PREFIX = IS_WIN ? 'pages\\' : 'pages/' const PREFIX = IS_WIN ? 'pages\\' : 'pages/'
// 线程太多, 效率反而不高 // 线程太多, 效率反而不高
@ -19,11 +17,6 @@ function readFile(file) {
} }
function doJob() { function doJob() {
// console.log('<><><>', JOBS_QUEUE.length, WORKER_POOL.size)
// if (JOBS_QUEUE.length === 0 && WORKER_POOL.size === THREADS_NUM) {
// process.exit()
// }
while (JOBS_QUEUE.length && WORKER_POOL.size) { while (JOBS_QUEUE.length && WORKER_POOL.size) {
let job = JOBS_QUEUE.shift() let job = JOBS_QUEUE.shift()
let worker = WORKER_POOL.values().next().value let worker = WORKER_POOL.values().next().value
@ -31,10 +24,14 @@ function doJob() {
WORKER_POOL.delete(worker) WORKER_POOL.delete(worker)
worker.once('message', _ => { worker.once('message', _ => {
WORKER_POOL.add(worker) if (JOBS_QUEUE.length) {
WORKER_POOL.add(worker)
doJob() doJob()
} else {
worker.terminate()
}
}) })
worker.postMessage(job) worker.postMessage(job)
} }
} }
@ -64,8 +61,7 @@ export default function compile(root = '', dist = '', conf = {}, verbose) {
INJECT_SCSS, INJECT_SCSS,
LEGACY_MODE, LEGACY_MODE,
// 线程通讯无法传递函数类型, 需要转为字符串, 之后再转回来 // 线程通讯无法传递函数类型, 需要转为字符串, 之后再转回来
// isCustomElement: conf.isCustomElement || isCustomElement isCustomElement: conf.isCustomElement
isCustomElement: (conf.isCustomElement || isCustomElement).toString()
} }
fs.ls(SOURCE_DIR, true).forEach(path => { fs.ls(SOURCE_DIR, true).forEach(path => {
@ -128,16 +124,6 @@ export default function compile(root = '', dist = '', conf = {}, verbose) {
} }
if (IS_MPA) { if (IS_MPA) {
// 电脑线程数比页面数量还多时, 取小
// let num = Math.min(PAGES_KEYS.length, THREADS_NUM)
// let chunkSize = Math.ceil(PAGES_KEYS.length / num)
// for (let i = 0; i < num; i++) {
// let start = i * chunkSize
// let end = start + chunkSize
// let pages = PAGES_KEYS.slice(start, end)
// let chunk = new Map()
for (let currentPage of PAGES_KEYS) { for (let currentPage of PAGES_KEYS) {
let page = conf.pages[currentPage] let page = conf.pages[currentPage]
let dir = dirname(page.entry) let dir = dirname(page.entry)

View File

@ -5,17 +5,24 @@
*/ */
import { parentPort, workerData } from 'node:worker_threads' import { parentPort, workerData } from 'node:worker_threads'
import { compileFiles } from './compile.js' import { compileFiles } from './compile.js'
import { isCustomElement } from './utils.js'
const { options, verbose, dist, imports } = workerData const { options, verbose, dist, imports } = workerData
options.isCustomElement = Function('return ' + options.isCustomElement)() options.isCustomElement = Function('return ' + options.isCustomElement)()
parentPort.on('message', job => { async function doJob(job) {
let [currentPage, { page, files }] = job.entries().next().value let [currentPage, { page, files }] = job.entries().next().value
console.log( console.log(
currentPage ? `正在生成 ${currentPage}.html ...` : '\n正在解析公共依赖 ...' currentPage ? `正在生成 ${currentPage}.html ...` : '\n正在解析公共依赖 ...'
) )
compileFiles(currentPage, page, files, options, { verbose, dist, imports }) await compileFiles(currentPage, page, files, options, {
verbose,
dist,
imports
})
parentPort.postMessage('ok') parentPort.postMessage('ok')
}) }
parentPort.on('message', doJob)

View File

@ -7,7 +7,6 @@
import { createHash, randomUUID } from 'node:crypto' import { createHash, randomUUID } from 'node:crypto'
import { join } from 'node:path' import { join } from 'node:path'
import { gzipSync } from 'node:zlib' import { gzipSync } from 'node:zlib'
import { Worker } from 'node:worker_threads'
import { red, cyan, blue } from 'kolorist' import { red, cyan, blue } from 'kolorist'
// 修正路径合并 避免在windows下被转义 // 修正路径合并 避免在windows下被转义
@ -98,16 +97,3 @@ export function createHmrScript(legacy, session = '') {
export function isCustomElement(tag) { export function isCustomElement(tag) {
return tag.startsWith('wc-') return tag.startsWith('wc-')
} }
export function startWorker(file) {
return new Promise((resolve, reject) => {
let worker = new Worker(file)
worker.on('message', resolve)
worker.on('error', reject)
worker.on('exit', code => {
if (code !== 0) {
reject(new Error(`Worker stopped with exit code ${code}`))
}
})
})
}

View File

@ -32,7 +32,7 @@ class WebSocket {
send(msg = {}) { send(msg = {}) {
if (this.#clients.size) { if (this.#clients.size) {
for (let [key, client] of this.#clients.entries()) { for (let [key, client] of this.#clients) {
client.send(JSON.stringify(msg)) client.send(JSON.stringify(msg))
} }
} else { } else {