Skip to content
This repository was archived by the owner on May 1, 2020. It is now read-only.

Ionic 3 build using "--prod" flag does not use custom webpack configuration file. Build using "--dev" flag works. #954

Closed
jgw96 opened this issue May 2, 2017 · 65 comments

Comments

@jgw96
Copy link
Contributor

jgw96 commented May 2, 2017

From @SusanKern on May 2, 2017 13:52

Ionic version: (check one with "x")
[ ] 1.x
[ ] 2.x
[x] 3.x

I'm submitting a ... (check one with "x")
[x] bug report
[ ] feature request
[ ] support request => Please do not submit support requests here, use one of these channels: https://forum.ionicframework.com/ or http://ionicworldwide.herokuapp.com/

Current behavior:
Build using "--dev" flag works fine, pulling in configuration from custom webpack configuration file. Build using "--prod" flag fails because it cannot resolve modules as specified in custom webpack configuration file.

Expected behavior:
Both --prod and --dev builds would use same custom webpack configuration.

Steps to reproduce:

Related code:

package.json:
{
  "name": "our-app",
  "author": "Our Team",
  "homepage": "http://ourteam.com/",
  "private": true,
  "config": {
    "ionic_webpack": "./webpack.config.js"
  },
  "scripts": {
    "ionic:build": "ionic-app-scripts build",
    "ionic:serve": "ionic-app-scripts serve",
    "preinstall": "npm link modules/ng2-contentful",
    "postinstall": "cp -R module_overrides/videogular2 ./node_modules"
  },
  "dependencies": {
    "@angular/animations": "^4.0.2",
    "@angular/common": "^4.0.2",
    "@angular/compiler": "^4.0.2",
    "@angular/compiler-cli": "^4.0.2",
    "@angular/core": "^4.0.2",
    "@angular/forms": "^4.0.2",
    "@angular/http": "^4.0.2",
    "@angular/platform-browser": "^4.0.2",
    "@angular/platform-browser-dynamic": "^4.0.2",
    "@angular/platform-server": "^4.0.2",
    "@angular/router": "^4.0.2",
    "@ionic-native/app-version": "3.6.1",
    "@ionic-native/core": "3.6.1",
    "@ionic-native/device": "3.6.1",
    "@ionic-native/google-analytics": "3.6.1",
    "@ionic-native/network": "3.6.1",
    "@ionic-native/splash-screen": "3.6.1",
    "@ionic-native/status-bar": "3.6.1",
    "@ionic/storage": "2.0.1",
    "@types/marked": "0.0.28",
    "contentful": "^3.7.0",
    "copy-webpack-plugin": "^4.0.1",
    "email-validator": "1.0.7",
    "ionic-angular": "3.1.0",
    "ionicons": "3.0.0",
    "marked": "^0.3.6",
    "rxjs": "5.1.1",
    "sw-toolbox": "3.4.0",
    "typescript": "^2.2.1",
    "util": "^0.10.3",
    "uuid": "^3.0.1",
    "videogular2": "^4.0.0",
    "zone.js": "^0.8.9"
  },
  "devDependencies": {
    "@ionic/app-scripts": "1.3.6",
    "@types/node": "^6.0.46",
    "css-loader": "^0.26.1",
    "email-validator": "1.0.7",
    "file-loader": "^0.9.0",
    "json-loader": "^0.5.4",
    "style-loader": "^0.13.1",
    "typescript": "~2.2.1",
    "url-loader": "^0.5.7"
  },
  "cordovaPlugins": [
    "cordova-fabric-plugin",
    "cordova-plugin-app-name",
    "cordova-plugin-google-analytics",
    "cordova-plugin-ios-no-export-compliance",
    "cordova-plugin-network-information",
    "cordova-plugin-device",
    "cordova-plugin-console",
    "cordova-plugin-whitelist",
    "cordova-plugin-splashscreen",
    "cordova-plugin-statusbar",
    "ionic-plugin-keyboard",
    "cordova-plugin-crosswalk-webview",
    "cordova-plugin-app-version",
    "nl.kingsquare.cordova.background-audio"
  ],
  "cordovaPlatforms": [
    "ios",
    {
      "platform": "ios",
      "version": "",
      "locator": "ios"
    },
    "android",
    {
      "platform": "android",
      "version": "",
      "locator": "android"
    }
  ],
  "description": "Our App"
}

Other information:
Partial output from successful "--dev" build: (Note that lines describing Env, Build type, Build flavor and Build variant come from custom webpack.config.js file)

$ ionic build --dev

> hcm-care@ ionic:build /Users/skern/LittleGreenSoftware/hcm-care/myokardia
> ionic-app-scripts build "--dev"

[09:47:23]  ionic-app-scripts 1.3.6 
[09:47:23]  build dev started ... 
[09:47:23]  clean started ... 
[09:47:23]  clean finished in less than 1 ms 
[09:47:23]  copy started ... 
[09:47:23]  transpile started ... 
Env is dev
Build type is debug
Build flavor is dev
Build variant is devDebug
[09:47:27]  transpile finished in 3.70 s 
[09:47:27]  preprocess started ... 
[09:47:27]  deeplinks started ... 
[09:47:27]  deeplinks finished in 97 ms 
[09:47:27]  preprocess finished in 99 ms 
[09:47:27]  webpack started ... 
[09:47:27]  copy finished in 4.04 s 
[09:47:42]  webpack finished in 15.38 s 
[09:47:42]  sass started ... 
[09:47:44]  sass finished in 1.42 s 
[09:47:44]  postprocess started ... 
[09:47:44]  postprocess finished in 9 ms 
[09:47:44]  lint started ... 
[09:47:44]  build dev finished in 20.67 s 
[09:47:48]  lint finished in 4.32 s 

Partial output from unsuccessful "--prod" build: (Note that the error indicates that a file from within a module cannot be resolved. This "resolve" should have been specified in the custom webpack configuration file, which apparently never ran.)

$ ionic build --prod --release

> our-app@ ionic:build /our-app/project-name
> ionic-app-scripts build "--prod" "--release"

