Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple absolute import causing 'Cannot find module' error

Tags:

typescript

I have reproduced this in the little project here.

So I have a main.ts that looks like:

import hello from "dm/lib/helper"

hello("Jeff")

and helper.ts in src/lib/herlper.ts that looks like:

export default function hello(name: string) {
    console.log(`Hello ${name}`)
}

Pretty simple. Now on to tsconfig.json:

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "outDir": "dist",
    "strict": true,
    "noImplicitAny": true,
    "moduleResolution": "node",
    "baseUrl": "./",
    "paths": {
        "dm/*": [
            "./src/*"
        ],
    },
  },
  "include": [
    "src/**/*"
  ]
}

The compile/transpile works fine and some Javascript is spewed out. Running main.js using npm start gives an error like:

module.js:549
    throw err;
    ^

Error: Cannot find module 'dm/lib/helper'
    at Function.Module._resolveFilename (module.js:547:15)

I didn't expect TypeScript to include dm/ I'm using to refer to the project root in the final JS. What am I doing wrong?

like image 200
MadeOfAir Avatar asked Dec 06 '18 08:12

MadeOfAir


1 Answers

Well according to this closed issue it's not possible to use absolute imports without external tools in TypeScript, mainly because it won't rewrite your imports in the emitted JavaScript.

In frontend projects you can have webpack resolve these imports but since I'm doing a nodejs/electron project I still don't have webpack setup here.

It's also intriguing that VSCode manages to use absolute imports in TypeScript but they are also using webpack but I don't know how they do achieve that effect just yet. If you know how do they pull that off feel free to answer this question.

UPDATE

So I managed to use webpack to enable absolute imports in my TypeScript/nodejs project. This is by no means the only way to do it but it works.

I updated my project code here. Here are some highlights:

Install these:

npm install --save-dev webpack webpack-cli webpack-node-externals ts-loader

Add webpack config in webpack.config.js:

const path = require("path")
const nodeExternals = require("webpack-node-externals")

module.exports = {
    mode: "development",
    target: "node",
    entry: {
        app: ["./src/main.ts"]
    },
    module: {
        rules: [
            {
                test: /\.ts$/,
                use: "ts-loader",
                exclude: /node_modules/
            }
        ]
    },
    resolve: {
        alias: {
            dm: path.resolve(__dirname, "src/")
        },
        extensions: [".ts", ".js"]
    },
    output: {
        path: path.resolve(__dirname, "dist/"),
        filename: "main.js"
    },
    externals: [nodeExternals()]
}

Build and run the project:

npm run build && npm start

like image 166
MadeOfAir Avatar answered Nov 10 '22 00:11

MadeOfAir