General setup
I am building a small website with webpack and pug based on this awesome boilerplate: https://github.com/alexnoz/webpack-pug-scss-boilerplate.git
The project is up and running and I am able to render pug files correctly.
Requirement
Now I need to load some data before all the webpack compiling happens. I want to pass that data to the pug-html-loader as described in this answered question.
Problem/Question
My problem is, that I have to load that data asynchronically. So what I have is a Promise. How can I make sure that the promise is finished before webpack compile happens?
This is my current aproach that doesn't work
// in webpack.config.js
var myData = []
loadSomeDataAsync().then(loadedData => myData = loadedData)
{
loader: 'pug-html-loader',
options: {
data: myData // <====
}
}
pug-html-loader
accepts the options.data
If I put static data there, then this data is available inside the pug template.
I know that my problem seems to be, that my Promise is not yet resolved, before the webpack compile happens. But how can get webpack to somehow "wait" for the Promise to resolve?
I already tried to register webpack event hooks. But did not succeed. Any further suggestions?
the default pattern for this situation looks like:
const configPromise = new Promise(function(resolve, reject) {
setTimeout(() => { resolve(webpackConfig) }, 1000);
});
configPromise
.then(webpack) // Passes the config to webpack
.then(compiler => {
// Do the work with the compiler
});
The feature is well documented in DOCS.
Webpack will run the function exported by the configuration file and wait for a Promise to be returned. Handy when you need to asynchronously load configuration variables.
module.exports = () => {
return new Promise((resolve, reject) => { // The promise could be an XHR call using fetch, Axios or whatever
setTimeout(() => {
resolve({ // Resolve webpack config
entry: './app.js',
/* ... */
});
}, 5000);
});
};
As simple as that:
module.exports = () => {
return loadSomeDataAsync().then(function(loadedData) {
return {
entry: './app.js',
...
options {
data: loadedData
}
...
}
});
};
Note that the setTimeout() in the documentation is for illustration purposes (to simulate a delay while fetching data).
How is it waiting? Internally, they must be using async + await.
For example, to help you better understand, look at this code (again, for illustration purposes):
function simulateLoadData() {
return new Promise(resolve => {
setTimeout(() => {
resolve("data"); // once I get the data, I pass it through resolve
}, 2000); // just for illustration purposes and simulate query to remote machine
});
}
function getConfig() {
return simulateLoadData().then(function(dataLoaded){ // here I retrieve the data resolved
return { data: dataLoaded }; // I can pass dataLoaded to my config
});
}
async function app() {
var config = await getConfig(); // here is where I retrieve the returned config
console.log("config", config); // config > Object { data: "data" }
}
app();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With