mirror of https://github.com/vuejs/core.git
fix(compiler-sfc): check lang before attempt to compile script (#13508)
close #8368
This commit is contained in:
parent
1e8b65aa49
commit
55922ff316
|
@ -1550,4 +1550,19 @@ describe('compileScript', () => {
|
||||||
)
|
)
|
||||||
assertCode(content)
|
assertCode(content)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('should not compile unrecognized language', () => {
|
||||||
|
const { content, lang, scriptAst } = compile(
|
||||||
|
`<script lang="coffee">
|
||||||
|
export default
|
||||||
|
data: ->
|
||||||
|
myVal: 0
|
||||||
|
</script>`,
|
||||||
|
)
|
||||||
|
expect(content).toMatch(`export default
|
||||||
|
data: ->
|
||||||
|
myVal: 0`)
|
||||||
|
expect(lang).toBe('coffee')
|
||||||
|
expect(scriptAst).not.toBeDefined()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -56,7 +56,13 @@ import { DEFINE_EXPOSE, processDefineExpose } from './script/defineExpose'
|
||||||
import { DEFINE_OPTIONS, processDefineOptions } from './script/defineOptions'
|
import { DEFINE_OPTIONS, processDefineOptions } from './script/defineOptions'
|
||||||
import { DEFINE_SLOTS, processDefineSlots } from './script/defineSlots'
|
import { DEFINE_SLOTS, processDefineSlots } from './script/defineSlots'
|
||||||
import { DEFINE_MODEL, processDefineModel } from './script/defineModel'
|
import { DEFINE_MODEL, processDefineModel } from './script/defineModel'
|
||||||
import { getImportedName, isCallOf, isLiteralNode } from './script/utils'
|
import {
|
||||||
|
getImportedName,
|
||||||
|
isCallOf,
|
||||||
|
isJS,
|
||||||
|
isLiteralNode,
|
||||||
|
isTS,
|
||||||
|
} from './script/utils'
|
||||||
import { analyzeScriptBindings } from './script/analyzeScriptBindings'
|
import { analyzeScriptBindings } from './script/analyzeScriptBindings'
|
||||||
import { isImportUsed } from './script/importUsageCheck'
|
import { isImportUsed } from './script/importUsageCheck'
|
||||||
import { processAwait } from './script/topLevelAwait'
|
import { processAwait } from './script/topLevelAwait'
|
||||||
|
@ -173,6 +179,8 @@ export function compileScript(
|
||||||
const scopeId = options.id ? options.id.replace(/^data-v-/, '') : ''
|
const scopeId = options.id ? options.id.replace(/^data-v-/, '') : ''
|
||||||
const scriptLang = script && script.lang
|
const scriptLang = script && script.lang
|
||||||
const scriptSetupLang = scriptSetup && scriptSetup.lang
|
const scriptSetupLang = scriptSetup && scriptSetup.lang
|
||||||
|
const isJSOrTS =
|
||||||
|
isJS(scriptLang, scriptSetupLang) || isTS(scriptLang, scriptSetupLang)
|
||||||
|
|
||||||
if (script && scriptSetup && scriptLang !== scriptSetupLang) {
|
if (script && scriptSetup && scriptLang !== scriptSetupLang) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
|
@ -181,21 +189,28 @@ export function compileScript(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const ctx = new ScriptCompileContext(sfc, options)
|
|
||||||
|
|
||||||
if (!scriptSetup) {
|
if (!scriptSetup) {
|
||||||
if (!script) {
|
if (!script) {
|
||||||
throw new Error(`[@vue/compiler-sfc] SFC contains no <script> tags.`)
|
throw new Error(`[@vue/compiler-sfc] SFC contains no <script> tags.`)
|
||||||
}
|
}
|
||||||
|
|
||||||
// normal <script> only
|
// normal <script> only
|
||||||
|
if (script.lang && !isJSOrTS) {
|
||||||
|
// do not process non js/ts script blocks
|
||||||
|
return script
|
||||||
|
}
|
||||||
|
|
||||||
|
const ctx = new ScriptCompileContext(sfc, options)
|
||||||
return processNormalScript(ctx, scopeId)
|
return processNormalScript(ctx, scopeId)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scriptSetupLang && !ctx.isJS && !ctx.isTS) {
|
if (scriptSetupLang && !isJSOrTS) {
|
||||||
// do not process non js/ts script blocks
|
// do not process non js/ts script blocks
|
||||||
return scriptSetup
|
return scriptSetup
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ctx = new ScriptCompileContext(sfc, options)
|
||||||
|
|
||||||
// metadata that needs to be returned
|
// metadata that needs to be returned
|
||||||
// const ctx.bindingMetadata: BindingMetadata = {}
|
// const ctx.bindingMetadata: BindingMetadata = {}
|
||||||
const scriptBindings: Record<string, BindingTypes> = Object.create(null)
|
const scriptBindings: Record<string, BindingTypes> = Object.create(null)
|
||||||
|
|
|
@ -9,6 +9,7 @@ import type { BindingMetadata } from '../../../compiler-core/src'
|
||||||
import MagicString from 'magic-string'
|
import MagicString from 'magic-string'
|
||||||
import type { TypeScope } from './resolveType'
|
import type { TypeScope } from './resolveType'
|
||||||
import { warn } from '../warn'
|
import { warn } from '../warn'
|
||||||
|
import { isJS, isTS } from './utils'
|
||||||
|
|
||||||
export class ScriptCompileContext {
|
export class ScriptCompileContext {
|
||||||
isJS: boolean
|
isJS: boolean
|
||||||
|
@ -87,16 +88,8 @@ export class ScriptCompileContext {
|
||||||
const scriptLang = script && script.lang
|
const scriptLang = script && script.lang
|
||||||
const scriptSetupLang = scriptSetup && scriptSetup.lang
|
const scriptSetupLang = scriptSetup && scriptSetup.lang
|
||||||
|
|
||||||
this.isJS =
|
this.isJS = isJS(scriptLang, scriptSetupLang)
|
||||||
scriptLang === 'js' ||
|
this.isTS = isTS(scriptLang, scriptSetupLang)
|
||||||
scriptLang === 'jsx' ||
|
|
||||||
scriptSetupLang === 'js' ||
|
|
||||||
scriptSetupLang === 'jsx'
|
|
||||||
this.isTS =
|
|
||||||
scriptLang === 'ts' ||
|
|
||||||
scriptLang === 'tsx' ||
|
|
||||||
scriptSetupLang === 'ts' ||
|
|
||||||
scriptSetupLang === 'tsx'
|
|
||||||
|
|
||||||
const customElement = options.customElement
|
const customElement = options.customElement
|
||||||
const filename = this.descriptor.filename
|
const filename = this.descriptor.filename
|
||||||
|
|
|
@ -12,10 +12,6 @@ export function processNormalScript(
|
||||||
scopeId: string,
|
scopeId: string,
|
||||||
): SFCScriptBlock {
|
): SFCScriptBlock {
|
||||||
const script = ctx.descriptor.script!
|
const script = ctx.descriptor.script!
|
||||||
if (script.lang && !ctx.isJS && !ctx.isTS) {
|
|
||||||
// do not process non js/ts script blocks
|
|
||||||
return script
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
let content = script.content
|
let content = script.content
|
||||||
let map = script.map
|
let map = script.map
|
||||||
|
|
|
@ -121,3 +121,8 @@ export const propNameEscapeSymbolsRE: RegExp =
|
||||||
export function getEscapedPropName(key: string): string {
|
export function getEscapedPropName(key: string): string {
|
||||||
return propNameEscapeSymbolsRE.test(key) ? JSON.stringify(key) : key
|
return propNameEscapeSymbolsRE.test(key) ? JSON.stringify(key) : key
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const isJS = (...langs: (string | null | undefined)[]): boolean =>
|
||||||
|
langs.some(lang => lang === 'js' || lang === 'jsx')
|
||||||
|
export const isTS = (...langs: (string | null | undefined)[]): boolean =>
|
||||||
|
langs.some(lang => lang === 'ts' || lang === 'tsx')
|
||||||
|
|
Loading…
Reference in New Issue