Skip to content

Commit 55922ff

Browse files
authored
fix(compiler-sfc): check lang before attempt to compile script (#13508)
close #8368
1 parent 1e8b65a commit 55922ff

File tree

5 files changed

+42
-18
lines changed

5 files changed

+42
-18
lines changed

packages/compiler-sfc/__tests__/compileScript.spec.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1550,4 +1550,19 @@ describe('compileScript', () => {
15501550
)
15511551
assertCode(content)
15521552
})
1553+
1554+
test('should not compile unrecognized language', () => {
1555+
const { content, lang, scriptAst } = compile(
1556+
`<script lang="coffee">
1557+
export default
1558+
data: ->
1559+
myVal: 0
1560+
</script>`,
1561+
)
1562+
expect(content).toMatch(`export default
1563+
data: ->
1564+
myVal: 0`)
1565+
expect(lang).toBe('coffee')
1566+
expect(scriptAst).not.toBeDefined()
1567+
})
15531568
})

packages/compiler-sfc/src/compileScript.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,13 @@ import { DEFINE_EXPOSE, processDefineExpose } from './script/defineExpose'
5656
import { DEFINE_OPTIONS, processDefineOptions } from './script/defineOptions'
5757
import { DEFINE_SLOTS, processDefineSlots } from './script/defineSlots'
5858
import { DEFINE_MODEL, processDefineModel } from './script/defineModel'
59-
import { getImportedName, isCallOf, isLiteralNode } from './script/utils'
59+
import {
60+
getImportedName,
61+
isCallOf,
62+
isJS,
63+
isLiteralNode,
64+
isTS,
65+
} from './script/utils'
6066
import { analyzeScriptBindings } from './script/analyzeScriptBindings'
6167
import { isImportUsed } from './script/importUsageCheck'
6268
import { processAwait } from './script/topLevelAwait'
@@ -173,6 +179,8 @@ export function compileScript(
173179
const scopeId = options.id ? options.id.replace(/^data-v-/, '') : ''
174180
const scriptLang = script && script.lang
175181
const scriptSetupLang = scriptSetup && scriptSetup.lang
182+
const isJSOrTS =
183+
isJS(scriptLang, scriptSetupLang) || isTS(scriptLang, scriptSetupLang)
176184

177185
if (script && scriptSetup && scriptLang !== scriptSetupLang) {
178186
throw new Error(
@@ -181,21 +189,28 @@ export function compileScript(
181189
)
182190
}
183191

184-
const ctx = new ScriptCompileContext(sfc, options)
185-
186192
if (!scriptSetup) {
187193
if (!script) {
188194
throw new Error(`[@vue/compiler-sfc] SFC contains no <script> tags.`)
189195
}
196+
190197
// normal <script> only
198+
if (script.lang && !isJSOrTS) {
199+
// do not process non js/ts script blocks
200+
return script
201+
}
202+
203+
const ctx = new ScriptCompileContext(sfc, options)
191204
return processNormalScript(ctx, scopeId)
192205
}
193206

194-
if (scriptSetupLang && !ctx.isJS && !ctx.isTS) {
207+
if (scriptSetupLang && !isJSOrTS) {
195208
// do not process non js/ts script blocks
196209
return scriptSetup
197210
}
198211

212+
const ctx = new ScriptCompileContext(sfc, options)
213+
199214
// metadata that needs to be returned
200215
// const ctx.bindingMetadata: BindingMetadata = {}
201216
const scriptBindings: Record<string, BindingTypes> = Object.create(null)

packages/compiler-sfc/src/script/context.ts

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import type { BindingMetadata } from '../../../compiler-core/src'
99
import MagicString from 'magic-string'
1010
import type { TypeScope } from './resolveType'
1111
import { warn } from '../warn'
12+
import { isJS, isTS } from './utils'
1213

1314
export class ScriptCompileContext {
1415
isJS: boolean
@@ -87,16 +88,8 @@ export class ScriptCompileContext {
8788
const scriptLang = script && script.lang
8889
const scriptSetupLang = scriptSetup && scriptSetup.lang
8990

90-
this.isJS =
91-
scriptLang === 'js' ||
92-
scriptLang === 'jsx' ||
93-
scriptSetupLang === 'js' ||
94-
scriptSetupLang === 'jsx'
95-
this.isTS =
96-
scriptLang === 'ts' ||
97-
scriptLang === 'tsx' ||
98-
scriptSetupLang === 'ts' ||
99-
scriptSetupLang === 'tsx'
91+
this.isJS = isJS(scriptLang, scriptSetupLang)
92+
this.isTS = isTS(scriptLang, scriptSetupLang)
10093

10194
const customElement = options.customElement
10295
const filename = this.descriptor.filename

packages/compiler-sfc/src/script/normalScript.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@ export function processNormalScript(
1212
scopeId: string,
1313
): SFCScriptBlock {
1414
const script = ctx.descriptor.script!
15-
if (script.lang && !ctx.isJS && !ctx.isTS) {
16-
// do not process non js/ts script blocks
17-
return script
18-
}
1915
try {
2016
let content = script.content
2117
let map = script.map

packages/compiler-sfc/src/script/utils.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,8 @@ export const propNameEscapeSymbolsRE: RegExp =
121121
export function getEscapedPropName(key: string): string {
122122
return propNameEscapeSymbolsRE.test(key) ? JSON.stringify(key) : key
123123
}
124+
125+
export const isJS = (...langs: (string | null | undefined)[]): boolean =>
126+
langs.some(lang => lang === 'js' || lang === 'jsx')
127+
export const isTS = (...langs: (string | null | undefined)[]): boolean =>
128+
langs.some(lang => lang === 'ts' || lang === 'tsx')

0 commit comments

Comments
 (0)