Skip to content

Commit

Permalink
fix(template-compiler): omit api_key for key outside iteration (#2699)
Browse files Browse the repository at this point in the history
* fix(template-compiler): omit api_key for key outside iteration

* fix: improve warning message
  • Loading branch information
nolanlawson authored Feb 23, 2022
1 parent ddb9404 commit fc2fd37
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 18 deletions.
11 changes: 2 additions & 9 deletions packages/@lwc/engine-core/src/framework/rendering.ts
Original file line number Diff line number Diff line change
Expand Up @@ -701,15 +701,8 @@ function updateStaticChildren(c1: VNodes, c2: VNodes, parent: ParentNode) {
if (n2 !== n1) {
if (isVNode(n1)) {
if (isVNode(n2)) {
if (isSameVnode(n1, n2)) {
// both vnodes are equivalent, and we just need to patch them
patch(n1, n2);
} else {
// TODO [#2697]: it is possible for the template to define key attributes outside of an
// iteration, leading to a situation where static children have different keys.
unmount(n1, parent, true);
mount(n2, parent, anchor);
}
// both vnodes are equivalent, and we just need to patch them
patch(n1, n2);
anchor = n2.elm!;
} else {
// removing the old vnode since the new one is null
Expand Down
2 changes: 1 addition & 1 deletion packages/@lwc/errors/src/compiler/error-info/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
*/
/**
* Next error code: 1149
* Next error code: 1150
*/

export * from './compiler';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -595,4 +595,11 @@ export const ParserDiagnostics = {
level: DiagnosticLevel.Warning,
url: '',
},
KEY_SHOULD_BE_IN_ITERATION: {
code: 1149,
message:
'Invalid key attribute on element <{0}>. The key attribute should be applied to an element with for:each or iterator:*, or to a direct child of a <template> element with for:each or iterator:*. This key will be ignored, and may throw an error in future versions of LWC.',
level: DiagnosticLevel.Warning,
url: '',
},
};
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { registerTemplate } from "lwc";
const stc0 = {
key: 0,
};
function tmpl($api, $cmp, $slotset, $ctx) {
const { k: api_key, h: api_element } = $api;
return [
api_element("div", {
key: api_key(0, $cmp.keyGetter),
}),
];
const { h: api_element } = $api;
return [api_element("div", stc0)];
}
export default registerTemplate(tmpl);
tmpl.stylesheets = [];
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
{
"warnings": []
"warnings": [
{
"code": 1149,
"message": "LWC1149: Invalid key attribute on element <div>. The key attribute should be applied to an element with for:each or iterator:*, or to a direct child of a <template> element with for:each or iterator:*. This key will be ignored, and may throw an error in future versions of LWC.",
"level": 2,
"location": {
"line": 2,
"column": 10,
"start": 20,
"length": 15
}
}
]
}
6 changes: 5 additions & 1 deletion packages/@lwc/template-compiler/src/parser/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -758,7 +758,11 @@ function applyKey(ctx: ParserCtx, parsedAttr: ParsedAttribute, element: BaseElem
}
}

element.directives.push(ast.keyDirective(keyAttribute.value, keyAttribute.location));
if (forOfParent || forEachParent) {
element.directives.push(ast.keyDirective(keyAttribute.value, keyAttribute.location));
} else {
ctx.warnOnNode(ParserDiagnostics.KEY_SHOULD_BE_IN_ITERATION, keyAttribute, [tag]);
}
} else if (isInIteratorElement(ctx)) {
ctx.throwOnNode(ParserDiagnostics.MISSING_KEY_IN_ITERATOR, element, [tag]);
}
Expand Down

0 comments on commit fc2fd37

Please sign in to comment.