Publishing Ionic component to NPM

I’m looking to publish my component that is dependent on Ionic UI components to the NPM library so that it’s easily shareable between my projects.

I have found a couple of articles that cover this however they do not explain in any sort of detail what the process is to allow me to gain a better understanding of why I am doing something!!

So I have created an empty folder and I have run the npm init command to initialize my package.json file which gives me a very basic file that is fine itself. I have then copied my component files along with supporting classes and my module file into the src folder and changed all of my paths to ensure everything is reference-able.

I have then created index.ts file that exports my two components and my module.

So I think this is a start point, now at this point how do I know which dependencies should be configured within my package.json file. Obviously I can go through my .ts files and pull out the items I directly use but is this enough?

At this point I have no idea what I can do to see if everything is configured correctly or not, but if I run npm run publishPackage then I get the following error: -

sh: ngc: command not found

Anybody any ideas?

Ionic:

   Ionic CLI : 6.1.0

Utility:

   cordova-res : 0.9.0
   native-run  : 0.3.0

System:

   NodeJS : v12.14.1
   npm    : 6.13.7
   OS     : macOS Catalina

and here’s my package.json for good measure

{
  "name": "ionic-selectric",
  "version": "1.0.0",
  "description": "An Ionic UI component to provide a searchable picker that is consistent in appearance to other Ionic UI components",
  "main": "./dist/index.js",
  "typings": "./dist/index.d.ts",
  "files": [
    "dist"
  ],
  "scripts": {
    "ngc": "ngc",
    "build": "rm -rf dist && npm run ngc",
    "publishPackage": "npm run build && npm publish"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/ChelloApps/ionic-selectric.git"
  },
  "author": "Chelloapps",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/ChelloApps/ionic-selectric/issues"
  },
  "homepage": "https://github.com/ChelloApps/ionic-selectric#readme",
  "devDependencies": {
    "@angular/common": "~8.2.14",
    "@angular/core": "~8.2.14",
    "@angular/forms": "~8.2.14",
    "@angular/compiler": "~8.2.14",
    "@angular/router": "~8.2.14",
    "@angular/platform-browser": "~8.2.14",
    "@angular/platform-browser-dynamic": "~8.2.14",
    "@ionic-native/core": "^5.0.0",
    "@ionic-native/splash-screen": "^5.0.0",
    "@ionic-native/status-bar": "^5.0.0",
    "@ionic/angular": "^5.0.0",
    "core-js": "^2.5.4",
    "rxjs": "~6.5.1",
    "tslib": "^1.10.0",
    "zone.js": "~0.9.1"
  }
}

Ok got the publish bit working, needed to add: -

    "@angular/compiler": "~8.2.14",
    "@angular/compiler-cli": "~8.2.14",
    "typescript": "^3.5.3"

My next issue is that when I come to use the component I get the error below, its clearly a 404 error but what does it relate to?

zone.js:3372 GET http://localhost:8100/%0A%3Cion-item%3E%0A%20%20%20%20%3Cion-label%20*ngIf=%22caption%22%20%5Bposition%5D=%22captionPosition%22%3E%7B%7B%0A%20%20%20%20%20%20%20%20caption%0A%20%20%20%20%7D%7D%3C/ion-label%3E%0A%20%20%20%20%3Cion-input%0A%20%20%20%20%20%20%20%20%5Breadonly%5D=%22isReadOnly%22%0A%20%20%20%20%20%20%20%20%5Bplaceholder%5D=%22placeholder%22%0A%20%20%20%20%20%20%20%20%5Bvalue%5D=%22selectedText%22%0A%20%20%20%20%20%20%20%20(click)=%22showOptions($event)%22%0A%20%20%20%20%3E%3C/ion-input%3E%0A%3C/ion-item%3E%0A 404 (Not Found)
scheduleTask @ zone.js:3372
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask @ zone.js:410
onScheduleTask @ zone.js:301
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask @ zone.js:404
push../node_modules/zone.js/dist/zone.js.Zone.scheduleTask @ zone.js:238
push../node_modules/zone.js/dist/zone.js.Zone.scheduleMacroTask @ zone.js:261
scheduleMacroTaskWithCurrentZone @ zone.js:1194
(anonymous) @ zone.js:3405
proto.<computed> @ zone.js:1518
push../node_modules/@angular/platform-browser-dynamic/fesm5/platform-browser-dynamic.js.ResourceLoaderImpl.get @ platform-browser-dynamic.js:357
push../node_modules/@angular/compiler/fesm5/compiler.js.DirectiveNormalizer._fetch @ compiler.js:18705
push../node_modules/@angular/compiler/fesm5/compiler.js.DirectiveNormalizer._preParseTemplate @ compiler.js:18744
push../node_modules/@angular/compiler/fesm5/compiler.js.DirectiveNormalizer.normalizeTemplate @ compiler.js:18732
push../node_modules/@angular/compiler/fesm5/compiler.js.CompileMetadataResolver.loadDirectiveMetadata @ compiler.js:20983
(anonymous) @ compiler.js:27385
(anonymous) @ compiler.js:27384
push../node_modules/@angular/compiler/fesm5/compiler.js.JitCompiler._loadModules @ compiler.js:27381
push../node_modules/@angular/compiler/fesm5/compiler.js.JitCompiler._compileModuleAndComponents @ compiler.js:27359
push../node_modules/@angular/compiler/fesm5/compiler.js.JitCompiler.compileModuleAsync @ compiler.js:27319
push../node_modules/@angular/platform-browser-dynamic/fesm5/platform-browser-dynamic.js.CompilerImpl.compileModuleAsync @ platform-browser-dynamic.js:143
(anonymous) @ router.js:3613
push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._tryNext @ mergeMap.js:61
push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._next @ mergeMap.js:51
push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next @ Subscriber.js:53
(anonymous) @ subscribeToPromise.js:7
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke @ zone.js:391
onInvoke @ core.js:26256
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke @ zone.js:390
push../node_modules/zone.js/dist/zone.js.Zone.run @ zone.js:150
(anonymous) @ zone.js:910
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask @ zone.js:423
onInvokeTask @ core.js:26247
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask @ zone.js:422
push../node_modules/zone.js/dist/zone.js.Zone.runTask @ zone.js:195
drainMicroTaskQueue @ zone.js:601
Promise.then (async)
scheduleMicroTask @ zone.js:584
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask @ zone.js:413
onScheduleTask @ zone.js:301
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask @ zone.js:404
push../node_modules/zone.js/dist/zone.js.Zone.scheduleTask @ zone.js:238
push../node_modules/zone.js/dist/zone.js.Zone.scheduleMicroTask @ zone.js:258
scheduleResolveOrReject @ zone.js:900
resolvePromise @ zone.js:846
(anonymous) @ zone.js:762
webpackJsonpCallback @ bootstrap:25
(anonymous) @ tab-snag-tab-snag-module.js:1
Show 5 more frames
zone.js:3372 GET http://localhost:8100/%0A%3Cion-header%20*ngIf=%22hasSearchbar%22%3E%0A%20%20%20%20%3Cion-toolbar%3E%0A%20%20%20%20%20%20%20%20%3Cion-searchbar%20(ionChange)=%22searchTextChanged($event.target.value)%22%3E%3C/ion-searchbar%3E%0A%20%20%20%20%3C/ion-toolbar%3E%0A%3C/ion-header%3E%0A%3Cion-content%3E%0A%20%20%20%20%3Cion-list%3E%0A%20%20%20%20%20%20%20%20%3Cion-item%0A%20%20%20%20%20%20%20%20%20%20%20%20*ngFor=%22let%20option%20of%20filteredOptions%22%0A%20%20%20%20%20%20%20%20%20%20%20%20button=%22true%22%0A%20%20%20%20%20%20%20%20%20%20%20%20(click)=%22selectOption(option)%22%0A%20%20%20%20%20%20%20%20%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cion-label%3E%7B%7B%20option%5BnameForText%5D%20%7D%7D%3C/ion-label%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cion-icon%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*ngIf=%22isSelected(option%5BnameForValue%5D)%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20slot=%22end%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name=%22checkmark%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%3E%3C/ion-icon%3E%0A%20%20%20%20%20%20%20%20%3C/ion-item%3E%0A%20%20%20%20%3C/ion-list%3E%0A%3C/ion-content%3E%0A%3Cion-footer%3E%0A%20%20%20%20%3Cion-toolbar%3E%0A%20%20%20%20%20%20%20%20%3Cion-buttons%20slot=%22start%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cion-button%20(click)=%22clear()%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cion-icon%20*ngIf=%22hasSelection%22%20name=%22trash%22%3E%3C/ion-icon%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C/ion-button%3E%0A%20%20%20%20%20%20%20%20%3C/ion-buttons%3E%0A%20%20%20%20%20%20%20%20%3Cion-buttons%20slot=%22end%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cion-button%20(click)=%22cancel()%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cion-icon%20name=%22close%22%3E%3C/ion-icon%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C/ion-button%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cion-button%20(click)=%22ok()%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cion-icon%20name=%22checkmark%22%3E%3C/ion-icon%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C/ion-button%3E%0A%20%20%20%20%20%20%20%20%3C/ion-buttons%3E%0A%20%20%20%20%3C/ion-toolbar%3E%0A%3C/ion-footer%3E%0A 404 (Not Found)
scheduleTask @ zone.js:3372
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask @ zone.js:410
onScheduleTask @ zone.js:301
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask @ zone.js:404
push../node_modules/zone.js/dist/zone.js.Zone.scheduleTask @ zone.js:238
push../node_modules/zone.js/dist/zone.js.Zone.scheduleMacroTask @ zone.js:261
scheduleMacroTaskWithCurrentZone @ zone.js:1194
(anonymous) @ zone.js:3405
proto.<computed> @ zone.js:1518
push../node_modules/@angular/platform-browser-dynamic/fesm5/platform-browser-dynamic.js.ResourceLoaderImpl.get @ platform-browser-dynamic.js:357
push../node_modules/@angular/compiler/fesm5/compiler.js.DirectiveNormalizer._fetch @ compiler.js:18705
push../node_modules/@angular/compiler/fesm5/compiler.js.DirectiveNormalizer._preParseTemplate @ compiler.js:18744
push../node_modules/@angular/compiler/fesm5/compiler.js.DirectiveNormalizer.normalizeTemplate @ compiler.js:18732
push../node_modules/@angular/compiler/fesm5/compiler.js.CompileMetadataResolver.loadDirectiveMetadata @ compiler.js:20983
(anonymous) @ compiler.js:27385
(anonymous) @ compiler.js:27384
push../node_modules/@angular/compiler/fesm5/compiler.js.JitCompiler._loadModules @ compiler.js:27381
push../node_modules/@angular/compiler/fesm5/compiler.js.JitCompiler._compileModuleAndComponents @ compiler.js:27359
push../node_modules/@angular/compiler/fesm5/compiler.js.JitCompiler.compileModuleAsync @ compiler.js:27319
push../node_modules/@angular/platform-browser-dynamic/fesm5/platform-browser-dynamic.js.CompilerImpl.compileModuleAsync @ platform-browser-dynamic.js:143
(anonymous) @ router.js:3613
push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._tryNext @ mergeMap.js:61
push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._next @ mergeMap.js:51
push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next @ Subscriber.js:53
(anonymous) @ subscribeToPromise.js:7
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke @ zone.js:391
onInvoke @ core.js:26256
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke @ zone.js:390
push../node_modules/zone.js/dist/zone.js.Zone.run @ zone.js:150
(anonymous) @ zone.js:910
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask @ zone.js:423
onInvokeTask @ core.js:26247
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask @ zone.js:422
push../node_modules/zone.js/dist/zone.js.Zone.runTask @ zone.js:195
drainMicroTaskQueue @ zone.js:601
Promise.then (async)
scheduleMicroTask @ zone.js:584
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask @ zone.js:413
onScheduleTask @ zone.js:301
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask @ zone.js:404
push../node_modules/zone.js/dist/zone.js.Zone.scheduleTask @ zone.js:238
push../node_modules/zone.js/dist/zone.js.Zone.scheduleMicroTask @ zone.js:258
scheduleResolveOrReject @ zone.js:900
resolvePromise @ zone.js:846
(anonymous) @ zone.js:762
webpackJsonpCallback @ bootstrap:25
(anonymous) @ tab-snag-tab-snag-module.js:1
Show 5 more frames
core.js:4002 ERROR Error: Uncaught (in promise): Failed to load %0A%3Cion-item%3E%0A%20%20%20%20%3Cion-label%20*ngIf=%22caption%22%20%5Bposition%5D=%22captionPosition%22%3E%7B%7B%0A%20%20%20%20%20%20%20%20caption%0A%20%20%20%20%7D%7D%3C/ion-label%3E%0A%20%20%20%20%3Cion-input%0A%20%20%20%20%20%20%20%20%5Breadonly%5D=%22isReadOnly%22%0A%20%20%20%20%20%20%20%20%5Bplaceholder%5D=%22placeholder%22%0A%20%20%20%20%20%20%20%20%5Bvalue%5D=%22selectedText%22%0A%20%20%20%20%20%20%20%20(click)=%22showOptions($event)%22%0A%20%20%20%20%3E%3C/ion-input%3E%0A%3C/ion-item%3E%0A
    at resolvePromise (zone.js:852)
    at resolvePromise (zone.js:809)
    at zone.js:913
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
    at Object.onInvokeTask (core.js:26247)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:422)
    at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:195)
    at drainMicroTaskQueue (zone.js:601)
    at ZoneTask.push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (zone.js:502)
    at invokeTask (zone.js:1693)