Sharing Ionic 2 Code Between Projects
Ionic 2 includes many components and native wrappers out of the box. However, you will probably want to share some of your own code between projects if you are working on more than one of them and they are at least remotely similar. Since Ionic 2 builds on top of Angular, shared modules are the right tool for the job.
Using NPM Packages
Although the official template for creating Ionic 2 modules isn't regularly maintained, it's still not difficult to get it running using the instructions from the repository. The following hints might help you expedite the process even more:
If you're using Windows, replace
rm -rf
in build script with its Node based cross-platform equivalentrimraf
. Install the package first withnpm install rimraf --save-dev
, then change the script inpackage.json
to:"build": "rimraf aot dist && npm run ngc"
To test the package locally before publishing it to npm, use
npm pack
instead ofnpm publish
. You can install generated package in your application by passing its relative path to npm:npm install ../module/ionic-module-template-0.0.12.tgz --save
.To avoid issues in the future, you should update the module package dependencies to match the versions of their counterparts in your application. You can simply change the versions in module's
package.json
and runnpm install
afterwards.
While the approach works from the technical standpoint, I can't say the same for the development process it imposes. I don't like how it doesn't support putting the component template into a separate file, but I could live with that. The main problem is the long feedback loop for any changes to the module. Live reload doesn't work. The shared package needs to be rebuilt and reinstalled. For a mostly stable module that's not a problem, but if you plan to develop it in parallel with the app, it's going to slow you down a lot. Using npm link
might help, but I had problems getting the sample to work and found it quite complex to set up reliably for the typical scenario with individual applications and the shared module in separate repositories.
Using Git Submodules
In the end, I decided for a less formal alternative approach, using git submodules. I abandoned the separate build process for the module in favor of directly including the sources in each application:
- In the shared module repository, there are only files from the
src
folder of the official module template. - In each application's
src
folder I added amodules
subfolder and initialized the shared module repository as a git submodule there:git submodule add https://bitbucket.org/damirarh/ionic-common-module.git src/modules/common
.
This way, the shared module will be compiled together with the rest of the application code and live reload will work as intended. Any shared module unit tests will be run together with each application's unit tests, as well. To reference the module from the application code, path to its source must now be specified:
import { MyModule } from '../modules/common';
The setup allows me to transparently develop the module in parallel to the application(s). Using the many git submodules operations, I can decide how to handle and potentially branch the changes in the module, and which version (i.e. commit) of the module I want to reference in each application at any point in time.
There are also disadvantages to this approach:
- There is no standalone build and test process for the module. Its correctness can only be evaluated when it is used from within another application.
- The module has no
package.json
file to track external dependencies. They must be installed into each individual application, or the build will fail. However failed import statements usually give a very good hint about the missing package that needs to be installed.
Yes, the solution isn't perfect, but I can live with it and I like it better than any of the alternatives I tried.