
本文详解 chart.js 在原生 javascript 中报错 “uncaught referenceerror: chart is not defined” 的根本原因,并提供兼容 v4+ 的标准化引入方案,涵盖模块化与全局模式的区别、脚本加载顺序、作用域陷阱及可运行示例。
在使用 Chart.js(尤其是 v4.x 及以上版本)进行前端图表开发时,开发者常遇到如下控制台错误:
Uncaught ReferenceError: Chart is not defined
该错误并非因 CDN 链接失效或版本不兼容导致,而是由 JavaScript 模块作用域机制引发的典型误解。
? 根本原因:type="module" 阻断全局暴露
你当前的 <script type="module"> 引入方式(如下):</script>
<script type="module" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.3.2/chart.umd.js"></script>
会使 Chart.js 以 ES 模块方式执行,其导出内容(如 Chart 类)仅在模块作用域内有效,不会自动挂载到全局 window 对象上。因此后续 <script type="text/javascript">(非模块脚本)中直接调用 new Chart(...) 时,Chart 在全局作用域中并不存在,自然抛出 ReferenceError。</script>
✅ 正确做法取决于你的使用场景:若需全局访问(即传统 中直接使用 Chart),应避免 type="module",改用标准 标签加载 UMD 版本。
✅ 推荐解决方案:使用 UMD + 全局模式(适用于大多数 vanilla JS 项目)
只需将引入方式改为标准脚本标签,并确保加载顺序在图表初始化代码之前:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Chart.js v4 示例</title>
<!-- ✅ 正确:UMD 版本,无 type="module",自动挂载 window.Chart -->
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.2/dist/chart.umd.min.js"></script>
</head>
<body>
<canvas id="myChart" style="max-height:400px; max-width:500px;"></canvas>
<script>
// 工具函数(修复原代码中的 this 调用问题)
function getRandomInt(n, min, max) {
const result = [];
const safeMin = Math.ceil(min);
const safeMax = Math.floor(max);
for (let i = 0; i < n; i++) {
result.push(Math.floor(Math.random() * (safeMax - safeMin) + safeMin));
}
return result;
}
const ctx = document.getElementById('myChart').getContext('2d');
const labels = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul'];
const config = {
type: 'line',
data: {
labels: labels,
datasets: [
{
label: 'Dataset 1',
data: getRandomInt(7, -100, 100),
borderColor: '#f22613',
tension: 0.3
},
{
label: 'Dataset 2',
data: getRandomInt(7, -100, 100),
borderColor: '#4287f5',
tension: 0.3
}
]
},
options: {
responsive: true,
plugins: {
legend: { position: 'top' }
}
}
};
// ✅ 现在 Chart 已在全局可用
new Chart(ctx, config);
</script>
</body>
</html>? 注意事项:
- 使用 getContext('2d') 获取 canvas 上下文是 Chart.js v4+ 的强制要求(v2.x 中可传 canvas 元素,v4+ 必须传 CanvasRenderingContext2D);
- 原代码中 this.getRandomInt(...) 是错误写法(this 指向全局对象,但函数未绑定),已修正为直接调用;
- CDN 推荐使用 jsDelivr 或官方推荐链接,稳定性优于某些公共 CDN;
- 若坚持使用模块化开发(如配合 Vite/Webpack),则需通过 import { Chart } from 'chart.js'; 显式导入,并确保所有相关逻辑在同一模块作用域内。
? 补充说明:UMD vs ESM 的选择逻辑
| 方式 | 标签写法 | Chart 是否全局可用 | 适用场景 |
|---|---|---|---|
| UMD(推荐 vanilla) | <script src="...chart.umd.js"></script> | ✅ 是 | 传统 HTML + JS 项目、快速原型、无构建工具环境 |
| ESM(现代构建项目) | <script type="module" src="...chart.esm.js"></script> | ❌ 否(需 import) | 使用 Vite、Webpack、Rollup 等打包工具的工程化项目 |
✅ 总结
- ❌ 错误实践:用 type="module" 加载 UMD 文件,期望全局变量 Chart;
- ✅ 正确实践:用普通 <script> 标签加载 .umd.js 文件,Chart.js 会自动注册 window.Chart;</script>
- ⚠️ 关键细节:v4+ 必须传 canvas.getContext('2d'),而非 canvas 元素本身;
- ? 官方文档始终是权威参考:Chart.js Getting Started。
按此规范调整后,图表即可正常渲染,再无 ReferenceError 干扰。










