让 Chart.js 在 Rails 7 中与 ImportMap 配合使用

Mar*_*son 3 ruby-on-rails chart.js import-maps

我试过:

./bin/importmap pin chart.js
Run Code Online (Sandbox Code Playgroud)

将其添加到 config/importmap.rb

pin "chart.js", to: "https://ga.jspm.io/npm:chart.js@3.9.1/dist/chart.mjs"
Run Code Online (Sandbox Code Playgroud)

在 application.js 中我添加了:

import 'chart.js'
Run Code Online (Sandbox Code Playgroud)

当我尝试创建新图表时,我收到“图表未定义”。

如果我尝试

import Chart from 'chart.js'
Run Code Online (Sandbox Code Playgroud)

我收到“请求的模块‘chart.js’不提供名为‘default’的导出”

import Chart from 'chart.js/auto' 
Run Code Online (Sandbox Code Playgroud)

说“无法解析模块说明符‘chart.js/auto’”

Mit*_*tch 8

这个周末我也遇到了同样的困难,并且一直在阅读这篇文章,所以在这里发布我的解决方案。

有几点值得注意:

  1. Chart.js 似乎有一些硬编码的附件文件,这些文件未在 CDN 中注册为依赖项。例如,我的在c1719c72.js和chunks/helpers.segment.js上保持 404ing 。因此,如果您在运行时不使用--downloadbin/importmap pin标志,效果会更好。归功于本文:在rail 7中使用chart.js和importmaps。
  2. 从 Chart.js 导入图表需要从这里使用一点魔法:Chart.js - 在哪里可以找到应该注册哪些组件?。具体来说,是下面 barchart_controller.js 的第 3-4 行。

以下是在使用导入映射的相当简单的 Rails 7 构建中对我有用的文件内容的摘要:

config/importmap.rb- 注意:运行bin/importmap pin chart.js应该引入一个依赖项(@kurkle/color)。请务必跳过 --download,否则您将陷入痛苦的世界。

# Pin npm packages by running ./bin/importmap

pin "application", preload: true
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin_all_from "app/javascript/controllers", under: "controllers"

pin "chart.js", to: "https://ga.jspm.io/npm:chart.js@4.2.0/dist/chart.js"
pin "@kurkle/color", to: "https://ga.jspm.io/npm:@kurkle/color@0.3.2/dist/color.esm.js"
Run Code Online (Sandbox Code Playgroud)

app/javascript/application.js

// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
import "@hotwired/turbo-rails"
import "controllers"

import "chart.js"
Run Code Online (Sandbox Code Playgroud)

app/javascript/controllers/barchart_controller.js

import {Controller} from "@hotwired/stimulus"

import { Chart, registerables } from "chart.js";
Chart.register(...registerables);

export default class extends Controller {
    static targets = ['myChart'];

    canvasContext() {
        return this.myChartTarget.getContext('2d');
    }

    connect() {
        new Chart(this.canvasContext(), {
            type: 'bar',
            data: {
                labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
                datasets: [{
                    label: '# of Votes',
                    data: [12, 19, 3, 5, 2, 3],
                    backgroundColor: [
                        'rgba(255, 99, 132, 0.2)',
                        'rgba(54, 162, 235, 0.2)',
                        'rgba(255, 206, 86, 0.2)',
                        'rgba(75, 192, 192, 0.2)',
                        'rgba(153, 102, 255, 0.2)',
                        'rgba(255, 159, 64, 0.2)'
                    ],
                    borderColor: [
                        'rgba(255, 99, 132, 1)',
                        'rgba(54, 162, 235, 1)',
                        'rgba(255, 206, 86, 1)',
                        'rgba(75, 192, 192, 1)',
                        'rgba(153, 102, 255, 1)',
                        'rgba(255, 159, 64, 1)'
                    ],
                    borderWidth: 1
                }]
            },
            options: {
                scales: {
                    y: {
                        beginAtZero: true
                    }
                }
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

我的模型中 div 的内容app/views/widgets/show.html.erb

<div data-controller="barchart">
  <canvas id="bar-chart" data-barchart-target="myChart" width="800" height="450"></canvas>
</div>
Run Code Online (Sandbox Code Playgroud)

不要忘记重建资产(bin/rails 资产:预编译)。