[15:34:36]  ionic-app-scripts 1.3.6 
[15:34:36]  build prod started ... 
[15:34:36]  clean started ... 
[15:34:36]  clean finished in 2 ms 
[15:34:36]  copy started ... 
[15:34:36]  ngc started ... 
[15:34:45]  ngc finished in 9.30 s 
[15:34:45]  preprocess started ... 
[15:34:45]  deeplinks started ... 
[15:34:46]  deeplinks finished in 566 ms 
[15:34:46]  optimization started ... 
[15:34:46]  copy finished in 10.19 s 
[15:34:54]  ionic-app-script task: "build" 
[15:34:54]  Error: ./src/app/app.module.js Module not found: Error: Can't resolve 'config/contentful.cfg.json' in 
            '/our-app/project-name/src/app' resolve 'config/contentful.cfg.json' in 
            '/our-app/project-name/src/app' Parsed request is a module using description 
            file: /our-app/project-name/package.json (relative path: ./src/app) Field 
            'browser' doesn't contain a valid alias configuration after using description file: 
            /our-app/project-name/package.json (relative path: ./src/app) resolve as 
            module /our-app/project-name/src/app/node_modules doesn't exist or is not a 
            directory /our-app/project-name/src/node_modules doesn't exist or is not a ...

Custom webpack.config.js:

var path = require('path');
var webpack = require('webpack');
var ionicWebpackFactory = require(process.env.IONIC_WEBPACK_FACTORY);
var CopyWebpackPlugin = require('copy-webpack-plugin');


// LGS: Figures out what build type/flavor/etc. Must be run before the exports are defined.
updateEnvironmentFlags();

module.exports = {
  entry: process.env.IONIC_APP_ENTRY_POINT,
  output: {
    path: '{{BUILD}}',
    publicPath: 'build/',
    filename: process.env.IONIC_OUTPUT_JS_FILE_NAME,
    devtoolModuleFilenameTemplate: ionicWebpackFactory.getSourceMapperFunction(),
  },

  devtool: process.env.IONIC_SOURCE_MAP_TYPE,

  resolve: {
    extensions: ['.ts', '.js', '.json', '.css', '.eot', '.svg', '.ttf', '.woff'],
    modules: [
      // LGS addition: to allow us to store custom modules that we can import
      path.resolve('modules'),
      path.resolve('node_modules')
    ]
  },

  module: {
    loaders: [
      {
        test: /\.json$/,
        loader: 'json-loader'
      },
      {
        //test: /\.(ts|ngfactory.js)$/,
        test: /\.ts$/,
        loader: process.env.IONIC_WEBPACK_LOADER
      },
      {
        test: /\.css$/,
        loaders: ['style-loader', 'css-loader']
      },
      {
        test: /\.(eot|svg|ttf|woff|woff2)$/,
        loader: 'url-loader'
      }
    ]
  },


  plugins: [
    ionicWebpackFactory.getIonicEnvironmentPlugin(),

    // LGS addition: to support a rough notion of build "flavors"
    new webpack.DefinePlugin({
      ENV: JSON.stringify( require(path.resolve("modules/config/config-" + process.env.IONIC_FLAVOR + ".js")) )
    }),

    new CopyWebpackPlugin([
      { from: 'static', to: '../' }
    ])
  ],

  // Some libraries import Node modules but don't use them in the browser.
  // Tell Webpack to provide empty mocks for them so importing them works.
  node: {
    fs: 'empty',
    net: 'empty',
    tls: 'empty'
  }
};


// Get the default "build flavor" if one is not specified.  For dev builds, 
// this will be "local" -- since just running "ionic serve" you would expect 
// it to try to connect to a local backend server. For production builds, 
// it will default to the production flavor as a safeguard in case it is not 
// explicitly set. For flavors like "dev" or "test" where you are trying to
// indicate that the app should connect to a shared dev or test backend 
// server, the build flavor will have to be set explicitly in the 
// environment.
function getDefaultFlavorForEnv(env_string) {
  var result = "local";
  switch (env_string) {
    case "prod":
      result = "production"; break;
    default:
      result = "local";
  }
  return result;
}

function getDefaultBuildTypeForEnv(env_string) {
  var result = "debug";
  switch (env_string) {
    case "prod":
      result = "release"; break;
    default:
      result = "debug";
  }
  return result;
}

function getAndroidVariant(buildType, flavor) {
  var result = flavor + buildType.capitalizeFirstLetter();
  return result;
}

function updateEnvironmentFlags() {
  String.prototype.capitalizeFirstLetter = function() {
      return this.charAt(0).toUpperCase() + this.slice(1);
  }

  process.env.IONIC_FLAVOR = (typeof process.env.IONIC_FLAVOR) != "undefined" ? 
    process.env.IONIC_FLAVOR : getDefaultFlavorForEnv(process.env.IONIC_ENV);

  process.env.IONIC_BUILDTYPE = (typeof process.env.IONIC_BUILDTYPE) != "undefined" ?
    process.env.IONIC_BUILDTYPE : getDefaultBuildTypeForEnv(process.env.IONIC_ENV);

  process.env.IONIC_VARIANT = (typeof process.env.IONIC_VARIANT) != "undefined" ? 
    process.env.IONIC_VARIANT : getAndroidVariant(process.env.IONIC_BUILDTYPE, process.env.IONIC_FLAVOR);

  console.log("Env is " + process.env.IONIC_ENV);
  console.log("Build type is " + process.env.IONIC_BUILDTYPE);
  console.log("Build flavor is " + process.env.IONIC_FLAVOR);
  console.log("Build variant is " + process.env.IONIC_VARIANT);
}

Ionic info: (run ionic info from a terminal/cmd prompt and paste output below):

insert the output from ionic info here

$ ionic info

Your system information:

Cordova CLI: 6.5.0 
Ionic Framework Version: 3.1.0
Ionic CLI Version: 2.2.3
Ionic App Lib Version: 2.2.1
Ionic App Scripts Version: 1.3.6
ios-deploy version: 1.9.0 
ios-sim version: 5.0.9 
OS: OS X El Capitan
Node Version: v7.8.0
Xcode version: Xcode 8.2.1 Build version 8C1002

Copied from original issue: ionic-team/ionic-framework#11478

@Sebastien-Guillon
Copy link

Sebastien-Guillon commented May 4, 2017

I am having this problem now with ionic3.0.0-rc.1

