Making a dependency optional in my package used by create-react-app, Vite, and others - create-react-app

We have an npm package #glowbuzzer/controls. This package can make use of STEP file import functionality from occt-import-js, but not all users of #glowbuzzer/controls are interested in STEP files and may not want to add occt-import-js to their package.json (and shouldn't need to).
I am attempting to handle this by doing a dynamic import:
try {
const occtLib = import("occt-import-js");
occtLib.then((occt) => {
// do something with lib
}).catch((err) => {
console.error("Error loading occt-import-js", err);
});
} catch (e) {
console.warn("No occt-import-js found. STEP files will not be supported");
}
However, when using #glowbuzzer/controls in a CRA app, we get the following error:
Module not found: Error: Can't resolve 'occt-import-js'
Project will not run without installing occt-import-js. Is there any way around this error if dependency is not present?

You can't catch static imports errors
Yet, you could use a dynamic import() for that.
It is supported by most browsers & Node and CRA(Tested it out)
const loadModule = async (modulePath) => {
try {
return await import(modulePath)
} catch (e) {
console.warn("No occt-import-js found. STEP files will not be supported");
}
}
loadModule('occt-import-js');

Related

Cannot read property 'computeModPow' of undefined

After I've upgraded my project to react-native 0.64, aws amplify doesn't work properly. Mainly, I'm trying to make an authentification workflow, but the login functionality throws me the "Cannot read property 'computeModPow' of undefined", even if signup function works completely fine.
After digging into the problem, I found that "aws-cognito-identity-js" is the main problem. If I try to link the library, rn bundler throws an error, that "aws-cognito-identity-js" is already linked, or that I can't override it.
Any suggestions?
Package.json
"react": "16.8.6",
"react-native": "0.60.4",
"aws-amplify": "^1.1.32",
"aws-amplify-react-native": "^2.1.15",
Implementation:
export const loginUser = (credentials: any) => async (dispatch: any) => {
dispatch({ type: LOGIN_USER });
try {
const data = await Auth.signIn(credentials.email, credentials.password);
return loginUserSuccess(dispatch, data);
} catch (error) {
return loginUserFail(dispatch, error);
}
};
const loginUserSuccess = (dispatch: any, data: any) => {
console.log({ data });
dispatch({ type: LOGIN_USER_SUCCESS, attributes: {} });
};
const loginUserFail = (dispatch: any, error: any) => {
console.log({ error });
dispatch({ type: LOGIN_USER_FAILED });
};
Error:
"TypeError: Cannot read property 'computeModPow' of undefined
at BigInteger.nativeModPow [as modPow] (blob:file:///6e426a68-ddf4-48ca-86cf-ba3536cb9a13:217690:17)
at AuthenticationHelper.calculateA (blob:file:///6e426a68-ddf4-48ca-86cf-ba3536cb9a13:217990:16)
at AuthenticationHelper.getLargeAValue (blob:file:///6e426a68-ddf4-48ca-86cf-ba3536cb9a13:217928:16)
at new AuthenticationHelper (blob:file:///6e426a68-ddf4-48ca-86cf-ba3536cb9a13:217910:12)
at CognitoUser.authenticateUserDefaultAuth (blob:file:///6e426a68-ddf4-48ca-86cf-ba3536cb9a13:219720:36)
at CognitoUser.authenticateUser (blob:file:///6e426a68-ddf4-48ca-86cf-ba3536cb9a13:219710:23)
at blob:file:///6e426a68-ddf4-48ca-86cf-ba3536cb9a13:185525:14
at tryCallTwo (blob:file:///6e426a68-ddf4-48ca-86cf-ba3536cb9a13:24791:7)
at doResolve (blob:file:///6e426a68-ddf4-48ca-86cf-ba3536cb9a13:24955:15)
at new Promise (blob:file:///6e426a68-ddf4-48ca-86cf-ba3536cb9a13:24814:5)"
I had the same problem and tried to run react-native link amazon-cognito-identity-js according to https://aws-amplify.github.io/docs/js/react#add-auth.
However the Cannot read property 'computeModPow' of undefined error persisted even after cleaning the build, restarting packager, etc.
The problem was that the package never got linked properly with react-native link amazon-cognito-identity-js. This requires us to manually link which is pretty easy to do luckily!
Assuming XCode (Look here to find how to do the similar process for Android) you go to the Project Navigator and right click Libraries folder which contains all your 3rd party .xcodeproj. Choose Add Files... and add the RNAWSCognito.xcodeproj from within the ${projectDir}/node_modules/amazon-cognito-identity-js/ios/ directory. Open the RNAWSCognito.xcodeproj and Products folders and drag libRNAWSCognito.a to Linked Frameworks and Libraries under the General tab. Re-run the project and should be good to go. May have to clean, restart packager, etc.
You can fix this by doing the following:
yarn add amazon-cognito-identity-js
react-native link amazon-cognito-identity-js
cd ios ; pod update ; cd ..
Cheers!
I don't know who needs this, but after I confirmed amazon-cognito-identity-js:
1) was in settings.gradle
2) was in app/build.gradle
I had to make sure to have the below in MainApplication.java
import com.amazonaws.RNAWSCognitoPackage;
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
// eg. new VectorIconsPackage()
new NetInfoPackage(),
new AsyncStoragePackage(),
new RNAWSCognitoPackage()
);
}
Good Luck.

React Native project - cannot make API calls with AwsAmplify through custom library

I have a react-native app (without expo) called myapp.
I have a private custom package called myapp-core, where I handle AwsAmplify services (Auth, Storage) - to do login/signOut/etc.
I want to use myapp-core in myapp project, so I added it as a dependency in package.json ("myapp-core": "file:../myapp-core",) and then yarn install.
The problem I’m facing is that when I call myapp-core.authService.login(username, password) from the mobile project, I catch the error:
“ { “line”:177826, “column”: 17, “sourceURL”:
“http://10.0.2.2:8081/index.delta?platform=android&dev=true&minify=false”
} ”
From my research, that means my custom library cannot make api calls - but I don’t know exactly.
When I use aws-amplify's Auth object directly in my mobile project, it works.
Hopefully relevant code:
/**=============================**/
/** myapp/CoreServices.js **/
import { AmplifyService } from “myapp-core";
export default class CoreServices {
constructor() {
AmplifyService.configure();
const auth = AmplifyService.authService();
auth
.login(“myusername”, “mypassword”)
.then(user => console.warn("success", user))
.catch(error => console.warn("error", error));
}
}
/**=============================**/
/** myapp-core/AmplifySevice.js **/
import Amplify from 'aws-amplify';
import AuthService from '../AuthService/AuthService';
import awsConfigs from '../aws-exports';
class AmplifyService {
static authServiceInstance = null;
static storageServiceInstance = null;
static configure(config = awsConfigs) {
if (config === null || config === undefined) {
throw new Error('AmplifyService must be initialized with Auth and Storage configurations.');
}
Amplify.configure({
Auth: { /*...*/ },
Storage: { /*...*/ }
});
}
static authService() {
if (!this.authServiceInstance) {
this.authServiceInstance = new AuthService();
}
return this.authServiceInstance;
}
static storageService() {
console.warn('storage service');
// initialize storage service
// return storage service
}
}
I managed to solve my project's issue.
Maybe someone will benefit from my solution.
The problem didn't have anything to do with AwsAmplify, but with the way I linked the projects: myapp-core with myapp.
The issue was that in the myapp-core I am using the aws-amplify package that I would normally link to the mobile projects (react-native link) but in my case I assumed (wrongly) that it wouldn't be the case.
The solution was to link whatever packages were needed in the iOS/Android projects to install the proper pods/gradle libraries, like react-native link amazon-cognito-identity-js for authentication.
... and now I am finally happy :))
Links that shed some light:
https://github.com/facebook/create-react-app/issues/1492
https://eshlox.net/2018/11/12/aws-amplify-react-native-typeerror-cannot-read-property-computemodpow-of-undefined/
In case somebody thinks this isn't the solution and I got lucky or something, please comment or post another response.

Unable to include AB Testing for React Native application

I am integrating A/B Testing for my React Native application using Firebase. I have tried two methods - using react-native-ab and react-native-ab-test.
In the first case, I get an error saying "undefined is not an object(evaluating PropTypes.string)"
In the second case, I get an error saying "index.ios.js tries to require 'react-native' but there are several files providing this module. You can delete or fix them."
In both the cases, I get these errors just by importing the dependency in my JS file. By seeing the github pages of both dependencies, I think there is no need to link both the dependencies and they run fine.
Links :
https://github.com/lwansbrough/react-native-ab
https://github.com/landaio/react-native-ab-test
I installed it with this module and it works perfectly, you can try this:
https://github.com/invertase/react-native-firebase
https://rnfirebase.io/docs/v5.x.x/getting-started
and then it is to configure the remote config so that the a-b test works for you
https://rnfirebase.io/docs/v5.x.x/config/reference/config
I'm using A/B testing and works for me with this module:
"react-native-firebase": "3.3.1",
and needs pod too.
pod 'Firebase/Core', '~> 5.11.0'
pod 'Firebase/RemoteConfig', '~> 5.11.0'
My logic
import firebase from 'react-native-firebase';
setRemoteConfigDefaults() {
if (__DEV__) {
firebase.config().enableDeveloperMode();
}
// Set default values
firebase.config().setDefaults({
my_variant_remote_config_param: ''
});
}
/**
* FIREBASE remote config fetch
* #param valueToFetch: remote config key
*/
export const fetchRemoteConfig = async (valueToFetch: RemoteConfigKeysTypes): Promise<string> => {
try {
await firebase.config().fetch();
await firebase.config().activateFetched();
const snapshot = await firebase.config().getValue(valueToFetch);
const response = snapshot.val();
return response;
} catch (error) {
firebase.analytics().logEvent('remote_config_get_value_error', { error, key: valueToFetch });
return null;
}
};
More Info:
https://www.npmjs.com/package/react-native-firebase

Tests are failing after Angular 2 RC5

I had used the following format for my tests:
export function main() {
describe('Angular2 component test', function() {
it('should initialize component',
async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
var template = '<specific-component-tag>';
return tcb.overrideTemplate(TestComponent, template)
.createAsync(TestComponent)
.then((fixture) => {
expect(fixture.componentInstance.viewChild).toBeDefined();
fixture.detectChanges();
expect(fixture.componentInstance.viewChild.items.length).toBe(1);
// .... etc.
}).catch (reason => {
console.log(reason);
return Promise.reject(reason);
});
})));
});
}
This work fine in RC4. But RC5 came suddenly and now this code have not worked.
It throws me the following errors:
Module ".... #angular/core/testing" has no exported member 'it'.
Module ".... #angular/core/testing" has no exported member 'describe'.
Module ".... #angular/core/testing" has no exported member 'expect'.
Module ".... #angular/core/testing" has no exported member 'beforeEachProviders'.
Module ".... #angular/compiler/testing" has no exported member 'TestComponentBuilder'.
Module ".... #angular/compiler/testing" has no exported member 'ComponentFixture'.
Please help me to migrate this test to angular2 RC5.
Update:
I have already read RC5 release notes but nothing comes to my mind how to achieve my goal.
The Jasmine imports available through #angular/core/testing are removed. So remove the imports for the following
Before:
import {
beforeEach,
beforeEachProviders,
describe,
expect,
it,
inject,
} from '#angular/core/testing';
after
/// <reference path="../../../typings/main/ambient/jasmine/index.d.ts" />
import {
inject, addProviders
} from '#angular/core/testing';
The reference path should be the first line in the file and it should point to jasmine type definition file. (Update the relative up. i.e the ../../ to whatever)To get jasmine type defitions, add the following line to ambientDevDependencies. Mine looks something like this
{
"ambientDevDependencies": {
"angular-protractor": "registry:dt/angular-protractor#1.5.0+20160425143459",
"jasmine": "registry:dt/jasmine#2.2.0+20160412134438",
"selenium-webdriver": "registry:dt/selenium-webdriver#2.44.0+20160317120654"
},
"ambientDependencies": {
"es6-shim": "registry:dt/es6-shim#0.31.2+20160317120654"
}
}
Also change
beforeEachProviders(() => [InMemoryDataService]);
to
import { TestBed } from '#angular/core/testing';
...
describe('...', () => {
TestBed.configureTestingModule({
providers: [ InMemoryDataService ]
});
it(...);
});
Take a look at changelog:
https://github.com/angular/angular/blob/master/CHANGELOG.md
It looks like API, which you are using is deprecated - path and names has changed. :)
For example:
TestComponentBuilder and ComponentFixture is now in #angular/core/testing,
beforeEachProviders:
code:
beforeEachProviders(() => [MyService]);
changed to:
beforeEach(() => {
addProviders([MyService]);
});
If you already read their release note. It's a lot of change in testing API package.
https://github.com/angular/angular/blob/master/CHANGELOG.md#breaking-changes
So, I didn't try to migrate test to RC5 yet. But I found link about change to new testing API.
https://ng2-info.github.io/2016/08/angular-2-rc-5/#テスティングapiに関する変更
Hope this help.

