Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bundling ES6 Module with classes using Webpack - Not a Constructor

I am building a library that uses ES6 modules and contains classes. If instead of bundling, I just point the package.json "main" to the source code, all works well! I can import the library into an application and it works wonderfully.

Once I bundle the application using WebPack and point the "main" to the packaged bundle, nothing works and I am left scratching what little hair I have left on my head.

Here is the error I am getting:

notablet__WEBPACK_IMPORTED_MODULE_3__.Notablet is not a constructor

Here is my package.json

{
  "name": "notablet",
  "version": "4.7.0",
  "main": "lib/index.js",
  "type": "module",
  "scripts": {
    "test": "npx mocha ./test/**/*.test.js",
    "coverage": "c8 --reporter=text --all npm run test",
    "build": "webpack --config webpack.config.js"
  },
  "license": "MIT",
  "devDependencies": {
    "c8": "^7.12.0",
    "chai": "^4.3.6",
    "clean-webpack-plugin": "^4.0.0",
    "css-loader": "^6.7.1",
    "jsdom": "^20.0.0",
    "mocha": "^10.0.0",
    "sinon": "^14.0.0",
    "style-loader": "^3.3.1",
    "webpack": "^5.73.0",
    "webpack-cli": "^4.10.0"
  }
}

And here is my webpack.config.js:

import path from 'path';

import {fileURLToPath} from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const config = {
  mode: 'development',
  devtool: false,
  entry: './src/Notablet.js',
  output: {
    path: path.resolve(__dirname, 'lib'),
    filename: "index.js",
    library: "notablet"
  },
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ["style-loader", "css-loader"],
      },
    ],
  }
};

export default config;

Note... I did change the "mode" above from "development" to "production", but got the same error after bundling and using.

Here is relevant parts of my Notablet.js file:

import { Queue } from './Queue.js';
// Themes
import style from './style.css'; // assert { type: "css" };
import light from './theme/light.css';
import dark from './theme/dark.css';
import elegant from './theme/elegant.css';
import fantasy from './theme/fantasy.css';
import robot from './theme/robot.css';


export class Notablet {

    constructor(conf = {}, queue = new Queue()) {
        this.queue = queue;
        var config = {
            backgroundColor: 'black',
            color: '#ffffff',
            theme : 'light'
        };
        this.config = {...config, ...conf};    
        this.loadTheme();
    }


    /**
     * Loads the theme identified in the configuration object along with the base stylesheet
     */
    loadTheme() {
        var theme = this.getTheme(this.config.theme)
        var sheet = new CSSStyleSheet();
        sheet.replace(theme);
        var baseSheet = new CSSStyleSheet();
        baseSheet.replace(style);
        document.adoptedStyleSheets = [baseSheet, sheet];
    }


    getTheme(theme = 'light') {
        var ret = light;
        switch(theme) {
            case "dark":
                ret = dark;
                break;
            case "elegant":
                ret = elegant;
                break;
            case "fantasy":
                ret = fantasy;
                break;
            case "robot":
                ret = robot;
                break;
        }
        return ret;
    }    
}

The error appears to be thrown in my application when I call let nt = new Notablet()

Notablet appears to be a valid class in ES6 and it has a constructor. My assumption is Webpack needs to be configured to handle the ES6 module somehow, but I understood I just needed to change my package.json "type" to "module".

Any help is greatly appreciated!

like image 597
birwin Avatar asked Feb 27 '26 10:02

birwin


1 Answers

Don't know if this is still relevant, but here's webpack's official docs https://webpack.js.org/configuration/output/

TLDR: Try to add libraryTarget: 'umd', to your output options

like image 133
redisotschek Avatar answered Mar 01 '26 23:03

redisotschek



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!