How to extend default webpack config in Ionic v2 - ionic-framework

I'd like to extend the default webpack config of ionic. Specifically, I'd like to add an alias for resolving modules so that I can import modules by their absolute path, rather than a relative one:
Instead of importing modules like this:
import { SomeComponent } from '../../components/some.component.ts';
I want to
import { SomeComponent } from '#app/components/some.component.ts';
where #app is an alias for the root source directory.
In other projects I was able to do this by adding something like this to the webpack config:
module.exports = {
...
resolve: {
extensions: ['.ts', '.js'],
alias: {
'#app': path.resolve('./'),
}
},
...
};
I'm not sure how to do this with Ionic without overriding the default webpack config.

The accepted answer works fine but you will have to update webpack.config.js each time you update app-script. So instead of copying code, require it in webpack.config.js
package.json
"config": {
"ionic_webpack": "./config/webpack.config.js"
}
webpack.config.js
const webpackConfig = require('../node_modules/#ionic/app-scripts/config/webpack.config');
webpackConfig.resolve = {
extensions: ['.ts', '.js'],
alias: {
'#app': path.resolve('./'),
}
}
In most cases you can follow this approach and you wont have to update config each time you update app-script

You may want to copy the existing webpack.config.js file, modify it and configure to use it instead of the initial one.
Here are the steps
On the root folder of your project create config folder and copy the file webpack.config.js there (this file is located in ..\node_modules\#ionic\app-scripts\config
Modify the copied file as required
In the file package.json from your project add:
"config": {
"ionic_bundler": "webpack",
"ionic_webpack": "./config/webpack.config.js"
}

Module path mapping in #Ionic version - 3.14.0
Incase someone is having similar trouble to figure out exact changes to get this working.
In ionic 3 (version 3.14.0), in order to get alias mapping working, you will have to define path mapping both in webpack.config.js & tsconfig.json
package.json
To use custom webpack config, configure your package.json to load your custom webpack.config.js.
"config": {
"ionic_webpack": "./config/webpack.config.js"
}
config/webpack.config.js
Reference the existing webpack
Define the alias path
Merge the alias with default webpack config
...
const path = require('path');
const { dev, prod } = require('#ionic/app-scripts/config/webpack.config');
const webpackMerge = require('webpack-merge');
const customConfig = {
resolve: {
alias: {
'#app': path.resolve('src/app'),
'#pages': path.resolve('src/app/pages'),
'#constants': path.resolve('src/app/constants'),
'#components': path.resolve('src/app/components'),
"#shared": path.resolve('src/app/shared')
}
}
};
module.exports = {
dev: webpackMerge(dev, customConfig),
prod: webpackMerge(prod, customConfig)
};
config/test/webpack.config.js
Reference the existing webpack
Define the alias path
Merge the alias with default webpack config
...
const path = require('path');
const webpackDefault = require('#ionic/app-scripts/config/webpack.config');
const webpackMerge = require('webpack-merge');
const customConfig = {
resolve: {
alias: {
'#app': path.resolve('src/app'),
'#pages': path.resolve('src/app/pages'),
'#constants': path.resolve('src/app/constants'),
'#components': path.resolve('src/app/components'),
"#shared": path.resolve('src/app/shared')
}
}
};
module.exports = webpackMerge(webpackDefault, customConfig);
tsconfig.json
Define baseUrl & paths in tsconfig.json like following:
{
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"#app/*": ["app/*"],
"#pages/*": ["app/pages/*"],
"#constants/*": ["app/constants/*"],
"#components/*": ["app/components/*"],
"#shared/*": ["app/shared/*"]
}
},
}
Ref: My ionic env info:
cli packages:
#ionic/cli-plugin-proxy : 1.4.13
#ionic/cli-utils : 1.14.0
ionic (Ionic CLI) : 3.14.0
global packages:
cordova (Cordova CLI) : 7.1.0
local packages:
#ionic/app-scripts : 2.1.4
Cordova Platforms : android 6.2.3 ios 4.5.1
Ionic Framework : ionic-angular 3.6.0

