@lwc/template-compiler 2.45.5 → 2.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/codegen/codegen.d.ts +2 -1
- package/dist/config.d.ts +6 -1
- package/dist/index.cjs.js +33 -16
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.js +34 -17
- package/dist/index.js.map +1 -1
- package/dist/parser/parser.d.ts +6 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -56,6 +56,7 @@ const { code, warnings } = compile(`<template><h1>Hello World!</h1></template>`,
|
|
|
56
56
|
- `enableStaticContentOptimization` (boolean, optional, `true` by default) - set to `false` to disable static content optimizations.
|
|
57
57
|
- `enableLwcSpread` (boolean, optional, `false` by default) - set to `true` to enable `lwc:spread` directive in the template.
|
|
58
58
|
- `customRendererConfig` (CustomRendererConfig, optional) - specifies a configuration to use to match elements. Matched elements will get a custom renderer hook in the generated template.
|
|
59
|
+
- `instrumentation` (InstrumentationObject, optional) - instrumentation object to gather metrics and non-error logs for internal use. See the `@lwc/errors` package for details on the interface.
|
|
59
60
|
|
|
60
61
|
- Example 1: Config to match `<use>` elements under the `svg` namespace and have `href` attribute set.
|
|
61
62
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as t from '../shared/estree';
|
|
2
|
-
import { ChildNode, Element, Expression, ComplexExpression, Literal, LWCDirectiveRenderMode, Root } from '../shared/types';
|
|
2
|
+
import { ChildNode, Element, Expression, ComplexExpression, Literal, LWCDirectiveRenderMode, Root, EventListener } from '../shared/types';
|
|
3
3
|
import State from '../state';
|
|
4
4
|
export default class CodeGen {
|
|
5
5
|
/** The AST root. */
|
|
@@ -76,6 +76,7 @@ export default class CodeGen {
|
|
|
76
76
|
genTabIndex(children: [t.Expression]): import("estree").CallExpression;
|
|
77
77
|
getMemorizationId(): import("estree").Identifier;
|
|
78
78
|
genBooleanAttributeExpr(bindExpr: t.Expression): import("estree").ConditionalExpression;
|
|
79
|
+
genEventListeners(listeners: EventListener[]): import("estree").ObjectExpression;
|
|
79
80
|
/**
|
|
80
81
|
* This routine generates an expression that avoids
|
|
81
82
|
* computing the sanitized html of a raw html if it does not change
|
package/dist/config.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { InstrumentationObject } from '@lwc/errors';
|
|
1
2
|
import { CustomRendererConfig } from './shared/renderer-hooks';
|
|
2
3
|
export interface Config {
|
|
3
4
|
/**
|
|
@@ -50,6 +51,10 @@ export interface Config {
|
|
|
50
51
|
* When true, enables `lwc:spread` directive.
|
|
51
52
|
*/
|
|
52
53
|
enableLwcSpread?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Config to use to collect metrics and logs
|
|
56
|
+
*/
|
|
57
|
+
instrumentation?: InstrumentationObject;
|
|
53
58
|
}
|
|
54
|
-
export type NormalizedConfig = Required<Omit<Config, 'customRendererConfig'>> & Partial<Pick<Config, 'customRendererConfig'>>;
|
|
59
|
+
export type NormalizedConfig = Required<Omit<Config, 'customRendererConfig' | 'instrumentation'>> & Partial<Pick<Config, 'customRendererConfig' | 'instrumentation'>>;
|
|
55
60
|
export declare function normalizeConfig(config: Config): NormalizedConfig;
|
package/dist/index.cjs.js
CHANGED
|
@@ -141,6 +141,7 @@ const AVAILABLE_OPTION_NAMES = new Set([
|
|
|
141
141
|
'experimentalDynamicDirective',
|
|
142
142
|
'enableDynamicComponents',
|
|
143
143
|
'preserveHtmlComments',
|
|
144
|
+
'instrumentation',
|
|
144
145
|
]);
|
|
145
146
|
function normalizeCustomRendererConfig(config) {
|
|
146
147
|
const tagNames = [];
|
|
@@ -175,6 +176,7 @@ function normalizeConfig(config) {
|
|
|
175
176
|
const customRendererConfig = config.customRendererConfig
|
|
176
177
|
? normalizeCustomRendererConfig(config.customRendererConfig)
|
|
177
178
|
: undefined;
|
|
179
|
+
const instrumentation = config.instrumentation || undefined;
|
|
178
180
|
for (const property in config) {
|
|
179
181
|
if (!AVAILABLE_OPTION_NAMES.has(property) && shared.hasOwnProperty.call(config, property)) {
|
|
180
182
|
throw errors.generateCompilerError(errors.TemplateErrors.UNKNOWN_OPTION_PROPERTY, {
|
|
@@ -182,9 +184,9 @@ function normalizeConfig(config) {
|
|
|
182
184
|
});
|
|
183
185
|
}
|
|
184
186
|
}
|
|
185
|
-
return Object.assign(Object.assign({ preserveHtmlComments: false, experimentalComputedMemberExpression: false,
|
|
187
|
+
return Object.assign(Object.assign(Object.assign({ preserveHtmlComments: false, experimentalComputedMemberExpression: false,
|
|
186
188
|
// TODO [#3370]: remove experimental template expression flag
|
|
187
|
-
experimentalComplexExpressions: false, experimentalDynamicDirective: false, enableDynamicComponents: false, enableStaticContentOptimization: true, enableLwcSpread: false }, config), { customRendererConfig });
|
|
189
|
+
experimentalComplexExpressions: false, experimentalDynamicDirective: false, enableDynamicComponents: false, enableStaticContentOptimization: true, enableLwcSpread: false }, config), { customRendererConfig }), { instrumentation });
|
|
188
190
|
}
|
|
189
191
|
|
|
190
192
|
function isIdentifier(node) {
|
|
@@ -1589,6 +1591,7 @@ class ParserCtx {
|
|
|
1589
1591
|
this.ecmaVersion = config.experimentalComplexExpressions
|
|
1590
1592
|
? TMPL_EXPR_ECMASCRIPT_EDITION
|
|
1591
1593
|
: 2020;
|
|
1594
|
+
this.instrumentation = config.instrumentation;
|
|
1592
1595
|
}
|
|
1593
1596
|
getSource(start, end) {
|
|
1594
1597
|
return this.source.slice(start, end);
|
|
@@ -3098,6 +3101,7 @@ function applyRootLwcDirectives(ctx, parsedAttr, root) {
|
|
|
3098
3101
|
applyLwcPreserveCommentsDirective(ctx, parsedAttr, root);
|
|
3099
3102
|
}
|
|
3100
3103
|
function applyLwcRenderModeDirective(ctx, parsedAttr, root) {
|
|
3104
|
+
var _a;
|
|
3101
3105
|
const lwcRenderModeAttribute = parsedAttr.pick(exports.RootDirectiveName.RenderMode);
|
|
3102
3106
|
if (!lwcRenderModeAttribute) {
|
|
3103
3107
|
return;
|
|
@@ -3109,6 +3113,7 @@ function applyLwcRenderModeDirective(ctx, parsedAttr, root) {
|
|
|
3109
3113
|
ctx.throwOnNode(errors.ParserDiagnostics.LWC_RENDER_MODE_INVALID_VALUE, root);
|
|
3110
3114
|
}
|
|
3111
3115
|
root.directives.push(renderModeDirective(renderDomAttr.value, lwcRenderModeAttribute.location));
|
|
3116
|
+
(_a = ctx.instrumentation) === null || _a === void 0 ? void 0 : _a.incrementCounter(errors.CompilerMetrics.LWCRenderModeDirective);
|
|
3112
3117
|
}
|
|
3113
3118
|
function applyLwcPreserveCommentsDirective(ctx, parsedAttr, root) {
|
|
3114
3119
|
const lwcPreserveCommentAttribute = parsedAttr.pick(exports.RootDirectiveName.PreserveComments);
|
|
@@ -3211,6 +3216,7 @@ function applyLwcExternalDirective(ctx, parsedAttr, element) {
|
|
|
3211
3216
|
}
|
|
3212
3217
|
}
|
|
3213
3218
|
function applyLwcDynamicDirective(ctx, parsedAttr, element) {
|
|
3219
|
+
var _a;
|
|
3214
3220
|
const { name: tag } = element;
|
|
3215
3221
|
const lwcDynamicAttribute = parsedAttr.pick(exports.ElementDirectiveName.Dynamic);
|
|
3216
3222
|
if (!lwcDynamicAttribute) {
|
|
@@ -3230,6 +3236,7 @@ function applyLwcDynamicDirective(ctx, parsedAttr, element) {
|
|
|
3230
3236
|
}
|
|
3231
3237
|
// lwc:dynamic will be deprecated in 246, issue a warning when usage is detected.
|
|
3232
3238
|
ctx.warnOnNode(errors.ParserDiagnostics.DEPRECATED_LWC_DYNAMIC_ATTRIBUTE, element);
|
|
3239
|
+
(_a = ctx.instrumentation) === null || _a === void 0 ? void 0 : _a.incrementCounter(errors.CompilerMetrics.LWCDynamicDirective);
|
|
3233
3240
|
element.directives.push(dynamicDirective(lwcDynamicAttr, location));
|
|
3234
3241
|
}
|
|
3235
3242
|
function applyLwcIsDirective(ctx, parsedAttr, element) {
|
|
@@ -3970,7 +3977,7 @@ function parseClassNames(classNames) {
|
|
|
3970
3977
|
}
|
|
3971
3978
|
function isStaticNode(node) {
|
|
3972
3979
|
let result = true;
|
|
3973
|
-
const { name: nodeName, namespace = '', attributes, directives, properties
|
|
3980
|
+
const { name: nodeName, namespace = '', attributes, directives, properties } = node;
|
|
3974
3981
|
if (namespace !== shared.HTML_NAMESPACE) {
|
|
3975
3982
|
// TODO [#3313]: re-enable static optimization for SVGs once scope token is always lowercase
|
|
3976
3983
|
return false;
|
|
@@ -3992,7 +3999,6 @@ function isStaticNode(node) {
|
|
|
3992
3999
|
})); // all attrs are static
|
|
3993
4000
|
result && (result = directives.length === 0); // do not have any directive
|
|
3994
4001
|
result && (result = properties.every((prop) => isLiteral(prop.value))); // all properties are static
|
|
3995
|
-
result && (result = listeners.length === 0); // do not have any event listener
|
|
3996
4002
|
return result;
|
|
3997
4003
|
}
|
|
3998
4004
|
function collectStaticNodes(node, staticNodes, state) {
|
|
@@ -4008,7 +4014,10 @@ function collectStaticNodes(node, staticNodes, state) {
|
|
|
4008
4014
|
// it is ElseBlock | ForBlock | If | BaseElement
|
|
4009
4015
|
node.children.forEach((childNode) => {
|
|
4010
4016
|
collectStaticNodes(childNode, staticNodes, state);
|
|
4011
|
-
childrenAreStatic
|
|
4017
|
+
childrenAreStatic && (childrenAreStatic = staticNodes.has(childNode));
|
|
4018
|
+
// Bail out if any children have event listeners. Event listeners are only allowed at the top level of a
|
|
4019
|
+
// static fragment, because the engine currently cannot attach listeners to nodes inside a static fragment.
|
|
4020
|
+
childrenAreStatic && (childrenAreStatic = !isBaseElement(childNode) || childNode.listeners.length === 0);
|
|
4012
4021
|
});
|
|
4013
4022
|
// for IfBlock and ElseifBlock, traverse down the else branch
|
|
4014
4023
|
if (isConditionalParentBlock(node) && node.else) {
|
|
@@ -4453,6 +4462,14 @@ class CodeGen {
|
|
|
4453
4462
|
genBooleanAttributeExpr(bindExpr) {
|
|
4454
4463
|
return conditionalExpression(bindExpr, literal$1(''), literal$1(null));
|
|
4455
4464
|
}
|
|
4465
|
+
genEventListeners(listeners) {
|
|
4466
|
+
const listenerObj = Object.fromEntries(listeners.map((listener) => [listener.name, listener]));
|
|
4467
|
+
return objectToAST(listenerObj, (key) => {
|
|
4468
|
+
const componentHandler = this.bindExpression(listenerObj[key].handler);
|
|
4469
|
+
const handler = this.genBind(componentHandler);
|
|
4470
|
+
return memorizeHandler(this, componentHandler, handler);
|
|
4471
|
+
});
|
|
4472
|
+
}
|
|
4456
4473
|
/**
|
|
4457
4474
|
* This routine generates an expression that avoids
|
|
4458
4475
|
* computing the sanitized html of a raw html if it does not change
|
|
@@ -4577,10 +4594,12 @@ class CodeGen {
|
|
|
4577
4594
|
identifier: identifier$1,
|
|
4578
4595
|
expr,
|
|
4579
4596
|
});
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
|
|
4583
|
-
|
|
4597
|
+
const args = [callExpression(identifier$1, []), literal$1(key)];
|
|
4598
|
+
if (element.listeners.length) {
|
|
4599
|
+
const listenerObjectAST = this.genEventListeners(element.listeners);
|
|
4600
|
+
args.push(objectExpression([property$1(identifier('on'), listenerObjectAST)]));
|
|
4601
|
+
}
|
|
4602
|
+
return this._renderApiCall(RENDER_APIS.staticFragment, args);
|
|
4584
4603
|
}
|
|
4585
4604
|
}
|
|
4586
4605
|
|
|
@@ -4767,6 +4786,7 @@ function format(templateFn, codeGen) {
|
|
|
4767
4786
|
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
4768
4787
|
*/
|
|
4769
4788
|
function transform(codeGen) {
|
|
4789
|
+
const instrumentation = codeGen.state.config.instrumentation;
|
|
4770
4790
|
function transformElement(element, slotParentName) {
|
|
4771
4791
|
const databag = elementDataBag(element, slotParentName);
|
|
4772
4792
|
let res;
|
|
@@ -5179,8 +5199,10 @@ function transform(codeGen) {
|
|
|
5179
5199
|
]);
|
|
5180
5200
|
data.push(property$1(identifier('context'), contextObj));
|
|
5181
5201
|
}
|
|
5202
|
+
// Spread
|
|
5182
5203
|
if (spread) {
|
|
5183
5204
|
data.push(property$1(identifier('spread'), codeGen.bindExpression(spread.value)));
|
|
5205
|
+
instrumentation === null || instrumentation === void 0 ? void 0 : instrumentation.incrementCounter(errors.CompilerMetrics.LWCSpreadDirective);
|
|
5184
5206
|
}
|
|
5185
5207
|
// Key property on VNode
|
|
5186
5208
|
if (forKey) {
|
|
@@ -5205,12 +5227,7 @@ function transform(codeGen) {
|
|
|
5205
5227
|
}
|
|
5206
5228
|
// Event handler
|
|
5207
5229
|
if (listeners.length) {
|
|
5208
|
-
const
|
|
5209
|
-
const listenerObjAST = objectToAST(listenerObj, (key) => {
|
|
5210
|
-
const componentHandler = codeGen.bindExpression(listenerObj[key].handler);
|
|
5211
|
-
const handler = codeGen.genBind(componentHandler);
|
|
5212
|
-
return memorizeHandler(codeGen, componentHandler, handler);
|
|
5213
|
-
});
|
|
5230
|
+
const listenerObjAST = codeGen.genEventListeners(listeners);
|
|
5214
5231
|
data.push(property$1(identifier('on'), listenerObjAST));
|
|
5215
5232
|
}
|
|
5216
5233
|
// SVG handling
|
|
@@ -5310,5 +5327,5 @@ function compile(source, config) {
|
|
|
5310
5327
|
exports.compile = compile;
|
|
5311
5328
|
exports.default = compile;
|
|
5312
5329
|
exports.parse = parse;
|
|
5313
|
-
/** version: 2.
|
|
5330
|
+
/** version: 2.46.0 */
|
|
5314
5331
|
//# sourceMappingURL=index.cjs.js.map
|