diff --git a/packages/client/src/index.ts b/packages/client/src/index.ts index 8e7623f4..c6fccdd5 100644 --- a/packages/client/src/index.ts +++ b/packages/client/src/index.ts @@ -34,10 +34,10 @@ export async function buildExtension(root: string, config: UserConfig = {}) { rollupOptions: { makeAbsoluteExternalsRelative: true, external: [ - root + '/vue.js', - root + '/vue-router.js', - root + '/vueuse.js', - root + '/client.js', + 'vue', + 'vue-router', + '@vueuse/core', + '@koishijs/client', ], output: { format: 'iife', @@ -57,12 +57,8 @@ export async function buildExtension(root: string, config: UserConfig = {}) { ], resolve: { alias: { - 'vue': root + '/vue.js', - 'vue-i18n': root + '/client.js', - 'vue-router': root + '/vue-router.js', - '@vueuse/core': root + '/vueuse.js', - '@koishijs/client': root + '/client.js', - '@koishijs/components': root + '/client.js', + 'vue-i18n': '@koishijs/client', + '@koishijs/components': '@koishijs/client', }, }, define: { @@ -78,6 +74,7 @@ export async function buildExtension(root: string, config: UserConfig = {}) { } else { const result = await transformWithEsbuild(item.code, dest, { minifyWhitespace: true, + charset: 'utf8', }) await fsp.writeFile(dest, result.code) } diff --git a/packages/client/src/yakumo.ts b/packages/client/src/yakumo.ts index 173a9719..04c19fd3 100644 --- a/packages/client/src/yakumo.ts +++ b/packages/client/src/yakumo.ts @@ -10,6 +10,8 @@ declare module 'yakumo' { } } +export const inject = ['yakumo'] + export function apply(ctx: Context) { ctx.register('client', async () => { const paths = ctx.yakumo.locate(ctx.yakumo.argv._) diff --git a/plugins/console/src/node/index.ts b/plugins/console/src/node/index.ts index 828465d4..d4415127 100644 --- a/plugins/console/src/node/index.ts +++ b/plugins/console/src/node/index.ts @@ -127,24 +127,48 @@ class NodeConsole extends Console { if (ctx.path === uiPath && !uiPath.endsWith('/')) { return ctx.redirect(ctx.path + '/') } + const name = ctx.path.slice(uiPath.length).replace(/^\/+/, '') const sendFile = (filename: string) => { ctx.type = extname(filename) return ctx.body = createReadStream(filename) } + if (name.startsWith('@plugin-')) { const [key] = name.slice(8).split('/', 1) if (this.entries[key]) { const files = makeArray(this.getFiles(this.entries[key].files)) - return sendFile(files[0] + name.slice(8 + key.length)) + const filename = files[0] + name.slice(8 + key.length) + ctx.type = extname(filename) + if (this.config.devMode || ctx.type !== 'application/javascript') { + return sendFile(filename) + } + + // we only transform js imports in production mode + let source = await fsp.readFile(filename, 'utf8') + let output = '' + let cap: RegExpExecArray + while ((cap = /^(import\b[^'"]+\bfrom\s*)(['"])([^'"]+)\2;/.exec(source))) { + const [stmt, left, quote, path] = cap + output += left + quote + ({ + 'vue': '../vue.js', + 'vue-router': '../vue-router.js', + '@vueuse/core': '../vueuse.js', + '@koishijs/client': '../client.js', + }[path] ?? path) + quote + ';' + source = source.slice(cap.index + stmt.length) + } + return ctx.body = output + source } else { return ctx.status = 404 } } + const filename = resolve(this.root, name) if (!filename.startsWith(this.root) && !filename.includes('node_modules')) { return ctx.status = 403 } + const stats = await fsp.stat(filename).catch(noop) if (stats?.isFile()) return sendFile(filename) const template = await fsp.readFile(resolve(this.root, 'index.html'), 'utf8') @@ -198,6 +222,7 @@ class NodeConsole extends Console { resolve: { dedupe: ['vue', 'vue-demi', 'vue-router', 'element-plus', '@vueuse/core', '@popperjs/core', 'marked', 'xss'], alias: { + // for backward compatibility '../client.js': '@koishijs/client', '../vue.js': 'vue', '../vue-router.js': 'vue-router', diff --git a/yakumo.yml b/yakumo.yml index 53c214de..a93854df 100644 --- a/yakumo.yml +++ b/yakumo.yml @@ -9,6 +9,5 @@ - tsc --clean - name: yakumo-esbuild - name: yakumo-mocha -- name: yakumo-publish-sync - name: yakumo-tsc -- name: '@koishijs/client/lib/yakumo' +- name: '@koishijs/client/lib/yakumo.js'