Open MyShah1 opened 4 years ago
Error | TS2580 | (TS) Cannot find name 'require'. Do you need to install type definitions for node? Try npm i @types/node
. | MyApp, MyApp JavaScript Content Files | C:\Users\MSHAH\source\repos\sandbox\MyApp\ClientApp\src\Login\LoginForm.tsx | 27 | Active
@MyShah1 Thanks for the report. Could you share here the relevant piece of code from LoginForm.tsx
?
Here's the code snippet, last line thows the error.
=====================================
var config = {
pkce: false,
// other config
issuer: props.issuer,
clientId: "123",
};
console.info('issuer' + props.issuer);
// var OktaAuth = require('@okta/okta-auth-js');
this.oktaAuth = new OktaAuth(config);
@MyShah1 Are you using the latest version of okta-auth-js
(4.0.0)? It was just released and the import style has changed to named exports. The guides in documentation need to be updated.
Use:
import { OktaAuth } from '@okta/okta-auth-js'
more information is here: https://github.com/okta/okta-auth-js#using-the-npm-module
import { OktaAuth } from '@okta/okta-auth-js'; import { withOktaAuth } from '@okta/okta-react'; import * as React from 'react';
The error
LoginForm.tsx:18 Uncaught TypeError: okta_auth_js_1.default is not a constructor
Indicates it is trying to use "default" import. This would happen by using a require()
statement with Typescripts "esModuleInterop" option turned on, or by import OktaAuth from '@okta/okta-auth-js'
. The way you have shown
import { OktaAuth } from '@okta/okta-auth-js' should not produce this error since it is using a named export.
The other possibility is a version conflict. The internal version of okta-auth-js
used by React is at version 3. It's possible if you are using yarn/lerna that the dependency may be hoisted to the top level and the error is being emitted from within the React SDK trying to instantiate okta-auth-js@4.0. Since the React SDK is using okta-auth-js@3.2, I would recommend using that same version in your project's package.json outside the React SDK. There are no major feature changes in 4.0.0, the main change is this import style. We will have an update for React SDK soon which uses 4.0.
Alternatively you can access the React SDK's internal auth-js instance, it is available as a property named _oktaAuth
require does not work as well, I'm willing to share my project and visual studio settings if required to troubleshoot the issue.
can you please share some more details on how to access _oktaAuth? thanks
@MyShah1 I notice you imported both okta-auth-js
and okta-react
in your code, which may cause tokens inconsistency issue if you have autoRenew
turned on (it's on by default), since more than one autoRenew process will run together in the background.
I would suggest to stay with only @okta/okta-react
v3.x (which is depends on auth-js v3.x) for now. We will have auth-js
v4.x included in the react SDK in the next major release.
Also wondering is there any specific reason that you want to use those two SDKs together?
@shuowu I believe both okta-auth-js
and okta-react
are required by Okta React v4.0.0 now.
I have this in my src/App.js
:
import React, { Component } from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import { OktaAuth } from '@okta/okta-auth-js';
import { LoginCallback, Security } from '@okta/okta-react';
import Home from './Home';
const oktaAuth = new OktaAuth({
issuer: 'https://dev-133320.okta.com/oauth2/default',
clientId: '0oa5nak5fmUbfT3O3357',
redirectUri: window.location.origin + '/callback'
});
class App extends Component {
render() {
return (
<Router>
<Security oktaAuth={oktaAuth}>
<Route path="/" exact={true} component={Home}/>
<Route path="/callback" component={LoginCallback}/>
</Security>
</Router>
);
}
}
export default App;
In my src/App.test.ts
, I have:
import React from 'react';
import ReactDOM from 'react-dom';
import { act } from 'react-dom/test-utils';
import App from './App';
let container;
beforeEach(() => {
container = document.createElement('div');
document.body.appendChild(container);
});
afterEach(() => {
document.body.removeChild(container);
container = null;
});
test('renders learn react link', async () => {
await act(async () => {
ReactDOM.render(<App/>, container);
});
const linkElement = container.querySelector('a');
expect(linkElement.textContent).toBe('Learn React');
});
When I run npm test
, it fails with this error:
FAIL src/App.test.js
✕ renders learn react link (76 ms)
● renders learn react link
TypeError: Cannot read property 'getAuthState' of undefined
18 | test('renders learn react link', async () => {
19 | await act(async () => {
> 20 | ReactDOM.render(<App/>, container);
| ^
21 | });
22 |
23 | const linkElement = container.querySelector('a');
at node_modules/@okta/src/Security.tsx:48:24
Any idea how to fix it?
For those seeing this issue in tests, you may need to adjust your config: https://github.com/okta/okta-react/blob/master/jest.config.js#L23
okta-auth-js
is an isomorphic module so it supports both a browser and node (server-side) endpoint. Jest tests run on Node and will use the server-side endpoint BY DEFAULT. The server-side module does not support the full interface, notably it does not have a getAuthState
method.
Thanks @aarongranick-okta! Adding this snippet to my package.json fixed the tests:
"jest": {
"moduleNameMapper": {
"^@okta/okta-auth-js$": "<rootDir>/node_modules/@okta/okta-auth-js/dist/okta-auth-js.umd.js"
}
}
@MyShah1 were you able to resolve your issue, or can we provide further assistance?
@mraible - I am facing exact issue while running my app locally (dint try tests) - were you able to fix this issue?
@niteshchaudhary This error usually means that the commonJS version of the library is loaded, but the calling code is expecting ES. This can happen easily with esModuleInterop
turned on in a typescript app, because it generates some code to make it work both ways.
If you are using ES syntax (recommended), it should be:
import { OktaAuth } from '@okta/okta-auth-js
Note that { OktaAuth }
is inside curly braces.
If using commonJS (not recommended unless this is a NodeJS application)
const OktaAuth = require('@okta/okta-auth-js')
@aarongranick-okta - I am using curly braces.
@niteshchaudhary I'm assuming you are using the latest version of okta-auth-js (4.7.x). Are you using a yarn or lerna workspace or otherwise hoisting modules such that it is possible it is using an older version of the module?
What are you using for bundling? typescript, babel, webpack?
Any of these tools should be able to find the correct "browser" or "module" entrypoint, but if the bundler is confused, you may have to point it directly to the module entry:
node_modules/@okta/okta-auth-js/dist/okta-auth-js.umd.js
(hopefully it should not come to this)
@aarongranick-okta - I guess, I got some hold of the issue.
when I try to print oktaAuth.authStateManager - it prints "undefined". Hence I get error as TypeError: Cannot read property 'getAuthState' of undefined
Can you suggest, how I should define it?
I am using webpack and using okta-auth-js=4.7.1 and okta-react=4.1.0
and I changed my oktaConfig
as below:
const oktaConfig = {
clientId: 'abcd,
issuer: 'https://abcdabcd.okta.com',
pkce: false,
transformAuthState: async (oktaAuth, authState) => {
if (!authState.isAuthenticated) {
return authState;
}
}
};
reference: https://github.com/okta/okta-auth-js#transformauthstate
@niteshchaudhary authStateManager
will exist on the browser instance, but would not exist on the node (server) instance. My guess is somehow your bundler is choosing the server entry point instead of browser. There is a module resolution strategy option for both babel and typescript, check if it is forcing commonJS.
Hey guys, adding this worked
"jest": {
"moduleNameMapper": {
"^@okta/okta-auth-js$": "<rootDir>/node_modules/@okta/okta-auth-js/dist/okta-auth-js.umd.js"
}
}
However, I'm curios to know if this makes a real call out to the issuer url? I'd rather not be making real network requests during tests and just mock the auth object itself instead which is passed into the <Security>
component. Any ideas on how to do that?
Is there any update on this?
I'm trying to test App.tsx file containing following code:
import { CircularProgress } from '@mui/material';
import { OktaAuth, toRelativeUrl } from '@okta/okta-auth-js';
import { LoginCallback, SecureRoute, Security } from '@okta/okta-react';
import {
Route, useHistory, useLocation, Redirect,
} from 'react-router-dom';
import './App.css';
import Header from './components/header';
import { oktaAuthConfig } from './config/env-constants';
import LandingPage from './modules/landing-page';
import LoginScreen from './modules/login';
import ErrorCallbackComponent from './modules/login-callback-error';
const errorCallbackComponent = (propsParam: any) => <ErrorCallbackComponent error={propsParam.error} />;
const oktaAuth = new OktaAuth({ ...oktaAuthConfig });
function App() {
const history = useHistory();
const restoreOriginalUri = async (_oktaAuth: any, originalUri: any) => {
history.replace(toRelativeUrl(originalUri, window.location.origin));
};
const location = useLocation();
const isUserLoggedIn = () => {
const localStorageItem = JSON.parse(localStorage.getItem('okta-token-storage') || '{ }');
return (
!!(localStorageItem
&& localStorageItem.accessToken
&& localStorageItem.accessToken.accessToken));
};
return (
<Security oktaAuth={oktaAuth} restoreOriginalUri={restoreOriginalUri}>
<Header />
<div>
<Route
path="/"
exact
render={() => { return isUserLoggedIn() ? <Redirect to="/home" /> : <LoginScreen />; }}
/>
<SecureRoute path="/home" exact component={LandingPage} />
<Route
path="/callback"
render={() => (
<LoginCallback
errorComponent={(props) => errorCallbackComponent(props)}
loadingElement={(
<div style={{
height: '100vh',
width: '100vw',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
alignContent: 'center',
}}
>
<CircularProgress color="inherit" />
</div>
)}
/>
)}
/>
</div>
</Security>
);
}
export default App;
And the test is
import { render, waitFor } from '@testing-library/react';
import { MemoryRouter as Router } from 'react-router-dom';
import App from './App';
test('renders app', async () => {
render(<Router initialEntries={['/home']}><App /></Router>);
// const linkElement = screen.getByText(/learn react/i);
// expect(linkElement).toBeInTheDocument();
await waitFor(() => {
expect(true).toBeTruthy();
});
});
I keep getting TypeError: _oktaAuthJs.OktaAuth is not a constructor
.
I've added following configuration in package.json.
"jest": {
"moduleNameMapper": {
"^@okta/okta-auth-js$": "<rootDir>/node_modules/@okta/okta-auth-js/dist/okta-auth-js.min.js"
}
}
However if I change the configuration to point to <rootDir>/node_modules/@okta/okta-auth-js/dist/okta-auth-js.umd.js
, I get
FAIL src/App.test.tsx (9.356 s)
× renders app (989 ms)
● renders app
No useable method found in ["native","idb","localstorage"]
5 |
6 | test('renders app', async () => {
> 7 | render(<Router initialEntries={['/home']}><App /></Router>);
| ^
8 | // const linkElement = screen.getByText(/learn react/i);
9 | // expect(linkElement).toBeInTheDocument();
10 | await waitFor(() => {
at node_modules/@okta/okta-auth-js/dist/webpack:/OktaAuth/node_modules/broadcast-channel/dist/esbrowser/method-chooser.js:42:25
@nikhileshncyb As a workaround, please add in jest setup file:
// broadcast-channel should not detect node environment
// https://github.com/pubkey/broadcast-channel/blob/master/src/util.js#L61
process[Symbol.toStringTag] = 'Process';
hey, did anyone manage to run it? I'm using jest, I've already done the mapping of the module and the solution above and still nothing
+1, The workaround is not working for me as well.
I am in an non-ejected create-react-app, which requires putting jest setup code in src/setupTests.js
(instead of configuring the setupFilesAfterEnv
clause). Ostensibly it should be the same effect.
I have the line process[Symbol.toStringTag] = 'Process';
in my setupTests.js file, and confirm it is updating process toString to return "Process". But still seeing:
TypeError: _oktaAuthJs.OktaAuth is not a constructor
I know there have been new releases in both okta-auth-js and broadcast-channel since a year ago, any of those changes effect this?
React, redux with Visual studio enterprise, created default react app using Visual studio and followed step by step user guide for react application. While rendering Login Page I encountered this error:
LoginForm.tsx:18 Uncaught TypeError: okta_auth_js_1.default is not a constructor at new LoginForm (LoginForm.tsx:18) at constructClassInstance (react-dom.development.js:14185) at updateClassComponent (react-dom.development.js:18394) at beginWork$1 (react-dom.development.js:20161) at HTMLUnknownElement.callCallback (react-dom.development.js:336) at Object.invokeGuardedCallbackDev (react-dom.development.js:385) at invokeGuardedCallback (react-dom.development.js:440) at beginWork$$1 (react-dom.development.js:25738) at performUnitOfWork (react-dom.development.js:24662) at workLoopSync (react-dom.development.js:24638) at performSyncWorkOnRoot (react-dom.development.js:24237) at react-dom.development.js:12180 at unstable_runWithPriority (scheduler.development.js:818) at runWithPriority$2 (react-dom.development.js:12130) at flushSyncCallbackQueueImpl (react-dom.development.js:12175) at flushSyncCallbackQueue (react-dom.development.js:12163) at discreteUpdates$1 (react-dom.development.js:24390) at discreteUpdates (react-dom.development.js:1442) at dispatchDiscreteEvent (react-dom.development.js:5885)