Search code examples
djangotwitter-bootstrapnpmwebpackbundle

How to use javascript libraries imported from NPM


Context

For a long time I was using Bootstrap and other libraries by sources. I mean I was including it as below:

- static
   - vendor
       - jquery
       - popper
       - bootstrap
       - ...

But nowadays, I need to improve myself in managing my web dependencies. For some reasons :

  • Less sources in repositories and a more efficient team project
  • Greater support to choose version or test migrations
  • Saving time for later projects with same dependencies
  • I need to include a library which is only provided through NPM which is codemirror

So I am currently trying to manage dependencies via NPM, in a django project. But I'm stuck at a very basic step I guess. I don't know where to continue after npm install --save jquery popper.js bootstrap. I'm disturbed by all examples which are for node.js application...

Where I'm stuck

I have an index.js at the same level of my main package.json. I thought I had to import my scripts in this file, then include this script in my page. So I tried require Jquery then bootstrap, but I get errors on bootstrap required because jquery is undefined.
I don't have much code to show, the more I need is to understand how it works step by step rather than having it done to me.


Questions

My primary goal is to manage my main javascripts, I mean scripts that must appear through the whole site. Wrap them into one script, then include this script in my base.html assuming I'm in a django project.

  1. I know that bootstrap < v5 depends on Jquery and popper.js, but it comes with its own package.json, isn't that enough ? Do we have to npm install jquery popper.js them anyway, as some people suggest in some SO thread or else ? Even after running npm install inside the node_module/bootstrap ? Additionally, the bootstrap.bundle.js contains popper.js, and node_modules inside bootstrap contains jquery. Why not use those ? See Bootstrap import with webpack Otherwise why are they there ?
  2. How to bundle my javascript dependencies ? Via webpack ? For example, Jquery from bootstrap/node_modules/jquery/dist/jquery.js with bootstrap/dist/js/bootstrap.bundle.js ? Then I will have same versions used by bootstrap developers.
  3. Then how to compile the wanted scripts into one script, and minify it for example ? Then I could get those scripts by collectstatic function into the folder where I group all my desired statics.

Perhaps I'm not clear, because all of this blurred my mind.


Webography

Use Sass/css within django, NPM way
Add react in django project, via NPM
Bootstrap package manager
Bootstrap import with webpack Npm install jquery, poper, bootstrap
React with webpack


Editions with my progress

package.json

{
  "name": "static_src",
  "version": "1.0.0",
  "description": "Static files from NPM.",
  "private": true,
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "npx webpack -c webpack-conf.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "bootstrap": "^4.5.3",
    "codemirror": "^5.58.2",
    "jquery": "^3.5.1",
    "popper.js": "^1.16.1"
  },
  "devDependencies": {
    "webpack": "^5.6.0",
    "webpack-cli": "^4.2.0"
  }
}

webpack-conf.js

var path = require('path');
var webpack = require('webpack');

module.exports = {
  entry: './index.js',
  output: { path: __dirname, filename: 'dist/bootstrap-bundle.js' }
};

index.js

import $ from 'jquery';
import {} from 'popper.js';
import 'bootstrap'

npm run build

> npx webpack -c webpack-conf.js

[webpack-cli] Compilation finished
asset dist/bootstrap-bundle.js 169 KiB [emitted] [minimized] (name: main) 1 related asset
runtime modules 1.13 KiB 5 modules
cacheable modules 508 KiB
  ./index.js 71 bytes [built] [code generated]
  ./node_modules/jquery/dist/jquery.js 281 KiB [built] [code generated]
  ./node_modules/bootstrap/dist/js/bootstrap.js 140 KiB [built] [code generated]
  ./node_modules/popper.js/dist/esm/popper.js 86.4 KiB [built] [code generated]
webpack 5.6.0 compiled successfully in 4541 ms

Result

Well for now I manage to include this bundle into my site, but an error occured, and it seems not including Jquery : ReferenceError: $ is not defined. Notably it occurs on this snippet for example :

$(function () {
    $('[data-toggle="popover"]').popover()
    $('[data-toggle="tooltip"]').tooltip()
})

Any idea ?


Solution

  • I came to a great solution !

    webpack-conf.js

    var path = require('path');
    var webpack = require('webpack');
    
    module.exports = {
        entry: './index.js',
        output: {path: __dirname, filename: 'dist/bootstrap-bundle.js'},
        plugins: [
            new webpack.ProvidePlugin({
                $: 'jquery',
                jQuery: 'jquery'
            })
        ]
    };
    

    index.js

    import $ from 'jquery';
    window.jQuery = $;
    window.$ = $;
    import {} from 'popper.js';
    import 'bootstrap'
    

    Then importing this script works well. Thanks to @Karanveer that unblurred my mind to put me on the right way. And this thread about webpack issues