-
-
Notifications
You must be signed in to change notification settings - Fork 198
Description
A common use case for NativeScript developers is the ability to install pure JavaScript modules from NPM. Currently this process is cumbersome and it is not straightforward how to require modules that have dependencies due to the nesting of node_modules folders. The end goal is that npm install ... should work out of the box.
Relying on 'standards'
In order to support this a couple of things have to be changed in the CLI. Currently we create a project file .tnsproject that stores the app id (bundle identifier) along with the currently used version of each runtime. We plan to replace this file with package.json that will be compatible with NPM package json format. Here is the structure of a simple app following this rule:
my-app/
|-- app/
|-- |-- App_Resources/
|-- |-- tns_modules/
|-- |-- ...
|-- platforms/
|-- node_modules/
`-- package.json
Preparing for a better world
Assuming we have package.json in the root of the project will allow us to support npm install lodash --save which will install lodash into node_modules folder and save it as dependency in the package.json. All good but how lodash will end-up in the tns_modules folder of the app? This is where the second significant change will come into place. We will extend the prepare command to recursively transform the node_modules folder contents into tns_modules in the native platform project. This transformation should exclude all modules defined in the devDependencies section of the package.json.
Open questions:
What should be the way to add NativeScript specific properties to the project.json?
- prefixed with
tns_ornativescript_Example:
{
"name": "myapp",
"version": "10.3.1",
"tns_id": "org.nativescript.myapp",
"tns_platforms": {
"ios" : "0.9.2",
"android" : "0.9.0"
}
}- in a designated
nativescriptkey. Example:
{
"name": "myapp",
"version": "10.3.1",
"nativescript": {
"id" : "org.nativescript.myapp",
"platforms": {
"ios" : "0.9.2",
"android" : "0.9.0"
}
}
}Should we require NativeScript tailored modules published to NPM to have nativescript as an engine?
Example:
{ "engines" : { "nativescript" : ">=0.9 <0.10" } }or
{
"engines" : {
"nativescript-android" : "0.9.0",
"nativescript-ios" : "0.9.3"
}
}This will give us a couple of advantages:
- We can warn (or error) the user if the module is not compatible with currently used runtime versions.
- (Future) We can implement a Node compatibility layer in the runtimes that will be able to load Node dependent modules from
node_modulesfolder by providing shims for all Node APIs.
Tasks
- Remove
.tnsprojectand introducepackage.json - Move project properties into
nativescriptkey in thepackage.json - Extend
prepareto copy the modules fromnode_modulesinto platform native project 'tns_modules'- Flatten nested dependencies
- Do not
preparedevDependencies. - Make sure we do not degrade the performance during
preparewhen copying the modules. We can consider things like symlinks or broccoli.js kind of infrastructure.
- Guard the new code with tests
- Implement an upgrade procedure for the old projects