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
+
no
+
{{ 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
+
no
+
{{ 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) => {