Importing HTML and CSS
Now let's write a similar class and instead of importing the HTML file directly into a string, we
will use the async function import()
. This will not include the text of the HTML file in our
bundle. It will be stored in an external file which will be loaded dynamically.
We will need an own HTML file for this:
src/amazing-button-dynamic.html
| <div class="amazing-button card h-100">
<div class="card-header">Amazing Dynamic Button</div>
<div class="card-body">
<p class="card-text">
<button class="btn btn-secondary">Press Me</button>
</p>
<div class="result border border-primary mb-2">No Result</div>
<img src="images/favicon.png" />
</div>
</div>
|
We write now a new class that imports the HTML structure, insert it into the container element.
Importing the HTML structure with the import()
function returns a promise which resolves to a
module. To get the HTML string you have to read the property`default
from this returned module:
src/amazing-button-dynamic.js
| import $ from "jquery";
import "./amazing-button.css";
export default class {
#maximumNumber = 9;
#button;
get maximumNumber() {
return this.#maximumNumber;
}
set maximumNumber(value) {
this.#maximumNumber = value;
if (this.#button)
this.#button.html(`Show number from 1 to ${this.#maximumNumber}`);
}
constructor(element) {
console.debug("Starting Dynamic Button");
import("./amazing-button-dynamic.html").then((html) => { // (1)!
$(element).html(html.default); // (2)!
this.#button = $(element)
.find("button")
.html(`Show number from 1 to ${this.#maximumNumber}`)
.on("click", () => {
this.resultDiv.html(Math.floor(Math.random() * this.#maximumNumber));
});
this.resultDiv = $(element).find("div.result");
});
}
}
|
- Import HTML file and wait for resolving the promise
- Use the HTML text with the property
default
from the resolved value
Let's add another container in which we will start the new class:
src/index.js
| import createTestContainer from "./create-test-container";
import { default as MyVanillaApp } from "./amazing-button-vanilla";
import { default as MyPackagesApp } from "./amazing-button-packages";
import { default as MyImportApp } from "./amazing-button-import";
import { default as MySvgApp } from "./amazing-button-svg";
import { default as MyDynamicApp } from "./amazing-button-dynamic";
import "./style.css";
createTestContainer("Testing Vanilla JS", "test-container-vanilla");
let myVanillaInstance = new MyVanillaApp(
document.getElementById("test-container-vanilla")
);
myVanillaInstance.maximumNumber = 99;
createTestContainer("Testing Packages", "test-container-packages");
let myPackagesInstance = new MyPackagesApp(
document.getElementById("test-container-packages")
);
myPackagesInstance.maximumNumber = 49;
createTestContainer("Testing Import HTML/CSS/Assets", "test-container-import");
let myImportInstance = new MyImportApp(
document.getElementById("test-container-import")
);
myImportInstance.maximumNumber = 79;
createTestContainer("Testing Import SVG", "test-container-svg");
new MySvgApp(document.getElementById("test-container-svg"));
createTestContainer("Testing Dynamic Imports", "test-container-dynamic");
let myDynamicInstance = new MyDynamicApp(
document.getElementById("test-container-dynamic")
);
myDynamicInstance.maximumNumber = 55;
|
When you run npm run start
you should see the running example in your browser.
When you run npm run build
you can see the results of dynamic importing HTML:
📁 dist
├─ walkthrough-env.<hash>.js
├─ walkthrough-env.<hash>.css
├─ index.html
├─ 📁 manifest
├─ 📁 vendor
├─ 📁 assets
└─ 📁 parts
The HTML file amazing-button-dynamic.html
was moved into a subfolder parts
. The file name is an
ID assigned by Webpack.
This file name can be determined as follows:
src/amazing-button-dynamic.js
| import $ from "jquery";
import "./amazing-button.css";
export default class {
#maximumNumber = 9;
#button;
get maximumNumber() {
return this.#maximumNumber;
}
set maximumNumber(value) {
this.#maximumNumber = value;
if (this.#button)
this.#button.html(`Show number from 1 to ${this.#maximumNumber}`);
}
constructor(element) {
console.debug("Starting Dynamic Button");
import(
/* webpackChunkName: "amazing-button-dynamic.html" */
"./amazing-button-dynamic.html"
).then((html) => {
$(element).html(html.default);
this.#button = $(element)
.find("button")
.html(`Show number from 1 to ${this.#maximumNumber}`)
.on("click", () => {
this.resultDiv.html(Math.floor(Math.random() * this.#maximumNumber));
});
this.resultDiv = $(element).find("div.result");
});
}
}
|
You could even define another subdirectory instead parts
with:
| /* webpackChunkName: "../other-directory/amazing-button-dynamic.html" */
|