Manage cordova plugins with npm + package.json - npm

We have an Angular + Ionic + Cordova project with multiple devs that we'd like to manage cordova plugin dependencies for. We are using Cordova CLI 5+, and when manually running the install commands (e.g. cordova plugin add cordova-plugin-camera), a new line gets added to the cordovaPlugins section of the package.json file. Here's what the finished product looks like:
"cordovaPlugins": [
"cordova-plugin-camera",
"cordova-plugin-console",
"cordova-plugin-contacts",
"cordova-plugin-device",
"cordova-plugin-dialogs",
"cordova-plugin-file",
"cordova-plugin-geolocation",
"cordova-plugin-media",
"cordova-plugin-media-capture",
"cordova-plugin-network-information",
"cordova-plugin-splashscreen",
"cordova-plugin-statusbar",
"cordova-plugin-vibration",
"com.ionic.keyboard"
]
That's all great, except we can't find any way for dev #2 to npm install those plugins - instead, he has to run the commands individually, which then adds a duplicate line to package.json, dirtying the repository. We are sure there must be a command to install these, but can't find it. Can anyone shed some light?

What Caused Our Issue
We had originally used this Ionic + Cordova + Grunt seed project to spawn our initial app. The project includes a number of Cordova hooks that, among other things, add and remove platforms and plugins from the relevant cordovaPlatforms and cordovaPlugins sections in package.json when you run the corresponding command (i.e. cordova plugin add cordova-plugin-media adds a line to cordovaPlugins).
To better support local testing (trying new versions of a plugin, for example), and to prevent cross-dev dependency issues, we disabled the seed project hook and now hand-craft the package.json as needed.
Properly Managing Cordova Plugins
In turns out, the Ionic CLI uses package.json to manage Cordova app state in terms of platforms and plugins (as of version 1.3.19, it appears).
Populating package.json with two sections, cordovaPlatforms and cordovaPlugins has allowed us to do a simple ionic state restore to get the Cordova environment in shape for emulation, building, etc.
Specifying Versions
To further lock-down our app's state and development environment, we've also specified the target version of the Cordova platforms and plugins that we are using by adding the version number. Here's what we use:
{
...
"cordovaPlatforms": [
"android#4.0.2",
"ios#3.8.0"
],
"cordovaPlugins": [
"cordova-plugin-camera#1.1.0",
"cordova-plugin-contacts#1.1.0",
"cordova-plugin-device#1.0.1",
"cordova-plugin-file#2.1.0",
"cordova-plugin-media#1.0.1",
"cordova-plugin-media-capture#1.0.1",
"cordova-plugin-network-information#1.0.1",
"cordova-plugin-splashscreen#2.1.0",
"cordova-plugin-statusbar#1.0.1",
"cordova-plugin-vibration#1.2.0",
"com.ionic.keyboard#1.0.5"
]
}
tl;dr
Once you have the above in your package.json, you can then ensure that your local environment is in the proper state via ionic state restore (v1.3.19+) which will chew through package.json and install platforms and plugins as needed.

You can add a postinstall command. Look below
{
"cordovaPlugins": [
"com.ionic.keyboard#1.0.4",
],
"cordovaPlatforms": [
"android#4.1.1",
],
"scripts": {
"postinstall": "ionic state restore",
"clean": "ionic platform remove android; ionic platform remove ios; ionic platform remove browser; git checkout package.json"
}
}
Bonus : use npm run clean followed by npm install if you wish to start clean i.e reinstall all platforms

may be it's a bit late into the game, but this is my postinstall script
"postinstall": "bower i && gulp && ionic state reset && ionic config build"
it installs the bower dependencies, e.g. ionic lib
it restores Cordova plugins
it re-builds the configuration you did via ionic config command

Related

NODE_ENV=production with react-app-rewired

