Home > Software engineering >  Webpack is not bundling a imported and used function
Webpack is not bundling a imported and used function

Time:10-16

I'm trying to include and use the function BootstrapCookieConsentSettings from the npm package bootstrap-cookie-consent-settings in my function initConsentBanner but webpack always throws it away and does not include it even though it is used in the referenced entry.js file. Why is it not included?

webpack.config.js:

module.exports = {
  // webpack folder’s entry js — excluded from jekll’s build process.
  entry: "./_webpack/entry.js",
  output: {
    path: __dirname   "/assets",
    filename: "js/bundle.js",
    library: "phasmo"
  },
/*  stats: {
    optimizationBailout: true
  }, */
  module: {
  rules: [
    {
      test: /\.js$/,
      exclude: /(node_modules)/,
      use: {
        loader: "babel-loader",
        options: {
          presets: ['@babel/preset-env']
        }
      }
    }
    ]
  }

_webpack/entry.js:

import "bootstrap";
import "expose-loader?exposes=panzoom!panzoom";

import {BootstrapCookieConsentSettings} from "bootstrap-cookie-consent-settings";

export function fitMap(elem, mapclass = 'svgmap') {
      var mwidth = elem.getAttribute("width")
      var mheight = elem.getAttribute("height")
      elem.setAttribute("viewBox", "0 0 " mwidth " " mheight)
      elem.classList.add(mapclass)
}

export var map_layers = new Map();

function setInvisible(layer, button) {
    layer.setAttribute('visibility', 'hidden');
    button.classList.remove('active')
}

function setVisible(layer, button) {
    layer.setAttribute('visibility', 'visible');
    button.classList.add('active')
}

export var matomo = null;

function matomoLoaded() {
  matomo = window['_paq'];
  return typeof matomo == 'object';
}

export function trackInteraction(elem, interaction_name = null) {
  if(matomoLoaded()) {
    matomo.push(['trackContentInteractionNode', elem, interaction_name]);
  }
}

export var cconsent = null;

export function initConsentBanner() {
  cconsent = new BootstrapCookieConsentSettings({
    autoShowDialog: true, // disable autoShowModal on the privacy policy and legal notice pages, to make these pages readable
    lang: navigator.language, // the language, in which the modal is shown
    languages: ["en", "de"], // supported languages (in ./content/), defaults to first in array
    contentURL: "./content", // this URL must contain the dialogs content in the needed languages
    cookieName: "cookie-consent-settings",  // the name of the cookie in which the configuration is stored as JSON
    cookieStorageDays: 365, // the duration the cookie configuration is stored on the client
    postSelectionCallback: undefined // callback function, called after the user has made his selection
  });
}

export function allInvisible(elem) {
  for (let map_layer of map_layers.values()) {
    setInvisible(map_layer.layer, map_layer.button)
  }
  trackInteraction(elem);
}

export function allVisible(elem) {
  for (let map_layer of map_layers.values()) {
    setVisible(map_layer.layer, map_layer.button)
  }
  trackInteraction(elem);
}

export function toggleVisibility(elem, lname) {
  var layer = map_layers.get(lname).layer
  var button = map_layers.get(lname).button
  if(layer.getAttribute('visibility') == "hidden") {
    setVisible(layer, button)
    trackInteraction(elem, 'SetVisible');
  } else {
    setInvisible(layer, button)
    trackInteraction(elem, 'SetInvisible');
  }
}

export function mapLayerButton(elem, map, layername) {
      console.log("Adding button for " layername)
      var layer = map.querySelector('[inkscape\\:label="' layername '"]')
      if (layer === null) {
        console.log("Layer " layername  " not found in SVG")
        return false
      }
      var layer_elem = document.createElement("li")
      layer_elem.innerHTML = '<button type="button"  data-track-content data-content-ignoreinteraction data-content-name="Layer Dropdown" data-content-piece="' layername '" onClick="phasmo.toggleVisibility(this, \'' layername '\')">' layername '</button>'
      var button = layer_elem.querySelector('button')
      button.classList.add('active')
      map_layers.set(layername, {'button': button, 'layer': layer})
      elem.appendChild(layer_elem)
      if(matomoLoaded()) {
        matomo.push(['trackContentImpressionsWithinNode', layer_elem]);
      }

compiling it:

 $ npx webpack-cli build --mode production                     asset js/bundle.js 97.1 KiB [compared for emit] [minimized] (name: main) 1 related asset
orphan modules 212 KiB [orphan] 59 modules
runtime modules 891 bytes 4 modules
cacheable modules 269 KiB
  modules by path ./node_modules/panzoom/ 35.5 KiB
    modules by path ./node_modules/panzoom/lib/*.js 7.27 KiB 5 modules
    modules by path ./node_modules/panzoom/*.js 28.3 KiB
      ./node_modules/expose-loader/dist/cjs.js?exposes=panzoom!./node_modules/panzoom/index-exposed.js 423 bytes [built] [code generated]
      ./node_modules/panzoom/index.js 27.9 KiB [built] [code generated]
  ./_webpack/entry.js   56 modules 214 KiB [built] [code generated]
  ./node_modules/bootstrap-cookie-consent-settings/src/bootstrap-cookie-consent-settings.js 8.2 KiB [built] [code generated]
  ./node_modules/expose-loader/dist/runtime/getGlobalThis.js 699 bytes [built] [code generated]
  ./node_modules/wheel/index.js 876 bytes [built] [code generated]
  ./node_modules/amator/index.js 3.67 KiB [built] [code generated]
  ./node_modules/ngraph.events/index.js 2.59 KiB [built] [code generated]
  ./node_modules/bezier-easing/src/index.js 3.35 KiB [built] [code generated]
webpack 5.31.2 compiled successfully in 11847 ms

When trying to call initConsentBanner() on the site:

Uncaught TypeError: Ki.BootstrapCookieConsentSettings is not a constructor
    so bundle.js:4930
    <anonymous> (index):7371
bundle.js:4930
    so bundle.js:4930
    <anonym> (index):7371

Does anyone know how to fix this? I tried a thousand things but I can't find out how to fix this.

CodePudding user response:

If you look at the source of bootstrap-cookie-consent-settings (source code), you see that the BootstrapCookieConsentSettings function is not exported. Therefore it is not visible in your entry.js, when you try to import it.

You could simply modify the function in node_modules/bootstrap-cookie-consent-settings/src/bootstrap-cookie-consent-settings.js, so that the function will be visible to your code:

export function BootstrapCookieConsentSettings(props) {

Then your code will be able to construct a new export function BootstrapCookieConsentSettings object.

  • Related