StealJS supports conditional module loading through the steal-conditional extension;
2 types of conditionals are currently supported, string substitution and boolean.
In this guide, we'll build a small demo that uses the boolean conditional syntax to import a
Custom Elements V1polyfill only when the host browser doesn't support it natively.
First, we import the polyfill, notice we are using the regular import syntax
here, we'll change it in a moment to use the steal-conditional boolean syntax; the rest of the code is defining the custom element constructor function.
the connectedCallback function is called every time the element is inserted into the DOM.
The following functions with _ in their names (e.g: _makeLinkElement) are used during rendering and the naming choice is to indicate that these are private methods that shouldn't be used by the custom element's consumer.
Finally, and probably the most interesting piece of the code:
customElements.define("my-element", MyElement);
This is where the custom element is actually defined, and the whole reason why we
might need to load the polyfill.
One issue with our current code is that the polyfill is loaded every time, even when the browser already supports the Custom Elements V1 api. We cannot afford wasting precious time and resources to download code that's not needed.
The goal here is to detect whether the browser already supports the feature and only
load the polyfill when it's needed.
The boolean conditional syntax
Let's change the import in index.js to look like this:
This should look a little bit weird to you, if it doesn't, you might want to read this article first.
The part before the #? is the polyfill package name we had before, the interesting bit is the text after; needs-polyfill is a module name, the steal-conditional extension will load it first and grab its default export; if the value is not a boolean it will throw an error, otherwise document-register-element will only be loaded if the value is true.
In the screenshot above, there is Chrome on the left (Version 55.0.2883.95) and Firefox on the right (Version 50.0.2), highlighted on blue is the request of the
condition module which happens on both browsers, in our example that's the needs-polyfill module, then highlighted on red is the request to load the polyfill which only happens in Firefox which (for the tested version) doesn't support the Custom Elements V1 api.
Build a production app
Now that we've created our application we need to share it with the public. To do this we'll create a build that will concat our JavaScript and styles down to only one file, each, for faster page loads in production.
Build the app and switch to production
When we first installed our initial dependencies for myhub, one of those was steal-tools. steal-tools is a set of tools that helps with bundling assets for production use.
In your package.json "scripts" section add:
{
"scripts": {
...
"build": "steal-tools"
}
}
And then you can run:
> npm run build
To use the production artifacts rather than the development files we need to update our index.html to load them.
By using steal.production.js instead of steal.js StealJS will know to load the production files we just built.
A bundle for each conditional module
During the build, steal-tools will create separate bundles for each conditionally loaded module, this way only browsers without support will get the penalty of downloading and parsing the polyfill code.
If we take a look at the artifacts created during the build process
We can see (the red hightlighted box) the bundle created for the document-register-element polyfill module.
If we reload index.html and inspect the network tab, we'll notice that the polyfill bundle is only loaded in Firefox.
StealJS supports conditional module loading through the steal-conditional extension; 2 types of conditionals are currently supported, string substitution and boolean.
In this guide, we'll build a small demo that uses the boolean conditional syntax to import a Custom Elements V1 polyfill only when the host browser doesn't support it natively.
Install Prerequisites
Window Setup
Linux / Mac Setup
Setting up a new project
Create a new project folder
Create a new folder for your project and then run
npm init
. Answer all questions with their defaults.Create and host the main page
Create index.html with:
Next install and run a local fileserver. http-server handles our basic needs. We'll install it locally and then and it to our npm scripts:
Next edit your
package.json
so that the start script looks like:This allows us to start the server with:
Open http://127.0.0.1:8080/. You should see the Hello world! test.
Install the application dependencies
Installing these dependencies gives us everything we need to build our application.
Set up polyfill and steal-conditional
Next we need to make sure the right modules are loaded, first edit your
package.json
with the following:We are using StealJS' paths configuration to make sure the browser version of the polyfill is loaded.
Then, we configure StealJS to load the
steal-conditional
extension as a configuration dependency; in yourpackage.json
add the following:Now restart your server; you can keep it on while you develop the rest of the application.
Import your first module
Create the module
Create index.js with the following:
Yikes! that's a lot of code there! But bear with me, let's break it up in smaller pieces and figure out what's going on:
First, we import the polyfill, notice we are using the regular
import
syntax here, we'll change it in a moment to use thesteal-conditional
boolean syntax; the rest of the code is defining the custom element constructor function.Next, we define the
connectedCallback
function:the
connectedCallback
function is called every time the element is inserted into the DOM.The following functions with
_
in their names (e.g:_makeLinkElement
) are used during rendering and the naming choice is to indicate that these are private methods that shouldn't be used by the custom element's consumer.Finally, and probably the most interesting piece of the code:
This is where the custom element is actually defined, and the whole reason why we might need to load the polyfill.
Use steal.js in your page
Update index.html with:
Add custom element to your page
Next, add the custom element to the index.html page:
Reload index.html to see your changes.
Use steal-conditional boolean syntax
One issue with our current code is that the polyfill is loaded every time, even when the browser already supports the Custom Elements V1 api. We cannot afford wasting precious time and resources to download code that's not needed.
The goal here is to detect whether the browser already supports the feature and only load the polyfill when it's needed.
The boolean conditional syntax
Let's change the
import
in index.js to look like this:This should look a little bit weird to you, if it doesn't, you might want to read this article first.
The part before the
#?
is the polyfill package name we had before, the interesting bit is the text after;needs-polyfill
is a module name, thesteal-conditional
extension will load it first and grab its default export; if the value is not a boolean it will throw an error, otherwisedocument-register-element
will only be loaded if the value istrue
.Create the condition module
Create needs-polyfill.js with:
Reload index.html to see your changes.
In the screenshot above, there is Chrome on the left (Version 55.0.2883.95) and Firefox on the right (Version 50.0.2), highlighted on blue is the request of the condition module which happens on both browsers, in our example that's the
needs-polyfill
module, then highlighted on red is the request to load the polyfill which only happens in Firefox which (for the tested version) doesn't support the Custom Elements V1 api.Build a production app
Now that we've created our application we need to share it with the public. To do this we'll create a build that will concat our JavaScript and styles down to only one file, each, for faster page loads in production.
Build the app and switch to production
When we first installed our initial dependencies for myhub, one of those was steal-tools. steal-tools is a set of tools that helps with bundling assets for production use.
In your package.json
"scripts"
section add:And then you can run:
To use the production artifacts rather than the development files we need to update our index.html to load them.
Update index.html with:
By using
steal.production.js
instead ofsteal.js
StealJS will know to load the production files we just built.A bundle for each conditional module
During the build,
steal-tools
will create separate bundles for each conditionally loaded module, this way only browsers without support will get the penalty of downloading and parsing the polyfill code.If we take a look at the artifacts created during the build process
We can see (the red hightlighted box) the bundle created for the
document-register-element
polyfill module.If we reload index.html and inspect the network tab, we'll notice that the polyfill bundle is only loaded in Firefox.