From fda2c9bdb78a00f7ffc9868111ae9083773071dd Mon Sep 17 00:00:00 2001 From: likui <2218301630@qq.com> Date: Wed, 1 Jul 2020 10:53:19 +0800 Subject: [PATCH 1/7] feat: custom template compiler for sfc close #480 --- src/node/config.ts | 5 +++++ src/node/server/serverPluginVue.ts | 28 +++++++++++++++++++++++----- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/node/config.ts b/src/node/config.ts index 3a2fd3317cb0fe..829b049226b6d2 100644 --- a/src/node/config.ts +++ b/src/node/config.ts @@ -18,6 +18,7 @@ import { DepOptimizationOptions } from './optimizer' import { IKoaProxiesOptions } from 'koa-proxies' import { ServerOptions } from 'https' import { lookupFile } from './utils' +import { TemplateCompilerOptions } from './server/serverPluginVue' export { Resolver, Transform } @@ -80,6 +81,10 @@ export interface SharedConfig { * https://github.com/vuejs/vue-next/blob/master/packages/compiler-core/src/options.ts */ vueCompilerOptions?: CompilerOptions + /** + * Customer template compiler. + */ + templateCompilers?: Record<string, TemplateCompilerOptions> /** * Transform functions for Vue custom blocks. * diff --git a/src/node/server/serverPluginVue.ts b/src/node/server/serverPluginVue.ts index 61094f2cd7fd8e..8730c972e094e8 100644 --- a/src/node/server/serverPluginVue.ts +++ b/src/node/server/serverPluginVue.ts @@ -1,7 +1,7 @@ import qs from 'querystring' import chalk from 'chalk' import path from 'path' -import { Context, ServerPlugin } from '.' +import { Context, ServerPlugin, ServerPluginContext } from '.' import { SFCBlock, SFCDescriptor, @@ -9,7 +9,8 @@ import { SFCStyleBlock, SFCStyleCompileResults, CompilerOptions, - SFCStyleCompileOptions + SFCStyleCompileOptions, + TemplateCompiler } from '@vue/compiler-sfc' import { resolveCompiler, resolveVue } from '../utils/resolveVue' import hash_sum from 'hash-sum' @@ -124,7 +125,7 @@ export const vuePlugin: ServerPlugin = ({ filePath, publicPath, descriptor.styles.some((s) => s.scoped), - config.vueCompilerOptions + config ) ctx.body = code ctx.map = map @@ -498,13 +499,15 @@ async function compileSFCMain( return result } +export type TemplateCompilerOptions = [TemplateCompiler, CompilerOptions] + function compileSFCTemplate( root: string, template: SFCTemplateBlock, filePath: string, publicPath: string, scoped: boolean, - userOptions: CompilerOptions | undefined + { vueCompilerOptions, templateCompilers = {} }: ServerPluginContext['config'] ): ResultWithMap { let cached = vueCache.get(filePath) if (cached && cached.template) { @@ -512,6 +515,19 @@ function compileSFCTemplate( return cached.template } + const compilerKey = (template as any).compiler + let compiler + let compilerOptions = {} + if (compilerKey) { + if (templateCompilers[compilerKey]) { + ;[compiler, compilerOptions] = templateCompilers[compilerKey] + } else { + console.error( + `The "${compilerKey}" compiler not found.Please add "templateCompilers" options.` + ) + } + } + const start = Date.now() const { compileTemplate, generateCodeFrame } = resolveCompiler(root) const { code, map, errors } = compileTemplate({ @@ -521,8 +537,10 @@ function compileSFCTemplate( transformAssetUrls: { base: path.posix.dirname(publicPath) }, + compiler: compiler, compilerOptions: { - ...userOptions, + ...vueCompilerOptions, + ...compilerOptions, scopeId: scoped ? `data-v-${hash_sum(publicPath)}` : null, runtimeModuleName: resolveVue(root).isLocal ? // in local mode, vue would have been optimized so must be referenced From 74e47edfaf64c074c6707f2d668e5eaf3ddee5d6 Mon Sep 17 00:00:00 2001 From: likui <2218301630@qq.com> Date: Wed, 1 Jul 2020 11:26:31 +0800 Subject: [PATCH 2/7] fix: add global template compiler option --- src/node/config.ts | 12 ++++++++++-- src/node/server/serverPluginVue.ts | 9 ++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/node/config.ts b/src/node/config.ts index 829b049226b6d2..385e7cb1a40bd2 100644 --- a/src/node/config.ts +++ b/src/node/config.ts @@ -4,7 +4,11 @@ import chalk from 'chalk' import dotenv, { DotenvParseOutput } from 'dotenv' import dotenvExpand from 'dotenv-expand' import { Options as RollupPluginVueOptions } from 'rollup-plugin-vue' -import { CompilerOptions, SFCStyleCompileOptions } from '@vue/compiler-sfc' +import { + CompilerOptions, + SFCStyleCompileOptions, + TemplateCompiler +} from '@vue/compiler-sfc' import Rollup, { InputOptions as RollupInputOptions, OutputOptions as RollupOutputOptions, @@ -82,7 +86,11 @@ export interface SharedConfig { */ vueCompilerOptions?: CompilerOptions /** - * Customer template compiler. + * Customer template compiler for global sfc template block. + */ + compiler?: TemplateCompiler + /** + * Customer template compiler for special sfc template block. */ templateCompilers?: Record<string, TemplateCompilerOptions> /** diff --git a/src/node/server/serverPluginVue.ts b/src/node/server/serverPluginVue.ts index 8730c972e094e8..f12ad077ea54fe 100644 --- a/src/node/server/serverPluginVue.ts +++ b/src/node/server/serverPluginVue.ts @@ -507,7 +507,11 @@ function compileSFCTemplate( filePath: string, publicPath: string, scoped: boolean, - { vueCompilerOptions, templateCompilers = {} }: ServerPluginContext['config'] + { + vueCompilerOptions, + templateCompilers = {}, + compiler + }: ServerPluginContext['config'] ): ResultWithMap { let cached = vueCache.get(filePath) if (cached && cached.template) { @@ -516,7 +520,6 @@ function compileSFCTemplate( } const compilerKey = (template as any).compiler - let compiler let compilerOptions = {} if (compilerKey) { if (templateCompilers[compilerKey]) { @@ -537,7 +540,7 @@ function compileSFCTemplate( transformAssetUrls: { base: path.posix.dirname(publicPath) }, - compiler: compiler, + compiler, compilerOptions: { ...vueCompilerOptions, ...compilerOptions, From 4cefde4562d24218946485ffceaf6fac1f23f24a Mon Sep 17 00:00:00 2001 From: likui <2218301630@qq.com> Date: Wed, 1 Jul 2020 11:30:03 +0800 Subject: [PATCH 3/7] refactor: reduce various --- src/node/server/serverPluginVue.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/node/server/serverPluginVue.ts b/src/node/server/serverPluginVue.ts index f12ad077ea54fe..893db2693c33df 100644 --- a/src/node/server/serverPluginVue.ts +++ b/src/node/server/serverPluginVue.ts @@ -509,7 +509,7 @@ function compileSFCTemplate( scoped: boolean, { vueCompilerOptions, - templateCompilers = {}, + templateCompilers, compiler }: ServerPluginContext['config'] ): ResultWithMap { @@ -520,10 +520,9 @@ function compileSFCTemplate( } const compilerKey = (template as any).compiler - let compilerOptions = {} if (compilerKey) { - if (templateCompilers[compilerKey]) { - ;[compiler, compilerOptions] = templateCompilers[compilerKey] + if (templateCompilers && templateCompilers[compilerKey]) { + ;[compiler, vueCompilerOptions] = templateCompilers[compilerKey] } else { console.error( `The "${compilerKey}" compiler not found.Please add "templateCompilers" options.` @@ -543,7 +542,6 @@ function compileSFCTemplate( compiler, compilerOptions: { ...vueCompilerOptions, - ...compilerOptions, scopeId: scoped ? `data-v-${hash_sum(publicPath)}` : null, runtimeModuleName: resolveVue(root).isLocal ? // in local mode, vue would have been optimized so must be referenced From 3eca973af8ef9c257da6b832603a9b02aa34963b Mon Sep 17 00:00:00 2001 From: likui <2218301630@qq.com> Date: Wed, 1 Jul 2020 11:34:09 +0800 Subject: [PATCH 4/7] fix: add miss default value for `vueCompilerOptions` --- src/node/server/serverPluginVue.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node/server/serverPluginVue.ts b/src/node/server/serverPluginVue.ts index 893db2693c33df..8ef992739bc3f7 100644 --- a/src/node/server/serverPluginVue.ts +++ b/src/node/server/serverPluginVue.ts @@ -508,7 +508,7 @@ function compileSFCTemplate( publicPath: string, scoped: boolean, { - vueCompilerOptions, + vueCompilerOptions = {}, templateCompilers, compiler }: ServerPluginContext['config'] From 77a6f6aab6d8943e889609bc255dd3ed02e84fdb Mon Sep 17 00:00:00 2001 From: likui <2218301630@qq.com> Date: Wed, 1 Jul 2020 11:44:01 +0800 Subject: [PATCH 5/7] fix: read compiler form block attr --- src/node/server/serverPluginVue.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node/server/serverPluginVue.ts b/src/node/server/serverPluginVue.ts index 8ef992739bc3f7..0376f3f8860e59 100644 --- a/src/node/server/serverPluginVue.ts +++ b/src/node/server/serverPluginVue.ts @@ -519,7 +519,7 @@ function compileSFCTemplate( return cached.template } - const compilerKey = (template as any).compiler + const compilerKey = template.attrs.compiler as string if (compilerKey) { if (templateCompilers && templateCompilers[compilerKey]) { ;[compiler, vueCompilerOptions] = templateCompilers[compilerKey] From 7ca7653519abb68da7843d5a26ee8cf99bfd1694 Mon Sep 17 00:00:00 2001 From: likui <2218301630@qq.com> Date: Thu, 2 Jul 2020 11:50:05 +0800 Subject: [PATCH 6/7] fix: fix some error and add test --- playground/App.vue | 5 ++- .../test-custom-compiler.vue | 9 ++++++ playground/vite.config.ts | 13 ++++++++ src/node/build/index.ts | 2 ++ src/node/config.ts | 11 +++++-- src/node/server/serverPluginVue.ts | 31 +++++++++++++------ test/test.js | 7 +++++ 7 files changed, 64 insertions(+), 14 deletions(-) create mode 100644 playground/test-custom-compiler/test-custom-compiler.vue diff --git a/playground/App.vue b/playground/App.vue index e8390c1ba05002..c5443c025e93b0 100644 --- a/playground/App.vue +++ b/playground/App.vue @@ -27,6 +27,7 @@ <Suspense> <TestWasm /> </Suspense> + <TestCustomCompiler/> </template> <script> @@ -54,6 +55,7 @@ import TestRewriteOptimized from './resolve/rewrite-optimized/TestRewriteOptimiz import TestDynamicImport from './dynamic-import/TestDynamicImport.vue' import TestWebWorker from './worker/TestWorker.vue' import TestWasm from './wasm/TestWasm.vue' +import TestCustomCompiler from './test-custom-compiler/test-custom-compiler.vue' export default { components: { @@ -80,7 +82,8 @@ export default { TestNormalizePublicPath, TestDynamicImport, TestWebWorker, - TestWasm + TestWasm, + TestCustomCompiler } } </script> diff --git a/playground/test-custom-compiler/test-custom-compiler.vue b/playground/test-custom-compiler/test-custom-compiler.vue new file mode 100644 index 00000000000000..4baac5e135b1ef --- /dev/null +++ b/playground/test-custom-compiler/test-custom-compiler.vue @@ -0,0 +1,9 @@ +<template compiler="custom"> + <div>111</div> +</template> + +<script> + export default { + name: "test-customer-compiler" + } +</script> diff --git a/playground/vite.config.ts b/playground/vite.config.ts index 3f8df559084933..e924b7cf8d6454 100644 --- a/playground/vite.config.ts +++ b/playground/vite.config.ts @@ -2,6 +2,16 @@ import type { UserConfig } from 'vite' import { jsPlugin } from './plugins/jsPlugin' import { i18nTransform } from './custom-blocks/i18nTransform' +const customCompiler = { + compile: () => { + return { + code: `import {h} from '/@modules/vue'\n export function render () { return [[h('h2', 'Custom Compiler'), h('div', {class: 'custom-compiler'}, 'custom compiler works!')]]}`, + ast: null + } + }, + parse: () => null +} + const config: UserConfig = { alias: { alias: '/alias/aliased', @@ -11,6 +21,9 @@ const config: UserConfig = { minify: false, serviceWorker: !!process.env.USE_SW, plugins: [jsPlugin], + vueTemplateCompilers: { + custom: customCompiler + }, vueCustomBlockTransforms: { i18n: i18nTransform }, optimizeDeps: { exclude: ['bootstrap', 'rewrite-unoptimized-test-package'], diff --git a/src/node/build/index.ts b/src/node/build/index.ts index d8d41710fc2af1..d8cc5ac7671eac 100644 --- a/src/node/build/index.ts +++ b/src/node/build/index.ts @@ -123,7 +123,9 @@ export async function createBaseRollupPlugins( ...cssPreprocessOptions }, preprocessCustomRequire: (id: string) => require(resolveFrom(root, id)), + compiler: options.vueCompiler, compilerOptions: options.vueCompilerOptions, + templateCompilers: options.vueTemplateCompilers, cssModulesOptions: { generateScopedName: (local: string, filename: string) => `${local}_${hash_sum(filename)}`, diff --git a/src/node/config.ts b/src/node/config.ts index 385e7cb1a40bd2..f1114a9d27a56f 100644 --- a/src/node/config.ts +++ b/src/node/config.ts @@ -22,7 +22,7 @@ import { DepOptimizationOptions } from './optimizer' import { IKoaProxiesOptions } from 'koa-proxies' import { ServerOptions } from 'https' import { lookupFile } from './utils' -import { TemplateCompilerOptions } from './server/serverPluginVue' +import { TemplateCompilers } from './server/serverPluginVue' export { Resolver, Transform } @@ -88,11 +88,11 @@ export interface SharedConfig { /** * Customer template compiler for global sfc template block. */ - compiler?: TemplateCompiler + vueCompiler?: TemplateCompiler /** * Customer template compiler for special sfc template block. */ - templateCompilers?: Record<string, TemplateCompilerOptions> + vueTemplateCompilers?: Record<string, TemplateCompilers> /** * Transform functions for Vue custom blocks. * @@ -288,6 +288,7 @@ export interface Plugin | 'transforms' | 'resolvers' | 'configureServer' + | 'vueTemplateCompilers' | 'vueCompilerOptions' | 'vueCustomBlockTransforms' | 'rollupInputOptions' @@ -443,6 +444,10 @@ function resolvePlugin(config: UserConfig, plugin: Plugin): UserConfig { config.configureServer || [], plugin.configureServer || [] ), + vueTemplateCompilers: { + ...config.vueTemplateCompilers, + ...plugin.vueTemplateCompilers + }, vueCompilerOptions: { ...config.vueCompilerOptions, ...plugin.vueCompilerOptions diff --git a/src/node/server/serverPluginVue.ts b/src/node/server/serverPluginVue.ts index 0376f3f8860e59..05f74db0f259f3 100644 --- a/src/node/server/serverPluginVue.ts +++ b/src/node/server/serverPluginVue.ts @@ -499,7 +499,9 @@ async function compileSFCMain( return result } -export type TemplateCompilerOptions = [TemplateCompiler, CompilerOptions] +export type TemplateCompilers = + | TemplateCompiler + | [TemplateCompiler, CompilerOptions] function compileSFCTemplate( root: string, @@ -509,8 +511,8 @@ function compileSFCTemplate( scoped: boolean, { vueCompilerOptions = {}, - templateCompilers, - compiler + vueTemplateCompilers, + vueCompiler }: ServerPluginContext['config'] ): ResultWithMap { let cached = vueCache.get(filePath) @@ -519,14 +521,23 @@ function compileSFCTemplate( return cached.template } - const compilerKey = template.attrs.compiler as string + const compilerKey = template.attrs.compiler if (compilerKey) { - if (templateCompilers && templateCompilers[compilerKey]) { - ;[compiler, vueCompilerOptions] = templateCompilers[compilerKey] + if (typeof compilerKey === 'string') { + if (vueTemplateCompilers && vueTemplateCompilers[compilerKey]) { + const compilers = vueTemplateCompilers[compilerKey] + if (Array.isArray(compilers)) { + ;[vueCompiler, vueCompilerOptions] = compilers + } else { + vueCompiler = compilers + } + } else { + console.error( + `The "${compilerKey}" compiler not found.Please add "vueTemplateCompilers" options.` + ) + } } else { - console.error( - `The "${compilerKey}" compiler not found.Please add "templateCompilers" options.` - ) + console.error(`Please ensure custom template compiler in ${filePath}`) } } @@ -539,7 +550,7 @@ function compileSFCTemplate( transformAssetUrls: { base: path.posix.dirname(publicPath) }, - compiler, + compiler: vueCompiler, compilerOptions: { ...vueCompilerOptions, scopeId: scoped ? `data-v-${hash_sum(publicPath)}` : null, diff --git a/test/test.js b/test/test.js index 97b23d43518483..d2729142fe1731 100644 --- a/test/test.js +++ b/test/test.js @@ -630,6 +630,13 @@ describe('vite', () => { await button.click() await expectByPolling(() => getText('.wasm-response'), '42') }) + + test('custom compiler', async () => { + await expectByPolling( + () => getText('.custom-compiler'), + 'custom compiler works!' + ) + }) } // test build first since we are going to edit the fixtures when testing dev From 350e3f76dbe69458eb1d52708a5c371229bc159a Mon Sep 17 00:00:00 2001 From: likui <2218301630@qq.com> Date: Thu, 2 Jul 2020 11:57:25 +0800 Subject: [PATCH 7/7] fix: fix test content --- playground/test-custom-compiler/test-custom-compiler.vue | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/playground/test-custom-compiler/test-custom-compiler.vue b/playground/test-custom-compiler/test-custom-compiler.vue index 4baac5e135b1ef..4f3ff471b2c00f 100644 --- a/playground/test-custom-compiler/test-custom-compiler.vue +++ b/playground/test-custom-compiler/test-custom-compiler.vue @@ -1,9 +1,7 @@ <template compiler="custom"> - <div>111</div> + <div></div> </template> <script> - export default { - name: "test-customer-compiler" - } + export default {} </script>