I have installed react-app-rewired as dev dependency according to docs.
"devDependencies": {
//...
"react-app-rewired": "^2.1.8",
},
Now I'd like to make a production build. When I use
NODE_ENV=production yarn install
consequent yarn build says that react-app-rewired: not found (because it is in dev only).
Does yarn build implies production under the hood?
If so, why do I need all the dev dependencies to be installed to make a production build?
Should I get rid of NODE_ENV or move react-app-rewired to production then?
When making the production build (when you need to transform your code, generate built assets, etc.), you usually need to have the dev dependencies installed since the dev dependencies contain the build tools needed to transform/compile the code into production code. When running the actual production code that is built from running yarn build, then you'd only need to have the production dependencies installed.
So, before the app is actually built, you need to run yarn install without NODE_ENV=production. Once the app is built (i.e. once you've ran yarn build and you have all the code transformed, all artifacts generated, etc.), then you'd re-run yarn install but with production mode turned on (NODE_ENV=production yarn install) so yarn only installs the dependencies in the dependencies section of package.json (these are the dependencies that your transformed code would depend on, whereas the build tools like react-app-rewired are only needed at build-time).

eslint config for exp init project

I was compiling perfect way for adding eslint-flow-prettier in all types of react native projects.
I have some question about using eslint in Expo project.
Does exp init also install eslint?
If not, I have tried using following command for installing eslint
1)yarn add --dev eslint eslint-config-airbnb eslint-plugin-import eslint-plugin-react eslint-plugin-jsx-a11y babel-eslint
2)yarn eslint --init
Is this the correct way to put eslint in expo project?
In the second step above it asked to Select 'Use a popular style guide', I selected Airbnb, after that it removed multiple packages and project is not running(obvious reason for error: missing libraries).So why this is happening?Should I have selected config other than Airbnb?(only 3 options for eslint config: Google, Airbnb, Standard)
Also I did use YARN for expo project because NPM was giving more complication, as it was removing 500+ packages during step1 above, which resulted in many of the libraries going missing from project, I tried npm install to install all packages but still had problems. So went with YARN.
For now I want to somehow include eslint in the Expo project.
Thanks in advance.
UPDATE 26th March 16:25 IST:
1)Here is the info after installing eslint using: npm install --save-dev eslint-config-airbnb babel-eslint (npm version 5.8.0)
install eslint-config-airbnb and babel-eslint as dev dependencies.
create a file in your root named .eslintrc and add this inside this file
{
"extends": "airbnb",
"parser": "babel-eslint",
"rules": {
}
}
install Eslint extension in your editor. this is the extension for vscode(you can enable eslint if you are using Webstorm)
This problem got solved by deleting node_modules folder in project directory and did npm intsall.
So, during any npm install <package> if it removes some other previously installed packages, only way for now is to delete whole node_module folder and perform npm install. This worked for me, when this problem occurred while creating react-native app with native code support(https://facebook.github.io/react-native/docs/getting-started.html).

Do yarn workspaces work with npm, too?

I checked out a repo which uses yarn instead of npm as build tool.
in the package.json, it defines workspaces to deal with multiple sub-projects:
{
"workspaces": [
"packages/*"
],
"dependencies": [],
"devDependencies": [
// long list
]
}
As a result, the root package.json does not contain any runtime dependency. Just the packages/*/package.json contain those.
To compile (and start in dev mode) I do:
yarn install
yarn start
I have found no documentation, that workspaces is also recognized and correctly used by npm.
Is there a way to make it work with npm, too?
Now that npm v7.0.0 is out, npm supports workspaces. You can manage multiple packages from within a singular top-level, root package. See more at https://github.blog/2020-10-13-presenting-v7-0-0-of-the-npm-cli/
Your workflows will not get npm v7.0.0 by default unless you install it using npm install -g npm#7.
Managing dependencies in a monorepo is not supported with npm. The Lerna package is used to manage JavaScript projects with cross dependencies. I believe Lerna uses Yarn under the hood, but with Yarn as your project's package manager, this feature is supported out of the box.
Here is a repo that might be helpful to see how Yarn and Lerna work together: https://github.com/Quramy/lerna-yarn-workspaces-example
npm has plans to implement workspaces somewhere along the v7, hopefully. They've written about it in their blog and there's an accepted proposal.
As of 2020-08-11 Workspaces are available in the v7 beta.
RFC 26 First phase of workspaces support is added. This changes
npm’s behavior when a root project’s package.json file contains a
workspaces field.
https://blog.npmjs.org/post/626173315965468672/npm-v7-series-beta-release-and-semver-major
You can view and download the beta here:
https://github.com/npm/cli/tags
NPM version 7 support workspace management. Now we can manage our workspace dependencies using npm workspace.
More on the workspace support can be found here official site here.
https://docs.npmjs.com/cli/v7/using-npm/workspaces
If you are looking for a simple example follow this link
https://github.com/pravanjan/npm-workspace-example/tree/master
Tested using node v16.6.1
npm 7.20.3

Twilio React Native - Unable to resolve module crypto

I'm working on implementing the twilio package into my react-native project and when I require it in my file the project wont load and I'm seeing the following error:
Unable to resolve module crypto from /Users/[myname]/Documents/Projects/React-Native/[app-name]/node_modules/twilio/lib/webhooks.js: Unable to find this module in its module map or any of the node_modules directories under /Users/node_modules/crypto and its parent directories
I've tried installing the crypto package directly and that doesn't seem to work either.
Has anyone experienced this issue, and has a way to resolve it?
You can use the rn-nodeify module to get crypto on react-native.
Add rn-nodeify to your devDependencies in package.json:
"devDependencies": {
"rn-nodeify": "^6.0.1"
}
Add the following to the scripts section of the same file:
"scripts": {
…
"postinstall": "node_modules/.bin/rn-nodeify --install crypto --hack"
}
Be aware that rn-nodeify will modify your package.json.
More information available here: https://www.npmjs.com/package/rn-nodeify
I suggest you have a look there, plenty of solutions are given because none seem to fix for everyone.
I suggest you try the following (taken from the issue from the link) :
rm -rf node_modules
rm -fr $TMPDIR/react-*
watchman watch-del-all
npm cache clean && npm install
npm start from ./node_modules/react-native
But check out the issue in its integrality, many found other fixes that worked for them.
It seems that React Native doesn't accept certain packages based on their dependencies, Twilio being one of these.
While not a direct solution, I created a work around to this issue by creating a separate Express server to make the Twilio call, and calling that route from within my React Native app.
React Native packager uses Babel under the hood. This means that you can use babel-plugin-rewrite-require Babel plugin to rewrite all require('crypto') calls to require('crypto-browserify'), assuming that the latter is installed in your node_modules.
As of January 2016, you can use .babelrc file to define optional configuration, so this becomes really easy. First, install the dependencies:
npm install --save crypto-browserify
npm install --save-dev babel-plugin-rewrite-require
Then add plugins config to your .babelrc file:
{
"presets": ["react-native"],
"plugins": [
["babel-plugin-rewrite-require", {
aliases: {
crypto: 'crypto-browserify'
}
}]
]
}
Restart the packager and that should be it.
This is the same approach that ReactNativify uses, except that here we use .babelrc instead of defining custom transformer. When ReactNativify was written, it was not supported, so they had to go with more complex solution. See this file from ReactNativify for almost complete list of node polyfills.

Need more elaboration regarding, --save-dev

I see --save-dev mentioned in Gulp tutorials and from what I see, it adds npm functionality to a project's dependency.
But what does that mean exactly? Is that significant when the project gets moved from one machine to another?
Thank you for any clarification of --save-dev importance with Gulp.
In a npm package there 2 types of dependencies: the production ones and the development ones.
{
"dependencies": {
// .. a list of production dependencies
// i.e. angular or express
},
"devDependencies": {
// .. a list of dependencies strictly needed only in development mode
// i.e. gulp or grunt
}
}
You need the former to make the application run in production. The latter are used when in development mode, so everything around the build system, minification, etc...
Gulp, as a building system, is more a devDependency by nature, than a production dependency. This is why you often find in Gulp/Gulp plugins tutorials things are:
$ npm install --save-dev gulp
That --save-dev flag will put the installed dependency you're asking in the devDependencies bucket while using --save sets the dependency in the dependencies (production) one.