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

View File

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

View File

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

View File

@ -13,32 +13,23 @@ export default function compile(root = '', dist = '', conf = {}) {
const IS_MPA = Object.keys(conf.pages).length > 1 const IS_MPA = Object.keys(conf.pages).length > 1
let timeStart = Date.now() 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 = '', let list = fs
currentPage = '' .ls(SOURCE_DIR, true)
.map(it => ({
if (IS_MPA) {
} else {
let page
let list = fs.ls(SOURCE_DIR, true).map(it => ({
name: it.slice(SOURCE_DIR.length + 1), name: it.slice(SOURCE_DIR.length + 1),
path: it, path: it,
ext: parse(it).ext ext: parse(it).ext
})) }))
.filter(it => fs.isfile(it.path))
currentPage = Object.keys(conf.pages)[0] let compileFiles = function (currentPage, page, files) {
page = conf.pages[currentPage] for (let it of files) {
console.log('正在生成 %s ...', `${currentPage}.html`)
for (let it of list) {
if (fs.isdir(it.path)) {
continue
}
// 入口文件, 特殊处理 // 入口文件, 特殊处理
if (it.path === page.entry) { if (page && it.path === page.entry) {
let entry = fs.cat(page.entry).toString() let entry = fs.cat(page.entry).toString()
entry = parseJs( entry = parseJs(
entry, entry,
conf.imports, conf.imports,
@ -46,7 +37,11 @@ export default function compile(root = '', dist = '', conf = {}) {
true 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`)) fs.echo(code, join(dist, `${currentPage}.html`))
continue continue
@ -60,14 +55,19 @@ export default function compile(root = '', dist = '', conf = {}) {
let code = compileVue( let code = compileVue(
it.path, it.path,
conf.imports, conf.imports,
{ IS_MPA, currentPage, SOURCE_DIR, pagesDir, DEPLOY_PATH }, { IS_MPA, currentPage, SOURCE_DIR, DEPLOY_PATH },
true true
) )
Es.transform(code, { minify: true }).then(r => { Es.transform(code, { minify: true }).then(r => {
fs.echo( fs.echo(
r.code, 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 true
) )
Es.transform(code, { minify: true }).then(r => { 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 break
@ -105,11 +108,41 @@ export default function compile(root = '', dist = '', conf = {}) {
break 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 => { fs.ls(PUBLIC_DIR, true).forEach(it => {
if (fs.isfile(it)) { if (fs.isfile(it)) {
let name = it.slice(PUBLIC_DIR.length + 1) let name = it.slice(PUBLIC_DIR.length + 1)
console.log('正在复制静态文件 %s ...', name) console.log(' 正在复制 %s ...', name)
fs.cp(it, join(dist, name)) fs.cp(it, join(dist, name))
} }
}) })