I always use the -prod flag and I get an error:
Module not found: Error: Can't resolve 'leaflet.awesome-markers' in...

The custom config in my webpack.config.js is an alias in the resolve section:

resolve: {
    extensions: ['.ts', '.js', '.json'],
    modules: [path.resolve('node_modules')],
    alias: {
      'leaflet.awesome-markers$': 'leaflet.awesome-markers/dist/leaflet.awesome-markers.js'
    }
  }

This used to work in ionic3.0.0-beta7 (then I jumped to rc1)
@danbucholtz thanks for checking this out, let me know if I can help you test.

Edit: building without the --prod flag works

@vkniazeu
Copy link

vkniazeu commented May 4, 2017

Confirming the same issue (--prod fails, --dev works) with:

ionic info

npm (global):

    @ionic/cli-utils : 1.0.0-beta1
    cordova          : 7.0.0
    ionic            : 3.0.0-beta10

npm (local):

    @ionic/app-scripts              : 1.3.6
    @ionic/cli-plugin-cordova       : 0.0.13
    @ionic/cli-plugin-ionic-angular : 0.0.7
    Ionic Framework                 : ionic-angular 3.1.1

System:

    Node       : v7.9.0
    OS         : Windows 10
    Xcode      : not installed
    ios-deploy : not installed
    ios-sim    : not installed

I'm curious as to why the error is thrown before preprocess finished shows in the trace, which I think should precede the webpack started related flow.

ionic cordova build browser --prod
Running app-scripts build: --prod --iscordovaserve --externalIpRequired --nobrowser

