From 091e6d67bfcc215227d78be578c68ead542481ad Mon Sep 17 00:00:00 2001 From: Evan You Date: Mon, 26 Apr 2021 11:46:29 -0400 Subject: [PATCH] feat(config): support configuring runtime compiler via `app.config.compilerOptions` - `config.isCustomElement` is deprecated - use `app.config.compilerOptions.isCustomElement` instead. --- packages/runtime-core/src/apiCreateApp.ts | 23 +++++++++++++-- packages/runtime-core/src/component.ts | 18 +++++++----- packages/runtime-dom/src/index.ts | 35 +++++++++++++++++------ packages/template-explorer/src/options.ts | 27 +++++++++++++++++ 4 files changed, 85 insertions(+), 18 deletions(-) diff --git a/packages/runtime-core/src/apiCreateApp.ts b/packages/runtime-core/src/apiCreateApp.ts index 53bb6b1aa..a2987e388 100644 --- a/packages/runtime-core/src/apiCreateApp.ts +++ b/packages/runtime-core/src/apiCreateApp.ts @@ -69,7 +69,6 @@ export interface AppConfig { performance: boolean optionMergeStrategies: Record globalProperties: Record - isCustomElement: (tag: string) => boolean errorHandler?: ( err: unknown, instance: ComponentPublicInstance | null, @@ -80,6 +79,22 @@ export interface AppConfig { instance: ComponentPublicInstance | null, trace: string ) => void + + /** + * @deprecated use config.compilerOptions.isCustomElement + */ + isCustomElement?: (tag: string) => boolean + + /** + * Options to pass to @vue/compiler-dom. + * *Only supported in runtime compiler build.* + */ + compilerOptions: { + isCustomElement: (tag: string) => boolean + whitespace?: 'preserve' | 'condense' + comments?: boolean + delimiters?: [string, string] + } } export interface AppContext { @@ -122,9 +137,11 @@ export function createAppContext(): AppContext { performance: false, globalProperties: {}, optionMergeStrategies: {}, - isCustomElement: NO, errorHandler: undefined, - warnHandler: undefined + warnHandler: undefined, + compilerOptions: { + isCustomElement: NO + } }, mixins: [], components: {}, diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts index 83ee02ea5..ee817d6ca 100644 --- a/packages/runtime-core/src/component.ts +++ b/packages/runtime-core/src/component.ts @@ -727,18 +727,22 @@ export function finishComponentSetup( if (__DEV__) { startMeasure(instance, `compile`) } - const compilerOptions: CompilerOptions = { - isCustomElement: instance.appContext.config.isCustomElement, - delimiters: Component.delimiters - } + const { isCustomElement, compilerOptions } = instance.appContext.config + const finalCompilerOptions: CompilerOptions = extend( + { + isCustomElement: isCustomElement || NO, + delimiters: Component.delimiters + }, + compilerOptions + ) if (__COMPAT__) { // pass runtime compat config into the compiler - compilerOptions.compatConfig = Object.create(globalCompatConfig) + finalCompilerOptions.compatConfig = Object.create(globalCompatConfig) if (Component.compatConfig) { - extend(compilerOptions.compatConfig, Component.compatConfig) + extend(finalCompilerOptions.compatConfig, Component.compatConfig) } } - Component.render = compile(template, compilerOptions) + Component.render = compile(template, finalCompilerOptions) if (__DEV__) { endMeasure(instance, `compile`) } diff --git a/packages/runtime-dom/src/index.ts b/packages/runtime-dom/src/index.ts index 780152aa5..2ad8f2b21 100644 --- a/packages/runtime-dom/src/index.ts +++ b/packages/runtime-dom/src/index.ts @@ -58,7 +58,7 @@ export const createApp = ((...args) => { if (__DEV__) { injectNativeTagCheck(app) - injectCustomElementCheck(app) + injectCompilerOptionsCheck(app) } const { mount } = app @@ -106,7 +106,7 @@ export const createSSRApp = ((...args) => { if (__DEV__) { injectNativeTagCheck(app) - injectCustomElementCheck(app) + injectCompilerOptionsCheck(app) } const { mount } = app @@ -130,21 +130,40 @@ function injectNativeTagCheck(app: App) { } // dev only -function injectCustomElementCheck(app: App) { +function injectCompilerOptionsCheck(app: App) { if (isRuntimeOnly()) { - const value = app.config.isCustomElement + const isCustomElement = app.config.isCustomElement Object.defineProperty(app.config, 'isCustomElement', { get() { - return value + return isCustomElement }, set() { warn( - `The \`isCustomElement\` config option is only respected when using the runtime compiler.` + - `If you are using the runtime-only build, \`isCustomElement\` must be passed to \`@vue/compiler-dom\` in the build setup instead` + - `- for example, via the \`compilerOptions\` option in vue-loader: https://vue-loader.vuejs.org/options.html#compileroptions.` + `The \`isCustomElement\` config option is deprecated. Use ` + + `\`compilerOptions.isCustomElement\` instead.` ) } }) + + const compilerOptions = app.config.compilerOptions + const msg = + `The \`compilerOptions\` config option is only respected when using ` + + `a build of Vue.js that includes the runtime compiler (aka "full build"). ` + + `Since you are using the runtime-only build, \`compilerOptions\` ` + + `must be passed to \`@vue/compiler-dom\` in the build setup instead.\n` + + `- For vue-loader: pass it via vue-loader's \`compilerOptions\` loader option.\n` + + `- For vue-cli: see https://cli.vuejs.org/guide/webpack.html#modifying-options-of-a-loader\n` + + `- For vite: pass it via @vitejs/plugin-vue options. See https://github.com/vitejs/vite/tree/main/packages/plugin-vue#example-for-passing-options-to-vuecompiler-dom` + + Object.defineProperty(app.config, 'compilerOptions', { + get() { + warn(msg) + return compilerOptions + }, + set() { + warn(msg) + } + }) } } diff --git a/packages/template-explorer/src/options.ts b/packages/template-explorer/src/options.ts index e7b56fcce..f757a7118 100644 --- a/packages/template-explorer/src/options.ts +++ b/packages/template-explorer/src/options.ts @@ -14,6 +14,7 @@ export const compilerOptions: CompilerOptions = reactive({ inline: false, ssrCssVars: `{ color }`, compatConfig: { MODE: 3 }, + whitespace: 'condense', bindingMetadata: { TestComponent: BindingTypes.SETUP_CONST, setupRef: BindingTypes.SETUP_REF, @@ -83,6 +84,32 @@ const App = { h('label', { for: 'mode-function' }, 'function') ]), + // whitespace handling + h('li', { id: 'whitespace' }, [ + h('span', { class: 'label' }, 'whitespace: '), + h('input', { + type: 'radio', + id: 'whitespace-condense', + name: 'whitespace', + checked: compilerOptions.whitespace === 'condense', + onChange() { + compilerOptions.whitespace = 'condense' + } + }), + h('label', { for: 'whitespace-condense' }, 'condense'), + ' ', + h('input', { + type: 'radio', + id: 'whitespace-preserve', + name: 'whitespace', + checked: compilerOptions.whitespace === 'preserve', + onChange() { + compilerOptions.whitespace = 'preserve' + } + }), + h('label', { for: 'whitespace-preserve' }, 'preserve') + ]), + // SSR h('li', [ h('input', {