You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cordova.apache.org by Norman Breau <no...@nbsolutions.ca> on 2023/03/30 04:45:11 UTC

Testing a new Plugin "Module" authoring method

Hi all,

I just wanted to announce that I've been experimenting with a different 
way of authoring Cordova plugins.
I don't really have anything to show right now, but looking to get some 
abstract high-level feedback based on the idea.

This is more or less a preliminary start of a discussion so that I can 
get some early feedback. The plan is to come back some time later with
a more official specification document and usable PoCs for both Android 
& iOS platforms.

Privately I've been experimenting with a more closer "native" method 
which I feel like solves several issues
with the way that cordova plugins are traditionally authored.

First I'll explain briefly the pains of authoring cordova plugins, and 
then I'll explain a high level idea that will likely solve the problems.

Currently the plugins are authored by having a set of arbitrary source 
files as defined by the <source-file> / <header-file> directives,
which also declares where these files should be copied to into the 
cordova native app project. Additionally, if the plugin requires
changing resource files or adding additional configurations, they must 
make use of several directives which may include:

- config-file
- edit-config
- resource-file
- lib-file
- framework
- source-file / header-file
- asset


Most of these works well enough, but shouldn't be necessary to begin 
with. Others, are very finicky or are barely usable due to bugs or other 
caveats (e.g. config-file and edit-config)

The second issue with the way that Cordova plugins are traditionally 
authored (based on the Official Apache plugins) is that they
aren't unit testable. They can only really be tested as part of a real 
cordova project, which we currently do via cordova-paramedic.
This is because there is a disconnect between the plugin sources and an 
actual native project.

So I've been experimenting with authoring cordova plugins using a native 
project that gets imported a cordova project. Right now
my experimentation has been exclusively with the Android platform, so 
I'll be using more Android-specific examples.

But my experimentation has me building a cordova plugin that instead of 
containing loose java source files, they contain an actual
Gradle project that builds an Android Library. This means that the 
Cordova Plugin has it's own:

- Source files
- AndroidManifest
- resources
- Gradle configs & dependency management

With these tools at the plugin's author disposal... it should eliminate, 
or mostly eliminate the need of the aforementioned directives:

- edit-config

Is no longer required to edit AndroidManifest.xml, but may still be 
required to edit config.xml (but is there really a need to?). Instead
native libraries have their own AndroidManifest.xml which will get 
merged with the App's manifest.

- lib-file

A native library can bundle their own lib-files.

- resource-file

A native library can bundle their own resource files.

- framework

A native library has it's own gradle file to manage frameworks/dependencies

- source-file / header-file

A native library has it's own file structure for their source files, 
whether java or native C++ modules.

- config-file*

While won't be needed to edit AndroidManifest.xml for the same reason as 
edit-config, which was a common use case...
It will still be required for setting up cordova Feature 
tags/declarations which gets placed into `config.xml`.

- asset*

Untested, I'm not sure if assets will get merged in a way that is usable 
by the app. So this directive may still be relevant.

Additionally, the js-module directive will still be relevant as the 
native project has no concept of setting up the webview JS modules.

*To be clear*, I'm not suggesting that the current plugin.xml directives 
to be deprecated or removed. They are still going
to be required to support any cordova plugin authored in a traditional 
method. However, with the module method, most of these directives won't 
be necessary to use.
In fact, I think the module method could continue to use any one of the 
existing directives if they choose to, but in all likeliness, there 
won't be a need to. In
practice we may want to discourage people to use the "legacy" directives 
so that support could be considered to be dropped in the future.

I foresee a new directive being created to declare the "module" 
directory, which is the root folder of a native project, which would 
simply be copied in full to a directory inside the app project.
For example, the module format really needs 4 main actions to be done in 
a cordova android project. I'll pretend that cordova-plugin-file is 
authored in a module format containing a gradle project.

Cordova will need to:

1. Copy the cordova-plugin-file gradle project into a subdirectory (e.g. 
/platforms/android/cdvModules/cordova-plugin-file)
2. settings.gradle needs a line to include the gradle project into it's 
build system (e.g. include ":cdvModules:cordova-plugin-file")
3. The "app" module needs to depend on cordova-plugin-file (e.g: 
implementation project(":cdvModules:cordova-plugin-file"))
4. Configure the JS-modules / config.xml "Feature" tags just like it 
always did before.

