capacitor
capacitor copied to clipboard
bug: `capacitor.config.ts` cannot support top-level `await`
Bug Report
Capacitor Version
💊 Capacitor Doctor 💊
Latest Dependencies:
@capacitor/cli: 5.4.2
@capacitor/core: 5.4.2
@capacitor/android: 5.4.2
@capacitor/ios: 5.4.2
Installed Dependencies:
@capacitor/cli: 5.4.2
@capacitor/core: 5.4.2
@capacitor/android: 5.4.2
@capacitor/ios: 5.4.2
[success] iOS looking great! 👌
Current Behavior
I was not sure if I should report this as a bug or feature. I consider it a bug, but a fix would most likely introduce a new feature.
See the Code Reproduction. It is impossible to use top-level await statements in capacitor.config.ts. This is due to https://github.com/ionic-team/capacitor/blob/main/cli/src/util/node.ts#L12-L50. The module is always loaded as a CommonJS module, which does not support top-level await statements.
You may think that you could make the whole module asynchronous:
// capacitor.config.ts
export default new Promise((resolve, reject) => {
// ...
});
but Capacitor does not handle this.
Expected Behavior
Capacitor should not limit developers to write a CommonJS-compliant capacitor.config.ts. It is a mobile framework, not a JS one. Thus, in my opinion, it can be mobile-opinionated, but not JS opinionated.
I propose two solutions:
- Instead of the DIY compiler found on https://github.com/ionic-team/capacitor/blob/main/cli/src/util/node.ts#L12-L50, Capacitor could use a configuration loader. https://github.com/cosmiconfig/cosmiconfig would be a top choice. This would also enable developers to write their Capacitor configurations in whatever format they so chose.
- Somehow allow the developer to specify the module type when importing
capacitor.config.ts. Perhaps use a predefined TSConfig file, such astsconfig.capacitor.json. Better if the code allows developers to specify the file, though.
Code Reproduction
https://github.com/oliveryasuna/capacitor-config-bug
Try running cap add ios, for example.
Here's a config that would cause problems.
// capacitor.config.ts
const myFunc = (async(): Promise<void> => {
});
await myFunc();
return {};
This issue needs more information before it can be addressed. In particular, the reporter needs to provide a minimal sample app that demonstrates the issue. If no sample app is provided within 15 days, the issue will be closed. Please see the Contributing Guide for how to create a Sample App. Thanks! Ionitron 💙
Looks like this is a duplicate of https://github.com/ionic-team/capacitor/issues/6836. However, that issue was closed. My temporary workaround was to write a script that imports my Capacitor TS config and writes capacitor.config.json.
@jcesarmobile This is a pretty big limitation. Is it being considered?
Alternatively, the CLI could support an function export, e.g.,
//capacitor.config.ts
import type {CapacitorConfig} from '@capacitor/cli';
export default async(): Promise<CapacitorConfig> => {
// `await` will work here.
};
@mlynch @jcesarmobile I would love to start contributing to Capacitor and am happy to open a PR for this.
@oliveryasuna If your not already aware, this feature is coming in capacitor 6: https://github.com/ionic-team/capacitor/pull/4299
it's not, it allows to use async code, but not top level await
@jcesarmobile Still, it will remove the need for top-level await.
Thanks @bosh-code !