Hi Maverick09 answer is awesome but it did not work for me I am using this configuration:
cli packages:
#ionic/cli-utils : 1.15.2
ionic (Ionic CLI) : 3.15.2
local packages:
#ionic/app-scripts : 3.0.1
Ionic Framework : ionic-angular 3.8.0
System:
Node : v6.10.0
npm : 3.10.10
OS : Windows 10
default configuraion has two parts dev and prod so if you change custom config like this seems every thing working
const customConfig = {
dev: {
resolve: {
alias: {
'#app': path.resolve('src/app'),
'#pages': path.resolve('src/pages'),
'#common': path.resolve('src/common'),
'#storyboards': path.resolve('src/storyboards'),
"#locale": path.resolve('src/locale')
}
}
},
prod: {
resolve: {
alias: {
'#app': path.resolve('src/app'),
'#pages': path.resolve('src/pages'),
'#common': path.resolve('src/common'),
'#storyboards': path.resolve('src/storyboards'),
"#locale": path.resolve('src/locale')
}
}
}
};

In recent versions of ionic, alias is not working unless you use this fix (let typescript loader know the alias):
tsconfig.json
"compilerOptions": {
...
"baseUrl": "./src",
"paths": {
"#app/config": ["config/config"]
}
}
...
credit: https://github.com/ionic-team/ionic-app-scripts/pull/683#issuecomment-294078919
My ionic info:
cli packages: (/Users/.../node_modules)
#ionic/cli-plugin-cordova : 1.6.2
#ionic/cli-plugin-ionic-angular : 1.4.1
#ionic/cli-utils : 1.7.0
ionic (Ionic CLI) : 3.7.0
global packages:
Cordova CLI : 7.0.1
local packages:
#ionic/app-scripts : 2.1.3
Cordova Platforms : none
Ionic Framework : ionic-angular 3.6.0
System:
Node : v6.9.5
OS : macOS Sierra
Xcode : Xcode 8.3.3 Build version 8E3004b
ios-deploy : 1.9.1
ios-sim : 5.0.13
npm : 5.3.0

Related

admobfree.service.ts is missing from the TypeScript compilation. Please make sure it is in your tsconfig via the 'files' or 'include' property

My project is running.it is code working.I was use admob-free npm plugin then show the error on android build time.i was user firebase notification.I show all list of plugin and ionic info.
Show Error
ERROR in ./src/app/service/admobfree.service.ts Module build failed
(from ./node_modules/#ngtools/webpack/src/index.js): Error: E:\git
Live Project\service
app\Service-User-App-\src\app\service\admobfree.service.ts is missing
from the TypeScript compilation. Please make sure it is in your
tsconfig via the 'files' or 'include' property.
at AngularCompilerPlugin.getCompiledFile (E:\git Live Project\service
app\Service-User-App-\node_modules#ngtools\webpack\src\angular_compiler_plugin.js:938:23)
at E:\git Live Project\service app\Service-User-App-\node_modules#ngtools\webpack\src\loader.js:42:31
at runMicrotasks ()
at processTicksAndRejections (node:internal/process/task_queues:96:5) # ./src/app/app.module.ts
29:0-63 56:12-28 # ./src/main.ts # multi ./src/main.ts [ERROR] An
error occurred while running subprocess ng.
ng.cmd run app:ionic-cordova-build:production --platform=android exited with exit code 1.
Re-running this command with the --verbose flag may provide more information.
My ionic Info
Ionic:
Ionic CLI : 6.19.0 (C:\Users\abc\AppData\Roaming\npm\node_modules\#ionic\cli)
Ionic Framework : #ionic/angular 5.5.2
#angular-devkit/build-angular : 0.1000.8
#angular-devkit/schematics : 10.0.8
#angular/cli : 10.0.8
#ionic/angular-toolkit : 2.3.3
Cordova:
Cordova CLI : 10.0.0
Cordova Platforms : not available
Cordova Plugins : not available
Utility:
cordova-res : 0.15.4
native-run : 1.5.0
System:
Android SDK Tools : 26.1.1 (D:\androidsdk\Sdk)
NodeJS : v16.15.0 (C:\Program Files\nodejs\node.exe)
npm : 8.5.5
OS : Windows 10
My plugin Info
cordova-admob-sdk 0.24.1 "AdMob SDK"
cordova-plugin-add-swift-support 2.0.2 "AddSwiftSupport"
cordova-plugin-admob-free 0.27.0 "Cordova AdMob Plugin"
cordova-plugin-androidx-adapter 1.1.3 "cordova-plugin-androidx-adapter"
cordova-plugin-androidx 3.0.0 "cordova-plugin-androidx"
cordova-plugin-app-version 0.1.12 "AppVersion"
cordova-plugin-device 2.0.3 "Device"
cordova-plugin-file 6.0.2 "File"
cordova-plugin-firebasex 11.0.3 "Google Firebase Plugin"
cordova-plugin-geolocation 4.1.0 "Geolocation"
cordova-plugin-ionic-keyboard 2.2.0 "cordova-plugin-ionic-keyboard"
cordova-plugin-ionic-webview 4.2.1 "cordova-plugin-ionic-webview"
cordova-plugin-market 1.2.0 "Market"
cordova-plugin-nativegeocoder 3.4.1 "NativeGeocoder"
cordova-plugin-network-information 2.0.2 "Network Information"
cordova-plugin-statusbar 2.4.3 "StatusBar"
cordova-plugin-whitelist 1.3.4 "Whitelist"
cordova-plugin-x-socialsharing 6.0.2 "SocialSharing"
cordova-promise-polyfill 0.0.2 "cordova-promise-polyfill"
es6-promise-plugin 4.2.2 "Promise"
my service pagecode( admobfree.service.ts)
import { Injectable } from '#angular/core';
import {
AdMobFree,
AdMobFreeBannerConfig,
AdMobFreeInterstitialConfig,
} from '#ionic-native/admob-free/ngx';
import { Platform } from '#ionic/angular';
#Injectable({
providedIn: 'root'
})
export class AdmobfreeService {
interstitialConfig: AdMobFreeInterstitialConfig = {
isTesting: true, // Remove in production
autoShow: false,
id: "ca-app-pub-3940256099942544/1033173712"
};
constructor(private admobFree: AdMobFree,public platform: Platform) {
platform.ready().then(() => {
this.admobFree.interstitial.config(this.interstitialConfig);
this.admobFree.interstitial.prepare()
.then(() => { }).catch(e => alert(e));
});
this.admobFree.on('admob.interstitial.events.CLOSE').subscribe(() => {
this.admobFree.interstitial.prepare()
.then(() => {}).catch(e => alert(e));
});
}
showBannerAd() {
let bannerConfig: AdMobFreeBannerConfig = {
isTesting: true, // Remove in production
autoShow: true,
bannerAtTop: false,
id: "ca-app-pub-3940256099942544/6300978111"
};
this.admobFree.banner.config(bannerConfig);
this.admobFree.banner.prepare().then(() => {
// success
}).catch(e => alert(e));
}
showInterstitialAd() {
this.admobFree.interstitial.isReady().then(() => {
this.admobFree.interstitial.show().then(() => {
})
.catch(e =>alert("show "+e));
})
.catch(e =>alert("isReady "+e));
}
}

Error io.branch.referral.InstallListener Class Not Found Crash Ionic v5

I have an issue with an ionic app and branch SDK, at test ENV everything works as expected but users' in PROD crash continuously.
As stated in the branch docs I have initialized branch on platform ready event at app.component.ts:
app.component.ts
import { Component } from "#angular/core";
import { Platform } from "ionic-angular";
import { StatusBar, Splashscreen } from "ionic-native";
import { TabsPage } from "../pages/tabs/tabs";
#Component({
template: `<ion-nav [root]="rootPage"></ion-nav>`
})
export class MyApp {
rootPage = TabsPage;
constructor(platform: Platform) {
platform.ready().then(() => {
StatusBar.styleDefault();
Splashscreen.hide();
branchInit();
});
platform.resume.subscribe(() => {
branchInit();
});
// Branch initialization
const branchInit = () => {
// only on devices
if (!platform.is("cordova")) {
return;
}
const Branch = window["Branch"];
Branch.initSession().then(data => {
if (data["+clicked_branch_link"]) {
// read deep link data on click
alert("Deep Link Data: " + JSON.stringify(data));
}
});
};
}
}
The error is as follows:
Unable to instantiate receiver io.branch.referral.InstallListener: java.lang.ClassNotFoundException: Didn't find class "io.branch.referral.InstallListener"
Here's my ionic info
Ionic:
Ionic CLI : 5.4.15 (/Users/path/.nvm/versions/node/v9.6.0/lib/node_modules/ionic)
Ionic Framework : #ionic/angular 4.11.5
#angular-devkit/build-angular : 0.12.4
#angular-devkit/schematics : 7.2.4
#angular/cli : 7.2.4
#ionic/angular-toolkit : 1.3.0
Cordova:
Cordova CLI : 9.0.0 (cordova-lib#9.0.1)
Cordova Platforms : android 8.1.0
Cordova Plugins : cordova-plugin-ionic-keyboard 2.2.0, cordova-plugin-ionic-webview 4.1.1, (and 30 other plugins)
Utility:
cordova-res : not installed
native-run (update available: 0.3.0) : 0.2.7
System:
Android SDK Tools : 26.1.1 (/Users/path/Library/Android/sdk)
NodeJS : v9.6.0 (/Users/path/.nvm/versions/node/v9.6.0/bin/node)
npm : 2.15.12
OS : macOS High Sierra
Xcode : Xcode 10.1 Build version 10B61
I didn't find good documentation about the issue and I am not sure if removing the library will result in not getting the install referrer, but after some investigation, I decided to remove these lines from AndroidManifest.xml
<receiver android:name="io.branch.referral.InstallListener" android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
The following link talks about a communication sent by branch and outdated documentation and makes allusion to the above solution.
https://github.com/BranchMetrics/unity-branch-deep-linking-attribution/issues/171
I think it can be fixed with switching to new Install referrer. Because this crash started from builds that have been released in March, and it tells that from March 1, 2020 it's deprecated: https://android-developers.googleblog.com/2019/11/still-using-installbroadcast-switch-to.html

How can I use the GeoLocation PlugIn in Ionic 3?

I'm having difficulties with getting GeoLocation working in Ionic 3. I've
looked at several tutorials and run into the same problem with all of them.
Here is my setup.
PS C:\> ionic info
cli packages: (C:\Users\myID\AppData\Roaming\npm\node_modules)
#ionic/cli-utils : 1.9.2
ionic (Ionic CLI) : 3.9.2
global packages:
Cordova CLI : 8.1.2 (cordova-lib#8.1.1)
local packages:
#ionic/app-scripts : 3.1.0
Cordova Platforms : none
Ionic Framework : ionic-angular 3.9.2
System:
Android SDK Tools : 26.1.1
Node : v8.10.0
npm : 5.6.0
OS : Windows 10
PS C:\>
PS C:\>
PS C:\>
PS C:\> ionic cordova plugin list
> cordova plugin ls
v Running command - done!
cordova-plugin-geolocation 4.0.1 "Geolocation"
PS C:\>
PS C:\>
PS C:\>
In setting up a hello-world / blank geo location app, I get errors referencing the
GeoLocation plugin.
// app.module.ts
import { Geolocation } from '#ionic-native/geolocation';
// ...
providers: [
StatusBar,
SplashScreen,
{provide: ErrorHandler, useClass: IonicErrorHandler},
Geolocation // <-- Errors here
]
I can get around this error by adding the ngx suffix:
// app.module.ts
import { Geolocation } from '#ionic-native/geolocation/ngx';
// ...
providers: [
StatusBar,
SplashScreen,
{provide: ErrorHandler, useClass: IonicErrorHandler},
Geolocation // OK now
]
However, when I actually go to use it:
//home.ts
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { Geolocation } from '#ionic-native/geolocation/ngx';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
lat: any;
lng: any;
constructor(public navCtrl: NavController,
public geo: Geolocation) {
}
ionViewDidLoad() {
this.geo.getCurrentPosition().then(pos => {
this.lat = pos.coords.latitude;
this.lng = pos.coords.longitude;
}).catch(err => console.log(err));
}
}
I start getting this error:
TypeError: Object(...) is not a function at Geolocation.getCurrentPosition
Commenting out the call to getCurrentPosition makes the error go away.
What have I missed? Have I got the wrong version of the plugin? Is there a way
to know which one works with the last version of Ionic 3?
Did you install the Geolocation plugin v3? As you can see here, the command is:
$ ionic cordova plugin add cordova-plugin-geolocation --variable GEOLOCATION_USAGE_DESCRIPTION="To locate you"
$ npm install --save #ionic-native/geolocation#4
After installing it, you have to import the plugin into app.module as well into your home.ts
import { Geolocation } from '#ionic-native/geolocation';
The code to use the plugin is right, so you don't need to change it.
this.geo.getCurrentPosition().then(pos => {
this.lat = pos.coords.latitude;
this.lng = pos.coords.longitude;
}).catch(err => console.log(err));

Ionic 3 : geolocation isn't stable across the different Android versions

I'm working on an Ionic project based on geolocation and after testing my App on four real devices, I distinguished three different behaviors:
1) Android 4.x ( J1 Samsung) => works Correctly
2) Android 5.0.1 => The first time I install the App all works as expected but when I disable GPS and enable it again, the geolocation returns a position which is far about 1Km of my position and it still bugged until I restart the Phone and then it works correctly again until I restart GPS.
3) Android 5.1 => Same scenario of the Android 5.0.1 but after turning GPS OFF and enabling it again, the geolocation still returning an error "timeout" until I restart the Phone.
Please, I have to know if there is no solution or I can continue with this plugin?
Home.ts:
import { Component, ViewChild, ElementRef } from '#angular/core';
import { NavController, Platform } from 'ionic-angular';
import { Geolocation } from '#ionic-native/geolocation';
declare const google;
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
#ViewChild('map') mapElement: ElementRef;
map: any;
constructor(public navCtrl: NavController,
private platform:Platform,
private geolocation:Geolocation) {
}
ionViewDidLoad(){
new Promise(resolve => {
setTimeout(() => {
this.initMap();
resolve();
},2000);
})
.then(()=>{
setTimeout(() => {
this.getGeolocation();
},2000);
});
}
initMap() {
// map implementation
}
getGeolocation(){
this.platform.ready().then(() => {
alert('start geolocation');
var options = {
timeout: 20000,
enableHighAccuracy:true,
};
this.geolocation.getCurrentPosition(options).then(resp => {
alert('done');
console.log(resp.coords.latitude);
console.log(resp.coords.longitude);
let origin = new google.maps.LatLng( resp.coords.latitude,resp.coords.longitude);
this.addMarker(origin);
this.map.setCenter(origin);
}).catch((error) => {
this.debugError(error);
alert('error geoloc');
});
});
}
addMarker(location) {
//addMarker implementation
}
debugError(object){
var output = '';
for (var property in object) {
output += property + ': ' + object[property]+'; ';
}
alert(output);
console.log(output);
}
}
ionic info:
cli packages: (/usr/lib/node_modules)
#ionic/cli-utils : 1.19.2
ionic (Ionic CLI) : 3.20.0
global packages:
cordova (Cordova CLI) : 7.1.0
local packages:
#ionic/app-scripts : 3.1.8
Cordova Platforms : android 6.3.0
Ionic Framework : ionic-angular 3.9.2
System:
Android SDK Tools : 26.1.1
Node : v8.9.4
npm : 5.7.1
OS : Linux 4.13
Environment Variables:
ANDROID_HOME : xxx
Misc:
backend : pro
cli packages: (/usr/lib/node_modules)
#ionic/cli-utils : 1.19.2
ionic (Ionic CLI) : 3.20.0
global packages:
cordova (Cordova CLI) : 7.1.0
local packages:
#ionic/app-scripts : 3.1.8
Cordova Platforms : android 6.3.0
Ionic Framework : ionic-angular 3.9.2
System:
Android SDK Tools : 26.1.1
Node : v8.9.4
npm : 5.7.1
OS : Linux 4.13
Environment Variables:
ANDROID_HOME: xxx/Sdk
Misc:
backend: pro