[21:22:57]  build prod started ...
[21:22:58]  clean started ...
[21:22:58]  clean finished in 5 ms
[21:22:58]  copy started ...
[21:22:58]  ngc started ...
[21:23:06]  ngc finished in 8.30 s
[21:23:06]  preprocess started ...
[21:23:06]  deeplinks started ...
[21:23:06]  deeplinks finished in 493 ms
[21:23:06]  optimization started ...
[21:23:07]  copy finished in 9.04 s
{ Error: ./src/app/app.module.js
Module not found: Error: Can't resolve '@app/config' ...

@biesbjerg
Copy link

This happened somewhere between release 1.3.4 and 1.3.5 (1.3.4 works for me using --prod flag).

Compare: v1.3.4...v1.3.5

@vkniazeu
Copy link

vkniazeu commented May 5, 2017

The issue is present as well with ionic 3.0.0-rc.1 and "@ionic/app-scripts": "1.3.7".

@biesbjerg
Copy link

@vkniazeu: Downgrade app-scripts to 1.3.4 until a fix is out, I'm pretty certain it will work.

@Sebastien-Guillon
Copy link

Thanks @biesbjerg, downgrading app scripts to v1.3.4 did the trick for me.

With Ionic version 3.0.0-rc.1, go to project directory:

npm install @ionic/[email protected] --save-dev

Then modify the webpack.config.js as needed and run:

ionic cordova build android --prod or similar.

@osamasoliman
Copy link

ionic-app-scripts performance with webpack and other stuff on ver 1.3.7 showing new updates for the browser is so good.
the problem that the--prod flag is not working anymore :(

Should I downgrade to 1.3.4 for production?
@jgw96
@danbucholtz

@SusanKern
Copy link

SusanKern commented May 5, 2017

I also was able to get --prod to work when I downgraded to 1.3.4. This seems to be a good solution for us for now.

[ Unfortunately once we tested further, we found that much of the interaction in the app did not function with 1.3.4, so this is not a solution we can move forward with. ]

@danbucholtz
Copy link
Contributor

@SusanKern, @osamasoliman, why isn't the --prod flag working for you?

Thanks,
Dan

@danbucholtz
Copy link
Contributor

@biesbjerg,

What issue are you having?

Thanks,
Dan

@osamasoliman
Copy link

osamasoliman commented May 6, 2017

What's your Advice @danbucholtz ?

Running ionic build android --prod

> Parent@ ionic:build C:\Users\Osama\Documents\GitHub\ParentApp
> ionic-app-scripts build "--prod"

[05:54:20]  ionic-app-scripts 1.3.7
[05:54:20]  build prod started ...
[05:54:20]  clean started ...
[05:54:20]  clean finished in 14 ms
[05:54:20]  copy started ...
[05:54:20]  ngc started ...
[05:54:50]  ngc finished in 29.82 s
[05:54:50]  preprocess started ...
[05:54:50]  deeplinks started ...
[05:54:51]  deeplinks finished in 1.50 s
[05:54:51]  optimization started ...
[05:54:52]  copy finished in 31.89 s
[05:55:26]  optimization finished in 34.16 s
[05:55:26]  preprocess finished in 35.66 s
[05:55:26]  webpack started ...
[05:57:47]  webpack finished in 141.36 s
[05:57:47]  sass started ...
[05:57:47]  uglifyjs started ...
[05:57:52]  ionic-app-script task: "build"
[05:57:52]  Error: Unexpected token operator «=», expected punc «,» in
            C:\Users\Osama\Documents\GitHub\ParentApp\www\build\main.js at line 107769, col 38, pos 4160177
Error: Unexpected token operator «=», expected punc «,» in C:\Users\Osama\Documents\GitHub\ParentApp\www\build\main.js at line 107769, col 38, pos 4160177
    at new BuildError (C:\Users\Osama\Documents\GitHub\ParentApp\node_modules\@ionic\app-scripts\dist\util\errors.js:16:28)
    at taskReject (C:\Users\Osama\Documents\GitHub\ParentApp\node_modules\@ionic\app-scripts\dist\worker-process.js:36:22)
    at C:\Users\Osama\Documents\GitHub\ParentApp\node_modules\@ionic\app-scripts\dist\worker-process.js:14:13
    at process._tickCallback (internal/process/next_tick.js:109:7)

npm ERR! Windows_NT 10.0.14393
npm ERR! argv "C:\\Program Files\\nodejs\\node.exe" "C:\\Users\\Osama\\AppData\\Roaming\\npm\\node_modules\\npm\\bin\\npm-cli.js" "run" "ionic:build" "--" "--prod"
npm ERR! node v7.9.0
npm ERR! npm  v4.1.2
npm ERR! code ELIFECYCLE
npm ERR! Parent@ ionic:build: `ionic-app-scripts build "--prod"`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the Parent@ ionic:build script 'ionic-app-scripts build "--prod"'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the Parent package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     ionic-app-scripts build "--prod"
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs Parent
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls Parent
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     C:\Users\Osama\Documents\GitHub\ParentApp\npm-debug.log```


Running `ionic info`:

```Your system information:
Cordova CLI: 6.5.0
Ionic Framework Version: 3.1.1
Ionic CLI Version: 2.2.3
Ionic App Lib Version: 2.2.1
Ionic App Scripts Version: 1.3.7
ios-deploy version: Not installed
ios-sim version: Not installed
OS: Windows 10
Node Version: v7.9.0
Xcode version: Not installed```

@ainulya16
Copy link

ainulya16 commented May 6, 2017

ionic build android --prod --release is not working for me

Cordova CLI: 6.5.0
Ionic Framework Version: 3.1.1
Ionic CLI Version: 2.2.3
Ionic App Lib Version: 2.2.1
Ionic App Scripts Version: 1.3.6
ios-deploy version: Not installed
ios-sim version: Not installed
OS: Windows 10
Node Version: v7.9.0
Xcode version: Not installed

{
  "name": "X",
  "author": "X",
  "homepage": "http://ionicframework.com/",
  "private": true,
  "config": {
    "ionic_webpack": "./webpack.config.js"
  },
  "scripts": {
    "clean": "ionic-app-scripts clean",
    "build": "ionic-app-scripts build",
    "ionic:build": "ionic-app-scripts build",
    "ionic:serve": "ionic-app-scripts serve"
  },
  "dependencies": {
    "@angular/common": "4.0.0",
    "@angular/compiler": "4.0.0",
    "@angular/compiler-cli": "4.0.0",
    "@angular/core": "4.0.0",
    "@angular/forms": "4.0.0",
    "@angular/http": "4.0.0",
    "@angular/platform-browser": "4.0.0",
    "@angular/platform-browser-dynamic": "4.0.0",
    "@ionic-native/barcode-scanner": "^3.6.1",
    "@ionic-native/core": "^3.6.1",
    "@ionic-native/splash-screen": "3.4.2",
    "@ionic-native/status-bar": "3.4.2",
    "@ionic/app-scripts": "^1.3.6",
    "@ionic/storage": "2.0.1",
    "angular2-elastic": "^0.13.0",
    "angular2-qrcode": "^2.0.0",
    "chart.js": "^2.5.0",
    "copy-webpack-plugin": "^4.0.1",
    "ionic-angular": "^3.1.1",
    "ionic-native": "^3.5.0",
    "ionicons": "3.0.0",
    "jsbarcode": "^3.5.9",
    "ng2-charts": "^1.5.0",
    "qrcode-generator-ts": "0.0.4",
    "qrious": "^2.2.0",
    "rxjs": "5.1.1",
    "sw-toolbox": "3.4.0",
    "zone.js": "^0.8.4"
  },
  "devDependencies": {
    "@ionic/app-scripts": "^1.3.4",
    "typescript": "~2.2.1"
  },
  "cordovaPlugins": [
    "cordova-plugin-whitelist",
    "cordova-plugin-console",
    "cordova-plugin-statusbar",
    "cordova-plugin-device",
    "cordova-plugin-splashscreen",
    "ionic-plugin-keyboard",
    "phonegap-plugin-barcodescanner"
  ],
  "cordovaPlatforms": [
    "android",
    {
      "platform": "android",
      "version": "",
      "locator": "android"
    }
  ],
  "description": "Flow: An template project"
}



@biesbjerg
Copy link

@danbucholtz

Like the others describe, my custom webpack config is not being picked up when --prod flag is used.

@danbucholtz
Copy link
Contributor

@biesbjerg,

I'll check it out next week.

Thanks,
Dan

@SusanKern
Copy link

Any updates on this?

@jbarbede
Copy link

I debugged it and it is related to the JS optimization that doesn't load the right webpack config: https://github.com/driftyco/ionic-app-scripts/blob/v1.3.5/src/optimization.ts#L28.

You can run without the --optimizejs option and it will build successfully.

I am not really sure how to fix that but the preprocess task pass null in place of the user's webpack config file there @danbucholtz: https://github.com/driftyco/ionic-app-scripts/blob/v1.3.5/src/preprocess.ts#L33

Or maybe the config file doesn't need to be passed there but in that case the problem comes from the getConfig method: https://github.com/driftyco/ionic-app-scripts/blob/v1.3.5/src/optimization.ts#L28

@danbucholtz
Copy link
Contributor

@jbarbede,

I need to look into this issue still. PRs are welcome if someone wants to dive in and fix it. The optimize task should use the optimization config. You can pass in your own (I think) but I don't recommend that for optimization. The optimization task really just runs webpack to build a dependency tree to purge unused components since we know about the internal structure of Ionic.

The webpack task is fair game to use a custom config and this does actual bundling. There is also an issue with the virtual file system and where we need to write files to disk in addition to the virtual fs. This could be a PR opportunity as well.

Thanks,
Dan

@SusanKern
Copy link

Is running without the --optimizejs option something we should consider for our production release? We currently build with ionic build android --release --prod. Could you give me an idea of what type of command to use to change that option?

@jbarbede
Copy link

jbarbede commented May 16, 2017

@SusanKern, like Dan commented some days ago there #870 (comment), you can just replace --prod by --aot --optimizejs --minifyjs --minifycss. --prod is just a shortcut if I understood well.

The best solution is just to downgrade to v1.3.4 for now I guess, this is at least what we are doing on our project.

If you definitvely want to use latest versions, you could test ionic build android --release --aot --minifyjs --minifycss.

I'm not sure what is the gain of optimization, probably build size as Dan said it purges unused components from Ionic.

@danbucholtz
Copy link
Contributor

@jbarbede,

Can you create a quick sample repo that shows the issue? I can probably fix it pretty quickly.

Thanks,
Dan

@jbarbede
Copy link

Sample there https://github.com/jbarbede/ionic-preview-app/tree/custom-webpack.

The custom webpack config uses a css-loader to simply load a classic .css file imported in app.component to change the color of the header title.

npm run build works, npm run build --prod doesn't.

@DavidWiesner
Copy link

@jbarbede you are reference a custom webpack script in your package.json
"ionic_webpack": "./build/webpack.config.js"

But I can not find this in your project

@jbarbede
Copy link

@DavidWiesner oh you're right, I just pushed it on the branch.

@Nilos
Copy link
Contributor

Nilos commented May 24, 2017

You have to add an own config for optimization like so:
"ionic_dependency_tree": "./config/optimization.config.js"

If you do that the optimization.config.js is picked up correctly. Only problem so far is that I can't get it to work. It always results in problems with ngfactory.ts files.

Edit: 🎉 Got it working on masterwith a custom ionic_dependency_tree config.

@chriswep
Copy link

Putting my webpack config additionally to "ionic_dependency_tree" in package.json solved the issue for me.

It stills feels like a bug though.

@Nilos
Copy link
Contributor

Nilos commented May 24, 2017

Just copying your config over will not make the optimization step work correctly though. You would still have to change the module loader for ts/js files to the custom optimization loader (I guess?)

This feels less like a bug and more like a breaking change to me. On the other hand, the error until now was just swallowed (webpack errors were not reported) and optimization was thus "skipped")

Commit that broke this:
3df19bf

@chriswep
Copy link

well there definitely is something off here. i'm just saying that for my special setup and webpack config it works for now if do this in package.json:

        "ionic_webpack": "./webpack.config.js",
        "ionic_dependency_tree": "./webpack.config.js",

The dev build ignores the dependency tree setting, the prod build ignores the ionic_webpack one. Both build run fine now and produce the desired (working) outcome.

Maybe @danbucholtz can you shed some light on why this is working? I expect that in a future version of app-scripts the production build will also load the ionic_webpack config? Or is it indeed supposed to work like that now?

@chriswep
Copy link

chriswep commented Jul 6, 2017

Please let me know if this isn't working as expected.

@danbucholtz actually the typo is not the real issue here, i think it bothered you more than the rest of us ;-) - the problem is that custom webpack configs (via ionic_webpack) are not loaded when building in production mode. Unless it is supposed to be like that now (having to set your webpack config to ionic_optimization as well as ionic_webpack). If its not, then this ticket should stay open. If yes, then i would agree with some others here that this is now a confusing situation and needs documentation.

@danbucholtz
Copy link
Contributor

The optimization part of webpack is purely for building a dependency tree. It just happens to run Webpack. It could just as easily run Rollup, or even a custom tool. I am not clear on why this part needs to be customized.

Is the build process failing on the webpack step, or the optimization step? What sort of customization? If it just simply not finding the file? I will take a look at this tonight.

Thanks,
Dan

@fiznool
Copy link
Contributor

fiznool commented Jul 6, 2017

@danbucholtz please refer to my previous comment for a sample repo which shows the problem. The most common issue I can gather from this thread is for customising the webpack resolver so you can write

import { HomePage } from 'src/pages/home/home';

instead of

import { HomePage } from '../../pages/home/home';

Obviously if code is written using the former syntax, any webpack processing needs to include the custom resolver configuration. This is why (currently) you need 2 custom webpack files when building with the --prod flag - one for optimization, and one for bundling.

@chriswep
Copy link

chriswep commented Jul 6, 2017

@danbucholtz because you asked: the build is failing on the optimization step. @fiznool explained why.

Contrary to what i thought first, the problem is not that the webpack step ignores the custom config file but that there is an additional (webpack-)optimization step before it that is failing, because it misses the custom configs that the project depends on. Thats why it started to work when we added the config to the optimisation step (which i only understand now why).

If i think about it, it may be necessary to keep having two separate configuration options. If the "normal" config e.g. does some copy tasks, we wouldn't want that to be done in the optimisation step. We just need the stuff there that is needed for the code to "compile" properly.

Again, in that case the documentation should make clear that both steps need to be configured in a lot of use cases.

The optimization part of webpack is purely for building a dependency tree. It just happens to run Webpack. It could just as easily run Rollup, or even a custom tool.
Considering the issue at hand, i think using a different bundler here would make the situation much more difficult for people with custom configs.

@Xepe
Copy link

Xepe commented Jul 8, 2017

Hello,

I think that ionic_optimization config should be added in the README

Thanks @danbucholtz
Regards.

@JoeMeeks
Copy link

JoeMeeks commented Jul 11, 2017

@Xepe @metzc @fiznool @danbucholtz with @ionic/app-scripts 2.0.0 you can use the --optimization flag per https://github.com/ionic-team/ionic-app-scripts/blob/v2.0.0/src/optimization.ts.

So the package.json build script for my "mpm" app looks like this:

"build:mpm": "ionic-app-scripts build --copy src/app/mpm/config/copy.config.js --sass src/app/mpm/config/sass.config.js --appNgModulePath src/app/mpm/app.module.ts --appEntryPoint src/app/mpm/main.ts --tsconfig src/app/mpm/config/tsconfig.json --webpack src/app/mpm/config/webpack.config.js --optimization src/app/mpm/config/optimization.config.js --enableLint false --prod",

However, now I get a webpack error after optimization completes successfully but without the --prod argument builds still work fine.
image

@danbucholtz
Copy link
Contributor

danbucholtz commented Jul 11, 2017

You are likely running out of memory. You'll need to provide additional memory to Node.

node --max-old-space-size=8192 path/to/ionic/command serve
node --max-old-space-size=8192 path/to/ionic/command cordova run build --prod

I think that will fix it.

Thanks,
Dan

@JoeMeeks
Copy link

JoeMeeks commented Jul 11, 2017

Thanks @danbucholtz , but even with these two modified build scripts I get the same error (and the scripts still work without the --prod flag):
"build:mpm": "node --max-old-space-size=8192 node_modules/@ionic/app-scripts/bin/ionic-app-scripts.js build --wwwDir MPM.App --copy src/app/mpm/config/copy.config.js --sass src/app/mpm/config/sass.config.js --appNgModulePath src/app/mpm/app.module.ts --appEntryPoint src/app/mpm/main.ts --tsconfig src/app/mpm/config/tsconfig.json --webpack src/app/mpm/config/webpack.config.js --optimization src/app/mpm/config/optimization.config.js --enableLint false --prod"

"build:mpm": "node --max-old-space-size=16384 node_modules/@ionic/app-scripts/bin/ionic-app-scripts.js build --wwwDir MPM.App --copy src/app/mpm/config/copy.config.js --sass src/app/mpm/config/sass.config.js --appNgModulePath src/app/mpm/app.module.ts --appEntryPoint src/app/mpm/main.ts --tsconfig src/app/mpm/config/tsconfig.json --webpack src/app/mpm/config/webpack.config.js --optimization src/app/mpm/config/optimization.config.js --enableLint false --prod"

I have 32 GB RAM so I tried 16384 to no avail. Before upgrading yesterday I was able to run the build script with --prod just fine with @ionic/app-scripts 1.3.1. I also implemented the 2.0.0 new default webpack configuration. Does the introduction of the ModuleConcatenationPlugin or CommonChunksPlugin in 2.0.0 cause memory leaks or do memory leaks occur in ngc or optimization build tasks that affect webpack?

@JoeMeeks
Copy link

@danbucholtz after a little more digging, my error is "Maximum call stack size exceeded at..." and not "Javascript heap out of memory" so I wonder if it is related to this issue? I am looking at node_modules/@ionic/app-scripts/bin/ionic-app-scripts.js and will attempt to add Kleeb's fix for that old version in the 2.0.0 ionic-app-scripts.js:

FIX:
add --stack-size=1968 to the first line of node_modules/@ionic/app-scripts/bin/ionic-app-scripts.js (or to be safe --max_old_space_size=4096 --stack-size=1968)

@danbucholtz
Copy link
Contributor

@JoeMeeks, I'm not sure, maybe they do. I haven't seen that, though.

Thanks,
Dan

@JoeMeeks
Copy link

@danbucholtz looks like this original issue is solved with the --optimization arg so moving "Maximum call stack size exceeded" error convo to #996

@carlos-olivera
Copy link

added an ionic_dependency_tree entry to package.json.

And

Downgrade app-scripts was the solution in my case.

Carlos.

@pyboosted
Copy link

As for @ionic/[email protected] version I had to modify @ionic/app-scripts/config/optimization.config.js to make --prod builds work.

  1. Copy node_modules/@ionic/app-scripts/config/optimization.config.js to your root folder.
  2. Modify it adding plugins: [ new TsConfigPathsPlugin() ] to resolve section.
  3. Modify package.json by adding "ionic_optimization": "./optimization.config.js" to config section

@stalniy
Copy link

stalniy commented Aug 2, 2017

@pyboosted could you please share your configuration?

@russcarver
Copy link

russcarver commented Aug 2, 2017

That didn't work for me, even after installing, reading and configuring the awesome-typescript-loader. However I did copy the node_modules/@ionic/app-scripts/config/optimization.config.js and set it to the ionic_optimization part of the package.json config. However, mine is a a bit different. It got me a lot farther along (the absolute path errors are gone), but I get a new error.

Here are the relevant parts:

package.json:

    "dependencies": {
        "@angular/animations": "4.1.3",
        "@angular/common": "4.1.3",
        "@angular/compiler": "4.1.3",
        "@angular/compiler-cli": "4.1.3",
        "@angular/core": "4.1.3",
        "@angular/forms": "4.1.3",
        "@angular/http": "4.1.3",
        "@angular/platform-browser": "4.1.3",
        "@angular/platform-browser-dynamic": "4.1.3",
        "@angular/platform-server": "4.1.3",
        "@angular/router": "4.1.3",
        "@angular/tsc-wrapped": "4.2.5",
        "@ionic-native/core": "4.1.0",
        "@ionic-native/keyboard": "4.1.0",
        "@ionic-native/network": "4.1.0",
        "@ionic-native/screen-orientation": "4.1.0",
        "@ionic-native/splash-screen": "4.1.0",
        "@ionic-native/status-bar": "4.1.0",
        "@ionic/storage": "2.0.1",
        "cordova": "7.0.1",
        "cordova-android": "6.2.3",
        "cordova-ios": "4.4.0",
        "cordova-plugin-compat": "1.1.0",
        "cordova-plugin-console": "1.0.7",
        "cordova-plugin-device": "1.1.6",
        "cordova-plugin-file": "4.3.3",
        "cordova-plugin-ios-disableshaketoedit": "1.0.0",
        "cordova-plugin-keyboard": "1.1.5",
        "cordova-plugin-network-information": "1.3.3",
        "cordova-plugin-privacyscreen": "0.3.1",
        "cordova-plugin-screen-orientation": "https://github.com/Exilz/cordova-plugin-screen-orientation",
        "cordova-plugin-splashscreen": "4.0.3",
        "cordova-plugin-statusbar": "2.2.3",
        "cordova-plugin-whitelist": "1.3.2",
        "cordova-plugin-wkwebview-engine": "https://github.com/driftyco/cordova-plugin-wkwebview-engine",
        "core-js": "2.4.1",
        "es6-promise-plugin": "4.1.0",
        "ionic": "3.6.0",
        "ionic-angular": "3.6.0",
        "ionic-plugin-keyboard": "2.2.1",
        "ionicons": "3.0.0",
        "rxjs": "5.4.2",
        "sw-toolbox": "3.6.0",
        "webpack": "3.1.0",
        "zone.js": "0.8.12"
    },
    "devDependencies": {
        "@ionic/app-scripts": "2.1.3",
        "@ionic/cli-plugin-cordova": "1.5.0",
        "@ionic/cli-plugin-ionic-angular": "1.4.0",
        "@ionic/cli-plugin-proxy": "1.4.0",
        "@types/angular": "1.6.25",
        "@types/ionic": "0.0.34",
        "@types/jasmine": "2.5.53",
        "@types/jest": "20.0.2",
        "@types/node": "6.0.60",
        "@types/sinon": "2.3.2",
        "codelyzer": "3.0.1",
        "fs": "0.0.1-security",
        "indexeddb-mock": "1.1.0",
        "jasmine-core": "2.6.2",
        "jasmine-spec-reporter": "4.1.0",
        "jest": "20.0.4",
        "jest-preset-angular": "2.0.4",
        "plist": "2.1.0",
        "protractor": "5.1.2",
        "rollup-plugin-replace": "1.1.1",
        "sinon": "2.3.5",
        "ts-node": "3.0.4",
        "tslint": "5.4.3",
        "typescript": "2.4.2"
    },
    "config": {
         "ionic_optimization": "./optimization.config.js",
        "ionic_webpack": "./webpack.config.js"
    }

optimization.config.js:

var path = require('path')
var webpack = require('webpack')
var ionicWebpackFactory = require(process.env.IONIC_WEBPACK_FACTORY)

module.exports = {
  entry: process.env.IONIC_APP_ENTRY_POINT,
  output: {
    path: '{{BUILD}}',
    publicPath: 'build/',
    filename: 'deptree.js'
  },

  resolve: {
    extensions: ['.js', '.ts', '.tsx'],
    modules: [path.resolve('node_modules'), path.resolve('src')],
    alias: {
      environments: path.resolve('src/environments'),
      app: path.resolve('src/app'),
      lib: path.resolve('src/lib'),
      pages: path.resolve('src/pages'),
      components: path.resolve('src/components'),
      validators: path.resolve('src/validators'),
      providers: path.resolve('src/providers'),
      models: path.resolve('src/models'),
      decorators: path.resolve('src/decorators'),
      pipes: path.resolve('src/pipes')
    }
  },

  module: {
    loaders: [
      {
        test: /\.tsx?$/,
        loader: process.env.IONIC_OPTIMIZATION_LOADER
      },
      {
        test: /\.js$/,
        loader: process.env.IONIC_OPTIMIZATION_LOADER
      }
    ]
  },

  plugins: [
    ionicWebpackFactory.getIonicOptimizationEnvironmentPlugin()
  ],

  // Some libraries import Node modules but don't use them in the browser.
  // Tell Webpack to provide empty mocks for them so importing them works.
  node: {
    fs: 'empty',
    net: 'empty',
    tls: 'empty'
  }
}

Ionic info:

cli packages:

    @ionic/cli-plugin-cordova       : 1.5.0
    @ionic/cli-plugin-ionic-angular : 1.4.0
    @ionic/cli-plugin-proxy         : 1.4.0
    @ionic/cli-utils                : 1.6.0
    ionic (Ionic CLI)               : 3.6.0

global packages:

    Cordova CLI : 7.0.1

local packages:

    @ionic/app-scripts : 2.1.3
    Cordova Platforms  : android 6.2.3 ios 4.4.0
    Ionic Framework    : ionic-angular 3.6.0

System:

    Android SDK Tools : 26.0.2
    Node              : v8.1.4
    OS                : macOS Sierra
    Xcode             : Xcode 8.3.3 Build version 8E3004b
    ios-deploy        : 1.9.1
    ios-sim           : 6.0.0
    npm               : 5.0.3

Command run:
ionic cordova build ios --prod --no-interactive

Error:

npm WARN invalid config loglevel="notice"

Running app-scripts build: --build --prod --iscordovaserve --externalIpRequired --nobrowser

[15:10:44]  build prod started ...
[15:10:44]  clean started ...
[15:10:44]  clean finished in 1 ms
[15:10:44]  copy started ...
[15:10:44]  ngc started ...
[15:11:01]  ngc finished in 16.92 s
[15:11:01]  preprocess started ...
[15:11:01]  deeplinks started ...
[15:11:03]  deeplinks finished in 2.22 s
[15:11:03]  optimization started ...
[15:11:27]  optimization finished in 23.28 s
[15:11:27]  preprocess finished in 25.50 s
[15:11:27]  webpack started ...
[15:13:46]  copy finished in 181.57 s
[WARN] Error occurred during command execution from a CLI plugin (@ionic/cli-plugin-cordova).
Error: ./node_modules/ionic-native/dist/esm/plugins/plugin.js
Module build failed: TypeError: Cannot read property 'type' of undefined
    at Object.getEffectiveTypeAnnotationNode (/xxx/node_modules/typescript/lib/typescript.js:9341:17)
    at assignContextualParameterTypes (/xxx/node_modules/typescript/lib/typescript.js:41652:25)
    at checkFunctionExpressionOrObjectLiteralMethod (/xxx/node_modules/typescript/lib/typescript.js:41948:29)
    at checkExpressionWorker (/xxx/node_modules/typescript/lib/typescript.js:42959:28)
    at checkExpression (/xxx/node_modules/typescript/lib/typescript.js:42898:42)
    at checkExpressionCached (/xxx/node_modules/typescript/lib/typescript.js:42779:38)
    at checkReturnStatement (/xxx/node_modules/typescript/lib/typescript.js:45418:54)
    at checkSourceElement (/xxx/node_modules/typescript/lib/typescript.js:46763:28)
    at Object.forEach (/xxx/node_modules/typescript/lib/typescript.js:1506:30)
    at checkBlock (/xxx/node_modules/typescript/lib/typescript.js:44563:16)
 @ ./node_modules/ionic-native/dist/esm/index.js 233:0-33
 @ ./node_modules/@ionic/cloud/dist/es5/di.js
 @ ./src/app/app.module.ngfactory.js
 @ ./src/app/main.ts
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! Foo@ build-ios-qa: `ionic cordova build ios --prod --no-interactive`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the Foo@ build-ios-qa script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

tsconfig.json:

{
  "compilerOptions": {
    "allowJs": true,
    "allowSyntheticDefaultImports": true,
    "baseUrl": "./src",
    "paths": {
      "environments/*": [
        "./environments/*"
      ],
      "app/*": [
        "./app/*"
      ],
      "lib/*": [
        "./lib/*"
      ],
      "pages/*": [
        "./pages/*"
      ],
      "components/*": [
        "./components/*"
      ],
      "validators/*": [
        "./validators/*"
      ],
      "providers/*": [
        "./providers/*"
      ],
      "models/*": [
        "./models/*"
      ],
      "decorators/*": [
        "./decorators/*"
      ],
      "pipes/*": [
        "./pipes/*"
      ]
    },
    "declaration": false,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "lib": [
      "dom",
      "es2015"
    ],
    "module": "es2015",
    "moduleResolution": "node",
    "noStrictGenericChecks": true,
    "removeComments": true,
    "sourceMap": true,
    "target": "es5",
    "typeRoots": [
      "node_modules/@types"
    ],
    "types": [
      "jasmine",
      "sinon"
    ]
  },
  "include": [
    "src/**/*.ts"
  ],
  "exclude": [
    "node_modules",
    "src/**/*.spec.ts"
  ],
  "compileOnSave": false,
  "atom": {
    "rewriteTsconfig": false
  }
}

webpack.config.js

var path = require('path')
var webpack = require('webpack')
var ionicWebpackFactory = require(process.env.IONIC_WEBPACK_FACTORY)

var ModuleConcatPlugin = require('webpack/lib/optimize/ModuleConcatenationPlugin')

var prodPlugins = []
if (process.env.IONIC_ENV === 'prod') {
  prodPlugins.push(new ModuleConcatPlugin())
}

var env = process.env.NODE_ENV || 'dev'

console.log('------------------------')
console.log('environment:', env)
console.log('------------------------')

module.exports = {
  entry: process.env.IONIC_APP_ENTRY_POINT,
  output: {
    path: '{{BUILD}}',
    publicPath: 'build/',
    filename: '[name].js',
    devtoolModuleFilenameTemplate: ionicWebpackFactory.getSourceMapperFunction(),
  },
  devtool: process.env.IONIC_SOURCE_MAP_TYPE,

  resolve: {
    extensions: ['.js', '.json', '.ts', '.tsx'],
    modules: [path.resolve('node_modules'), path.resolve('src')],
    alias: {
      environments: path.resolve('src/environments'),
      app: path.resolve('src/app'),
      lib: path.resolve('src/lib'),
      pages: path.resolve('src/pages'),
      components: path.resolve('src/components'),
      validators: path.resolve('src/validators'),
      providers: path.resolve('src/providers'),
      models: path.resolve('src/models'),
      decorators: path.resolve('src/decorators'),
      pipes: path.resolve('src/pipes')
    }
  },

  module: {
    loaders: [
      {
        test: /\.json$/,
        loader: 'json-loader'
      },
      {
        test: /\.tsx?$/,
        loader: process.env.IONIC_WEBPACK_LOADER
      },
      {
        test: /\.js$/,
        loader: process.env.IONIC_WEBPACK_TRANSPILE_LOADER
      }
    ]
  },

  plugins: [
    ionicWebpackFactory.getIonicEnvironmentPlugin(),
    ionicWebpackFactory.getCommonChunksPlugin(),
    new webpack.DefinePlugin({
      TA_ENV: {environment: JSON.stringify(env)}
    })
  ].concat(prodPlugins),

  // Some libraries import Node modules but don't use them in the browser.
  // Tell Webpack to provide empty mocks for them so importing them works.
  node: {
    fs: 'empty',
    net: 'empty',
    tls: 'empty'
  }
}

This error is referenced here (https://forum.ionicframework.com/t/error-during-executing-ionic-cordova-run-android-prod/100252/2) but no one has found a solution yet.

@russcarver
Copy link

russcarver commented Aug 3, 2017

Update: I think I've figured out this problem. I had to remove some unused code related to using:
import { CloudModule, CloudSettings } from '@ionic/cloud-angular'. Now everything works with --prod. Woot!

@sburnicki
Copy link

For me the ionic_dependency_tree solution worked just well until I upgraded to "@ionic/app-scripts": "^2.1.3".
Based on the answer by @pyboosted I now modify optimization.config.js as follows:

package.json

...
"config": {
         ...
        "ionic_optimization": "./config/optimization.config.js"
    }

./config/optimization.config.js

var path = require('path');
var useDefaultConfig = require('@ionic/app-scripts/config/optimization.config.js');

module.exports = function () {
  // your modifications on useDefaultConfig, in my case somethings like
  //
  // var env = process.env.DEPLOY_ENV || "develop";
  // var deploymentConfigFile = './src/app/DeploymentConfig.' + env + '.ts';
  // useDefaultConfig.resolve.alias = {
  //  "@app/DeploymentConfig": path.resolve(deploymentConfigFile)
  //};

  return useDefaultConfig;
};

So no need to actually copy and modify the optimization configuration from app-scripts.

@enif-lee
Copy link

enif-lee commented Aug 11, 2017

hi, guys.

this problem is always occured when using alias in custom webpack.

usually, we have to profiling for each environments. but ionic-cli is not provide environments setting like ng-cli as default.

As i know it happens when we build an AOT compile time in ngc. so, i change to webpackNormalModuleReplacementPlugin and properly works --prod --release build.

here is my webpack.config.js, i hope this config will help you.

const webpack = require('webpack');
const defaults = require('@ionic/app-scripts/config/webpack.config');
const os = require('os');
const options = require('yargs').argv;

const CONFIG_REGEXP = os.type().indexOf("Windows") !== -1
	? /src\\env\\dev.config.ts/
	: /src\/env\/dev.config.ts/;


const configFilePath = ( options.profile ? options.profile : process.env.IONIC_ENV ) + '.config.ts';

console.log("Using config file is src/env/" + configFilePath);

module.exports = function () {
	defaults.plugins.push(new webpack.NormalModuleReplacementPlugin(
		CONFIG_REGEXP,
		configFilePath
	))

	return defaults;
}

@kinglionsoft
Copy link

@sburnicki, @pyboosted thanks, it works. And my optimization.config.js:

const path = require('path');
const defaults = require('@ionic/app-scripts/config/optimization.config');

module.exports = function () {
 // here to redefine alias again, just same as webpack.config.js
  defaults.resolve.alias = {
    kl: path.resolve('src/kl')
  };

  return defaults;
};

@emcniece
Copy link

emcniece commented Mar 23, 2018

I can't seem to make this work with @ionic/[email protected]. The README no longer has any mention of ionic_optimization, and node_modules/@ionic/app/scripts/config/optimization.config.js doesn't exist.

The --prod build is clearly not respecting my custom webpack config, and running ionic cordova build browser --release --aot --optimizejs --minifyjs --minifycss doesn't do the trick either. What gives?! 😢

Edit: not sure why this comment unasigned @danbucholtz ...

@tabirkeland
Copy link

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests