简体   繁体   中英

Bootstrap4 typings(index.d.ts) cannot find module 'popper.js' on VisualStudio 2019 with TypeScript3.9 and Libman

I use VisualStudio 2019 with TypeScript3.9 and Libman.

And I need Bootstrap4 and jQuery. So try get these libraries and typings(index.d.ts) by Libman.

Then Bootstrap4 typing(index.d.ts) get error "Cannot find module popper.js".

// Type definitions for Bootstrap 4.5
// Project: https://github.com/twbs/bootstrap/, https://getbootstrap.com
// Definitions by: denisname <https://github.com/denisname>
//                 Piotr Błażejewicz <https://github.com/peterblazejewicz>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.3

/// <reference types="jquery"/>

import * as Popper from "popper.js";     // ERROR!: "Cannot find module popper.js"

I found similar problems and answers.

It could only solve the problem temporarily.

I changed bootstrap4 typing(index.d.ts) to relative path as import * as Popper from "../popper_v1"; is fixed error. But Libman override this manually-changed index.d.ts.

_

What can I do to fix this error? Do I need to install manually modified index.d.ts, like Popper v1.X?

Thanks.


Steps to reporduce error.

  1. Create ASP.Net4 MVC Project on.Net Framework 4.8

  2. Create libman.json to add some libraries and TS typings

{
  "version": "1.0",
  "defaultProvider": "jsDelivr",
  "libraries": [
    {
      "library": "bootstrap@4.5.2",
      "destination": "lib/bootstrap/"
    },
    {
      "library": "@types/bootstrap@4.5.0",
      "destination": "lib/types/bootstrap/"
    },
    {
      "library": "jquery@3.5.1",
      "destination": "lib/jquery/",
      "files": [
        "dist/jquery.js",
        "dist/jquery.min.js",
        "dist/jquery.min.map",
        "dist/jquery.slim.js",
        "dist/jquery.slim.min.js",
        "dist/jquery.slim.min.map",
        "external/sizzle/LICENSE.txt",
        "external/sizzle/dist/sizzle.js",
        "external/sizzle/dist/sizzle.min.js",
        "external/sizzle/dist/sizzle.min.map",
        "AUTHORS.txt",
        "LICENSE.txt",
        "README.md"
      ]
    },
    {
      "library": "@types/jquery@3.5.1",
      "destination": "lib/types/jquery/"
    },
    {
      "library": "@types/sizzle@2.3.2",
      "destination": "lib/types/sizzle/"
    },
    {
      "provider": "cdnjs",
      "library": "popper.js@1.16.1",
      "destination": "lib/popper.js/"
    },
    {
      "provider": "filesystem",
      "library": "lib_ManualInstallSources/popper_v1/",
      "destination": "lib/types/popper_v1/"
    }
  ]
}

** Note: I got typing(index.d.ts) of popper.js ver.1.X from GitHub repository.

  1. Create tsconfig.json
{
  "compilerOptions": {
    "noImplicitAny": false,
    "noEmitOnError": true,
    "removeComments": false,
    "sourceMap": true,
    "target": "es5",
    "lib": [ "ES6", "DOM" ],
    "baseUrl": ".",
    "typeRoots": [
      "./lib/types"
    ]
  },
  "exclude": [
    "node_modules",
    "wwwroot",
    "lib"
  ]
}

After these steps, bootstrap4 typing(index.d.ts) get error "Cannot find module popper.js" on import * as Popper from "popper.js"; .


I found two petterns to fix.

  1. Change tsconfig.json settings to compiler can search "lib" directory.
  2. Change directory name of libraries via Libman to "node_modules"(Not recommended).

This problem is caused by multiple reasons.

  1. TypeScript's default module management mechanism is based on node.js.
  2. Libman use "lib" directory to put libraries by default.
  3. Directory names of library must be same as ModuleName.

[Reasons]

1. TypeScript's module management mechanism is based on node.js.

My tsconfig.json has "target": "ES5" . And has not "module" property.

It makes "module" property to default. And under "ES5" target, default is "CommonJS" .

Then, has not "moduleResolution" property too. So "module": "CommonJS" makes "moduleResolution" property to "Node" .

Yes, compiler uses "Node" module resolution system.

.

> "Node" resolution system on TypeScript 3.9

This handbook said, non-relative import(eg import * from "banana" ) will search "node_modules" directory recursively(to parent).

Yes, directory must be named as "node_modules".

Otherwise we use Libman, but latest TypeSciript's basic theory is based on "node.js"!
And "Classic" resolution system is legacy and useless.

Finally, we need to change tsconfig.json to search our "lib" directory. Or change directory name as "node_modules" for adjusting to "Node" resolution system(Not recommended. We use Libman, not node).


2. Libman use "lib" directory to put libraries by default.

As a reason by 1, we need "node_modules" directory. But libman's default directory name is "lib".

This cause compiler can not search libraries on "lib" directory.


3. Directory names of library must be same as ModuleName.

If non-relative import(eg import * from "banana" ) is used, compiler search "./node_modules/banana.js(ts)" or "./node_modules/banana/*".

