stimulus: Class constructor Controller cannot be invoked without 'new' (3.0.0-beta1)

Just had a go at updating our Stimulus 2.x app to the beta. We’re using Rails/Webpacker.

I think there’s some missing parts of the docs around this change (in the push to importmaps) so I did have to guess some of the new Webpack configuration code. Namely - definitionsFromContext used to come from stimulus/webpack-helpers and I think it now comes from just @hotwired/stimulus.

import { Application } from "@hotwired/stimulus";
import { definitionsFromContext } from "@hotwired/stimulus";

const application = Application.start();
const context = require.context("./controllers", true, /\.js$/);
application.load(definitionsFromContext(context));

This runs, however in the browser I get the following error - following the stacktrace it occurs in each of my controller modules.

Uncaught (in promise) TypeError: Class constructor Controller cannot be invoked without 'new'
    at new _default (application.js:3048)
    at new extended (vendors-node_modules_babel_runtime_regenerator_index_js-node_modules_hotwired_stimulus_dist_s-68817b.js:1338)
    at new Context (vendors-node_modules_babel_runtime_regenerator_index_js-node_modules_hotwired_stimulus_dist_s-68817b.js:1198)
    at Module.fetchContextForScope (vendors-node_modules_babel_runtime_regenerator_index_js-node_modules_hotwired_stimulus_dist_s-68817b.js:1400)
    at Module.connectContextForScope (vendors-node_modules_babel_runtime_regenerator_index_js-node_modules_hotwired_stimulus_dist_s-68817b.js:1386)
    at Router.scopeConnected (vendors-node_modules_babel_runtime_regenerator_index_js-node_modules_hotwired_stimulus_dist_s-68817b.js:1705)
    at ScopeObserver.elementMatchedValue (vendors-node_modules_babel_runtime_regenerator_index_js-node_modules_hotwired_stimulus_dist_s-68817b.js:1623)
    at ValueListObserver.tokenMatched (vendors-node_modules_babel_runtime_regenerator_index_js-node_modules_hotwired_stimulus_dist_s-68817b.js:814)
    at TokenListObserver.tokenMatched (vendors-node_modules_babel_runtime_regenerator_index_js-node_modules_hotwired_stimulus_dist_s-68817b.js:747)
    at vendors-node_modules_babel_runtime_regenerator_index_js-node_modules_hotwired_stimulus_dist_s-68817b.js:741

Nothing fancy going on with my controllers - just updated the import from stimulus to @hotwired/stimulus as expected.

import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
  //
}

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 1
  • Comments: 16 (6 by maintainers)

Commits related to this issue

Most upvoted comments

In package.json add "not IE 11" to "browserslist"

"browserslist": [
    "defaults",
    "not IE 11"
  ]

@m3xq’s suggestion appears to have done the trick for me.

I fixed this issue when I removed "@webpack-cli/serve": "^1.6.0". It somehow got installed together with "webpack-dev-server": "^4.6.0". Ref:. https://github.com/rails/webpacker/pull/3225#discussion_r750726841

I don’t think this error is limited to the webpacker-helpers I had a similar issue with Webpacker 6 and Stimulus rc-1 I am using the webpack helpers from the dedicated package and now the same error propagates to Stimulus.

The error I get is :

Uncaught (in promise) TypeError: Class constructor G cannot be invoked without 'new'
    at t.n [as constructor] (3-fcb5efc612db67d72f35.js:1)
    at new s (3-fcb5efc612db67d72f35.js:1)
    at new t (91-e95a1cbb0dcd51977d93.js:2)
    at new T (91-e95a1cbb0dcd51977d93.js:2)
    at D.fetchContextForScope (91-e95a1cbb0dcd51977d93.js:2)
    at D.connectContextForScope (91-e95a1cbb0dcd51977d93.js:2)
    at H.scopeConnected (91-e95a1cbb0dcd51977d93.js:2)
    at F.elementMatchedValue (91-e95a1cbb0dcd51977d93.js:2)
    at k.tokenMatched (91-e95a1cbb0dcd51977d93.js:2)
    at x.tokenMatched (91-e95a1cbb0dcd51977d93.js:2)

Solution

After several testing and comparison with Webpacker 5 settings, I think I found the source. removing loose: true in babel seems to solve the issue.

{
  useBuiltIns: 'entry',
  corejs: '3.8',
  modules: 'auto',
  bugfixes: true,
-  loose: true,
  exclude: ['transform-typeof-symbol']
}

Posting a solution here and will report back in https://github.com/rails/webpacker/issues/3153

I’m also running into this issue. I am not an expert on Webpack, Webpacker, or Babel, just a frightened user of all three 😅. I tried the change suggested above but was unable to get it to work. Webpack was still able to compile, but the resulting JS was giving me the titular error.

Apologies if I’m saying something everyone already knows, but from some googling I learned that this particular error is usually from extending a native JS class with a Babel transformed class. In this case, I think Stimulus has changed its export so that it is no longer exporting a babel transformed class, it’s now exporting a real JS class. And Webpacker 6 does not run on node_modules, so the Stimulus Controller class is not being transformed such that it can work with the transformed classes in my application.

I spent almost the entirety of yesterday trying things to get it to work, and I unfortunately am going to have to bail on it for now and just use the dev build of stimulus that I was using before: https://github.com/hotwired/dev-builds/archive/stimulus/353890e.tar.gz