From 502d4e4a233b754326c844a255470b76ee8ae190 Mon Sep 17 00:00:00 2001 From: yutent Date: Mon, 10 Oct 2022 15:05:30 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=BC=80=E5=8F=91=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F=E6=9C=80=E5=88=9D=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.js | 11 ++--- lib/compile-vue.js | 32 +++++++++----- lib/dev.js | 107 ++++++++++++++++++++++++++++++--------------- lib/index.js | 10 ----- package.json | 1 + 5 files changed, 98 insertions(+), 63 deletions(-) delete mode 100644 lib/index.js diff --git a/index.js b/index.js index 4526d3b..89220aa 100755 --- a/index.js +++ b/index.js @@ -7,11 +7,14 @@ */ import { join } from 'path' -import { createServer, compile } from './lib/index.js' + +import createServer from './lib/dev.js' +import compile from './lib/prod.js' const WORK_SPACE = process.env.INIT_CWD const CONFIG_FILE = join(WORK_SPACE, 'vue.live.js') +const SOURCE_DIR = join(WORK_SPACE, 'src') let args = process.argv.slice(2) @@ -19,8 +22,7 @@ switch (args[0]) { case 'dev': import(CONFIG_FILE) .then(function (conf) { - // console.log(conf) - createServer(WORK_SPACE, conf.default) + createServer(SOURCE_DIR, conf.default) }) .catch(err => { console.log('Import Error:', err) @@ -30,8 +32,7 @@ switch (args[0]) { case 'build': import(CONFIG_FILE) .then(function (conf) { - // console.log(conf) - compile(WORK_SPACE, conf.default) + compile(SOURCE_DIR, conf.default) }) .catch(err => { console.log('Import Error:', err) diff --git a/lib/compile-vue.js b/lib/compile-vue.js index 77f62d6..a1ea876 100644 --- a/lib/compile-vue.js +++ b/lib/compile-vue.js @@ -14,6 +14,8 @@ const OPTIONS = { indentWidth: 2 } +let imports = {} + /** * 编译scss为css * @param file 文件路径或scss代码 @@ -36,21 +38,24 @@ export function compileScss(file, style = 'expanded') { * 主要是处理js的依赖引用 * @param code js代码 */ -export function parseJs(code = '', currentPage = '') { +export function parseJs(code = '', { IS_MPA, currentPage, root, pagesDir } = {}) { let fixedStyle = '\n\n' return ( code .replace(/import (.*?) from (["'])(.*?)\2/g, function (m, alias, q, name) { if (name.startsWith('@/')) { - name = name.replace('@/', '/aseets/js/') + name = name.replace('@/', '/assets/js/') } - if (!conf.imports[name]) { + if (!imports[name]) { if (name.startsWith('./')) { - name = name.replace('./', `/aseets/js/${currentPage}/`) - } else if (name.startsWith('/') && !name.startsWith('/aseets/js/')) { - name = name.replace(/^\//, '/aseets/js/') + name = name.replace('./', '/assets/js/') + if (IS_MPA) { + name += `${currentPage}/` + } + } else if (name.startsWith('/') && !name.startsWith('/assets/js/')) { + name = name.replace(/^\//, '/assets/js/') } if (!name.endsWith('.js') && !name.endsWith('.vue')) { @@ -66,7 +71,7 @@ export function parseJs(code = '', currentPage = '') { .replace(/import (["'])(.*?)\1/g, function (m, q, name) { if (name.endsWith('.css') || name.endsWith('.scss')) { if (name.startsWith('@/')) { - name = name.replace('@/', '/aseets/css/') + name = name.replace('@/', '/assets/css/') } let tmp = `style${Date.now()}` fixedStyle += `document.adoptedStyleSheets.push(${tmp})\n` @@ -74,10 +79,10 @@ export function parseJs(code = '', currentPage = '') { return `import ${tmp} from '${name}' assert { type: 'css' }` } else { if (name.startsWith('@/')) { - name = name.replace('@/', '/aseets/js/') + name = name.replace('@/', '/assets/js/') } - // console.log(name, conf.imports[name]) - if (!conf.imports[name]) { + // console.log(name, imports[name]) + if (!imports[name]) { if (!name.startsWith('/') && !name.startsWith('./')) { name = '/' + name } @@ -97,7 +102,7 @@ export function parseJs(code = '', currentPage = '') { * @param file 文件路径 * @return 返回转换后的js代码 */ -export function compileVue(file) { +export function compileVue(file, conf, options = {}) { let code = (fs.cat(file) || '').toString() let js = code.match(JS_EXP) @@ -106,12 +111,14 @@ export function compileVue(file) { let fixedStyle = '\n\n' + imports = conf.imports + // console.log(typeof scss) scss = [...scss].flatMap(it => (it ? it[1] : '')) js = js ? js[1] : '' html = (html ? html[1] : '').replace(/`/g, '\\`').replace(/\$\{/g, '\\${') - js = parseJs(js).replace( + js = parseJs(js, options).replace( 'export default {', `${fixedStyle}export default {\n template: \`${html}\`,` ) @@ -119,6 +126,7 @@ export function compileVue(file) { if (scss.length) { js += ` let stylesheet = new CSSStyleSheet() + stylesheet.path = '${file.slice(options.IS_MPA ? options.pagesDir.length : options.root.length)}' stylesheet.replaceSync(\`${compileScss(scss.join('\n'))}\`) document.adoptedStyleSheets.push(stylesheet) ` diff --git a/lib/dev.js b/lib/dev.js index b730fd8..c5e9e72 100644 --- a/lib/dev.js +++ b/lib/dev.js @@ -1,6 +1,6 @@ import http from 'http' import fs from 'iofs' -import { join, resolve,dirname } from 'path' +import { join, resolve, dirname } from 'path' import { parse } from 'url' import { compileScss, parseJs, compileVue } from './compile-vue.js' @@ -11,25 +11,50 @@ import { COMMON_HEADERS } from './constants.js' const decode = decodeURIComponent export default function createServer(root = '', conf = {}) { - let pagesDir = '' - let indexPage = Object.keys(conf.pages).map(it => { - let tmp = it + '.html' - return `
  • ${tmp}
  • ` - }).join('') + const IS_MPA = Object.keys(conf.pages).length > 1 + let indexPage = Object.keys(conf.pages) + .map(it => { + let tmp = it + '.html' + return `
  • ${tmp}
  • ` + }) + .join('') - let currentPage = '' + let pagesDir = '', + currentPage = '' http .createServer(function (req, res) { let pathname = parse(req.url.slice(1)).pathname - let isIndex = pathname === '' + let pageName = '', + isIndex = false + let ext + + if (pathname) { + pathname = pathname.split('/') + + if (pathname[0].endsWith('.html')) { + pageName = pathname.shift() + + let tmp = pageName.split('.') + + ext = tmp.pop() + pageName = tmp.join('.') + + currentPage = pageName + pagesDir = dirname(conf.pages[pageName].entry) + } else { + ext = pathname[pathname.length - 1].split('.').pop() + pageName = currentPage + } + pathname = pathname.join('/') + } else { + isIndex = true + } for (let k in COMMON_HEADERS) { res.setHeader(k, COMMON_HEADERS[k]) } - - if (isIndex) { res.setHeader('content-type', MIME_TYPES.html) res.writeHead(200, 'OK') @@ -37,37 +62,36 @@ export default function createServer(root = '', conf = {}) { } else { res.setHeader('accept-ranges', 'bytes') - let tmp = pathname.split('.') - let ext = tmp.pop() - let page = tmp.join('.') - let code = '' - console.log(req); + // return res.end(JSON.stringify({url: req.url, ext, pageName})) - return res.end(JSON.stringify({url: req.url,ext, page})) + res.setHeader('x-ext', ext) + res.setHeader('x-page', pageName) switch (ext) { case 'html': { - let entry = fs.cat(join(pagesDir, page, 'main.js')).toString() + let entry = fs.cat(conf.pages[pageName].entry).toString() let fixedStyle = '\n\n' - currentPage = page - res.setHeader('content-type', MIME_TYPES.html) entry = entry .replace(/import (.*?) from (["'])(.*?)\2/g, function (m, alias, q, name) { if (name.startsWith('@/')) { - name = name.replace('@/', '/aseets/js/') + name = name.replace('@/', '/assets/js/') } if (!conf.imports[name]) { if (name.startsWith('./')) { - name = name.replace('./', `/aseets/js/${currentPage}/`) - } else if (name.startsWith('/') && !name.startsWith('/aseets/js/')) { - name = name.replace(/^\//, '/aseets/js/') + name = name.replace('./', '/assets/js/') + + if (IS_MPA) { + name += `${currentPage}/` + } + } else if (name.startsWith('/') && !name.startsWith('/assets/js/')) { + name = name.replace(/^\//, '/assets/js/') } if (!name.endsWith('.js') && !name.endsWith('.vue')) { @@ -79,7 +103,7 @@ export default function createServer(root = '', conf = {}) { .replace(/import (["'])(.*?)\1/g, function (m, q, name) { if (name.endsWith('.css') || name.endsWith('.scss')) { if (name.startsWith('@/')) { - name = name.replace('@/', '/aseets/css/') + name = name.replace('@/', '/assets/css/') } let tmp = `style${Date.now()}` fixedStyle += `document.adoptedStyleSheets.push(${tmp})\n` @@ -87,7 +111,7 @@ export default function createServer(root = '', conf = {}) { return `import ${tmp} from '${name}' assert { type: 'css' }` } else { if (name.startsWith('@/')) { - name = name.replace('@/', '/aseets/js/') + name = name.replace('@/', '/assets/js/') } // console.log(name, conf.imports[name]) if (!conf.imports[name]) { @@ -111,6 +135,7 @@ export default function createServer(root = '', conf = {}) { '', "" ) + .replace('{{title}}', conf.pages[pageName].title) .replace('{{importmap}}', JSON.stringify({ imports: conf.imports })) .replace( '', @@ -122,13 +147,13 @@ export default function createServer(root = '', conf = {}) { case 'vue': { - pathname = pathname.replace(/^aseets\/js\//, '') + let rpath = pathname.replace(/^assets\/js\//, '') let file - if (pathname.startsWith(currentPage)) { - file = join(conf.pages, pathname) + if (rpath.startsWith(currentPage)) { + file = join(pagesDir, rpath) } else { - file = join(root, pathname) + file = join(root, rpath) } if (!fs.isfile(file)) { @@ -136,8 +161,7 @@ export default function createServer(root = '', conf = {}) { } // console.log('>>>>', file) - code = compileVue(file) - + code = compileVue(file, conf, { IS_MPA, currentPage, root, pagesDir }) res.setHeader('content-type', MIME_TYPES.js) } break @@ -145,7 +169,7 @@ export default function createServer(root = '', conf = {}) { case 'scss': case 'css': { - let file = join(root, pathname.replace(/^aseets\/css\//, '')) + let file = join(root, pathname.replace(/^assets\/css\//, '')) code = compileScss(file) res.setHeader('content-type', MIME_TYPES.css) } @@ -153,10 +177,10 @@ export default function createServer(root = '', conf = {}) { case 'js': { - pathname = pathname.replace(/^aseets\/js\//, '') + pathname = pathname.replace(/^assets\/js\//, '') let file if (pathname.startsWith(currentPage)) { - file = join(conf.pages, pathname) + file = join(pagesDir, pathname) } else { file = join(root, pathname) } @@ -166,13 +190,24 @@ export default function createServer(root = '', conf = {}) { file = file.replace(/\.js$/, '/index.js') code = fs.cat(file) } - console.log(req.url, '>>>>', file) code = parseJs(code + '') res.setHeader('content-type', MIME_TYPES.js) } break + case 'png': + case 'jpg': + case 'jpeg': + case 'webp': + case 'gif': + case 'svg': + case 'ico': + case 'bmp': + res.setHeader('content-type', MIME_TYPES[ext]) + code = fs.cat(join(root, pathname)) + break + default: res.setHeader('content-type', MIME_TYPES[ext] || MIME_TYPES.other) break @@ -180,7 +215,7 @@ export default function createServer(root = '', conf = {}) { res.setHeader('content-length', Buffer.byteLength(code)) res.writeHead(200, 'OK') - res.end(code + '') + res.end(code) } }) .listen(conf.port) diff --git a/lib/index.js b/lib/index.js deleted file mode 100644 index 5878d34..0000000 --- a/lib/index.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * {vue live开发环境} - * @author yutent - * @date 2022/08/31 18:00:37 - */ - -import createServer from './dev.js' -import compile from './prod.js' - -export { createServer, compile } diff --git a/package.json b/package.json index 722eeaa..5abc1ff 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "name": "@bytedo/vue-live", "type": "module", + "version": "0.0.1", "dependencies": { "iofs": "^1.5.2", "@bytedo/sass": "^1.54.8"