优化scoped解析;初步支持多页应用
parent
ea3d812c0b
commit
69fc5f5415
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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
|
||||||
|
|
19
lib/dev.js
19
lib/dev.js
|
@ -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
|
||||||
})
|
})
|
||||||
|
|
79
lib/prod.js
79
lib/prod.js
|
@ -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))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue