“ReferenceError: capacitorExports is not defined” while running jest tests in a project with CapacitorJs (fix)
(Last Updated On: December 30, 2020)I got this horrible “ReferenceError: capacitorExports is not defined” error in my tests after adding the web version of a plugin to my Ionic/Angular/Capacitor project. For luck I was able to find a workaround for this problem and keep the tests running.
capacitorExports is not defined. Why does it happen?
Well, at least in capacitor 2 and 3 you need to register your plugin in this way:
// Import custom plugin package for web support too
import 'my-plugin';
Each plugin’s web implementation register it self inside a capacitorExports
object at run time. As expected, this object is not available while running tests so you get the “capacitorExports is not defined” error. Also register it manually does not help.
Typescript dynamic imports to the rescue.
The overall solution is to just import the web implementations in non test environments. For this we can use Typescript’s dynamic import expressions.
In my specific use case, I already have a global configuration object and I added there a flag angularEnvironmet
. It is always set to true
before Angular is started.
After that, in the service where the plugin dependency is needed it is called in this way
// The regular native plugin import
import { HeadsetDetectionPlugin } from '@saninn/capacitor-plugin-headset-detection';
// The optional web import
if (Saninn.angularEnvironment) {
import('@saninn/capacitor-plugin-headset-detection');
}
@Injectable({
providedIn: 'root',
})
export class MyService {
...
}
Although I am not so happy about changing the production code for testing, this is not overhead at all since I have my native imports centralized.
Be aware!
If your native plugin exports anything more than interfaces in their definitions.ts
(for exampleenums
) then this fix will not work because things like MyEnum.MyValue
will throw an error because MyEnum
will be undefined
.
I have already created a GitHub issue about this but at the time of this writing it did not had any official answer.