Skip to content

Commit 091e6d6

Browse files
committed
feat(config): support configuring runtime compiler via app.config.compilerOptions
- `config.isCustomElement` is deprecated - use `app.config.compilerOptions.isCustomElement` instead.
1 parent b047a08 commit 091e6d6

File tree

4 files changed

+85
-18
lines changed

4 files changed

+85
-18
lines changed

packages/runtime-core/src/apiCreateApp.ts

+20-3
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ export interface AppConfig {
6969
performance: boolean
7070
optionMergeStrategies: Record<string, OptionMergeFunction>
7171
globalProperties: Record<string, any>
72-
isCustomElement: (tag: string) => boolean
7372
errorHandler?: (
7473
err: unknown,
7574
instance: ComponentPublicInstance | null,
@@ -80,6 +79,22 @@ export interface AppConfig {
8079
instance: ComponentPublicInstance | null,
8180
trace: string
8281
) => void
82+
83+
/**
84+
* @deprecated use config.compilerOptions.isCustomElement
85+
*/
86+
isCustomElement?: (tag: string) => boolean
87+
88+
/**
89+
* Options to pass to @vue/compiler-dom.
90+
* *Only supported in runtime compiler build.*
91+
*/
92+
compilerOptions: {
93+
isCustomElement: (tag: string) => boolean
94+
whitespace?: 'preserve' | 'condense'
95+
comments?: boolean
96+
delimiters?: [string, string]
97+
}
8398
}
8499

85100
export interface AppContext {
@@ -122,9 +137,11 @@ export function createAppContext(): AppContext {
122137
performance: false,
123138
globalProperties: {},
124139
optionMergeStrategies: {},
125-
isCustomElement: NO,
126140
errorHandler: undefined,
127-
warnHandler: undefined
141+
warnHandler: undefined,
142+
compilerOptions: {
143+
isCustomElement: NO
144+
}
128145
},
129146
mixins: [],
130147
components: {},

packages/runtime-core/src/component.ts

+11-7
Original file line numberDiff line numberDiff line change
@@ -727,18 +727,22 @@ export function finishComponentSetup(
727727
if (__DEV__) {
728728
startMeasure(instance, `compile`)
729729
}
730-
const compilerOptions: CompilerOptions = {
731-
isCustomElement: instance.appContext.config.isCustomElement,
732-
delimiters: Component.delimiters
733-
}
730+
const { isCustomElement, compilerOptions } = instance.appContext.config
731+
const finalCompilerOptions: CompilerOptions = extend(
732+
{
733+
isCustomElement: isCustomElement || NO,
734+
delimiters: Component.delimiters
735+
},
736+
compilerOptions
737+
)
734738
if (__COMPAT__) {
735739
// pass runtime compat config into the compiler
736-
compilerOptions.compatConfig = Object.create(globalCompatConfig)
740+
finalCompilerOptions.compatConfig = Object.create(globalCompatConfig)
737741
if (Component.compatConfig) {
738-
extend(compilerOptions.compatConfig, Component.compatConfig)
742+
extend(finalCompilerOptions.compatConfig, Component.compatConfig)
739743
}
740744
}
741-
Component.render = compile(template, compilerOptions)
745+
Component.render = compile(template, finalCompilerOptions)
742746
if (__DEV__) {
743747
endMeasure(instance, `compile`)
744748
}

packages/runtime-dom/src/index.ts

+27-8
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export const createApp = ((...args) => {
5858

5959
if (__DEV__) {
6060
injectNativeTagCheck(app)
61-
injectCustomElementCheck(app)
61+
injectCompilerOptionsCheck(app)
6262
}
6363

6464
const { mount } = app
@@ -106,7 +106,7 @@ export const createSSRApp = ((...args) => {
106106

107107
if (__DEV__) {
108108
injectNativeTagCheck(app)
109-
injectCustomElementCheck(app)
109+
injectCompilerOptionsCheck(app)
110110
}
111111

112112
const { mount } = app
@@ -130,21 +130,40 @@ function injectNativeTagCheck(app: App) {
130130
}
131131

132132
// dev only
133-
function injectCustomElementCheck(app: App) {
133+
function injectCompilerOptionsCheck(app: App) {
134134
if (isRuntimeOnly()) {
135-
const value = app.config.isCustomElement
135+
const isCustomElement = app.config.isCustomElement
136136
Object.defineProperty(app.config, 'isCustomElement', {
137137
get() {
138-
return value
138+
return isCustomElement
139139
},
140140
set() {
141141
warn(
142-
`The \`isCustomElement\` config option is only respected when using the runtime compiler.` +
143-
`If you are using the runtime-only build, \`isCustomElement\` must be passed to \`@vue/compiler-dom\` in the build setup instead` +
144-
`- for example, via the \`compilerOptions\` option in vue-loader: https://vue-loader.vuejs.org/options.html#compileroptions.`
142+
`The \`isCustomElement\` config option is deprecated. Use ` +
143+
`\`compilerOptions.isCustomElement\` instead.`
145144
)
146145
}
147146
})
147+
148+
const compilerOptions = app.config.compilerOptions
149+
const msg =
150+
`The \`compilerOptions\` config option is only respected when using ` +
151+
`a build of Vue.js that includes the runtime compiler (aka "full build"). ` +
152+
`Since you are using the runtime-only build, \`compilerOptions\` ` +
153+
`must be passed to \`@vue/compiler-dom\` in the build setup instead.\n` +
154+
`- For vue-loader: pass it via vue-loader's \`compilerOptions\` loader option.\n` +
155+
`- For vue-cli: see https://cli.vuejs.org/guide/webpack.html#modifying-options-of-a-loader\n` +
156+
`- 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`
157+
158+
Object.defineProperty(app.config, 'compilerOptions', {
159+
get() {
160+
warn(msg)
161+
return compilerOptions
162+
},
163+
set() {
164+
warn(msg)
165+
}
166+
})
148167
}
149168
}
150169

packages/template-explorer/src/options.ts

+27
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export const compilerOptions: CompilerOptions = reactive({
1414
inline: false,
1515
ssrCssVars: `{ color }`,
1616
compatConfig: { MODE: 3 },
17+
whitespace: 'condense',
1718
bindingMetadata: {
1819
TestComponent: BindingTypes.SETUP_CONST,
1920
setupRef: BindingTypes.SETUP_REF,
@@ -83,6 +84,32 @@ const App = {
8384
h('label', { for: 'mode-function' }, 'function')
8485
]),
8586

87+
// whitespace handling
88+
h('li', { id: 'whitespace' }, [
89+
h('span', { class: 'label' }, 'whitespace: '),
90+
h('input', {
91+
type: 'radio',
92+
id: 'whitespace-condense',
93+
name: 'whitespace',
94+
checked: compilerOptions.whitespace === 'condense',
95+
onChange() {
96+
compilerOptions.whitespace = 'condense'
97+
}
98+
}),
99+
h('label', { for: 'whitespace-condense' }, 'condense'),
100+
' ',
101+
h('input', {
102+
type: 'radio',
103+
id: 'whitespace-preserve',
104+
name: 'whitespace',
105+
checked: compilerOptions.whitespace === 'preserve',
106+
onChange() {
107+
compilerOptions.whitespace = 'preserve'
108+
}
109+
}),
110+
h('label', { for: 'whitespace-preserve' }, 'preserve')
111+
]),
112+
86113
// SSR
87114
h('li', [
88115
h('input', {

0 commit comments

Comments
 (0)