Description
Description
There are more than 700 000 packages in npm. Most of them cannot be used in NativeScript application as they have some browser or Node.js specific calls, which cannot work in the NativeScript runtime.
It will be great if there's an easy way to use all of these plugins in the application.
This could be done in several ways:
- Provide polyfills for all Node.js and browser specific APIs - this way the packages will work. However, this requires implementing a huge amount of APIs in the NativeScript framework itself. When new API is added or change in Node.js for example, we will have to assert it behaves in the same way in NativeScript.
- Replace specific dependencies during project build with their nativescript equivalents. For example, in case you have a project that is shared for web and mobile use, you may have a single package.json file. When building the NativeScript application, you may want to replace some of the dependencies with other ones, that provide the same API. This way you'll not have to change the code, but during build, the correct NativeScript dependency will be used.
- Replace specific files of the dependency when building the project with NativeScript specific ones - in many cases only specific files of the package should be replaced in order to make it work in NativeScript. The replacements could be defined and package level or application level.
Suggestion
The current suggestion to implement this feature is to make CLI replace specific files and packages during build of the NativeScript application. How can we achieve this:
- Allow declaring replacement details in the nativescript key inside package.json
- The replacement data should allow replacements of dependencies and specific files.
- Replacement could be defined in the plugin and in the project itself.
- Project replacements should be executed last, this will allow "fixing" a plugin that has incorrect replacement data (for example forgotten to replace some files).
- Replacement should allow excluding some files from the plugins source, in case they are not compatible with the NativeScript project
- We may add a different entry point to the plugin, when it is used inside nativescript environment.
Example of plugin's package.json:
{
"name": "nativescript-plugin",
"version": "1.0.0",
"main": "index.js",
"nativescript": {
"platforms": {
"android": "3.0.0",
"ios": "3.0.0"
},
"replacementData": {
"main": "./lib/nativescript/index.js",
"dependencies": {
"firebase": {
"nativescript-plugin-firebase": "2.0.0"
}
},
"files": {
"./lib/service.js": "./lib/nativescript/service.js"
},
"exclude": [
"./server/**/*",
"./lib/**/*.client.js"
]
}
},
"dependencies": {
"firebase": "*"
},
"author": "rosen-vladimirov",
"license": "Apache-2.0"
}
When this nativescript-plugin
is added to the application and CLI builds the NativeScript project, the firebase
dependency should be replaced with nativescript-plugin-firebase
. However, this leads to problem in the plugin's code when you use require("firebase")
. CLI will have to replace the require("firebase")
with require("nativescript-plugin-firebase")
in the application. We'll have to modify the .ts
, .js
files, Angular specific files, etc.
During building the application, CLI should move all plugin files to the <project dir>/platforms/<platform>/.../tns_modules/nativescript-plugin/
directory. At this point CLI should move only files, which are not included in exclude patterns, i.e. all files under server
directory should not be included. Also all files under lib
directory, which are named <smth>.client.js
should not be moved to tns_modules
.
After that CLI should replace the content of lib/service.js
file with the content of lib/nativescript/service.js
file (directly in the tns_modules/nativescript-plugin
directory.
The last part is the replacement of the entry point. CLI can directly replace the content of the index.js
with the content of lib/nativescript/index.js
file.
This approach will allow the plugin authors to allow using their plugin in many environments: server side, browser, nativescript, etc.
Same rules can be applied based on project's package.json
. For example, it may contain information how to replace specific files from the project, for some plugins, etc.
CLI should support with and without using webpack for building the application.
NOTE: Part of this approach is already implemented by nativescript-nodeify plugin.