How to properly import and use the MSAL (Microsoft Authentication Library for js) into a typescript react single page application?
Solution 1
As you have correctly mentioned - in the msal.d.ts there are no exports - its not a module, and therefore you should not try importing.
Instead you can use it like this:
/// <reference path="./node_modules/msal/out/msal.d.ts" />
const userAgentApplication = new Msal.UserAgentApplication("your_client_id", null, (errorDes, token, error, tokenType) =>
{
});
Note that even in readme they specify only one way of using their library - by including script tag, not by importing module. And further looking into their source code shows they are not using modules as well.
Solution 2
It looks like the latest version of MSAL.js does have a CommonJS export. You can now just do the following in TypeScript (tested with version 2.3.3 of TypeScript and 0.1.3 of MSAL.js):
import * as Msal from 'msal';
Now in your .ts
(or in my case .tsx
file) you can, for instance, setup a click event handler and create a UserAgentApplication object:
// In you class somewhere
private userAgentApplication: any = undefined;
// The login button click handler
handleLoginClick = (event: any): void => {
if (!this.userAgentApplication) {
this.userAgentApplication = new Msal.UserAgentApplication(
'clientID string', 'authority string or empty', this.authCallback, { cacheLocation: 'localStorage'});
}
// Other login stuff...
}
// In React render()
public render() {
return (
<Button
bsStyle="warning"
type="button"
onClick={(e) => this.handleLoginClick(e)}
>
Log in
</Button>
);
}
Solution 3
I had the same issue and couldn't wait for the author to fix it, so forked and modified the original code. Just as a temporary fix you can use my version msalx
instead of msal
.
npm install msalx
You can find the source code and an example usage in react at: https://github.com/malekpour/microsoft-authentication-library-for-js#example
Solution 4
If you install the exports-loader (npm install exports-loader --save-dev
) you can avoid the script tag and add the following to your directives:
var Msal = require("exports-loader?Msal!../../../node_modules/msal/out/msal.js");
Related videos on Youtube
nbrowne
I'm a software professional and software development manager who's passionate about technology, creating great solutions, building teams, and remote work. I have a B.Sc. and M.Sc. in Computer Science, and my M.Sc. specialized in artificial intelligence. I've worked in Canada, Mexico and the United States building software systems and currently lead a small development team. For more information or to chat, you can find me on LinkedIn at https://www.linkedin.com/in/nigelbrowne/ and https://nigelbrowne.com.
Updated on July 09, 2022Comments
-
nbrowne almost 2 years
Problem
I can't seem to get the MSAL library to import properly into my typescript code. I'm using the MSAL for JS library (which is supposed to have typings) in a simple typescript/react project scaffolded using the create-react-app with react-typescript scripts. I'm new to typescript and not sure if I'm missing something obvious or if there is a problem with the MSAL package when using it with typescript projects.
Details:
- I added the MSAL package from NPM using
npm install --save msal
. - I attempted to import the MSAL into my .ts using different forms of
import {Msal} from 'msal';
- This results in a typescript error
Could not find a declaration file for module 'msal'. '<path>/node_modules/msal/out/msal.js' implicitly has an 'any' type.
- Thinking that was odd, I looked at the the node_module/msal/out folder and saw a 'msal.d.ts' file, which is what I would expect.
- When I look at the contents of the msal.d.ts file, I don't see any exports, which I would normally expect to see.
- I tried install the declaration from @types using
npm install --save-dev @types/msal
, but it doesn't exist. - I also tried importing it into my file using
let Msal = require('Msal');
, but get an error that the Msal.UserAgentApplication isn't a constructor. - I didn't have much luck trying to use the /// reference directive and adding a script tag to the main index.html. This also doesn't feel like the right way to solve the problem.
ExampleMsal.ts
import { observable, action, computed } from 'mobx'; import * as Msal from 'msal'; // <-- This line gives the error class ExampleMsal{ @observable private _isLoggedIn: boolean; constructor() { this._isLoggedIn = false; } @computed get isLoggedIn(): boolean { return this._isLoggedIn; } @action signIn() { let userAgentApplication = new Msal.UserAgentApplication('<client-id>', null, function (errorDes: string, token: string, error: string, tokenType: string) { // this callback is called after loginRedirect OR acquireTokenRedirect // (not used for loginPopup/aquireTokenPopup) } ); userAgentApplication.loginPopup(['user.read']).then(function(token: string) { let user = userAgentApplication.getUser(); if (user) { // signin successful alert('success'); } else { // signin failure alert('fail'); } }, function (error: string) { // handle error alert('Error' + error); }); this._isLoggedIn = true; } @action signOut() { this._isLoggedIn = false; } } export default ExampleMsal;
tsconfig.json
{ "compilerOptions": { "outDir": "build/dist", "module": "commonjs", "target": "es5", "lib": ["es6", "dom"], "sourceMap": true, "allowJs": true, "jsx": "react", "moduleResolution": "node", "rootDir": "src", "forceConsistentCasingInFileNames": true, "noImplicitReturns": true, "noImplicitThis": true, "noImplicitAny": true, "strictNullChecks": true, "suppressImplicitAnyIndexErrors": true, "noUnusedLocals": true, "experimentalDecorators": true }, "exclude": [ "node_modules", "build", "scripts", "acceptance-tests", "webpack", "jest", "src/setupTests.ts" ], "types": [ "typePatches" ] }
- I added the MSAL package from NPM using
-
nbrowne almost 7 yearsThe reference path definition combined with including the js file from the CDN in my index.html got it working for me. I'll update back if I figure out a cleaner way to do it.
-
Thiago Custodio almost 7 yearsHi Nigel, can you upload your project to your Github? I am trying to find samples with React and MSAL. Thanks in advance
-
Paweł Skorupiński over 6 yearsI am getting exception: Unexpected '!' in 'exports-loader?Msal!./node_modules/msal/out/msal.js'. Do not use import syntax to configure webpack loaders import/no-webpack-loader-syntax
-
Dibran over 6 yearsYou sir are a hero
-
Jed over 6 yearsI was able to import using this but I am getting the following error:
Msal.UserAgentApplication is not a constructor
-
RHarris over 6 yearsI've been able to do what you suggested to new up a
UserAgentAppliation
, however, in previous code (where I loaded Msal from CDN), I did the followingMsal.Storage("localStorage").getItem(...)
. This now gives an error when I useimport * as Msal from 'msal'
. Is there a way to make that work? -
StephenD over 6 yearsLater versions of MSAL seem to work well now, I'm using version 0.1.3, and it a simple:
import * as Msal from 'msal';
works well.