无法通过npm本地包引入Chart.js的问题求助
问题:本地npm安装Chart.js后在Express中无法加载,出现404及Chart未定义错误
我正在开发一款记录技能/活动时长并通过Chart.js柱状图展示数据的Web应用,使用CDNJS引入Chart.js可正常显示模拟图表,但希望改用npm安装的本地包。已在express中配置node_modules为静态资源,在HTML中尝试引入/node_modules/chart.js/dist/chart.umd.js,但页面出现404资源未找到、MIME类型错误及Chart未定义的报错,多次检查路径无效,请问是否有解决办法,还是只能回归CDN方式?
可正常运行的HTML(CDN方式)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Main Page</title> <!-- Reference Chart.js from cdnjs --> <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.1/chart.umd.js"></script> </head> <body> <h1>Main Page</h1> <canvas id="hoursChart" width="400" height="400"></canvas> <button onclick="addLoggedHours()">Add Logged Hours</button> <button onclick="addNewSkill()">Add New Skill</button> <script> function updateChart(data) { var ctx = document.getElementById('hoursChart').getContext('2d'); var myChart = new Chart(ctx, { type: 'bar', data: { labels: data.labels, datasets: [{ label: 'Logged Hours', data: data.hours, backgroundColor: 'rgba(75, 192, 192, 0.2)', borderColor: 'rgba(75, 192, 192, 1)', borderWidth: 1 }] }, options: { scales: { yAxes: [{ ticks: { beginAtZero: true } }] } } }); } var sampleData = { labels: ['Skill 1', 'Skill 2', 'Skill 3'], hours: [10, 20, 30] } updateChart(sampleData); </script> </body> </html>
可正常运行的app.js相关片段
const express = require('express'); const exphbs = require('express-handlebars'); const path = require('path'); const app = express(); app.engine('.hbs', exphbs.engine({ extname: '.hbs', defaultLayout: 'main', layoutsDir: path.join(__dirname, '..', 'frontend', 'views', 'layouts'), partialsDir: path.join(__dirname, '..', 'frontend', 'views', 'partials') })); app.set('view engine', '.hbs'); app.set('views', path.join(__dirname, '..', 'frontend', 'views')); app.use(express.static(path.join(__dirname, '..', 'frontend'))); app.get('/main', (req,res) => { res.render('mainpage'); });
尝试修改后的HTML片段
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Main Page</title> <!-- Reference Chart.js from node_modules --> <script src="/node_modules/chart.js/dist/chart.umd.js">
app.js新增配置
app.use(express.static(path.join(__dirname, '..', 'node_modules')));
控制台报错
"GET http://localhost:3000/node_modules/chart.js/dist/chart.umd.js net::ERR_ABORTED 404 (Not Found)" "Refused to execute script from 'http://localhost:3000/node_modules/chart.js/dist/chart.umd.js' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled." "main:45 Uncaught ReferenceError: Chart is not defined"
解决办法
1. 修正静态资源挂载顺序与路径验证
MIME类型错误是404的衍生问题,核心是资源路径配置错误。首先调整静态资源的挂载顺序:先挂载node_modules,再挂载frontend,避免路由覆盖:
// 先配置node_modules静态资源 app.use(express.static(path.join(__dirname, '..', 'node_modules'))); // 再配置frontend静态资源 app.use(express.static(path.join(__dirname, '..', 'frontend')));
同时打印路径验证是否指向正确的node_modules目录:
const nodeModulesPath = path.join(__dirname, '..', 'node_modules'); console.log(nodeModulesPath); // 运行后查看控制台输出的路径是否正确
2. 简化HTML引入路径
因为已经将node_modules挂载为静态资源,HTML中无需添加node_modules前缀,直接访问包名即可:
<script src="/chart.js/dist/chart.umd.js"></script>
3. 备选方案:复制文件到前端静态目录
如果上述方法无效,可手动将node_modules/chart.js/dist/chart.umd.js复制到frontend/static/js/目录,然后在HTML中引入:
<script src="/js/chart.umd.js"></script>
这种方式更直观,还能避免暴露整个node_modules目录的安全风险。
内容的提问来源于stack exchange,提问作者Etow
相关产品推荐
相关产品推荐