Apache Cordova will still not be distributing prebuilt libraries (e.g. 
plugins are not AAR or xcframeworks) but rather the complete module that 
can be copied into a project as a module.
The module itself will contain all the build scripts and source code. I 
believe this still satisfies Apache's Release policy requiring source 
packages with no compiled code[1]. Of course,
third-party plugin authors can still utilize this method of authoring 
plugins and still include closed sources or libraries if they choose so.

Lastly, now that the plugin has a native project housed, it will also be 
much easier to unit test the native side. However there is one caveat 
where e2e tests cannot be done as that will still require a real cordova 
project,
so cordova-paramedic will still have to be used for e2e testing.

I do have a working example of this system I described for Android but I 
still have lots of testing to do myself. Still, I feel very confident 
that this is major improvements to how plugins are authored, which 
hopefully will encourage well written and well tested plugins, as well 
as reducing
the need for plugin authors to manipulate the app's resource files, 
which can often result in conflicts.

Moving forward I'd be continuing to experiment with both the Android & 
iOS platforms, preparing proof of concept repositories as well as a 
specification document for a lower level detailed
of what implementation may look like, which can then be further 
reviewed/commented.

Looking forward for any comments, questions, or concerns.

Cheers,
Norman

References:
[1] https://www.apache.org/legal/release-policy.html#source-packages

Re: Testing a new Plugin "Module" authoring method

Posted by julio cesar sanchez <jc...@gmail.com>.
I’ve seen this error pop up sometimes that seems to indicate that it’s not
possible, but not always, so might depend on how the aar is configured to
be used, glad to know it works for you.


> Direct local .aar file dependencies are not supported when building an AAR.
> The resulting AAR would be broken because the classes and Android resources from any local .aar file dependencies would not be packaged in the resulting AAR. Previous versions of the Android Gradle Plugin produce broken AARs in this case too (despite not throwing this error).

About the SDKs that don’t work in modules, it’s not the SDK by itself, but
gradle plugins it might require to run, fabric is the one that comes to
mind, but I think it’s now part of some firebase project, don’t know which
one.


El jueves, 30 de marzo de 2023, Norman Breau <no...@nbsolutions.ca>
escribió:

> Modules can bundle AARs and native libraries however there will be a
> conflict if you have multiple modules bundling the same libraries.
>
> Internally at my workplace we handle this by wrapping the native library
> (either native C++ or AAR/xcframework) around a plugin whose
> sole purpose is to provide the library, which multiple modules can use the
> <dependency> directive to import the plugin. This ensures that a single
> copy of the library is present for the application.
>
> Some examples:
> https://github.com/totalpaveinc/cordova-plugin-libcxx
> https://github.com/totalpaveinc/cordova-plugin-libsqlite (depends on
> libcxx)
> https://github.com/totalpaveinc/cordova-plugin-sqlite (depends on
> libsqlite)
>
> Where sqlite is a cordova plugin API into libsqlite, which contains the
> native SQLite C library, with additional C++ addons, making it depend on
> libcxx for android.
> We have another internal/private plugin that also depends on libsqlite and
> libcxx and it's cordova plugin declares the dependency so that the library
> wrappers
> are present at the application level.
>
> I believe this is only an issue if you bundle the libraries yourself as
> well. If you use Gradle to manage dependency artifacts, I believe those are
> all resolved at build time,
> assuming that you don't have two modules requiring on incompatible
> versions. (e.g. Plugin A wants X:1.0.0 where Plugin B wants X:2.0.0).
>
> If you know of any specific libraries that **has** to be bundled at the
> application level, would be interesting to know, but in those cases I think
> the existing <lib-file> directive
> could be used to support that kind of use case.
>
> On 2023-03-30 11:57 a.m., julio cesar sanchez wrote:
>
>> I had similar thoughts in the past, but never had time to implement it
>> myself.
>>
>> For reference, Joe already tried to convert the Android part of
>> InAppBrowser plugin into a library project back in 2018
>>
>> https://github.com/apache/cordova-plugin-inappbrowser/pull/242
>>
>> Modules have some problems too, like not being able to bundle aar
>> libraries, and some native SDKs can’t be used in modules.
>>
>>
>>
>> El jueves, 30 de marzo de 2023, Norman Breau <no...@nbsolutions.ca>
>> escribió:
>>
>> Hi all,
>>>
>>> I just wanted to announce that I've been experimenting with a different
>>> way of authoring Cordova plugins.
>>> I don't really have anything to show right now, but looking to get some
>>> abstract high-level feedback based on the idea.
>>>
>>> This is more or less a preliminary start of a discussion so that I can
>>> get
>>> some early feedback. The plan is to come back some time later with
>>> a more official specification document and usable PoCs for both Android &
>>> iOS platforms.
>>>
>>> Privately I've been experimenting with a more closer "native" method
>>> which
>>> I feel like solves several issues
>>> with the way that cordova plugins are traditionally authored.
>>>
>>> First I'll explain briefly the pains of authoring cordova plugins, and
>>> then I'll explain a high level idea that will likely solve the problems.
>>>
>>> Currently the plugins are authored by having a set of arbitrary source
>>> files as defined by the <source-file> / <header-file> directives,
>>> which also declares where these files should be copied to into the
>>> cordova
>>> native app project. Additionally, if the plugin requires
>>> changing resource files or adding additional configurations, they must
>>> make use of several directives which may include:
>>>
>>> - config-file
>>> - edit-config
>>> - resource-file
>>> - lib-file
>>> - framework
>>> - source-file / header-file
>>> - asset
>>>
>>>
>>> Most of these works well enough, but shouldn't be necessary to begin
>>> with.
>>> Others, are very finicky or are barely usable due to bugs or other
>>> caveats
>>> (e.g. config-file and edit-config)
>>>
>>> The second issue with the way that Cordova plugins are traditionally
>>> authored (based on the Official Apache plugins) is that they
>>> aren't unit testable. They can only really be tested as part of a real
>>> cordova project, which we currently do via cordova-paramedic.
>>> This is because there is a disconnect between the plugin sources and an
>>> actual native project.
>>>
>>> So I've been experimenting with authoring cordova plugins using a native
>>> project that gets imported a cordova project. Right now
>>> my experimentation has been exclusively with the Android platform, so
>>> I'll
>>> be using more Android-specific examples.
>>>
>>> But my experimentation has me building a cordova plugin that instead of
>>> containing loose java source files, they contain an actual
>>> Gradle project that builds an Android Library. This means that the
>>> Cordova
>>> Plugin has it's own:
>>>
>>> - Source files
>>> - AndroidManifest
>>> - resources
>>> - Gradle configs & dependency management
>>>
>>> With these tools at the plugin's author disposal... it should eliminate,
>>> or mostly eliminate the need of the aforementioned directives:
>>>
>>> - edit-config
>>>
>>> Is no longer required to edit AndroidManifest.xml, but may still be
>>> required to edit config.xml (but is there really a need to?). Instead
>>> native libraries have their own AndroidManifest.xml which will get merged
>>> with the App's manifest.
>>>
>>> - lib-file
>>>
>>> A native library can bundle their own lib-files.
>>>
>>> - resource-file
>>>
>>> A native library can bundle their own resource files.
>>>
>>> - framework
>>>
>>> A native library has it's own gradle file to manage
>>> frameworks/dependencies
>>>
>>> - source-file / header-file
>>>
>>> A native library has it's own file structure for their source files,
>>> whether java or native C++ modules.
>>>
>>> - config-file*
>>>
>>> While won't be needed to edit AndroidManifest.xml for the same reason as
>>> edit-config, which was a common use case...
>>> It will still be required for setting up cordova Feature
>>> tags/declarations
>>> which gets placed into `config.xml`.
>>>
>>> - asset*
>>>
>>> Untested, I'm not sure if assets will get merged in a way that is usable
>>> by the app. So this directive may still be relevant.
>>>
>>> Additionally, the js-module directive will still be relevant as the
>>> native
>>> project has no concept of setting up the webview JS modules.
>>>
>>> *To be clear*, I'm not suggesting that the current plugin.xml directives
>>> to be deprecated or removed. They are still going
>>> to be required to support any cordova plugin authored in a traditional
>>> method. However, with the module method, most of these directives won't
>>> be
>>> necessary to use.
>>> In fact, I think the module method could continue to use any one of the
>>> existing directives if they choose to, but in all likeliness, there won't
>>> be a need to. In
>>> practice we may want to discourage people to use the "legacy" directives
>>> so that support could be considered to be dropped in the future.
>>>
>>> I foresee a new directive being created to declare the "module"
>>> directory,
>>> which is the root folder of a native project, which would simply be
>>> copied
>>> in full to a directory inside the app project.
>>> For example, the module format really needs 4 main actions to be done in
>>> a
>>> cordova android project. I'll pretend that cordova-plugin-file is
>>> authored
>>> in a module format containing a gradle project.
>>>
>>> Cordova will need to:
>>>
>>> 1. Copy the cordova-plugin-file gradle project into a subdirectory (e.g.
>>> /platforms/android/cdvModules/cordova-plugin-file)
>>> 2. settings.gradle needs a line to include the gradle project into it's
>>> build system (e.g. include ":cdvModules:cordova-plugin-file")
>>> 3. The "app" module needs to depend on cordova-plugin-file (e.g:
>>> implementation project(":cdvModules:cordova-plugin-file"))
>>> 4. Configure the JS-modules / config.xml "Feature" tags just like it
>>> always did before.
>>>
>>> Apache Cordova will still not be distributing prebuilt libraries (e.g.
>>> plugins are not AAR or xcframeworks) but rather the complete module that
>>> can be copied into a project as a module.
>>> The module itself will contain all the build scripts and source code. I
>>> believe this still satisfies Apache's Release policy requiring source
>>> packages with no compiled code[1]. Of course,
>>> third-party plugin authors can still utilize this method of authoring
>>> plugins and still include closed sources or libraries if they choose so.
>>>
>>> Lastly, now that the plugin has a native project housed, it will also be
>>> much easier to unit test the native side. However there is one caveat
>>> where
>>> e2e tests cannot be done as that will still require a real cordova
>>> project,
>>> so cordova-paramedic will still have to be used for e2e testing.
>>>
>>> I do have a working example of this system I described for Android but I
>>> still have lots of testing to do myself. Still, I feel very confident
>>> that
>>> this is major improvements to how plugins are authored, which hopefully
>>> will encourage well written and well tested plugins, as well as reducing
>>> the need for plugin authors to manipulate the app's resource files, which
>>> can often result in conflicts.
>>>
>>> Moving forward I'd be continuing to experiment with both the Android &
>>> iOS
>>> platforms, preparing proof of concept repositories as well as a
>>> specification document for a lower level detailed
>>> of what implementation may look like, which can then be further
>>> reviewed/commented.
>>>
>>> Looking forward for any comments, questions, or concerns.
>>>
>>> Cheers,
>>> Norman
>>>
>>> References:
>>> [1] https://www.apache.org/legal/release-policy.html#source-packages
>>>
>>>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
> For additional commands, e-mail: dev-help@cordova.apache.org
>
>

