I want to include slickgrid (npm install slickgrid
, slickgrid.net) in my Python Flask project and I don't want to use CDN, so I'm looking at a Webpack solution.
I have been following the procedure for integrating npm packages in Flask using Webpack and as a starting point I have forked the following minimum working example https://github.com/jrybicki-jsc/flasknpm which by default works fine.
I change the file my.js to simply:
import SlickGrid from 'slickgrid';
but when I run the command npm run build
(which uses webpack), I get the following error:
ERROR in ./node_modules/slickgrid/dist/esm/index.js
Module parse failed: Unexpected token (67:54)
You may need an appropriate loader to handle this file type.
| */
| stopPropagation() {
| this._isPropagationStopped = !0, this.nativeEvent?.stopPropagation();
| }
| /**
@ ./src/my.js 1:0-34
As a MWE I would like to get Slickgrid "Example1" working, which can be found at this link in the official slickgrid
repo:
example1
Anybody has some pointers on how to integrate Slickgrid with Flask through Webpack?
It was not a WebPack issue. Apparently Babel is required for the proper translation. I followed this answer to find my way to a solution, in particular the answer from the Babel team member khizerrehandev
. I choose this because it was using the most recent version of Babel7 and works with the latest Webpack5.
After some trial and error I came to this MWE.
EDIT: I noticed that the original solution (still reported here below under "VERSION-0" for completeness was having issues displaying the position of the Slickgrid grid. Sometimes it would show with a "top: 32pix" (correct) and sometimes with "top: 108px" randomly as I would refresh the browser page. I later found out that this is because the slick-alpine-theme.css file was loaded directly into the index.html and not bundled into the bundle.js. In "VERSION-1" I show the changes to bundle the css with webpack and avoid this issue.
VERSION-0
package.json
{
"name": "slickgrid_webpack_flask_MWE",
"version": "1.0.0",
"description": "",
"main": "bundle.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --config webpack.config.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.25.2",
"@babel/preset-env": "^7.25.3",
"babel-loader": "^9.1.3",
"webpack": "^5.93.0",
"webpack-cli": "^5.1.4"
},
"dependencies": {
"slickgrid": "^5.11.0",
"sortablejs": "^1.15.2"
}
}
.babelrc
{
"presets": ["@babel/preset-env"]
}
webpack.config.js
const path = require('path');
module.exports = {
entry: './static/my.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'static')
},
module: {
rules: [{
test: /\.(js)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
}
]
},
};
app.py
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def main():
return render_template('index.html')
if __name__=="__main__":
app.run(debug=True)
index.html
Notice that here I hard copied slick-alpine-theme.css
from the node_modules
directory to my static
folder. In fact I don't know how to load the css directly from node_modules
or somehow include it in the bundle. Also notice the type="module"
when loading the bundle.
<html lang="en">
<head>
<link rel="stylesheet" href="{{ url_for('static', filename='slick-alpine-theme.css') }}" type="text/css"/>
<script type="module" src="{{ url_for('static', filename='bundle.js') }}"></script>
<title>slickgrid webpack flask MWE</title>
</head>
<body>
<div id="myGrid" class="slick-container" style="width:600px;height:500px;"></div>
</body>
</html>
my.js
This is the same code as example1-simple.html with slight modifications
import { SlickGrid } from 'slickgrid';
import Sortable from 'sortablejs';
var grid;
var columns = [
{id: "title", name: "Title", field: "title"},
{id: "duration", name: "Duration", field: "duration"},
{id: "%", name: "% Complete", field: "percentComplete", width: 90 },
{id: "start", name: "Start", field: "start"},
{id: "finish", name: "Finish", field: "finish"},
{id: "effort-driven", name: "Effort Driven", field: "effortDriven", width: 90 }
];
var options = {
enableCellNavigation: true,
enableColumnReorder: false
};
var data = [];
for (var i = 0; i < 500; i++) {
data[i] = {
title: "Task " + i,
duration: "5 days",
percentComplete: Math.round(Math.random() * 100),
start: "01/01/2009",
finish: "01/05/2009",
effortDriven: (i % 5 == 0)
};
}
grid = new SlickGrid("#myGrid", data, columns, options);
Now for the bundle.js creation with the command
npm run build
and of course launch flask.
One thing that is left to find out for me is if I included sortablejs
correctly.
VERSION-1
To solve the issue mentioned at the beginning we need to bundle the css
file with bundle.js
using webpack
. This requires three changes:
index.html
Remove the line
<link rel="stylesheet" href="{{ url_for('static', filename='slick-alpine-theme.css') }}" type="text/css"/>
my.js
Add the line
import "./slick-alpine-theme.css"
webpack.config.js
Add the rule
{
test: /\.css$/,
use: [
'style-loader',
'css-loader']
}
The last steps are to install the npm packages
npm install --save-dev style-loader css-loader
and rebuild `npm run build'