Lazy loading 3rd party component in loaded page (Ionic)

The app working when i run ionic cordova run android --device but gives error when i try ionic cordova run android --prod --release
I am trying use ng2-qrcode into my lazy loaded page
Error: Unexpected value 'QRCodeComponent in
D:/qrstore/node_modules/ng2-qrcode/dist/ng2-qrcode.d.ts' declared by
the module 'ItemDetailPageModule in
D:/qrstore/src/pages/item-detail/item-detail.module.ts'. Please add a #Pipe/#Directive/#Component annotation.
at Error (native)
at syntaxError (D:\qrstore\node_modules\#angular\compiler\bundles\compiler.umd.js:1729:34)
at D:\qrstore\node_modules\#angular\compiler\bundles\compiler.umd.js:15625:40
at Array.forEach (native)
at CompileMetadataResolver.getNgModuleMetadata (D:\qrstore\node_modules\#angular\compiler\bundles\compiler.umd.js:15607:54)
at addNgModule (D:\qrstore\node_modules\#angular\compiler\bundles\compiler.umd.js:24403:58)
at D:\qrstore\node_modules\#angular\compiler\bundles\compiler.umd.js:24414:14
at Array.forEach (native)
at _createNgModules (D:\qrstore\node_modules\#angular\compiler\bundles\compiler.umd.js:24413:26)
at analyzeNgModules (D:\qrstore\node_modules\#angular\compiler\bundles\compiler.umd.js:24288:14)
ionic info
#ionic/cli-utils : 1.12.0
ionic (Ionic CLI) : 3.12.0
global packages:
cordova (Cordova CLI) : 7.0.1
local packages:
#ionic/app-scripts : 3.0.0
Cordova Platforms : android 6.2.3
Ionic Framework : ionic-angular 3.7.1
System:
Android SDK Tools : 25.2.3
Node : v6.9.4
npm : 3.10.8
OS : Windows 10
Misc:
backend : pro
item detail module
import { NgModule } from '#angular/core';
import { IonicPageModule } from 'ionic-angular';
import { ItemDetailPage } from './item-detail';
import { HttpModule, Http } from '#angular/http';
//native
import { File } from '#ionic-native/file';
import { FilePath } from '#ionic-native/file-path';
import { SQLite } from '#ionic-native/sqlite';
//providers
import { ItemsProvider, LabelsProvider, SQLiteDatabaseProvider } from '../../providers/providers';
//components
import { ItemCreatePage } from '../item-create/item-create';
import { QRCodeComponent } from 'ng2-qrcode'
//directive
import { AbsoluteDragDirective } from '../../directives/absolute-drag/absolute-drag';
#NgModule({
declarations: [
ItemDetailPage,
QRCodeComponent,
AbsoluteDragDirective
],
imports: [
IonicPageModule.forChild(ItemDetailPage),
HttpModule
],
exports: [
ItemDetailPage
],
entryComponents: []
,
providers:[
ItemsProvider,
SQLite,
SQLiteDatabaseProvider,
File,
FilePath
]
})
export class ItemDetailPageModule {}
ng2-qrcode is no longer maintained and does not work with the AoT compiler of angular (which is used when you build your app with --prod). But there is a drop in replacement which is built for usage in Ionic3/Angular4+ projects which use the AoT compiler: angularx-qrcode. It is based on the same library and provides the same API.
Add it as follows:
npm install angularx-qrcode --save
And to use it import it in your NgModule:
import { QRCodeModule } from 'angularx-qrcode';
And then add it to the imports array:
imports: [
QRCodeModule
],
I'm the author of angularx-qrcode mentioned above.
For those coming here and using the angularx-qrcode-package, I prepared a working angular-app for angular5/6 to have an easier start:
https://github.com/Cordobo/angularx-qrcode-sample-app
master-branch: latest angular, at the time of posting angular6
angular5-branch: you guessed it, is for angular5
HTH