简体   繁体   中英

Fixing “Uncaught ReferenceError: Highcharts is not defined” in Rails app

I'm trying to use Highcharts in a Rails 5.2 / webpacker application. (I'm new to webpacker and am using it because we've adopted a third-party theme for the application that is built on webpack. That theme is now working fully.) When I include the Highcharts code in the app, I get no charts and instead an error at the console: Uncaught ReferenceError: Highcharts is not defined at HTMLDocument.<anonymous> . Unfortunately, I'm new to webpacker and JS isn't really my thing.

I have followed the instructions on the Highcharts site for installing Highcharts using npm (although my system is using yarn) and everything seems to be correct, apart from this error being generated!

package.json:

{
...
  "devDependencies": {
    "webpack-dev-server": "^3.7.2"
  },
  "dependencies": {
    "highcharts": "^7.1.2",
    "webpack": "4.32.2",
    "webpack-cli": "3.3.2",
...
  }
}

config/webpack/environment.js:

const { environment } = require('@rails/webpacker');
...
const Highcharts = require("highcharts");

const webpack = require('webpack');

environment.plugins.prepend(
  'Provide',
  new webpack.ProvidePlugin({
    $: 'jquery',
    '$': 'jquery',
    'window.$': 'jquery',
    jQuery: "jquery",
    jquery: "jquery",
    "window.$": "jquery",
    "window.jQuery": "jquery",
    Popper: ["popper.js", "default"]
  })
);

environment.loaders.append('expose', {
  test: require.resolve('jquery'),
  use: [{
    loader: 'expose-loader',
    options: '$'
  }, {
    loader: 'expose-loader',
    options: 'jQuery'
  }]
});

module.exports = environment;

app/javascripts/packs/app.js:

const images = require.context('../images', true)
const imagePath = (name) => images(name, true)

import Highcharts from 'highcharts/modules/exporting';

import Rails from 'rails-ujs'
Rails.start()

import "../modules/bootstrap";
import "../modules/feather";
import "../modules/sidebar";
import "../modules/user-agent";
import "../modules/mask";
import "../modules/select2";
import "../modules/validation";
import '../scss/app.scss';

app/views/layouts/application.html.erb:

<!DOCTYPE html>
<html lang="en">

  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <link rel="preconnect" href="//fonts.gstatic.com/" crossorigin>
    <title><%= full_title(yield(:title)) %></title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>
    <%= render 'layouts/shim' %>
    <%= stylesheet_pack_tag 'app' %>
  </head>

  <body>
    <%= render 'layouts/app_pages' %>
    <%= javascript_pack_tag 'app' %>
  </body>
</html>

page template (essentially direct from the Highcharts "Your first chart" page):

...
<div class="col-12 text-center" id="chart"></div>
<script>
  document.addEventListener('DOMContentLoaded', function () {
      var myChart = Highcharts.chart('chart', {
          chart: {
              type: 'bar'
          },
          title: {
              text: 'Fruit Consumption'
          },
          xAxis: {
              categories: ['Apples', 'Bananas', 'Oranges']
          },
          yAxis: {
              title: {
                  text: 'Fruit eaten'
              }
          },
          series: [{
              name: 'Jane',
              data: [1, 0, 4]
          }, {
              name: 'John',
              data: [5, 7, 3]
          }]
      });
  });
</script>
...

I've tried changing the order in which I import the module (right at the top, right at the end, or in the middle) but to no avail. Webpack is compiling the code happily, and I've restarted webpack-dev-server multiple times during the process, to make sure environment.js changes are being run. I've also confirmed that the Highcharts code is in the app.js file emitted by webpack and that it's accessible from the web page (ie I can load the app.js file in the Developer Tools in my browser, and searching the file shows code from Highcharts 7.1.2).

I've also tried having the require / import line in app.js formatted as require('highcharts/modules/exporting')(Highcharts); (as indicated in the Highcharts docs) and as import 'highcharts/modules/exporting'; (to match the other import lines in the file), but they both produce the same result - no charts and a Highcharts is not defined error.

Can anyone suggest how to get charts generated successfully by Highcharts on the web page, with no JS errors?

Thanks!

====Edit====

I've tried creating a completely new Rails app using rails new test --webpack , doing yarn add highcharts and then adding just the lines to get Highcharts installed:

  • setting route and controller to a static page;
  • adding the following to environment.js:
const Highcharts = require("highcharts");

const webpack = require('webpack');

environment.plugins.prepend(
  'Provide',
  new webpack.ProvidePlugin({
    $: 'jquery',
    '$': 'jquery',
    'window.$': 'jquery',
    jQuery: "jquery",
    jquery: "jquery",
    "window.$": "jquery",
    "window.jQuery": "jquery"
  })
);
  • adding import Highcharts from 'highcharts/modules/exporting'; to app/javascript/packs/application.js
  • adding template HTML from the Highcharts docs to the application_layout.html page.

And, after doing this, I get exactly the same error. What am I missing?

Can you try like this. Because high chart module may not loaded before

 var chart = new Highcharts.Chart({ }); 

The answer was adding window.Highcharts = Highcharts; to the application.js file along with the import Highcharts from 'highcharts'; line.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM