I’m pretty sure I have seen a similar topic in the past but I cannot find it using any search method, so I’ll ask it again:
Is there ANY advice how to share modules between apps? I have structured my apps in mainly generic modules which are meant to be reused in other apps. But I do not want to copy & paste any changes around for multiple apps. So how can I easily reuse such modules in multiple apps? Is there any advice/tutorial/documentation about this? I think this is a core issue for using ionic in companies, as they always will have modules generic enough to be reused to reduce costs.
If it helps: I’m using a private Git server, so if there is a way using this it would also be ok.
That’s a super interesting question, I would love to hear it solved too, that would help me too, thx for posting it
My guess, I would go for a component library build with the Angular CLI (see tutorial link here under). Then, if you could publish it to npm as open source project, publish it and check it out from there. If you could not publish it, you could just build your library locally and install it from there.
But like I said just a thought I planned to apply, but maybe it’s not the good way to go. If someone got a proper better idea, I would love to hear it that would help me too!
no I don’t use it yet to share components and providers across projects. Like I said, I would be super interesting to know a clean or proper solution and this would only be my spontaneous first thought
@robinyo
Thanks for the links, but unfortunately I think you miss the point here. I am not talking about sharing modules WITHIN an app. I am talking about sharing modules between multiple apps. None of these links cover this topic as far as I can see.
@Rasioc I think you may be missing my point, that being it is easier to ‘share code between multiple Ionic Apps’ if each App adopts a standardised project structure (see this guide and this post).
You can ‘share code between multiple Ionic Apps’ by:
cutting and pasting (not recommended)
using a Cordova plugin
using a Node module (packaged using npm) as @reedrichards described (BTW, the npm registry also supports private packages)
“Library support — Today the CLI can produce UMDs optimized for the browser, and CommonJS bundles optimized for the server. What if the CLI could help you produce a bundle that could be consumed by other Angular applications?”
Hi @robinyo,
seems I misunderstood partly - sorry! I already have my apps structured in separate (kind of) standalone modules - which I want to share now by not using copy & paste.
I would prefer not to publish to npm (also not using private repos). But the last links you provided seem like what I was looking for.
Thanks for these hints and I will take a look which seems more suitable to my use case.
Ok so let me summarize my first analysis (without trying out yet):
NPM packages:
Seems the cleanest solution so far and includes versioning, but also contains quite some effort. Using NPM Link sounds good for development, but not sure how to utilize this while I need to be able to checkout the repository of each app on a MAC build pc to build the apple app. I could install from GIT URls, which would help with the multi-platform issue, but I guess using npm LINK at the sime time will not work well?
Symlinks:
According to Best way to share components etc. between multiple apps? the build system doesn’t play too nice with symlinks. Also I would always need some setup script which adds the symlinks after checkout (e.g. for mac)
Cordova Plugin
Doesn’t seem too right for me for this
Sooo… At the moment I think it would be best to try the npm solution and figure out if I somehow can still use linking while also use github repos for installation on different platform. Would be nice if the CLI would provide an easy way for such requirement in future, but looks like right now there is no better way of doing it.
As the linked module contains his own node_modules folder, I start seeing random errors about type mismatches. For example if I use some class of the shared code, which returns an observable. Then I try calling .pipe() on this observable and passing in first() method as argument:
Error:(152, 38) TS2345: Argument of type ‘UnaryFunction<Observable, Observable>’ is not assignable to parameter of type ‘UnaryFunction<Observable, Observable>’.
Types of parameters ‘source’ and ‘source’ are incompatible.
Type ‘Observable’ is not assignable to type ‘Observable’. Two different types with this name exist, but they are unrelated.
Property ‘source’ is protected but type ‘Observable’ is not a class derived from ‘Observable’.
I guess it’s because the shared code references its own node_modules folder for the Observable, while the app uses the other node_modules folder for the first() reference (import { first } from ‘rxjs/operators’;). Not sure how to solve this yet.
Edit2:
Still no solution. Only working solution is deleting node_modules and dist/node_modules in the library folder, but this requires another “npm i” whenever you want to rebuild the library, so this is also not a solution
As I am running out of time to solve this, I’m taking the shorter path now. I think I got it working with symlinks as follows:
Moved out an exemplary shared module to some shared folder
Created a symlink (windows, admin CMD required): cd …\src\modules && mklink /D shared …\ …\ …\ …\SharedModules\shared (hint: be aware that the forum modifies the target path somehow strangely)
Add ./config/watch.config.js:
const watchConfig = require('@ionic/app-scripts/config/watch.config');
// add symlinked paths manually to enforce them being watched - even though they are in src/ folder they will otherwise be ignored
watchConfig.srcFiles.paths.push('{{SRC}}/modules/shared/**/*.(ts|html|s(c|a)ss)');
module.exports = watchConfig;
Add ./config/webpack.config.js:
const webpackConfig = require('@ionic/app-scripts/config/webpack.config');
// When using symlinks for modules this must be set to FALSE, otherwise compile issues will be shown
// yes this sounds counter intuitive...
webpackConfig.dev.resolve.symlinks = false;
webpackConfig.prod.resolve.symlinks = false;
module.exports = webpackConfig;
This seems to work, including ionic serve, live reload and production build.
If somebody else has some spare time and can go on with my results to investigate better options, I would be glad…
All I need now is some kind of setup script which initializes the symlinks after checkout on all platforms.
edit: does somebody know a cross-platform solution for adding symlinks, e.g. via npm “postinstall” script which does not require admin privileges on windows?