Skip to content

Commit 2975dcd

Browse files
authored
Merge branch 'minor' into bwsy/feat/compilerSearchElm
2 parents 9d1f862 + bc7698d commit 2975dcd

File tree

17 files changed

+342
-101
lines changed

17 files changed

+342
-101
lines changed

packages/compiler-core/__tests__/transform.spec.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,26 @@ describe('compiler: transform', () => {
201201
expect((ast as any).children[1].props[0].exp.content).toBe(`_hoisted_2`)
202202
})
203203

204+
test('context.filename and selfName', () => {
205+
const ast = baseParse(`<div />`)
206+
207+
const calls: any[] = []
208+
const plugin: NodeTransform = (node, context) => {
209+
calls.push({ ...context })
210+
}
211+
212+
transform(ast, {
213+
filename: '/the/fileName.vue',
214+
nodeTransforms: [plugin]
215+
})
216+
217+
expect(calls.length).toBe(2)
218+
expect(calls[1]).toMatchObject({
219+
filename: '/the/fileName.vue',
220+
selfName: 'FileName'
221+
})
222+
})
223+
204224
test('onError option', () => {
205225
const ast = baseParse(`<div/>`)
206226
const loc = ast.children[0].loc

packages/compiler-core/src/compile.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,10 @@ export function baseCompile(
8282
onError(createCompilerError(ErrorCodes.X_SCOPE_ID_NOT_SUPPORTED))
8383
}
8484

85-
const ast = isString(source) ? baseParse(source, options) : source
85+
const resolvedOptions = extend({}, options, {
86+
prefixIdentifiers
87+
})
88+
const ast = isString(source) ? baseParse(source, resolvedOptions) : source
8689
const [nodeTransforms, directiveTransforms] =
8790
getBaseTransformPreset(prefixIdentifiers)
8891

@@ -95,8 +98,7 @@ export function baseCompile(
9598

9699
transform(
97100
ast,
98-
extend({}, options, {
99-
prefixIdentifiers,
101+
extend({}, resolvedOptions, {
100102
nodeTransforms: [
101103
...nodeTransforms,
102104
...(options.nodeTransforms || []) // user transforms
@@ -109,10 +111,5 @@ export function baseCompile(
109111
})
110112
)
111113

112-
return generate(
113-
ast,
114-
extend({}, options, {
115-
prefixIdentifiers
116-
})
117-
)
114+
return generate(ast, resolvedOptions)
118115
}

packages/compiler-core/src/transform.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,7 @@ export interface ImportItem {
8383
}
8484

8585
export interface TransformContext
86-
extends Required<
87-
Omit<TransformOptions, 'filename' | keyof CompilerCompatOptions>
88-
>,
86+
extends Required<Omit<TransformOptions, keyof CompilerCompatOptions>>,
8987
CompilerCompatOptions {
9088
selfName: string | null
9189
root: RootNode
@@ -153,6 +151,7 @@ export function createTransformContext(
153151
const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/)
154152
const context: TransformContext = {
155153
// options
154+
filename,
156155
selfName: nameMatch && capitalize(camelize(nameMatch[1])),
157156
prefixIdentifiers,
158157
hoistStatic,

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,3 +1483,31 @@ _sfc_.setup = __setup__
14831483
: __injectCSSVars__
14841484
"
14851485
`;
1486+
1487+
exports[`SFC genDefaultAs > parser plugins > import attributes (user override for deprecated syntax) 1`] = `
1488+
"import { foo } from './foo.js' assert { type: 'foobar' }
1489+
1490+
export default {
1491+
setup(__props, { expose: __expose }) {
1492+
__expose();
1493+
1494+
1495+
return { get foo() { return foo } }
1496+
}
1497+
1498+
}"
1499+
`;
1500+
1501+
exports[`SFC genDefaultAs > parser plugins > import attributes 1`] = `
1502+
"import { foo } from './foo.js' with { type: 'foobar' }
1503+
1504+
export default {
1505+
setup(__props, { expose: __expose }) {
1506+
__expose();
1507+
1508+
1509+
return { get foo() { return foo } }
1510+
}
1511+
1512+
}"
1513+
`;

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1600,4 +1600,38 @@ describe('SFC genDefaultAs', () => {
16001600
foo: BindingTypes.SETUP_REF
16011601
})
16021602
})
1603+
1604+
describe('parser plugins', () => {
1605+
test('import attributes', () => {
1606+
const { content } = compile(`
1607+
<script setup>
1608+
import { foo } from './foo.js' with { type: 'foobar' }
1609+
</script>
1610+
`)
1611+
assertCode(content)
1612+
1613+
expect(() =>
1614+
compile(`
1615+
<script setup>
1616+
import { foo } from './foo.js' assert { type: 'foobar' }
1617+
</script>`)
1618+
).toThrow()
1619+
})
1620+
1621+
test('import attributes (user override for deprecated syntax)', () => {
1622+
const { content } = compile(
1623+
`
1624+
<script setup>
1625+
import { foo } from './foo.js' assert { type: 'foobar' }
1626+
</script>
1627+
`,
1628+
{
1629+
babelParserPlugins: [
1630+
['importAttributes', { deprecatedAssertSyntax: true }]
1631+
]
1632+
}
1633+
)
1634+
assertCode(content)
1635+
})
1636+
})
16031637
})

packages/compiler-sfc/__tests__/utils.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ export function assertCode(code: string) {
2828
try {
2929
babelParse(code, {
3030
sourceType: 'module',
31-
plugins: ['typescript']
31+
plugins: [
32+
'typescript',
33+
['importAttributes', { deprecatedAssertSyntax: true }]
34+
]
3235
})
3336
} catch (e: any) {
3437
console.log(code)

packages/compiler-sfc/src/rewriteDefault.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { parse } from '@babel/parser'
22
import MagicString from 'magic-string'
33
import type { ParserPlugin } from '@babel/parser'
44
import type { Identifier, Statement } from '@babel/types'
5+
import { resolveParserPlugins } from './script/context'
56

67
export function rewriteDefault(
78
input: string,
@@ -10,7 +11,7 @@ export function rewriteDefault(
1011
): string {
1112
const ast = parse(input, {
1213
sourceType: 'module',
13-
plugins: parserPlugins
14+
plugins: resolveParserPlugins('js', parserPlugins)
1415
}).program.body
1516
const s = new MagicString(input)
1617

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { CallExpression, Node, ObjectPattern, Program } from '@babel/types'
22
import { SFCDescriptor } from '../parse'
3-
import { generateCodeFrame } from '@vue/shared'
3+
import { generateCodeFrame, isArray } from '@vue/shared'
44
import { parse as babelParse, ParserPlugin } from '@babel/parser'
55
import { ImportBinding, SFCScriptCompileOptions } from '../compileScript'
66
import { PropsDestructureBindings } from './defineProps'
@@ -155,6 +155,17 @@ export function resolveParserPlugins(
155155
dts = false
156156
) {
157157
const plugins: ParserPlugin[] = []
158+
if (
159+
!userPlugins ||
160+
!userPlugins.some(
161+
p =>
162+
p === 'importAssertions' ||
163+
p === 'importAttributes' ||
164+
(isArray(p) && p[0] === 'importAttributes')
165+
)
166+
) {
167+
plugins.push('importAttributes')
168+
}
158169
if (lang === 'jsx' || lang === 'tsx') {
159170
plugins.push('jsx')
160171
} else if (userPlugins) {
@@ -163,7 +174,7 @@ export function resolveParserPlugins(
163174
userPlugins = userPlugins.filter(p => p !== 'jsx')
164175
}
165176
if (lang === 'ts' || lang === 'tsx') {
166-
plugins.push(['typescript', { dts }])
177+
plugins.push(['typescript', { dts }], 'explicitResourceManagement')
167178
if (!userPlugins || !userPlugins.includes('decorators')) {
168179
plugins.push('decorators-legacy')
169180
}

packages/global.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ declare var __COMPAT__: boolean
1717
declare var __FEATURE_OPTIONS_API__: boolean
1818
declare var __FEATURE_PROD_DEVTOOLS__: boolean
1919
declare var __FEATURE_SUSPENSE__: boolean
20+
declare var __FEATURE_PROD_HYDRATION_MISMATCH_DETAILS__: boolean
2021

2122
// for tests
2223
declare namespace jest {

packages/runtime-core/__tests__/hydration.spec.ts

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -981,7 +981,7 @@ describe('SSR hydration', () => {
981981

982982
test('force hydrate select option with non-string value bindings', () => {
983983
const { container } = mountWithHydration(
984-
'<select><option :value="true">ok</option></select>',
984+
'<select><option value="true">ok</option></select>',
985985
() =>
986986
h('select', [
987987
// hoisted because bound value is a constant...
@@ -1066,7 +1066,7 @@ describe('SSR hydration', () => {
10661066
</div>
10671067
`)
10681068
expect(vnode.el).toBe(container.firstChild)
1069-
expect(`mismatch`).not.toHaveBeenWarned()
1069+
// expect(`mismatch`).not.toHaveBeenWarned()
10701070
})
10711071

10721072
test('transition appear with v-if', () => {
@@ -1126,7 +1126,7 @@ describe('SSR hydration', () => {
11261126
h('div', 'bar')
11271127
)
11281128
expect(container.innerHTML).toBe('<div>bar</div>')
1129-
expect(`Hydration text content mismatch in <div>`).toHaveBeenWarned()
1129+
expect(`Hydration text content mismatch`).toHaveBeenWarned()
11301130
})
11311131

11321132
test('not enough children', () => {
@@ -1136,7 +1136,7 @@ describe('SSR hydration', () => {
11361136
expect(container.innerHTML).toBe(
11371137
'<div><span>foo</span><span>bar</span></div>'
11381138
)
1139-
expect(`Hydration children mismatch in <div>`).toHaveBeenWarned()
1139+
expect(`Hydration children mismatch`).toHaveBeenWarned()
11401140
})
11411141

11421142
test('too many children', () => {
@@ -1145,7 +1145,7 @@ describe('SSR hydration', () => {
11451145
() => h('div', [h('span', 'foo')])
11461146
)
11471147
expect(container.innerHTML).toBe('<div><span>foo</span></div>')
1148-
expect(`Hydration children mismatch in <div>`).toHaveBeenWarned()
1148+
expect(`Hydration children mismatch`).toHaveBeenWarned()
11491149
})
11501150

11511151
test('complete mismatch', () => {
@@ -1219,5 +1219,57 @@ describe('SSR hydration', () => {
12191219
expect(container.innerHTML).toBe('<div><!--hi--></div>')
12201220
expect(`Hydration node mismatch`).toHaveBeenWarned()
12211221
})
1222+
1223+
test('class mismatch', () => {
1224+
mountWithHydration(`<div class="foo bar"></div>`, () =>
1225+
h('div', { class: ['foo', 'bar'] })
1226+
)
1227+
mountWithHydration(`<div class="foo bar"></div>`, () =>
1228+
h('div', { class: { foo: true, bar: true } })
1229+
)
1230+
mountWithHydration(`<div class="foo bar"></div>`, () =>
1231+
h('div', { class: 'foo bar' })
1232+
)
1233+
expect(`Hydration class mismatch`).not.toHaveBeenWarned()
1234+
mountWithHydration(`<div class="foo bar"></div>`, () =>
1235+
h('div', { class: 'foo' })
1236+
)
1237+
expect(`Hydration class mismatch`).toHaveBeenWarned()
1238+
})
1239+
1240+
test('style mismatch', () => {
1241+
mountWithHydration(`<div style="color:red;"></div>`, () =>
1242+
h('div', { style: { color: 'red' } })
1243+
)
1244+
mountWithHydration(`<div style="color:red;"></div>`, () =>
1245+
h('div', { style: `color:red;` })
1246+
)
1247+
expect(`Hydration style mismatch`).not.toHaveBeenWarned()
1248+
mountWithHydration(`<div style="color:red;"></div>`, () =>
1249+
h('div', { style: { color: 'green' } })
1250+
)
1251+
expect(`Hydration style mismatch`).toHaveBeenWarned()
1252+
})
1253+
1254+
test('attr mismatch', () => {
1255+
mountWithHydration(`<div id="foo"></div>`, () => h('div', { id: 'foo' }))
1256+
mountWithHydration(`<div spellcheck></div>`, () =>
1257+
h('div', { spellcheck: '' })
1258+
)
1259+
// boolean
1260+
mountWithHydration(`<select multiple></div>`, () =>
1261+
h('select', { multiple: true })
1262+
)
1263+
mountWithHydration(`<select multiple></div>`, () =>
1264+
h('select', { multiple: 'multiple' })
1265+
)
1266+
expect(`Hydration attribute mismatch`).not.toHaveBeenWarned()
1267+
1268+
mountWithHydration(`<div></div>`, () => h('div', { id: 'foo' }))
1269+
expect(`Hydration attribute mismatch`).toHaveBeenWarned()
1270+
1271+
mountWithHydration(`<div id="bar"></div>`, () => h('div', { id: 'foo' }))
1272+
expect(`Hydration attribute mismatch`).toHaveBeenWarnedTimes(2)
1273+
})
12221274
})
12231275
})

0 commit comments

Comments
 (0)