How to Correctly import JS modules - (Nodejs - Express)
Asked Answered
G

1

1

I am currently learning to use nodejs with express as my franework and handlebar as the template engine.

PS: This is from the chartjs tutorial where they use parcel.

When I am trying to do the same with express (node src/app.js) I am getting an error Failed to resolve module specifier "chart.js/auto"

I have noticed couple of times where I am not able to import modules in external js files. Is there a way to import modules in external js files or is it that express in particular is unable to the same.

I have already npm installed chartjs. I have a page index.hbs

<!doctype html>
<html lang="en">
  <head>
    <title>Chart.js example</title>
  </head>
  <body>
    <div style="width: 800px;"><canvas id="acquisitions"></canvas></div>
    <script type="module" src="./js/acquisitions.js"></script>
  </body>
</html>

and acquisitions.js

import Chart from 'chart.js/auto'

(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)
          }
        ]
      }
    }
  );
})();
Gyromagnetic answered 3/4, 2023 at 17:37 Comment(0)
M
1

You can use Importing modules using import maps

Import maps allow developers to instead specify almost any text they want in the module specifier when importing a module; the map provides a corresponding value that will replace the text when the module URL is resolved.

Let's see an example, I will use the HTML file to demonstrate. It's the same for using any template engine.

Directory structure:

- project
  - node_modules
    - chart.js
      - auto
      - dist
    - @kurkle
      - color
        - dist
          - color.cjs.js
          - color.d.ts
          - color.esm.js
  - src
    - importmap
      - public
        - js
          - acquisitions.js
      - index.html

app.js:

const express = require('express')
const path = require('path');

const app = express();

app.use('/node_modules', express.static(path.resolve(__dirname, '../../node_modules')))
app.use(express.static(path.resolve(__dirname, 'public')))

app.listen(3000, () => console.log('Server is listening on http://localhost:3000'))

public/index.html:

<!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.0">
  <title>Document</title>
</head>

<body>
  <div style="width: 800px;"><canvas id="acquisitions"></canvas></div>

  <script type="importmap">
    {
      "imports": {
        "@kurkle/color": "/node_modules/@kurkle/color/dist/color.esm.js",
        "chart.js/auto": "/node_modules/chart.js/auto/auto.js"
      }
    }
  </script>
  <script type="module" src="./js/acquisitions.js"></script>
</body>

</html>

public/js/acquisitions.js:

import Chart from 'chart.js/auto'

(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)
          }
        ]
      }
    }
  );
})();

chart.js use @kurkle/color as its dependency, so we must add it to import maps. chart.js will use import '@kurkle/color' statement to import it.

Start the server and access the http://localhost:3000 endpoint, result:

enter image description here

Mosenthal answered 30/5, 2023 at 7:20 Comment(1)
While this works, I would'nt wanna expose my whole node_modules folder.Eatton

© 2022 - 2024 — McMap. All rights reserved.