You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Node.js+Express中正确导入JS模块

解决Express中浏览器端ES模块导入npm包的问题

你遇到的Failed to resolve module specifier "chart.js/auto"错误,核心原因是浏览器原生ES模块系统无法识别npm包名——浏览器只能解析相对路径、绝对URL或已映射的模块名,而像chart.js/auto这种npm包标识符,只有Parcel这类打包工具能处理,Express作为Web服务器本身不具备模块解析打包的能力。

下面是几种可行的解决方法:

方法1:通过CDN引入Chart.js(最简单)

直接在HTML中通过CDN导入Chart.js,让浏览器能直接识别模块:

方式A:使用Import Map映射模块

修改index.hbs,添加模块映射配置:

<!doctype html>
<html lang="en">
  <head>
    <title>Chart.js example</title>
    <script type="importmap">
      {
        "imports": {
          "chart.js/auto": "https://cdn.jsdelivr.net/npm/chart.js@4.4.8/dist/chart.umd.min.js"
        }
      }
    </script>
  </head>
  <body>
    <div style="width: 800px;"><canvas id="acquisitions"></canvas></div>
    <script type="module" src="./js/acquisitions.js"></script>
  </body>
</html>

方式B:直接在JS中用CDN URL导入

修改acquisitions.js,把npm包名替换为CDN地址:

import Chart from 'https://cdn.jsdelivr.net/npm/chart.js@4.4.8/dist/chart.umd.min.js'

(async function() {
  const data = [
    { year: 2010, count: 10 },
    { year: 2011, count: 20 },
    { year: 2012, count: 15 },
    { year: 2013, count: 25 },
    { year: 2014, count: 22 },
    { year: 2015, count: 30 },
    { year: 2016, count: 28 },
  ];

  new Chart(
    document.getElementById('acquisitions'),
    {
      type: 'bar',
      data: {
        labels: data.map(row => row.year),
        datasets: [
          {
            label: 'Acquisitions by year',
            data: data.map(row => row.count)
          }
        ]
      }
    }
  );
})();

方法2:使用打包工具构建前端代码

沿用你参照的Parcel流程,打包后让Express托管静态文件:

  1. 安装Parcel开发依赖:
npm install -D parcel
  1. 在package.json中添加打包脚本:
{
  "scripts": {
    "build": "parcel build src/views/index.hbs"
  }
}
  1. 执行打包命令生成静态资源:
npm run build
  1. 修改Express配置,托管Parcel生成的dist目录:
// src/app.js
const express = require('express');
const app = express();
const path = require('path');

// 托管打包后的静态文件
app.use(express.static(path.join(__dirname, '../dist')));

// 其他路由配置...
app.listen(3000, () => {
  console.log('Server running on port 3000');
});

启动Express后访问对应路径即可,Parcel已将所有模块打包为浏览器可识别的代码。

方法3:用中间件补全模块解析(仅开发环境推荐)

使用es-module-shims在浏览器端补全npm模块解析能力,注意生产环境不建议这么做:

  1. 安装依赖:
npm install es-module-shims
  1. 修改index.hbs引入垫片并配置映射:
<!doctype html>
<html lang="en">
  <head>
    <title>Chart.js example</title>
    <script async src="/node_modules/es-module-shims/dist/es-module-shims.js"></script>
    <script type="importmap-shim">
      {
        "imports": {
          "chart.js/auto": "/node_modules/chart.js/dist/chart.umd.min.js"
        }
      }
    </script>
  </head>
  <body>
    <div style="width: 800px;"><canvas id="acquisitions"></canvas></div>
    <script type="module-shim" src="./js/acquisitions.js"></script>
  </body>
</html>
  1. 让Express托管node_modules目录:
app.use(express.static(path.join(__dirname, '../node_modules')));

内容的提问来源于stack exchange,提问作者Bumi Trueman Doley

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 23:35:09