Background
I have a django app that I want to create an admin widget for. The widget will display text in a particular way (like a terminal). It’s so that app admins can see forwarded logs from an analytics process that is orchestrated by django (the app is django-twined).
To do that I want to use something like terminal-kit or one of the other libraries requiring npm install <whatever>
Building the app
The app is built in docker, and I don’t want the entire node stack to end up in my production image.
I could use a multi-stage docker build; so install node and a lib from NPM in the first stage, then copy the library from node_modules
in the second stage, but this feels unnecessarily slow.
Also, because all I’m doing then is using the raw js static assets that get bundled with the django app, I’m not sure how to go about importing the module (or if this is even possible).
The questions
Can I install an npm module without having the node stack present, and therefore avoid dealing with unwieldy multi stage builds?
How can I then
import
orrequire
the contents of that module into vanilla javascript to use in a django widget?Is this even in general possible? If it looks like moving a mountain, I’ll give up and just slap a text area with monospace font on there… but it would be nice if log highlighting and colours were properly handled in a terminal-like way.
Advertisement
Answer
Can I install an npm module without having the node stack present, and therefore avoid dealing with unwieldy multi stage builds?
You can rollup an npm package using a dev tool like Browserify. This can be done by rolling up the entire package using something like:
browserify --require terminal-kit
Browserify will parse the package and create a single JS file that you can try loading in the browser. There are some limitations to this so I’d recommend experimenting and exploring the Browserify docs.
How can I then import or require the contents of that module into vanilla javascript to use in a django widget?
You can do this by including a Django template file reference in the backend admin class definition. In the template you’ll need to include an html JS source tag that points to the JS script you want to load. Django can include static files when building, you can use that to include the JS file during build time and then a local resource reference to point the template file to the right location.
Is this even in general possible?
Generally speaking this is definitely possible but YMMV. It boils down to the complexities of the npm package and what exactly it is trying to do in the browser.
In steps I would do the following:
- Use Browserify to convert the npm package to a single JS file.
- Create an html file that loads the local JS file, open this in the browser.
- Open the console and see if the commands/context you’re hoping to reproduce are working as expected in the browser. You could also write another vanilla JS file and load that in the html file to test.
- Include the JS file reference in the Django admin template/widget.
- Write custom JS code in the widget that uses/shows the globally instantiated JS script.
This strategy is based off my personal experience, I have had success following this strategy, hopefully it is helpful.