优化scoped解析;初步支持多页应用

pull/1/head
yutent 2023-02-24 15:45:55 +08:00
parent ea3d812c0b
commit 69fc5f5415
4 changed files with 107 additions and 53 deletions

View File

@ -191,19 +191,39 @@ export function parseJs(
export function compileVue(file, imports, options = {}, isBuild) {
let code = (fs.cat(file) || '').toString().replace(/\r\n/g, '\n')
let CACHE = options.CACHE || {}
let output = '',
scoped = false
let js = code.match(JS_EXP)
let scss = code.matchAll(STYLE_EXP)
let scss = [...code.matchAll(STYLE_EXP)]
let html = code.match(HTML_EXP)
let hash = md5(file)
// console.log(typeof scss)
scss = [...scss].map(it => [it[0], it[1]])
scss = scss
.map(it => {
let css
if (it.length > 2) {
css = compileScss(it[2])
if (it[1].includes('scoped')) {
scoped = true
css = scopeCss(css, hash)
}
} else {
css = compileScss(it[1])
}
return css
})
.join(' ')
js = js ? js[1] : ''
html = (html ? html[1] : '').replace(/`/g, '\\`').replace(/\$\{/g, '\\${')
html = html.replace(/<([\w\-]+)([^>]*?)>/g, `<$1 data-${hash} $2>`)
if (scoped) {
html = html.replace(/<([\w\-]+)([^>]*?)>/g, `<$1 data-${hash} $2>`)
}
if (CACHE[file]) {
CACHE[file] = {
@ -215,36 +235,24 @@ export function compileVue(file, imports, options = {}, isBuild) {
CACHE[file] = { changed: false, js, html }
}
js = parseJs(js, imports, options, isBuild).replace(
output += parseJs(js, imports, options, isBuild).replace(
'export default {',
`export default {\n template: \`${html}\`,`
)
if (scss.length) {
scss = scss.map(it => {
let scoped = it[0].includes('scoped')
let css = compileScss(it[1])
if (scoped) {
css = scopeCss(css, hash)
}
return css
})
CACHE[file].css = scss.join(' ')
if (scss) {
CACHE[file].css = scss
// 修正那反人类的windows路径
js += `
output += `
let stylesheet = new CSSStyleSheet()
stylesheet.path = '${file
.slice(
options.IS_MPA ? options.pagesDir.length : options.SOURCE_DIR.length
)
.replace(/\\/g, '/')}'
stylesheet.replaceSync(\`${CACHE[file].css}\`)
stylesheet.path = '${file.slice(options.SOURCE_DIR.length).replace(/\\/g, '/')}'
stylesheet.replaceSync(\`${scss}\`)
document.adoptedStyleSheets.push(stylesheet)
`
}
return js
return output
}
/**

View File

@ -5,7 +5,7 @@
*/
export const JS_EXP = /<script[^>]*?>([\w\W]*?)<\/script>/
export const STYLE_EXP = /<style[^>]*?>([\w\W]*?)<\/style>/g
export const STYLE_EXP = /<style([^>]*?)>([\w\W]*?)<\/style>/g
export const HTML_EXP = /<template[^>]*?>([\w\W]*?)\n<\/template>/
export const CSS_SHEET_EXP = /([@\w\.,#\-:>\+\~\|\(\)\[\]"'\=\s]+)\{/g

View File

@ -149,12 +149,22 @@ export default async function createServer(root = '', conf = {}) {
let file
if (IS_MPA) {
file = join(pagesDir, rpath)
if (rpath.startsWith(currentPage)) {
rpath = rpath.slice(currentPage.length)
file = join(pagesDir, rpath)
} else {
file = join(SOURCE_DIR, rpath)
}
} else {
file = join(SOURCE_DIR, rpath)
}
if (!fs.isfile(file)) {
console.log(cyan(rpath), red(`not found!!!`))
console.log(
'%s %s \n @try to read %s',
cyan(rpath),
red(`not found!!!`),
file
)
console.log(
red(
'请正确填写引入的文件路径, vue-live 不再自动补全【%s】\n'
@ -170,7 +180,6 @@ export default async function createServer(root = '', conf = {}) {
IS_MPA,
currentPage,
SOURCE_DIR,
pagesDir,
CACHE,
DEPLOY_PATH
})
@ -197,11 +206,16 @@ export default async function createServer(root = '', conf = {}) {
{
pathname = pathname.replace(/^assets\/js\//, '')
let file
if (pathname.startsWith(currentPage)) {
file = join(pagesDir, pathname)
if (IS_MPA) {
if (pathname.startsWith(currentPage)) {
file = join(pagesDir, pathname.slice(currentPage.length))
} else {
file = join(pagesDir, pathname)
}
} else {
file = join(SOURCE_DIR, pathname)
}
if (fs.isfile(file)) {
code = fs.cat(file)
} else if (fs.isfile(join(PUBLIC_DIR, pathname))) {
@ -306,7 +320,6 @@ export default async function createServer(root = '', conf = {}) {
IS_MPA,
currentPage,
SOURCE_DIR,
pagesDir,
CACHE,
DEPLOY_PATH
})

View File

@ -13,32 +13,23 @@ export default function compile(root = '', dist = '', conf = {}) {
const IS_MPA = Object.keys(conf.pages).length > 1
let timeStart = Date.now()
let html = fs.cat(join(process.env.PWD, 'index.html')).toString()
let template = fs.cat(join(process.env.PWD, 'index.html')).toString()
let pagesDir = '',
currentPage = ''
if (IS_MPA) {
} else {
let page
let list = fs.ls(SOURCE_DIR, true).map(it => ({
let list = fs
.ls(SOURCE_DIR, true)
.map(it => ({
name: it.slice(SOURCE_DIR.length + 1),
path: it,
ext: parse(it).ext
}))
.filter(it => fs.isfile(it.path))
currentPage = Object.keys(conf.pages)[0]
page = conf.pages[currentPage]
console.log('正在生成 %s ...', `${currentPage}.html`)
for (let it of list) {
if (fs.isdir(it.path)) {
continue
}
let compileFiles = function (currentPage, page, files) {
for (let it of files) {
// 入口文件, 特殊处理
if (it.path === page.entry) {
if (page && it.path === page.entry) {
let entry = fs.cat(page.entry).toString()
entry = parseJs(
entry,
conf.imports,
@ -46,7 +37,11 @@ export default function compile(root = '', dist = '', conf = {}) {
true
)
let code = parseHtml(html, { page, imports: conf.imports, entry }, true)
let code = parseHtml(
template,
{ page, imports: conf.imports, entry },
true
)
fs.echo(code, join(dist, `${currentPage}.html`))
continue
@ -60,14 +55,19 @@ export default function compile(root = '', dist = '', conf = {}) {
let code = compileVue(
it.path,
conf.imports,
{ IS_MPA, currentPage, SOURCE_DIR, pagesDir, DEPLOY_PATH },
{ IS_MPA, currentPage, SOURCE_DIR, DEPLOY_PATH },
true
)
Es.transform(code, { minify: true }).then(r => {
fs.echo(
r.code,
join(dist, `assets/js/${it.name.split('.').shift()}.js`)
join(
dist,
'assets/js/',
IS_MPA ? currentPage : '',
it.name.replace(/\.vue$/, '.js')
)
)
})
}
@ -84,7 +84,10 @@ export default function compile(root = '', dist = '', conf = {}) {
true
)
Es.transform(code, { minify: true }).then(r => {
fs.echo(r.code, join(dist, `assets/js/${it.name}`))
fs.echo(
r.code,
join(dist, 'assets/js/', IS_MPA ? currentPage : '', it.name)
)
})
}
break
@ -105,11 +108,41 @@ export default function compile(root = '', dist = '', conf = {}) {
break
}
}
}
for (let currentPage in conf.pages) {
let page = conf.pages[currentPage]
let dir = dirname(page.entry)
let files = []
fs.ls(dir, true).forEach(it => {
if (fs.isdir(it)) {
return
}
let idx = list.findIndex(_ => _.path === it)
list.splice(idx, 1)
files.push({
name: it.slice(dir.length + 1),
path: it,
ext: parse(it).ext
})
})
console.log('正在生成 %s ...', `${currentPage}.html`)
compileFiles(currentPage, page, files)
}
console.log('正在解析公共依赖 ...')
compileFiles('', null, list)
//
if (fs.isdir(PUBLIC_DIR)) {
console.log('正在处理静态资源 ...')
fs.ls(PUBLIC_DIR, true).forEach(it => {
if (fs.isfile(it)) {
let name = it.slice(PUBLIC_DIR.length + 1)
console.log('正在复制静态文件 %s ...', name)
console.log(' 正在复制 %s ...', name)
fs.cp(it, join(dist, name))
}
})