Hi,
on this tutorial, we'll be dealing with lazy-loading in Mithril.
On the Mithril documentation, this is described under Code splitting in the routes page as:
Code splitting
In a large application, it may be desirable to download the code for each route on demand, rather than upfront. Dividing the code-base this way is known as code splitting or lazy loading. In Mithril, this can be accomplished by returning a promise from the
onmatch
hook:At its most basic form, one could do the following:
// Home.js
module.export = {
view: function() {
return [
m(Menu),
m("h1", "Home")
]
}
}
// index.js
function load(file) {
return m.request({
method: "GET",
url: file,
extract: function(xhr) {
return new Function("var module = {};" + xhr.responseText + ";return module.exports;")
}
})
}
m.route(document.body, "/", {
"/": {
onmatch: function() {
return load("Home.js")
},
},
})
However, realistically, in order for that to work on a production scale, it would be necessary to bundle all of the dependencies for the Home.js module into the file that is ultimately served by the server.Fortunately, there are a number of tools that facilitate the task of bundling modules for lazy loading. Here's an example using webpack's code splitting system:
// index.js
function load(file) {
return m.request({
method: "GET",
url: file,
extract: function(xhr) {
return new Function("var module = {};" + xhr.responseText + ";return module.exports;")
}
})
}
m.route(document.body, "/", {
"/": {
onmatch: function() {
return load("Home.js")
// using Webpack async code splitting
return new Promise(function(resolve) {
require(['./Home.js'], resolve)
})
},
},
})
This can also be achieved using es6 dynamic import and default export as follows:
// Home.js
const Home = {
view: function() {
return [
m(Menu),
m("h1", "Home")
]
}
}
export default Home;
// index.js
m.route(document.body, "/", {
"/": {
onmatch: () => {
// using Webpack async code splitting
return new Promise((resolve) => {
// using dynamic import
import(/* webpackChunkName: "landing" */'./home.js').then((home) => {
resolve(home.default);
}
});
},
},
});
This is the same as above, using
async
await
:// Home.js
const Home = {
view: function() {
return [
m(Menu),
m("h1", "Home")
]
}
}
export default Home;
// index.js
m.route(document.body, "/", {
"/": {
onmatch: () => {
// using Webpack async code splitting
return new Promise(async (resolve) => {
// using dynamic import
const home = await import(/* webpackChunkName: "home" */'./Home.js');
resolve(home.default);
});
},
},
});
Notice this
/* webpackChunkName: "home" */
This name is used internally by webpack during module imports
climigApuncge Jeff Krogman https://wakelet.com/wake/fv2EhO9wG1NUBonCIdc4N
ReplyDeletebinanewma