Thank you for asking this question, it's definitely something many developers encounter. Before we delve into the specifics, I want to address that this issue is related to TypeScript, JavaScript, and Webpack rather than Angular itself. I will be preparing a detailed write-up on this topic very soon on my blog.
The Problem:
Let's say you perform the following command:
npm install mathjs
- Next, you attempt to utilize math.js from a component.
To do this, locate the math.js dist js file (node_modules/mathjs/dist/math.js) and import it like so:
import {mathjs} from "../../node_modules/mathjs/dist/math";
You might encounter an error message requesting to set "--allowJS." To resolve this, update your config in tsconfig.json as follows:
Set --allowJS in config (tsconfig.json)
{ "compilerOptions": {
"allowJs": true, ...
Subsequently, you may encounter:
ERROR in ../node_modules/mathjs/dist/math.js (12209,13): Unreachable
code detected.
- Upon inspecting the source of math.js, you'll notice it lacks a root wrapper function (the one function to rule them all). We'll dive deeper into this shortly.
Solution: install a typings file for the target library (@types/mathjs)
- Initially, check if you can obtain @typings files for your module at .
Acquire the mathjs typings file from npm (https://www.npmjs.com/package/@types/mathjs) and proceed with npm install to include the typings .d.ts files within the target lib's node_modules directory
npm install --save @types/mathjs
Ensure to reference the type correctly
import * as mjs from "mathjs"
Utilize it as shown:
console.log("e was: " + mjs.e);
I have provided a comprehensive solution for the math.js library on my GitHub repository: https://github.com/res63661/importOldJSDemoWithTypings/
Additional Tips:
For illustrations, explore your Angular project. The CLI generates a node_modules folder each time you execute npm install after creating a new project using ng new. Dive into this directory and observe the d.ts files associated with numerous .js files.
When dealing with typings or defining your own (.d.ts files), remember to restart your server between builds since the typings don't update automatically.
Further Resources:
- http://www.typescriptlang.org/docs/handbook/declaration-files/consumption.html
- https://angular.io/guide/typescript-configuration#typescript-typings
Lastly:
If you find yourself stuck and the solutions mentioned above aren't working, consider crafting a custom wrapper for a different module by encapsulating it in a master export type like this:
export var moduleNamer = (function(){
//module implementation
}());
Then place the .js file locally within your component and reference it accordingly:
//include the following line in your component:
import {moduleNamer} from "./source"; //from source.js
--rich