How to test a server side debugOnly package

I don't understand how it is possible to test a package that is debugOnly.
My package.js is quite simple :
Package.describe({
name: 'lambda',
version: '0.0.1',
debugOnly: true // Will not be packaged into the production build
});
Package.onUse(function(api) {
api.versionsFrom('1.2.1');
api.addFiles('lambda.js');
api.export("Lambda", 'server');
});
Package.onTest(function(api) {
api.use('tinytest');
api.use('lambda');
api.addFiles('lambda-tests.js', 'server');
});
My lambda-test.js :
Tinytest.add('example', function (test) {
test.equal(Lambda.func(), true);
});
My lambda.js :
Lambda = {
func: function() {
return "Christmas";
}
}
When I run meteor test-packages, it just fails : Lambda is not defined. If I remove the debugOnly: true the test pass. So how can I test my package using tinytest ?
Or this is a bug !
I had the same issue! It turns out the tests are working fine. The Lambda is not getting exported in the project either.
from https://github.com/meteor/meteor/blob/0f0c5d3bb3a5492254cd0843339a6716ef65fce1/tools/isobuild/compiler.js
// don't import symbols from debugOnly and prodOnly packages, because
// if the package is not linked it will cause a runtime error.
// the code must access them with `Package["my-package"].MySymbol`.
Try:
Tinytest.add('example', function (test) {
//also changed expected value from true to Christmas to make test pass
test.equal(Package['lambda']['Lambda'].func(), "Christmas");
//you can use Package['lambda'].Lambda as well, but my IDE complains
});
Now you can do something like this:
if (Package['lambda']) {
console.log("we are in debug mode and we have lamda");
console.log("does this say Christmas? " + Package['lambda']["Lambda"]['func']());
} else {
console.log("we are in production mode, or we have not installed lambda");
}