Re: Testing a new Plugin "Module" authoring method

Posted by Norman Breau <no...@nbsolutions.ca>.
Modules can bundle AARs and native libraries however there will be a 
conflict if you have multiple modules bundling the same libraries.

Internally at my workplace we handle this by wrapping the native library 
(either native C++ or AAR/xcframework) around a plugin whose
sole purpose is to provide the library, which multiple modules can use 
the <dependency> directive to import the plugin. This ensures that a single
copy of the library is present for the application.

Some examples:
https://github.com/totalpaveinc/cordova-plugin-libcxx
https://github.com/totalpaveinc/cordova-plugin-libsqlite (depends on libcxx)
https://github.com/totalpaveinc/cordova-plugin-sqlite (depends on libsqlite)

Where sqlite is a cordova plugin API into libsqlite, which contains the 
native SQLite C library, with additional C++ addons, making it depend on 
libcxx for android.
We have another internal/private plugin that also depends on libsqlite 
and libcxx and it's cordova plugin declares the dependency so that the 
library wrappers
are present at the application level.

I believe this is only an issue if you bundle the libraries yourself as 
well. If you use Gradle to manage dependency artifacts, I believe those 
are all resolved at build time,
assuming that you don't have two modules requiring on incompatible 
versions. (e.g. Plugin A wants X:1.0.0 where Plugin B wants X:2.0.0).

If you know of any specific libraries that **has** to be bundled at the 
application level, would be interesting to know, but in those cases I 
think the existing <lib-file> directive
could be used to support that kind of use case.

