Skip to content

msal-react: only publishing as ESM breaks jest tests #6487

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jansepke opened this issue Sep 18, 2023 · 22 comments · Fixed by #7284
Closed

msal-react: only publishing as ESM breaks jest tests #6487

jansepke opened this issue Sep 18, 2023 · 22 comments · Fixed by #7284
Assignees
Labels
feature Feature requests. msal-browser Related to msal-browser package msal-react Related to @azure/msal-react public-client Issues regarding PublicClientApplications

Comments

@jansepke
Copy link

Core Library

MSAL.js (@azure/msal-browser)

Core Library Version

3.1.0

Wrapper Library

MSAL React (@azure/msal-react)

Wrapper Library Version

2.0.3

Public or Confidential Client?

Public

Description

The latest major release of msal-react is only published as ESM. Currently jest is not able to test code that contains ESM dependencies. Before msal-react V2 we tested our components together with msal-react and only mocked some functions of it. Now with msal-react V2 we have to mock the complete library as jest is unable to load any code from it.

I can see that you are still building other msal libraries as commonjs+ESM (e.g. msal-browser) could you also add a commonjs build to msal-react so it continous to work with jest.

Thank you!

Error Message

No response

Msal Logs

No response

MSAL Configuration

{}

Relevant Code Snippets

-

Reproduction Steps

Expected Behavior

Identity Provider

Azure AD / MSA

Browsers Affected (Select all that apply)

None (Server)

Regression

msal-react 1.5.11

Source

External (Customer)

@jansepke jansepke added bug-unconfirmed A reported bug that needs to be investigated and confirmed question Customer is asking for a clarification, use case or information. labels Sep 18, 2023
@microsoft-github-policy-service microsoft-github-policy-service bot added the Needs: Attention 👋 Awaiting response from the MSAL.js team label Sep 18, 2023
@github-actions github-actions bot added msal-browser Related to msal-browser package msal-react Related to @azure/msal-react public-client Issues regarding PublicClientApplications labels Sep 18, 2023
@Mexx77
Copy link

Mexx77 commented Sep 18, 2023

it would be nice to have such a change also announced in the release notes. e.g. here https://github.com/AzureAD/microsoft-authentication-library-for-js/releases/tag/msal-react-v2.0.0

@microsoft-github-policy-service
Copy link
Contributor

This issue requires attention from the MSAL.js team and has not seen activity in 5 days. @hectormmg please follow up.

1 similar comment
@microsoft-github-policy-service
Copy link
Contributor

This issue requires attention from the MSAL.js team and has not seen activity in 5 days. @hectormmg please follow up.

@jmosney
Copy link

jmosney commented Oct 6, 2023

This issue is affecting my projects as well. Any sense as to if/when it will be possible to resolve it? Thank you!!

@tnorling tnorling added the feature Feature requests. label Oct 9, 2023
@microsoft-github-policy-service microsoft-github-policy-service bot removed bug-unconfirmed A reported bug that needs to be investigated and confirmed question Customer is asking for a clarification, use case or information. Needs: Attention 👋 Awaiting response from the MSAL.js team labels Oct 9, 2023
@tnorling
Copy link
Collaborator

tnorling commented Oct 9, 2023

Marking as a feature, feel free to open a pull request if you need this resolved sooner rather than later.

@karlamarice
Copy link

Does anyone have insights into why this problem is impacting my UAT pipeline while it doesn't seem to have the same effect on my local machine? Also, is there a possible solution or workaround for this issue within a React project?

"Error [ERR_REQUIRE_ESM]: require() of ES Module /app/node_modules/@azure/msal-react/dist/index.js from /app/dist/server/assets/all.page.9a5890d9.js not supported."

@ciu8
Copy link

ciu8 commented Oct 13, 2023

hi, same issue on my project!
@jansepke can you suggest me how i can mock the entire msal-react library in order to unblock the tests, please?

@jmosney
Copy link

jmosney commented Oct 13, 2023

I'm using create-react-app and I was able to resolve the Jest issue by adding the following into my package.json:

  "jest": {
    "transformIgnorePatterns": [
      "node_modules/(?!(@azure/msal-react)).*\\.js$"
    ]
  },

If you're not using create-react-app you should be able to add this into your jest.config.js file.

Docs: https://jestjs.io/docs/configuration#transformignorepatterns-arraystring

@Mexx77
Copy link

Mexx77 commented Oct 13, 2023

hi, same issue on my project! @jansepke can you suggest me how i can mock the entire msal-react library in order to unblock the tests, please?

you can mock it like this:
jest.mock('@azure/msal-react', () => ({ useMsal: jest.fn(), }));

EDIT: since I see a few downvotes I would like to explain that my suggestion is not a solution to the issue. I shows how @jansepke and I currently work around it by mocking the entire msal library until the issue is fixed. Keeping this workaround is not desirable.

