capacitor icon indicating copy to clipboard operation
capacitor copied to clipboard

bug: `capacitor.config.ts` cannot support top-level `await`

Open oliveryasuna opened this issue 2 years ago • 8 comments

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:

  1. 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.
  2. Somehow allow the developer to specify the module type when importing capacitor.config.ts. Perhaps use a predefined TSConfig file, such as tsconfig.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 {};

oliveryasuna avatar Oct 06 '23 02:10 oliveryasuna

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 💙

ionitron-bot[bot] avatar Oct 06 '23 11:10 ionitron-bot[bot]

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.

oliveryasuna avatar Oct 06 '23 15:10 oliveryasuna

@jcesarmobile This is a pretty big limitation. Is it being considered?

oliveryasuna avatar Oct 19 '23 13:10 oliveryasuna

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 avatar Dec 16 '23 22:12 oliveryasuna

@oliveryasuna If your not already aware, this feature is coming in capacitor 6: https://github.com/ionic-team/capacitor/pull/4299

bosh-code avatar Feb 03 '24 22:02 bosh-code

it's not, it allows to use async code, but not top level await

jcesarmobile avatar Feb 05 '24 11:02 jcesarmobile

@jcesarmobile Still, it will remove the need for top-level await.

Thanks @bosh-code !

oliveryasuna avatar Mar 28 '24 01:03 oliveryasuna