diff --git a/packages/compiler-core/__tests__/__snapshots__/compile.spec.ts.snap b/packages/compiler-core/__tests__/__snapshots__/compile.spec.ts.snap index db2bfb17f..91d3bf425 100644 --- a/packages/compiler-core/__tests__/__snapshots__/compile.spec.ts.snap +++ b/packages/compiler-core/__tests__/__snapshots__/compile.spec.ts.snap @@ -21,6 +21,25 @@ return function render() { }" `; +exports[`compiler: integration tests function mode 2`] = ` +Object { + "mappings": ";;;;WAAA,oBAAA;MAAK,IAAG;MAAO,OAAO;;gBACpB;MACW;UAAX,uBAAe;UACE;MACjB,YAA8B,OAAjB,OAAO;eAApB,wBAAoC,kCAAM", + "names": Array [], + "sources": Array [ + "foo.vue", + ], + "sourcesContent": Array [ + "
+ {{ world }} +
yes
+ +
{{ value + index }}
+
", + ], + "version": 3, +} +`; + exports[`compiler: integration tests function mode w/ prefixIdentifiers: true 1`] = ` "const { createVNode, toString, renderList } = Vue @@ -41,6 +60,30 @@ return function render() { }" `; +exports[`compiler: integration tests function mode w/ prefixIdentifiers: true 2`] = ` +Object { + "mappings": ";;;;SAAA,mBAAA;IAAK,IAAG;IAAO,OAAOA;;aACpBC;KACWC;QAAX,sBAAe;QACE;IACjB,WAA8BC,YAAjB,OAAO;aAApB,uBAAoC,gCAAS,QAAQ", + "names": Array [ + "bar", + "world", + "ok", + "list", + ], + "sources": Array [ + "foo.vue", + ], + "sourcesContent": Array [ + "
+ {{ world }} +
yes
+ +
{{ value + index }}
+
", + ], + "version": 3, +} +`; + exports[`compiler: integration tests module mode 1`] = ` "import { createVNode, toString, renderList } from \\"vue\\" diff --git a/packages/compiler-core/__tests__/compile.spec.ts b/packages/compiler-core/__tests__/compile.spec.ts index 1d56e92a6..b7bf9f47c 100644 --- a/packages/compiler-core/__tests__/compile.spec.ts +++ b/packages/compiler-core/__tests__/compile.spec.ts @@ -11,7 +11,17 @@ describe('compiler: integration tests', () => { `.trim() - function getPositionInCode(code: string, token: string) { + interface Pos { + line: number + column: number + name?: string + } + + function getPositionInCode( + code: string, + token: string, + expectName: string | boolean = false + ): Pos { const generatedOffset = code.indexOf(token) let line = 1 let lastNewLinePos = -1 @@ -21,13 +31,17 @@ describe('compiler: integration tests', () => { lastNewLinePos = i } } - return { + const res: Pos = { line, column: lastNewLinePos === -1 ? generatedOffset : generatedOffset - lastNewLinePos - 1 } + if (expectName) { + res.name = typeof expectName === 'string' ? expectName : token + } + return res } test('function mode', async () => { @@ -41,6 +55,7 @@ describe('compiler: integration tests', () => { ) expect(code).toMatchSnapshot() + expect(map).toMatchSnapshot() expect(map!.sources).toEqual([`foo.vue`]) expect(map!.sourcesContent).toEqual([source]) @@ -97,6 +112,7 @@ describe('compiler: integration tests', () => { expect(code).toMatch(`const { createVNode, toString, renderList } = Vue`) expect(code).toMatchSnapshot() + expect(map).toMatchSnapshot() expect(map!.sources).toEqual([`foo.vue`]) expect(map!.sourcesContent).toEqual([source]) @@ -118,29 +134,31 @@ describe('compiler: integration tests', () => { consumer.originalPositionFor(getPositionInCode(code, `bar`)) ).toMatchObject(getPositionInCode(source, `bar`)) expect( - consumer.originalPositionFor(getPositionInCode(code, `_ctx.bar`)) - ).toMatchObject(getPositionInCode(source, `bar`)) + consumer.originalPositionFor(getPositionInCode(code, `_ctx.bar`, `bar`)) + ).toMatchObject(getPositionInCode(source, `bar`, true)) expect( - consumer.originalPositionFor(getPositionInCode(code, `world`)) - ).toMatchObject(getPositionInCode(source, `{{ world }}`)) + consumer.originalPositionFor(getPositionInCode(code, `world`, true)) + ).toMatchObject(getPositionInCode(source, `{{ world }}`, `world`)) expect( - consumer.originalPositionFor(getPositionInCode(code, `_ctx.world`)) - ).toMatchObject(getPositionInCode(source, `{{ world }}`)) + consumer.originalPositionFor( + getPositionInCode(code, `_ctx.world`, `world`) + ) + ).toMatchObject(getPositionInCode(source, `{{ world }}`, `world`)) expect( consumer.originalPositionFor(getPositionInCode(code, `ok`)) ).toMatchObject(getPositionInCode(source, `ok`)) expect( - consumer.originalPositionFor(getPositionInCode(code, `_ctx.ok`)) - ).toMatchObject(getPositionInCode(source, `ok`)) + consumer.originalPositionFor(getPositionInCode(code, `_ctx.ok`, `ok`)) + ).toMatchObject(getPositionInCode(source, `ok`, true)) expect( consumer.originalPositionFor(getPositionInCode(code, `list`)) ).toMatchObject(getPositionInCode(source, `list`)) expect( - consumer.originalPositionFor(getPositionInCode(code, `_ctx.list`)) - ).toMatchObject(getPositionInCode(source, `list`)) + consumer.originalPositionFor(getPositionInCode(code, `_ctx.list`, `list`)) + ).toMatchObject(getPositionInCode(source, `list`, true)) expect( consumer.originalPositionFor(getPositionInCode(code, `value`)) @@ -188,29 +206,31 @@ describe('compiler: integration tests', () => { consumer.originalPositionFor(getPositionInCode(code, `bar`)) ).toMatchObject(getPositionInCode(source, `bar`)) expect( - consumer.originalPositionFor(getPositionInCode(code, `_ctx.bar`)) - ).toMatchObject(getPositionInCode(source, `bar`)) + consumer.originalPositionFor(getPositionInCode(code, `_ctx.bar`, `bar`)) + ).toMatchObject(getPositionInCode(source, `bar`, true)) expect( - consumer.originalPositionFor(getPositionInCode(code, `world`)) - ).toMatchObject(getPositionInCode(source, `{{ world }}`)) + consumer.originalPositionFor(getPositionInCode(code, `world`, true)) + ).toMatchObject(getPositionInCode(source, `{{ world }}`, `world`)) expect( - consumer.originalPositionFor(getPositionInCode(code, `_ctx.world`)) - ).toMatchObject(getPositionInCode(source, `{{ world }}`)) + consumer.originalPositionFor( + getPositionInCode(code, `_ctx.world`, `world`) + ) + ).toMatchObject(getPositionInCode(source, `{{ world }}`, `world`)) expect( consumer.originalPositionFor(getPositionInCode(code, `ok`)) ).toMatchObject(getPositionInCode(source, `ok`)) expect( - consumer.originalPositionFor(getPositionInCode(code, `_ctx.ok`)) - ).toMatchObject(getPositionInCode(source, `ok`)) + consumer.originalPositionFor(getPositionInCode(code, `_ctx.ok`, `ok`)) + ).toMatchObject(getPositionInCode(source, `ok`, true)) expect( consumer.originalPositionFor(getPositionInCode(code, `list`)) ).toMatchObject(getPositionInCode(source, `list`)) expect( - consumer.originalPositionFor(getPositionInCode(code, `_ctx.list`)) - ).toMatchObject(getPositionInCode(source, `list`)) + consumer.originalPositionFor(getPositionInCode(code, `_ctx.list`, `list`)) + ).toMatchObject(getPositionInCode(source, `list`, true)) expect( consumer.originalPositionFor(getPositionInCode(code, `value`)) diff --git a/packages/compiler-core/src/codegen.ts b/packages/compiler-core/src/codegen.ts index 9e69c62eb..566a9f71a 100644 --- a/packages/compiler-core/src/codegen.ts +++ b/packages/compiler-core/src/codegen.ts @@ -106,7 +106,19 @@ function createCodegenContext( context.code += code if (context.map) { if (node) { - const mapping = { + let name + if ( + node.type === NodeTypes.EXPRESSION && + !node.children && + !node.isStatic + ) { + const content = node.content.replace(/^_ctx\./, '') + if (content !== node.content && isSimpleIdentifier(content)) { + name = content + } + } + context.map.addMapping({ + name, source: context.filename, original: { line: node.loc.start.line, @@ -116,8 +128,7 @@ function createCodegenContext( line: context.line, column: context.column - 1 } - } - context.map.addMapping(mapping) + }) } advancePositionWithMutation(context, code) } diff --git a/packages/compiler-core/src/transforms/transformStyle.ts b/packages/compiler-core/src/transforms/transformStyle.ts index d2c10db2b..297b5e726 100644 --- a/packages/compiler-core/src/transforms/transformStyle.ts +++ b/packages/compiler-core/src/transforms/transformStyle.ts @@ -1,7 +1,12 @@ import { NodeTransform } from '../transform' import { NodeTypes, createExpression } from '../ast' -// prase inline CSS strings for static style attributes into an object +// Parse inline CSS strings for static style attributes into an object. +// This is a NodeTransform since it works on the static `style` attribute and +// converts it into a dynamic equivalent: +// style="color: red" -> :style='{ "color": "red" }' +// It is then processed by `transformElement` and included in the generated +// props. export const transformStyle: NodeTransform = (node, context) => { if (node.type === NodeTypes.ELEMENT) { node.props.forEach((p, i) => {