@jamie-laux-waracle
Copy link

jamie-laux-waracle commented Dec 14, 2023

The fix won't work with Next.js which overwrites jest config.

  1. compile with es-build to a vendor folder and check it in
npx esbuild @azure/msal-react --bundle --platform=node --sourcemap=inline --outfile=vendor/@azure/msal-react.js
  1. update your jest config - map @azure/msal-react to your newly vendored module
const nextJest = require("next/jest");

const createJestConfig = nextJest({
  // Provide the path to your Next.js app to load next.config.js and .env files in your test environment
  dir: "./",
});

// Add any custom config to be passed to Jest
const customJestConfig = {
  setupFilesAfterEnv: ["<rootDir>/jest.setup.js"],
  testEnvironment: "jest-environment-jsdom",
  moduleNameMapper: {
    "@azure/msal-react": "<rootDir>/vendor/@azuremsal-react",
  },
};

// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
module.exports = createJestConfig(customJestConfig);
  1. mock
jest.mock('@azure/msal-react', () => ({ useMsal: jest.fn(), }));

@ranshine
Copy link

ranshine commented Dec 26, 2023

I have been trying different things, still i am getting same issue
export { MsalConsumer, MsalContext } from './MsalContext.js';
^^^^^^

SyntaxError: Unexpected token 'export'

   7 |   RedirectRequest,
   8 | } from '@azure/msal-browser'
>  9 | import {MsalProvider} from '@azure/msal-react'

SyntaxError: Unexpected token 'export'

@birpet4
Copy link

birpet4 commented Jan 25, 2024

Still an issue for me

  • @azure/msal-browser": "^3.7.1"
  • @azure/msal-react": "^2.0.10"

workaround: mocking the entire msal-react/msal-browser libraries.

Extremely annoying.

@julian-alarcon
Copy link

Issue in jest jestjs/jest#14805

@jbouder
Copy link

jbouder commented Apr 17, 2024

Any updates on this? Looks like this issue blames Jest...and Jest blames this library.

...or does anyone have a good workaround?

@patrickfatrick
Copy link

patrickfatrick commented Apr 17, 2024

It’s a jest problem at heart. Moving to ESM is the right move long-term, jest just doesn’t support it well yet. As a workaround you can add it to your transformIgnorePatterns (eg transformIgnorePatterns: [“node_modules(?!(@azure/msal-react))“]) so that it is transformed.

@jbouder
Copy link

jbouder commented Apr 18, 2024

It’s a jest problem at heart. Moving to ESM is the right move long-term, jest just doesn’t support it well yet. As a workaround you can add it to your transformIgnorePatterns (eg transformIgnorePatterns: [“node_modules(?!(@azure/msal-react))“]) so that it is transformed.

Still getting the error with that added. Is there maybe some other jest or tsconfig values that maybe I need to be aware of?

Or maybe you can point me to a repo where this is already setup?

TIA!

@g-otn
Copy link

g-otn commented Apr 26, 2024

I'm using:

  • jest 29.7.0
  • ts-jest 29.1.1
  • typescript 5.0.2
  • @azure/msal-browser 3.13.0
  • @azure/msal-react 2.0.15

