Search code examples
node.jsruby-on-railswebpackpassengerwebpacker

Cannot read property 'jquery' of undefined


I have a Rails 6 application with Webpacker. Node packages have been successfully installed with yarn.

The application works locally both in development and production modes with Puma server. But when calling the website on our virtual host, Phusion Passenger fails loading the Bootstrap 4 JavaScript part:

/var/www/vhosts/mydomain.com/httpdocs/myapp/public/packs/js/application-2432a12b5b63094eb637.js:21178
          var e = i.default.fn.jquery.split(' ')[0].split('.');
                               ^

TypeError: Cannot read property 'jquery' of undefined
    at Object.jQueryDetection (/var/www/vhosts/mydomain.com/httpdocs/myapp/public/packs/js/application-2432a12b5b63094eb637.js:21178:32)
    at a (/var/www/vhosts/mydomain.com/httpdocs/myapp/public/packs/js/application-2432a12b5b63094eb637.js:21183:9)
    at Object.<anonymous> (/var/www/vhosts/mydomain.com/httpdocs/myapp/public/packs/js/application-2432a12b5b63094eb637.js:22435:56)
    at n (/var/www/vhosts/mydomain.com/httpdocs/myapp/public/packs/js/application-2432a12b5b63094eb637.js:8:17)
    at Module.<anonymous> (/var/www/vhosts/mydomain.com/httpdocs/myapp/public/packs/js/application-2432a12b5b63094eb637.js:18176:7)
    at Module.<anonymous> (/var/www/vhosts/mydomain.com/httpdocs/myapp/public/packs/js/application-2432a12b5b63094eb637.js:18179:7)
    at n (/var/www/vhosts/mydomain.com/httpdocs/myapp/public/packs/js/application-2432a12b5b63094eb637.js:8:17)
    at /var/www/vhosts/mydomain.com/httpdocs/myapp/public/packs/js/application-2432a12b5b63094eb637.js:26:98
    at Object.<anonymous> (/var/www/vhosts/mydomain.com/httpdocs/myapp/public/packs/js/application-2432a12b5b63094eb637.js:27:2)
    at Module._compile (internal/modules/cjs/loader.js:1085:14)

enter image description here

app/javascript/packs/application.js:

// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.

console.log('Webpacker: START application.js');

require('@rails/ujs').start();
require('turbolinks').start();
require('@rails/activestorage').start();
require('channels');
require('jquery');

// Uncomment to copy all static images under ../images to the output folder and reference
// them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>)
// or the `imagePath` JavaScript helper below.
//
// const images = require.context('../images', true)
// const imagePath = (name) => images(name, true)

// #################### Proprietary configuration ####################

// JAVASCRIPT LIBRARIES
import 'popper.js';
import 'bootstrap';
import '@fortawesome/fontawesome-free';

// CSS OF USED LIBRARIES
import 'stylesheets/application';

// datetime picker
// load "moment" globally to avoid:
// "Error: Tempus Dominus Bootstrap4's requires moment.js. Moment.js must be included before Tempus Dominus Bootstrap4's JavaScript."
// See https://stackoverflow.com/questions/49580266/tempus-dominus-bootstrap4-requires-moment-js-datetime-picker
global.moment = require('moment');
require('moment/locale/de');
// If you require timezone data (see moment-timezone-rails for additional file options)
// import "moment-timezone-with-data"
require('tempusdominus-bootstrap-4');

console.log('Webpacker: END application.js');

config/webpack/environments.js (don't know what's correct here):

const { environment } = require('@rails/webpacker')

const webpack = require('webpack');
environment.plugins.prepend('Provide', // append
    new webpack.ProvidePlugin({
      $: 'jquery/src/jquery',
      jQuery: 'jquery/src/jquery' // ,
      // Popper: ['popper.js', 'defaults']
    })
);

module.exports = environment

package.json:

{
  "name": "myapp",
  "private": true,
  "dependencies": {
    "@fortawesome/fontawesome-free": "^5.15.4",
    "@popperjs/core": "^2.10.1",
    "@rails/activestorage": "^6.1.4-1",
    "@rails/ujs": "^6.1.4-1",
    "@rails/webpacker": "5.4.3",
    "bootstrap": "4.6.0",
    "jquery": "^3.6.0",
    "moment": "^2.29.1",
    "moment-timezone": "^0.5.33",
    "popper.js": "^1.16.1",
    "tempusdominus-bootstrap-4": "^5.39.0",
    "tempusdominus-core": "^5.19.0",
    "turbolinks": "^5.2.0",
    "webpack": "^4.46.0",
    "webpack-cli": "^3.3.12"
  },
  "devDependencies": {
    "webpack-dev-server": "^3"
  }
}

When I use

if (typeof window !== "undefined") {
  require('popper.js');
  require('bootstrap');
  require('@fortawesome/fontawesome-free');
}

like in Trying to import Bootstrap on Next.JS but says "TypeError: Cannot read property 'jquery' of undefined", I get another error:

/var/www/vhosts/mydomain.com/httpdocs/myapp/public/packs/js/application-2432a12b5b63094eb637.js:1785
      return window.document;
      ^

ReferenceError: window is not defined
    at Object.<anonymous> (/var/www/vhosts/mydomain.com/httpdocs/myapp/public/packs/js/application-2432a12b5b63094eb637.js:1785:7)
    at Object.<anonymous> (/var/www/vhosts/mydomain.com/httpdocs/myapp/public/packs/js/application-2432a12b5b63094eb637.js:1786:7)
    at n (/var/www/vhosts/mydomain.com/httpdocs/myapp/public/packs/js/application-2432a12b5b63094eb637.js:8:17)
    at Object.<anonymous> (/var/www/vhosts/mydomain.com/httpdocs/myapp/public/packs/js/application-2432a12b5b63094eb637.js:6524:10)
    at n (/var/www/vhosts/mydomain.com/httpdocs/myapp/public/packs/js/application-2432a12b5b63094eb637.js:8:17)
    at Object.<anonymous> (/var/www/vhosts/mydomain.com/httpdocs/myapp/public/packs/js/application-2432a12b5b63094eb637.js:1682:110)
    at Object.<anonymous> (/var/www/vhosts/mydomain.com/httpdocs/myapp/public/packs/js/application-2432a12b5b63094eb637.js:1772:8)
    at n (/var/www/vhosts/mydomain.com/httpdocs/myapp/public/packs/js/application-2432a12b5b63094eb637.js:8:17)
    at Object.<anonymous> (/var/www/vhosts/mydomain.com/httpdocs/myapp/public/packs/js/application-2432a12b5b63094eb637.js:1860:7)
    at n (/var/www/vhosts/mydomain.com/httpdocs/myapp/public/packs/js/application-2432a12b5b63094eb637.js:8:17)

What am I missing?


Solution

  • Rails applications with Webpacker must not run as Node.js application additionally, although there are some Node packages used with Webpacker. They are only for client-side.

    Phusion Passenger on the virtual host was configured not to load frequent application changes of all my numerous trial fixes. That's why the error didn't disappear when I tried the above solution weeks ago already ;-)


    https://stackoverflow.com/questions/60198141/trying-to-import-bootstrap-on-next-js-but-says-typeerror-cannot-read-property was correct. Just had to wrap ALL Javascript library loads in application.js into condition:
    if (typeof window !== "undefined")