On 2023-03-30 11:57 a.m., julio cesar sanchez wrote:
> I had similar thoughts in the past, but never had time to implement it
> myself.
>
> For reference, Joe already tried to convert the Android part of
> InAppBrowser plugin into a library project back in 2018
>
> https://github.com/apache/cordova-plugin-inappbrowser/pull/242
>
> Modules have some problems too, like not being able to bundle aar
> libraries, and some native SDKs can’t be used in modules.
>
>
>
> El jueves, 30 de marzo de 2023, Norman Breau <no...@nbsolutions.ca>
> escribió:
>
>> Hi all,
>>
>> I just wanted to announce that I've been experimenting with a different
>> way of authoring Cordova plugins.
>> I don't really have anything to show right now, but looking to get some
>> abstract high-level feedback based on the idea.
>>
>> This is more or less a preliminary start of a discussion so that I can get
>> some early feedback. The plan is to come back some time later with
>> a more official specification document and usable PoCs for both Android &
>> iOS platforms.
>>
>> Privately I've been experimenting with a more closer "native" method which
>> I feel like solves several issues
>> with the way that cordova plugins are traditionally authored.
>>
>> First I'll explain briefly the pains of authoring cordova plugins, and
>> then I'll explain a high level idea that will likely solve the problems.
>>
>> Currently the plugins are authored by having a set of arbitrary source
>> files as defined by the <source-file> / <header-file> directives,
>> which also declares where these files should be copied to into the cordova
>> native app project. Additionally, if the plugin requires
>> changing resource files or adding additional configurations, they must
>> make use of several directives which may include:
>>
>> - config-file
>> - edit-config
>> - resource-file
>> - lib-file
>> - framework
>> - source-file / header-file
>> - asset
>>
>>
>> Most of these works well enough, but shouldn't be necessary to begin with.
>> Others, are very finicky or are barely usable due to bugs or other caveats
>> (e.g. config-file and edit-config)
>>
>> The second issue with the way that Cordova plugins are traditionally
>> authored (based on the Official Apache plugins) is that they
>> aren't unit testable. They can only really be tested as part of a real
>> cordova project, which we currently do via cordova-paramedic.
>> This is because there is a disconnect between the plugin sources and an
>> actual native project.
>>
>> So I've been experimenting with authoring cordova plugins using a native
>> project that gets imported a cordova project. Right now
>> my experimentation has been exclusively with the Android platform, so I'll
>> be using more Android-specific examples.
>>
>> But my experimentation has me building a cordova plugin that instead of
>> containing loose java source files, they contain an actual
>> Gradle project that builds an Android Library. This means that the Cordova
>> Plugin has it's own:
>>
>> - Source files
>> - AndroidManifest
>> - resources
>> - Gradle configs & dependency management
>>
>> With these tools at the plugin's author disposal... it should eliminate,
>> or mostly eliminate the need of the aforementioned directives:
>>
>> - edit-config
>>
>> Is no longer required to edit AndroidManifest.xml, but may still be
>> required to edit config.xml (but is there really a need to?). Instead
>> native libraries have their own AndroidManifest.xml which will get merged
>> with the App's manifest.
>>
>> - lib-file
>>
>> A native library can bundle their own lib-files.
>>
>> - resource-file
>>
>> A native library can bundle their own resource files.
>>
>> - framework
>>
>> A native library has it's own gradle file to manage frameworks/dependencies
>>
>> - source-file / header-file
>>
>> A native library has it's own file structure for their source files,
>> whether java or native C++ modules.
>>
>> - config-file*
>>
>> While won't be needed to edit AndroidManifest.xml for the same reason as
>> edit-config, which was a common use case...
>> It will still be required for setting up cordova Feature tags/declarations
>> which gets placed into `config.xml`.
>>
>> - asset*
>>
>> Untested, I'm not sure if assets will get merged in a way that is usable
>> by the app. So this directive may still be relevant.
>>
>> Additionally, the js-module directive will still be relevant as the native
>> project has no concept of setting up the webview JS modules.
>>
>> *To be clear*, I'm not suggesting that the current plugin.xml directives
>> to be deprecated or removed. They are still going
>> to be required to support any cordova plugin authored in a traditional
>> method. However, with the module method, most of these directives won't be
>> necessary to use.
>> In fact, I think the module method could continue to use any one of the
>> existing directives if they choose to, but in all likeliness, there won't
>> be a need to. In
>> practice we may want to discourage people to use the "legacy" directives
>> so that support could be considered to be dropped in the future.
>>
>> I foresee a new directive being created to declare the "module" directory,
>> which is the root folder of a native project, which would simply be copied
>> in full to a directory inside the app project.
>> For example, the module format really needs 4 main actions to be done in a
>> cordova android project. I'll pretend that cordova-plugin-file is authored
>> in a module format containing a gradle project.
>>
>> Cordova will need to:
>>
>> 1. Copy the cordova-plugin-file gradle project into a subdirectory (e.g.
>> /platforms/android/cdvModules/cordova-plugin-file)
>> 2. settings.gradle needs a line to include the gradle project into it's
>> build system (e.g. include ":cdvModules:cordova-plugin-file")
>> 3. The "app" module needs to depend on cordova-plugin-file (e.g:
>> implementation project(":cdvModules:cordova-plugin-file"))
>> 4. Configure the JS-modules / config.xml "Feature" tags just like it
>> always did before.
>>
>> Apache Cordova will still not be distributing prebuilt libraries (e.g.
>> plugins are not AAR or xcframeworks) but rather the complete module that
>> can be copied into a project as a module.
>> The module itself will contain all the build scripts and source code. I
>> believe this still satisfies Apache's Release policy requiring source
>> packages with no compiled code[1]. Of course,
>> third-party plugin authors can still utilize this method of authoring
>> plugins and still include closed sources or libraries if they choose so.
>>
>> Lastly, now that the plugin has a native project housed, it will also be
>> much easier to unit test the native side. However there is one caveat where
>> e2e tests cannot be done as that will still require a real cordova project,
>> so cordova-paramedic will still have to be used for e2e testing.
>>
>> I do have a working example of this system I described for Android but I
>> still have lots of testing to do myself. Still, I feel very confident that
>> this is major improvements to how plugins are authored, which hopefully
>> will encourage well written and well tested plugins, as well as reducing
>> the need for plugin authors to manipulate the app's resource files, which
>> can often result in conflicts.
>>
>> Moving forward I'd be continuing to experiment with both the Android & iOS
>> platforms, preparing proof of concept repositories as well as a
>> specification document for a lower level detailed
>> of what implementation may look like, which can then be further
>> reviewed/commented.
>>
>> Looking forward for any comments, questions, or concerns.
>>
>> Cheers,
>> Norman
>>
>> References:
>> [1] https://www.apache.org/legal/release-policy.html#source-packages
>>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


