LWC compilation process
First, we run a linter that scans your code using the base configuration from our LWC Eslint plugin. This prevents common pitfalls with LWC, and enforces other Salesforce platform restrictions. Note that this is different than when the linter runs locally in VSCode. In VSCode you can choose which linting configuration to use: more or less restrictive.
Then, we compile the code that you’ve written. The LWC compiler uses Babel and Rollup to accomplish this task. This process entails three steps: parsing, transforming, and bundling.
First, the parser (Babel) reads your code to understand which syntax structures you’re using. For instance, it identifies if you’re using a function, a class (ES6), the object spread syntax (ES9), or the optional chaining operator (ES11). We upgrade the parser often to support parsing new syntax structures included in the newest ES versions.
Then, the code is transformed to generate two different outputs:
- ES6 output — This code runs in modern browsers, which support ES6 syntax natively and improve the performance considerably. For this version of the code, we transform a subset of ES6+ syntax features – including ES7, ES8, Rest/Spread Properties, and Class Fields – to ES6.
- ES5 output — This code runs in older browsers (we call them compatibility browsers), such as Internet Explorer 11. These browsers don’t support syntax features included in versions greater than ES5, so we transform a subset of ES5+ syntax features (that same as those listed above, plus ES6 syntax features) to ES5.
What happens if you’re using a syntax feature that we don’t transform (for example, the optional chaining operator from ES11)? If the parser understands it (it usually does, since we upgrade it often), the feature is included in both code versions, and it works only if your browser is able to understand the syntax (often the case for modern browsers).
Note that this landscape is correct by the blog post publication date. However, it may change soon, as the LWC team is working on adding new transforms to keep up with newly introduced syntaxes.
Runtime execution and polyfills
Now let’s talk about runtime execution. When your application runs in a browser, we use the user agent to detect which browser. Depending on the browser, the ES5 or ES6 version of the code is loaded, along with the required polyfills in the case of compatibility browsers. A polyfill is a missing feature (typically an object or method in the browser API) that’s added to the language at run time. Note that these are different than syntax features. Some examples of features that can be polyfilled are Promise (ES6), Object.entries() (ES8), and Promise.any() (ES12). LWC uses core-js polyfills.
- For compatibility browsers, all ES6 features are polyfilled.
- For modern browsers, no ES6 polyfills are loaded, as they’re not needed.
So, what happens if you use an API for which we don’t provide a polyfill (for example,
Promise.any() from ES12)? It works if the browser in which you run the app supports it, as long as Locker supports it as well.
Note: for LWC OSS only the ES6 version is generated by default. Also linting and polyfilling are not part of LWC OSS out of the box.
ESXX features supported in LWC
These are some of the most recent features that you can use as of today:
I created an app that makes it easy to understand which ESXX features can be used in LWC, given they’re supported by your browser, and how. The app contains components with code examples that showcase features included in versions from ES9 to ES12, although remember that features from previous versions are supported too. You can look at the code of each example, and optionally debug each example individually with the browser developer tools, for a deeper understanding.
I also created an LWC OSS version of the app, because when you create apps with LWC OSS, Locker doesn’t run and some restrictions are relaxed so you can use more ESXX features that the Salesforce platform supports. I recommend that you clone this version if you usually develop LWC outside of the platform.
With great power comes great responsibility!
In this blog post, I explained how the LWC compilation process works, how we provide a backwards-compatible version of your code, and how we polyfill missing features (ES6, and some from ES7 and ES8) for older browsers. You also learned that you can use most other ESXX features, as long as you’re using a browser that supports them.
To help you find out which ESXX features fall under each category, I’ve shared two apps that show you the supported features and how to use them. Clone the LWC app or the LWC OSS app and check them out. And if you want to learn more, know that I’m doing a webinar series on Trailhead Live about this topic starting Thursday February 25 – make sure to add it to your calendar. Thanks for reading and happy coding!
About the author
Alba Rivas works as a Lead Developer Evangelist at Salesforce. She focuses on Lightning Web Components and Lightning adoption strategy. You can follow her on Twitter @AlbaSFDC.