In my case I had to do two things:

  • Change the ts-jest preset (I was using ts-jest's default) to js-with-ts
    • The preset also requires changes allowJs to be true in my Typescript settings.
    • From the docs:

      TypeScript and JavaScript files (.ts, .tsx, .js, .jsx) will be transformed by ts-jest to CommonJS syntax.
      You'll need to set allowJs to true in your tsconfig.json file.

  • Add the transformIgnorePatterns entry like in other comments.
// jest.config.ts
const config: Config = {
  // ...
  preset: 'ts-jest/presets/js-with-ts',
  // ...
  transformIgnorePatterns: ['<rootDir>/node_modules/(?!@azure/msal-react)'],
  // ...
}
// tsconfig.json
{
  "compilerOptions": {
    // ...
    "allowJs": true /* Required by ts-jest/presets/js-with-ts */
  },
  // ...
}

I used this issue as reference: kulshekhar/ts-jest#970

@alexwasik
Copy link

What ended up working for me was writing the test to mock MSAL. This resolved my isssue

import React from "react";
import { render } from "@testing-library/react";
import App from "./App";

jest.mock("@azure/msal-react", () => ({
  MsalAuthenticationTemplate: ({ children }: { children: React.ReactNode }) =>
    children,
  useMsal: () => ({
    instance: {},
    inProgress: false,
  }),
}));

describe("App", () => {
  it("renders without crashing", () => {
    render(<App />);
  });
});

@amritham93
Copy link

adding global.crypto = require('crypto'); to the setupTests.js file, fixes the failing tests

@raulvictorrosa
Copy link

raulvictorrosa commented Jun 26, 2024

I'm using create-react-app structure for now and solved the issue for was to include this mock bellow in the setupTests.ts or jest.setup.ts. As with create-react-app we need to create an instance of the PublicClientApplication in the index.tsx and after call the initialize function, then we need to mock this instance.

jest.mock('./index', () => {
  const mockMsalInstance = {
    getActiveAccount: jest.fn(),
    acquireTokenSilent: jest.fn(),
    initialize: jest.fn().mockResolvedValue(undefined),
    getAllAccounts: jest.fn().mockReturnValue([]),
    setActiveAccount: jest.fn(),
    addEventCallback: jest.fn(),
  };

  return {
    msalInstance: mockMsalInstance,
  };
});

@netzulo
Copy link

netzulo commented Jul 4, 2024

I'm using create-react-app structure for now and solved the issue for was to include this mock bellow in the setupTests.ts or jest.setup.ts. As with create-react-app we need to create an instance of the PublicClientApplication in the index.tsx and after call the initialize function, then we need to mock this instance.

jest.mock('./index', () => {
  const mockMsalInstance = {
    getActiveAccount: jest.fn(),
    acquireTokenSilent: jest.fn(),
    initialize: jest.fn().mockResolvedValue(undefined),
    getAllAccounts: jest.fn().mockReturnValue([]),
    setActiveAccount: jest.fn(),
    addEventCallback: jest.fn(),
  };

  return {
    msalInstance: mockMsalInstance,
  };
});

this work for me like a charm with my package.json config

"jest": {
    "transform": {
      "^.+\\.(js|jsx|ts|tsx)$": "babel-jest"
    },
    "moduleNameMapper": {
      "^@azure/msal-react": "<rootDir>/node_modules/@azure/msal-react/dist/index.js"
    },
    "setupFilesAfterEnv": [
      "<rootDir>/setupTests.js"
    ],
}

@raulvictorrosa
Copy link

I'm using create-react-app structure for now and solved the issue for was to include this mock bellow in the setupTests.ts or jest.setup.ts. As with create-react-app we need to create an instance of the PublicClientApplication in the index.tsx and after call the initialize function, then we need to mock this instance.

jest.mock('./index', () => {
  const mockMsalInstance = {
    getActiveAccount: jest.fn(),
    acquireTokenSilent: jest.fn(),
    initialize: jest.fn().mockResolvedValue(undefined),
    getAllAccounts: jest.fn().mockReturnValue([]),
    setActiveAccount: jest.fn(),
    addEventCallback: jest.fn(),
  };

  return {
    msalInstance: mockMsalInstance,
  };
});

this work for me like a charm with my package.json config

"jest": {
    "transform": {
      "^.+\\.(js|jsx|ts|tsx)$": "babel-jest"
    },
    "moduleNameMapper": {
      "^@azure/msal-react": "<rootDir>/node_modules/@azure/msal-react/dist/index.js"
    },
    "setupFilesAfterEnv": [
      "<rootDir>/setupTests.js"
    ],
}

You also probably don't need the line "^@azure/msal-react": "<rootDir>/node_modules/@azure/msal-react/dist/index.js"

This is my configurations, I'm using the fileTransform.js because I'm using CRA and the identity-obj-proxy is a package to be installed to be mapping css and less files.:

// jest.config.ts
import type { JestConfigWithTsJest } from 'ts-jest';
import { defaults as tsjPreset } from 'ts-jest/presets';

const config: JestConfigWithTsJest = {
  roots: ['<rootDir>/src'],
  setupFilesAfterEnv: ['<rootDir>/src/jest.setup.ts'],
  testEnvironment: 'jsdom',
  transform: {
    ...tsjPreset.transform,
    '^(?!.*\\.(js|jsx|mjs|cjs|ts|tsx|css|json)$)':
      '<rootDir>/config/jest/fileTransform.js',
  },
  moduleNameMapper: {
    '\\.(css|less)$': 'identity-obj-proxy',
  },
};

export default config;

@tnorling tnorling linked a pull request Aug 29, 2024 that will close this issue
tnorling added a commit that referenced this issue Sep 19, 2024
Type resolution is broken for node16 resolution type due to several
issues, this PR:

- Updates all relative imports to include .js file extension, as
required by node16 resolution
- Includes type declaration files from lib folder in package publish
- Adds package.json file to `lib` folder to indicate contents are
commonjs
- Updates package exports field to point to the appropriate type
declaration files for ESM or CJS
- Adds browser and node subpaths to msal-common export to separate
node-only and browser-only features

Fixes #6781 #6487 #6269

---------

Co-authored-by: Hector Morales <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Feature requests. msal-browser Related to msal-browser package msal-react Related to @azure/msal-react public-client Issues regarding PublicClientApplications
Projects
None yet