Re: Testing a new Plugin "Module" authoring method

Posted by julio cesar sanchez <jc...@gmail.com>.
I had similar thoughts in the past, but never had time to implement it
myself.

For reference, Joe already tried to convert the Android part of
InAppBrowser plugin into a library project back in 2018

https://github.com/apache/cordova-plugin-inappbrowser/pull/242

Modules have some problems too, like not being able to bundle aar
libraries, and some native SDKs can’t be used in modules.



El jueves, 30 de marzo de 2023, Norman Breau <no...@nbsolutions.ca>
escribió:

> Hi all,
>
> I just wanted to announce that I've been experimenting with a different
> way of authoring Cordova plugins.
> I don't really have anything to show right now, but looking to get some
> abstract high-level feedback based on the idea.
>
> This is more or less a preliminary start of a discussion so that I can get
> some early feedback. The plan is to come back some time later with
> a more official specification document and usable PoCs for both Android &
> iOS platforms.
>
> Privately I've been experimenting with a more closer "native" method which
> I feel like solves several issues
> with the way that cordova plugins are traditionally authored.
>
> First I'll explain briefly the pains of authoring cordova plugins, and
> then I'll explain a high level idea that will likely solve the problems.
>
> Currently the plugins are authored by having a set of arbitrary source
> files as defined by the <source-file> / <header-file> directives,
> which also declares where these files should be copied to into the cordova
> native app project. Additionally, if the plugin requires
> changing resource files or adding additional configurations, they must
> make use of several directives which may include:
>
> - config-file
> - edit-config
> - resource-file
> - lib-file
> - framework
> - source-file / header-file
> - asset
>
>
> Most of these works well enough, but shouldn't be necessary to begin with.
> Others, are very finicky or are barely usable due to bugs or other caveats
> (e.g. config-file and edit-config)
>
> The second issue with the way that Cordova plugins are traditionally
> authored (based on the Official Apache plugins) is that they
> aren't unit testable. They can only really be tested as part of a real
> cordova project, which we currently do via cordova-paramedic.
> This is because there is a disconnect between the plugin sources and an
> actual native project.
>
> So I've been experimenting with authoring cordova plugins using a native
> project that gets imported a cordova project. Right now
> my experimentation has been exclusively with the Android platform, so I'll
> be using more Android-specific examples.
>
> But my experimentation has me building a cordova plugin that instead of
> containing loose java source files, they contain an actual
> Gradle project that builds an Android Library. This means that the Cordova
> Plugin has it's own:
>
> - Source files
> - AndroidManifest
> - resources
> - Gradle configs & dependency management
>
> With these tools at the plugin's author disposal... it should eliminate,
> or mostly eliminate the need of the aforementioned directives:
>
> - edit-config
>
> Is no longer required to edit AndroidManifest.xml, but may still be
> required to edit config.xml (but is there really a need to?). Instead
> native libraries have their own AndroidManifest.xml which will get merged
> with the App's manifest.
>
> - lib-file
>
> A native library can bundle their own lib-files.
>
> - resource-file
>
> A native library can bundle their own resource files.
>
> - framework
>
> A native library has it's own gradle file to manage frameworks/dependencies
>
> - source-file / header-file
>
> A native library has it's own file structure for their source files,
> whether java or native C++ modules.
>
> - config-file*
>
> While won't be needed to edit AndroidManifest.xml for the same reason as
> edit-config, which was a common use case...
> It will still be required for setting up cordova Feature tags/declarations
> which gets placed into `config.xml`.
>
> - asset*
>
> Untested, I'm not sure if assets will get merged in a way that is usable
> by the app. So this directive may still be relevant.
>
> Additionally, the js-module directive will still be relevant as the native
> project has no concept of setting up the webview JS modules.
>
> *To be clear*, I'm not suggesting that the current plugin.xml directives
> to be deprecated or removed. They are still going
> to be required to support any cordova plugin authored in a traditional
> method. However, with the module method, most of these directives won't be
> necessary to use.
> In fact, I think the module method could continue to use any one of the
> existing directives if they choose to, but in all likeliness, there won't
> be a need to. In
> practice we may want to discourage people to use the "legacy" directives
> so that support could be considered to be dropped in the future.
>
> I foresee a new directive being created to declare the "module" directory,
> which is the root folder of a native project, which would simply be copied
> in full to a directory inside the app project.
> For example, the module format really needs 4 main actions to be done in a
> cordova android project. I'll pretend that cordova-plugin-file is authored
> in a module format containing a gradle project.
>
> Cordova will need to:
>
> 1. Copy the cordova-plugin-file gradle project into a subdirectory (e.g.
> /platforms/android/cdvModules/cordova-plugin-file)
> 2. settings.gradle needs a line to include the gradle project into it's
> build system (e.g. include ":cdvModules:cordova-plugin-file")
> 3. The "app" module needs to depend on cordova-plugin-file (e.g:
> implementation project(":cdvModules:cordova-plugin-file"))
> 4. Configure the JS-modules / config.xml "Feature" tags just like it
> always did before.
>
> Apache Cordova will still not be distributing prebuilt libraries (e.g.
> plugins are not AAR or xcframeworks) but rather the complete module that
> can be copied into a project as a module.
> The module itself will contain all the build scripts and source code. I
> believe this still satisfies Apache's Release policy requiring source
> packages with no compiled code[1]. Of course,
> third-party plugin authors can still utilize this method of authoring
> plugins and still include closed sources or libraries if they choose so.
>
> Lastly, now that the plugin has a native project housed, it will also be
> much easier to unit test the native side. However there is one caveat where
> e2e tests cannot be done as that will still require a real cordova project,
> so cordova-paramedic will still have to be used for e2e testing.
>
> I do have a working example of this system I described for Android but I
> still have lots of testing to do myself. Still, I feel very confident that
> this is major improvements to how plugins are authored, which hopefully
> will encourage well written and well tested plugins, as well as reducing
> the need for plugin authors to manipulate the app's resource files, which
> can often result in conflicts.
>
> Moving forward I'd be continuing to experiment with both the Android & iOS
> platforms, preparing proof of concept repositories as well as a
> specification document for a lower level detailed
> of what implementation may look like, which can then be further
> reviewed/commented.
>
> Looking forward for any comments, questions, or concerns.
>
> Cheers,
> Norman
>
> References:
> [1] https://www.apache.org/legal/release-policy.html#source-packages
>