I want to bundle a grafana’s scripted dashboard with webpack to modularize it.
As a start, I am trying to bundle a simple test script provided by grafana as an example. The sample example is working, but when I bundle it with webpack with a very minimal configuration, the output script is not working. I am getting the following error :
Script dashboard error TypeError: Cannot read property ‘rows’ of undefined
const path = require(‘path’);
// webpack.config.js
module.exports = {
entry: './src/scripted.js',
output: {
filename: 'scripted_NEW.js',
path: path.resolve(__dirname, 'dist'),
},
mode: 'production'
};
What am I missing ?
Reproduction repo
1 Like
Found a solution that’s involve a custom webpack plugin : https://github.com/ThomasKientz/grafana-webpack
1 Like
If anyone stumbles on this in the future and does not want to use this custom webpack configuration we solved this in a slightly different way.
For us to have many scripted dashboard JS files outputted from our strict TypeScript monorepo, we introduced a custom Rollup plugin with a hook function to clean up the bundled JS output file.
const rollupConfig = [
{
input: `${scriptedDashboardsPath}/src/*.ts`,
output: [
{
dir: `${scriptedDashboardsPath}/dist`,
format: "cjs"
}
],
external: [...Object.keys(pkg.dependencies || {}), ...Object.keys(pkg.peerDependencies || {})],
plugins: [
multiInput({ relative: `${scriptedDashboardsPath}/src/` }),
commonjs(),
typescript(),
cleanDist(),
replaceModule()
]
}];
And for the custom function that will go through all of our different scripted dashboard bundled files and replace the needed object, set as a module.exports
to the return method that Grafana needs.
const replaceModule = () => ({
name: "replace Module",
writeBundle() {
const options = {
files: "apps/grafana/scripted-dashboards/dist/*.js",
from: "module.exports =",
to: "return"
};
try {
const results = replace.sync(options);
results.forEach((file) => {
if (file.hasChanged) console.log(` - ${file.file.split("/dist/")[1]}\n`);
});
} catch (error) {
console.error("Error occurred:", error);
}
}});
This can of course be done with the different build hooks in any modern bundler, but we chose to use Rollup in this case.