javascriptnode.jston

Problem with imports in NodeJS ( Failed to resolve module specifier )


I don't understand why my Test application don't work.

I have index.html, index.cjs, /public/js/app.js.

index.html

<!doctype html>
<html>
  <head>

    <script type="module" src="./js/app.js"></script>
    <title>This is the title of the webpage!</title>
  </head>
  <body>
    <p>Test HTML page</p>
  </body>
</html>

index.cjs

const express = require("express");
const app = express();

app.use(express.static(__dirname + '/public/'));


app.listen(3000, () => {
  console.log("Application started and Listening on port 3000");
});

app.get("/", (req, res) => {
  res.sendFile(__dirname + "/index.html");
});

app.js

import TonWeb from 'tonweb';
import { getHttpEndpoint } from "@orbs-network/ton-access";

console.log("import works!");

In VsCode i run node . , open browser and get this error: Uncaught TypeError: Failed to resolve module specifier "tonweb". Relative references must start with either "/", "./", or "../".

When i set whole path (import TonWeb from './node_modules/tonweb/tonweb.js';)

I get this error: GET http://localhost:3000/js/node_modules/tonweb/tonweb.js net::ERR_ABORTED 404 (Not Found)

I even tried jsDelivr: import TonWeb from 'https://cdn.jsdelivr.net/npm/tonweb@0.0.62/src/index.min.js';

But got this error: Uncaught SyntaxError: The requested module 'https://cdn.jsdelivr.net/npm/tonweb@0.0.62/src/index.min.js' does not provide an export named 'default'

How i can import and use tonweb?


Solution

  • I even tried jsDelivr: import TonWeb from 'https://cdn.jsdelivr.net/npm/tonweb@0.0.62/src/index.min.js';

    tonweb isn't a es module. it's built and distributed in cjs. therefore you would need some kind of build process such as webpack, esbuild or any other build tool.

    An other (simpler) alternative solution is to just use any cdn delivery network such as jsdeliver, esm.sh or jspm that can take care of that for you, then all you need to do is adding a tiny importmap

    <script type="importmap">
    {
      "imports": {
        "tonweb": "https://cdn.jsdelivr.net/npm/tonweb@0.0.62/+esm"
      }
    }
    </script>
    
    <script type="module">
      import Tonweb from 'tonweb'
      console.log(new Tonweb())
    </script>

    notices that i added /+esm at the end of the url, that means it will transform the module to esm. so

    import TonWeb from 'https://cdn.jsdelivr.net/npm/tonweb@0.0.62/src/index.min.js/+esm'
    

    would work just as well