Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { LightningElement as Component } from "lwc";

export default class Test extends Component {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"enableSyntheticElementInternals": true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import _tmpl from "./test.html";
import { LightningElement as Component, registerComponent as _registerComponent } from "lwc";
class Test extends Component {
/*LWC compiler vX.X.X*/
}
const __lwc_component_class_internal = _registerComponent(Test, {
tmpl: _tmpl,
sel: "lwc-test",
apiVersion: 9999999,
enableSyntheticElementInternals: true
});
export default __lwc_component_class_internal;
28 changes: 21 additions & 7 deletions packages/@lwc/babel-plugin-component/src/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
TEMPLATE_KEY,
API_VERSION_KEY,
COMPONENT_CLASS_ID,
SYNTHETIC_ELEMENT_INTERNALS_KEY,
} from './constants';
import type { types, NodePath, Visitor } from '@babel/core';
import type { BabelAPI, BabelTypes, LwcBabelPluginPass } from './types';
Expand Down Expand Up @@ -81,15 +82,28 @@ export default function ({ types: t }: BabelAPI): Visitor<LwcBabelPluginPass> {
// sel: 'x-foo',
// apiVersion: '58'
// })
const properties = [
t.objectProperty(t.identifier(TEMPLATE_KEY), templateIdentifier),
t.objectProperty(t.identifier(COMPONENT_NAME_KEY), componentRegisteredName),
// It's important that, at this point, we have an APIVersion rather than just a number.
// The client needs to trust the server that it's providing an actual known API version
t.objectProperty(t.identifier(API_VERSION_KEY), t.numericLiteral(apiVersion)),
];
// Only include enableSyntheticElementInternals if explicitly defined
if (typeof state.opts.enableSyntheticElementInternals === 'boolean') {
const supportsSyntheticElementInternals = t.booleanLiteral(
state.opts.enableSyntheticElementInternals || false
);
properties.push(
t.objectProperty(
t.identifier(SYNTHETIC_ELEMENT_INTERNALS_KEY),
supportsSyntheticElementInternals
)
);
}
const registerComponentExpression = t.callExpression(registerComponentId, [
node as types.Expression,
t.objectExpression([
t.objectProperty(t.identifier(TEMPLATE_KEY), templateIdentifier),
t.objectProperty(t.identifier(COMPONENT_NAME_KEY), componentRegisteredName),
// It's important that, at this point, we have an APIVersion rather than just a number.
// The client needs to trust the server that it's providing an actual known API version
t.objectProperty(t.identifier(API_VERSION_KEY), t.numericLiteral(apiVersion)),
]),
t.objectExpression(properties),
]);

// Example:
Expand Down
2 changes: 2 additions & 0 deletions packages/@lwc/babel-plugin-component/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const TEMPLATE_KEY = 'tmpl';
const COMPONENT_NAME_KEY = 'sel';
const API_VERSION_KEY = 'apiVersion';
const COMPONENT_CLASS_ID = '__lwc_component_class_internal';
const SYNTHETIC_ELEMENT_INTERNALS_KEY = 'enableSyntheticElementInternals';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 if this were written 8 years ago, we'd probably call it sei or something silly. I don't think we still care about that, though...


export {
DECORATOR_TYPES,
Expand All @@ -46,4 +47,5 @@ export {
COMPONENT_NAME_KEY,
API_VERSION_KEY,
COMPONENT_CLASS_ID,
SYNTHETIC_ELEMENT_INTERNALS_KEY,
};
1 change: 1 addition & 0 deletions packages/@lwc/babel-plugin-component/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export interface LwcBabelPluginOptions {
name: string;
instrumentation?: InstrumentationObject;
apiVersion?: number;
enableSyntheticElementInternals?: boolean;
}

export interface LwcBabelPluginPass extends PluginPass {
Expand Down
3 changes: 3 additions & 0 deletions packages/@lwc/compiler/src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ export interface TransformOptions {
experimentalDynamicDirective?: boolean;
/** Flag to enable usage of dynamic component(lwc:is) directive in HTML template */
enableDynamicComponents?: boolean;
/** Flag to enable usage of ElementInternals in synthetic shadow DOM */
enableSyntheticElementInternals?: boolean;
// TODO [#3370]: remove experimental template expression flag
/** Flag to enable use of (a subset of) JavaScript expressions in place of template bindings. Passed to `@lwc/template-compiler`. */
experimentalComplexExpressions?: boolean;
Expand Down Expand Up @@ -153,6 +155,7 @@ type OptionalTransformKeys =
| 'enableLwcOn'
| 'enableLightningWebSecurityTransforms'
| 'enableDynamicComponents'
| 'enableSyntheticElementInternals'
| 'experimentalDynamicDirective'
| 'experimentalDynamicComponent'
| 'instrumentation';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ import {
} from '../libs/reflection';

import { HTMLElementOriginalDescriptors } from './html-properties';
import { getComponentAPIVersion, getWrappedComponentsListener } from './component';
import {
getComponentAPIVersion,
getWrappedComponentsListener,
supportsSyntheticElementInternals,
} from './component';
import { isBeingConstructed, isInvokingRender, vmBeingConstructed } from './invoker';
import { associateVM, getAssociatedVM, RenderMode, ShadowMode } from './vm';
import { componentValueObserved } from './mutation-tracker';
Expand Down Expand Up @@ -493,6 +497,7 @@ function warnIfInvokedDuringConstruction(vm: VM, methodOrPropName: string) {
attachInternals(): ElementInternals {
const vm = getAssociatedVM(this);
const {
def: { ctor },
elm,
apiVersion,
renderer: { attachInternals },
Expand All @@ -507,7 +512,7 @@ function warnIfInvokedDuringConstruction(vm: VM, methodOrPropName: string) {
}

const internals = attachInternals(elm);
if (vm.shadowMode === ShadowMode.Synthetic) {
if (supportsSyntheticElementInternals(ctor) && vm.shadowMode === ShadowMode.Synthetic) {
const handler: ProxyHandler<ElementInternals> = {
get(target: ElementInternals, prop: keyof ElementInternals) {
if (prop === 'shadowRoot') {
Expand Down
5 changes: 5 additions & 0 deletions packages/@lwc/engine-core/src/framework/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type ComponentConstructorMetadata = {
tmpl: Template;
sel: string;
apiVersion: APIVersion;
enableSyntheticElementInternals?: boolean | undefined;
};
const registeredComponentMap: Map<LightningElementConstructor, ComponentConstructorMetadata> =
new Map();
Expand Down Expand Up @@ -76,6 +77,10 @@ export function getComponentAPIVersion(Ctor: LightningElementConstructor): APIVe
return apiVersion;
}

export function supportsSyntheticElementInternals(Ctor: LightningElementConstructor): boolean {
return registeredComponentMap.get(Ctor)?.enableSyntheticElementInternals || false;
}

export function getTemplateReactiveObserver(vm: VM): ReactiveObserver {
const reactiveObserver = createReactiveObserver(() => {
const { isDirty } = vm;
Expand Down
4 changes: 4 additions & 0 deletions packages/@lwc/rollup-plugin/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ export interface RollupLwcOptions {
/** The configuration to pass to `@lwc/template-compiler`. */
enableDynamicComponents?: boolean;
/** The configuration to pass to `@lwc/compiler`. */
enableSyntheticElementInternals?: boolean;
/** The configuration to pass to `@lwc/compiler`. */
enableLightningWebSecurityTransforms?: boolean;
// TODO [#3370]: remove experimental template expression flag
/** The configuration to pass to `@lwc/template-compiler`. */
Expand Down Expand Up @@ -181,6 +183,7 @@ export default function lwc(pluginOptions: RollupLwcOptions = {}): Plugin {
experimentalDynamicComponent,
experimentalDynamicDirective,
enableDynamicComponents,
enableSyntheticElementInternals,
enableLwcOn,
enableLightningWebSecurityTransforms,
// TODO [#3370]: remove experimental template expression flag
Expand Down Expand Up @@ -366,6 +369,7 @@ export default function lwc(pluginOptions: RollupLwcOptions = {}): Plugin {
experimentalDynamicComponent,
experimentalDynamicDirective,
enableDynamicComponents,
enableSyntheticElementInternals,
enableLwcOn,
enableLightningWebSecurityTransforms,
// TODO [#3370]: remove experimental template expression flag
Expand Down