My libman.config has typing(.d.ts) of popper.js version 1.X.

{
  "provider": "filesystem",
  "library": "lib_ManualInstallSources/popper_v1/",
  "destination": "lib/types/popper_v1/"
}

Yes... my "desitination" property is "popper_v1".

It is wrong named. import * as Popper from "popper.js" can not find this directory. Need fix directory name to "lib/types/popper.js".


[How to fix]

I found two petterns to fix.

  1. Change settings tsconfig.json to compiler can search "lib" directory.
  2. Change directory name of libraries via Libman to "node_modules"(Not recommended).

I suggest to use 1. Because we use Libman, not Node. If we see the "node_modules" directory, it leads to the misconception that we are using Node.

However, by changing to "node_modules", the overall configuration can be made to look easier.


1. Change settings tsconfig.json to compiler can search "lib" directory.

// tsconfig.json
{
  "compilerOptions": {
    "sourceMap": true,
    "target": "es5",
    "lib": [ "ES6", "DOM" ],
    "baseUrl": ".",
    "typeRoots": [
      "./node_modules/@types", // Default path to search typings.
      "./lib/types"            // Directory of typings that located by Libman.
    ],
    "paths": {
      // If absolute module name provided on .ts/.d.ts files, compiler will check "./lib/moduleName", "./lib/types/moduleName".
      // e.g. 'import * as Popper from "popper.js"' is convert to "./lib/popper.js" and "./lib/types/popper.js".
      //      Then "./lib/types/popper.js" is correctly path. Error fixed.
      "*": [ "lib/*", "lib/types/*" ]
    }
  },
  "exclude": [
    "node_modules",
    "wwwroot",
    "lib"
  ]
}
// libman.json
{
  "version": "1.0",
  "defaultProvider": "jsDelivr",
  "libraries": [
    {
      "provider": "cdnjs",
      "library": "popper.js@1.16.1",
      "destination": "lib/popper.js/"
    },
    {
      "provider": "filesystem",
      "library": "lib_ManualInstallSources/popper_v1/",
      "destination": "lib/types/popper.js/"
    },
    {
      "library": "bootstrap@4.5.2",
      "destination": "lib/bootstrap/"
    },
    {
      "library": "@types/bootstrap@4.5.0",
      "destination": "lib/types/bootstrap/"
    },
    {
      "library": "jquery@3.5.1",
      "destination": "lib/jquery/",
      "files": [
        "dist/jquery.js",
        "dist/jquery.min.js",
        "dist/jquery.min.map",
        "dist/jquery.slim.js",
        "dist/jquery.slim.min.js",
        "dist/jquery.slim.min.map",
        "external/sizzle/LICENSE.txt",
        "external/sizzle/dist/sizzle.js",
        "external/sizzle/dist/sizzle.min.js",
        "external/sizzle/dist/sizzle.min.map",
        "AUTHORS.txt",
        "LICENSE.txt",
        "README.md"
      ]
    },
    {
      "library": "@types/jquery@3.5.1",
      "destination": "lib/types/jquery/"
    },
    {
      "library": "@types/sizzle@2.3.2",
      "destination": "lib/types/sizzle/"
    }
  ]
}

2. Change directory name of libraries via Libman to "node_modules"(Not recommended).

{
  "compilerOptions": {
    "sourceMap": true,
    "target": "es5",
    "lib": [ "ES6", "DOM" ],
    "baseUrl": "."
  },
  "exclude": [
    "node_modules",
    "wwwroot",
    "lib"
  ]
}
{
  "version": "1.0",
  "defaultProvider": "jsDelivr",
  "libraries": [
    {
      "provider": "cdnjs",
      "library": "popper.js@1.16.1",
      "destination": "node_modules/popper.js/"
    },
    {
      "provider": "filesystem",
      "library": "lib_ManualInstallSources/popper_v1/",
      "destination": "node_modules/types/popper.js/"
    },
    {
      "library": "bootstrap@4.5.2",
      "destination": "node_modules/bootstrap/"
    },
    {
      "library": "@types/bootstrap@4.5.0",
      "destination": "node_modules/types/bootstrap/"
    },
    {
      "library": "jquery@3.5.1",
      "destination": "node_modules/jquery/",
      "files": [
        "dist/jquery.js",
        "dist/jquery.min.js",
        "dist/jquery.min.map",
        "dist/jquery.slim.js",
        "dist/jquery.slim.min.js",
        "dist/jquery.slim.min.map",
        "external/sizzle/LICENSE.txt",
        "external/sizzle/dist/sizzle.js",
        "external/sizzle/dist/sizzle.min.js",
        "external/sizzle/dist/sizzle.min.map",
        "AUTHORS.txt",
        "LICENSE.txt",
        "README.md"
      ]
    },
    {
      "library": "@types/jquery@3.5.1",
      "destination": "node_modules/types/jquery/"
    },
    {
      "library": "@types/sizzle@2.3.2",
      "destination": "node_modules/types/sizzle/"
    }
  ]
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM