ionic-team / ionic-unit-testing-example

Example of adding unit testing in your Ionic 2.x or greater apps with Karma and Jasmine
Other
374 stars 145 forks source link

ts-loader's default config makes Webpack extremely slow in larger projects #91

Open vilanz opened 6 years ago

vilanz commented 6 years ago

The nature of ts-loader makes it slower as the project's size increases. https://github.com/TypeStrong/ts-loader#faster-builds

There are 2 options to make it fast:

Any inputs on if these changes breaks anything?

neilbo commented 6 years ago

Hey @ludvon The second method I get: when I try and run npm run test

[at-loader] Using typescript@2.4.2 from typescript and "tsconfig.json" from /Users/neil/Projects/cardihabApp/tsconfig.json.

TypeError: Cannot read property 'watchRun' of undefined
neilbo commented 6 years ago

Hey @ludvon the first option I got working, it has better reporting on how long it took to compile, doesn't make it run faster though:

output Starting type checking service...
Using 1 worker with 2048MB memory limit
Type checking in progress...
webpack: Compiled successfully.
webpack: Compiling...
No type errors found
Version: typescript 2.4.2
Time: 140845ms
04 06 2018 15:52:27.402:WARN [karma]: No captured browser, open http://localhost:9876/
vilanz commented 6 years ago

@neilbo About the second method, it seems that awesome-typescript-loader@3.5.0 is the correct version for typescript@2.4.2

neilbo commented 6 years ago

@ludvon you are a legend! I ended up doing npm i awesome-typescript-loader@3.5.0 --saved-dev

It went from 14-15sec to compile to 1-2sec! I've got ~ 450 unit tests

[at-loader] Checking started in a separate process...

[at-loader] Ok, 1.156 sec.

Cheers!

distante commented 6 years ago

@neilbo About the second method, it seems that awesome-typescript-loader@3.5.0 is the correct version for typescript@2.4.2

Just to add that 3.5.0 is the correct version for typescript 2.x.x . I was not sure about this and maybe other person has the same doubt.

(4.0.0 works with typescript > 2.7 )

distante commented 6 years ago

After installing awesome-typescript-loader@3.5.0 the first time I call npm run test all work as expected but if I make a change into an spec.ts file Karma crashes with this message:


ℹ 「wdm」: Compiling...
06 10 2018 14:56:24.105:ERROR [karma]: TypeError: Cannot read property '_tsInstances' of undefined
    at resolveInstance (C:\Users\User\Documents\myProject\node_modules\awesome-typescript-loader\src\instance.ts:73:20)
    at C:\Users\User\Documents\myProject\node_modules\awesome-typescript-loader\src\instance.ts:366:26
    at _err1 (eval at create (C:\Users\User\Documents\myProject\node_modules\tapable\lib\HookCodeFactory.js:32:10), <anonymous>:17:1)
    at invalid (C:\Users\User\Documents\myProject\node_modules\webpack-dev-middleware\lib\context.js:76:7)
    at context.compiler.plugin (C:\Users\User\Documents\myProject\node_modules\webpack-dev-middleware\lib\context.js:116:5)
    at _err0 (eval at create (C:\Users\User\Documents\myProject\node_modules\tapable\lib\HookCodeFactory.js:32:10), <anonymous>:12:1)
    at C:\Users\User\Documents\myProject\node_modules\karma-webpack\lib\karma-webpack.js:124:9    at AsyncSeriesHook.eval [as callAsync] (eval at create (C:\Users\User\Documents\myProject\node_modules\tapable\lib\HookCodeFactory.js:32:10), <anonymous>:7:1)
    at AsyncSeriesHook.lazyCompileHook (C:\Users\User\Documents\myProject\node_modules\tapable\lib\Hook.js:154:20)
    at Watching._go (C:\Users\User\Documents\myProject\node_modules\webpack\lib\Watching.js:40:32)
    at Watching._invalidate (C:\Users\User\Documents\myProject\node_modules\webpack\lib\Watching.js:165:9)
    at watcher.compiler.watchFileSystem.watch (C:\Users\User\Documents\myProject\node_modules\webpack\lib\Watching.js:136:10)
    at Watchpack.watcher.once (C:\Users\User\Documents\myProject\node_modules\webpack\lib\node\NodeWatchFileSystem.js:54:4)
    at Object.onceWrapper (events.js:317:30)
    at emitTwo (events.js:126:13)
    at Watchpack.emit (events.js:214:7)

The problem is that awesome-typescript-loader@3.5.0 can not work with Webpack 4.x, so I downgraded Webpack to 3.10 and it works.

I can not say if it is faster because I am right now in my crappy old laptop.

Edit: A quick Warning. Using awesome-typescript-loader will break the detail page of your coverage tests.

v1bh0r commented 6 years ago

Updated Webpack to 4.23.1 and used the option 2. Got the following error:

✖ 「atl」: Child process failed to process the request: TypeError: Cannot read property 'Created' of undefined at onFileCreated (node_modules/awesome-typescript-loader/src/checker/runtime.ts:256:61) at updateFile (node_modules/awesome-typescript-loader/src/checker/runtime.ts:391:4) at processEmit (node_modules/awesome-typescript-loader/src/checker/runtime.ts:457:3) at node_modules/awesome-typescript-loader/src/checker/runtime.ts:610:6 at Object.send (node_modules/awesome-typescript-loader/src/checker/runtime.ts:49:6) at Checker.req (node_modules/awesome-typescript-loader/src/checker/checker.ts:100:15) at Checker.emitFile (node_modules/awesome-typescript-loader/src/checker/checker.ts:105:15) at transform (node_modules/awesome-typescript-loader/src/index.ts:130:26) at transformationFunction (node_modules/awesome-typescript-loader/src/index.ts:72:40) at compiler (node_modules/awesome-typescript-loader/src/index.ts:83:21) at Object.loader (node_modules/awesome-typescript-loader/src/index.ts:14:12) at LOADER_EXECUTION (node_modules/loader-runner/lib/LoaderRunner.js:119:14) at runSyncOrAsync (node_modules/loader-runner/lib/LoaderRunner.js:120:4) at iterateNormalLoaders (node_modules/loader-runner/lib/LoaderRunner.js:229:2) at iterateNormalLoaders (node_modules/loader-runner/lib/LoaderRunner.js:218:10)

Update: Upgrading typescript to 3.1.3 fixed it but the compilation is still slow. Here are my current dependencies:

  "dependencies": {
    "@angular/animations": "^5.0.3",
    "@angular/common": "5.0.3",
    "@angular/compiler": "5.0.3",
    "@angular/compiler-cli": "5.0.3",
    "@angular/core": "5.0.3",
    "@angular/forms": "5.0.3",
    "@angular/http": "5.0.3",
    "@angular/platform-browser": "5.0.3",
    "@angular/platform-browser-dynamic": "5.0.3",
    "@ionic-native/android-permissions": "^4.16.0",
    "@ionic-native/camera": "^4.9.1",
    "@ionic-native/core": "4.4.0",
    "@ionic-native/deeplinks": "^4.15.0",
    "@ionic-native/fcm": "^4.14.0",
    "@ionic-native/file": "^4.10.0",
    "@ionic-native/file-transfer": "^4.10.0",
    "@ionic-native/geolocation": "^4.7.0",
    "@ionic-native/globalization": "^4.16.0",
    "@ionic-native/splash-screen": "4.4.0",
    "@ionic-native/status-bar": "4.4.0",
    "@ionic/storage": "^2.1.3",
    "@ngx-translate/core": "^9.1.1",
    "@ngx-translate/http-loader": "^2.0.1",
    "@types/zen-observable": "^0.8.0",
    "angular-svg-round-progressbar": "^2.0.0",
    "apollo-angular": "1.0.0",
    "apollo-angular-link-http": "1.0.1",
    "apollo-cache-inmemory": "^1.2.5",
    "apollo-client": "2.0.0",
    "apollo-link": "1.0.0",
    "apollo-link-context": "^1.0.9",
    "apollo-link-dedup": "^1.0.9",
    "apollo-link-state": "^0.4.1",
    "cordova-android": "7.0.0",
    "cordova-browser": "5.0.3",
    "cordova-plugin-android-permissions": "^1.0.0",
    "cordova-plugin-camera": "^4.0.3",
    "cordova-plugin-device": "^2.0.2",
    "cordova-plugin-fcm-with-dependecy-updated": "^2.2.4",
    "cordova-plugin-file": "^6.0.1",
    "cordova-plugin-file-transfer": "^1.7.1",
    "cordova-plugin-geolocation": "^4.0.1",
    "cordova-plugin-globalization": "^1.11.0",
    "cordova-plugin-ionic-keyboard": "^2.1.2",
    "cordova-plugin-ionic-webview": "^1.2.1",
    "cordova-plugin-splashscreen": "^5.0.2",
    "cordova-plugin-whitelist": "^1.3.3",
    "cordova-sqlite-storage": "^2.3.2",
    "graphql": "^0.13.2",
    "graphql-tag": "^2.9.2",
    "hammerjs": "^2.0.8",
    "ionic-angular": "3.8.0",
    "ionic-img-viewer": "^2.9.0",
    "ionic-plugin-deeplinks": "~1.0.17",
    "ionicons": "3.0.0",
    "jwt-decode": "^2.2.0",
    "rxjs": "5.5.2",
    "sw-toolbox": "3.6.0",
    "zen-observable": "^0.8.8",
    "zone.js": "^0.8.20"
  },
  "devDependencies": {
    "@ionic/app-scripts": "3.1.8",
    "@types/googlemaps": "^3.30.11",
    "@types/jasmine": "^2.8.6",
    "@types/node": "^9.4.6",
    "angular2-template-loader": "^0.6.2",
    "awesome-typescript-loader": "^5.2.1",
    "html-loader": "^0.5.5",
    "ionic": "^4.0.1",
    "ionic-mocks": "^1.3.0",
    "istanbul-instrumenter-loader": "^3.0.0",
    "jasmine": "^2.9.0",
    "jasmine-spec-reporter": "^4.2.1",
    "karma": "^1.5.0",
    "karma-chrome-launcher": "^2.2.0",
    "karma-coverage-istanbul-reporter": "^1.4.1",
    "karma-jasmine": "^1.1.1",
    "karma-jasmine-html-reporter": "^0.2.2",
    "karma-sourcemap-loader": "^0.3.7",
    "karma-webpack": "^2.0.9",
    "null-loader": "^0.1.1",
    "prettier": "^1.14.2",
    "protractor": "^5.3.0",
    "stylelint": "^9.1.3",
    "stylelint-config-standard": "^18.2.0",
    "ts-loader": "^3.5.0",
    "ts-node": "^5.0.0",
    "tslint-ionic-rules": "0.0.14",
    "typescript": "3.1.3",
    "webpack": "^4.23.1",
    "webpack-cli": "^3.1.2",
    "webpack-dev-server": "^2.0.0"
  }

Update 2: Followed @distante 's suggestions and method 2 fixed the performance issue

Here are my current dependencies:

  "dependencies": {
    "@angular/animations": "^5.0.3",
    "@angular/common": "5.0.3",
    "@angular/compiler": "5.0.3",
    "@angular/compiler-cli": "5.0.3",
    "@angular/core": "5.0.3",
    "@angular/forms": "5.0.3",
    "@angular/http": "5.0.3",
    "@angular/platform-browser": "5.0.3",
    "@angular/platform-browser-dynamic": "5.0.3",
    "@ionic-native/android-permissions": "^4.16.0",
    "@ionic-native/camera": "^4.9.1",
    "@ionic-native/core": "4.4.0",
    "@ionic-native/deeplinks": "^4.15.0",
    "@ionic-native/fcm": "^4.14.0",
    "@ionic-native/file": "^4.10.0",
    "@ionic-native/file-transfer": "^4.10.0",
    "@ionic-native/geolocation": "^4.7.0",
    "@ionic-native/globalization": "^4.16.0",
    "@ionic-native/splash-screen": "4.4.0",
    "@ionic-native/status-bar": "4.4.0",
    "@ionic/storage": "^2.1.3",
    "@ngx-translate/core": "^9.1.1",
    "@ngx-translate/http-loader": "^2.0.1",
    "@types/zen-observable": "^0.8.0",
    "angular-svg-round-progressbar": "^2.0.0",
    "apollo-angular": "1.0.0",
    "apollo-angular-link-http": "1.0.1",
    "apollo-cache-inmemory": "^1.2.5",
    "apollo-client": "2.0.0",
    "apollo-link": "1.0.0",
    "apollo-link-context": "^1.0.9",
    "apollo-link-dedup": "^1.0.9",
    "apollo-link-state": "^0.4.1",
    "cordova-android": "7.0.0",
    "cordova-browser": "5.0.3",
    "cordova-plugin-android-permissions": "^1.0.0",
    "cordova-plugin-camera": "^4.0.3",
    "cordova-plugin-device": "^2.0.2",
    "cordova-plugin-fcm-with-dependecy-updated": "^2.2.4",
    "cordova-plugin-file": "^6.0.1",
    "cordova-plugin-file-transfer": "^1.7.1",
    "cordova-plugin-geolocation": "^4.0.1",
    "cordova-plugin-globalization": "^1.11.0",
    "cordova-plugin-ionic-keyboard": "^2.1.2",
    "cordova-plugin-ionic-webview": "^1.2.1",
    "cordova-plugin-splashscreen": "^5.0.2",
    "cordova-plugin-whitelist": "^1.3.3",
    "cordova-sqlite-storage": "^2.3.2",
    "graphql": "^0.13.2",
    "graphql-tag": "^2.9.2",
    "hammerjs": "^2.0.8",
    "ionic-angular": "3.8.0",
    "ionic-img-viewer": "^2.9.0",
    "ionic-plugin-deeplinks": "~1.0.17",
    "ionicons": "3.0.0",
    "jwt-decode": "^2.2.0",
    "rxjs": "5.5.2",
    "sw-toolbox": "3.6.0",
    "zen-observable": "^0.8.8",
    "zone.js": "^0.8.20"
  },
  "devDependencies": {
    "@ionic/app-scripts": "3.1.8",
    "@types/googlemaps": "^3.30.11",
    "@types/jasmine": "^2.8.6",
    "@types/node": "^9.4.6",
    "angular2-template-loader": "^0.6.2",
    "awesome-typescript-loader": "^3.5.0",
    "html-loader": "^0.5.5",
    "ionic": "^4.0.1",
    "ionic-mocks": "^1.3.0",
    "istanbul-instrumenter-loader": "^3.0.0",
    "jasmine": "^2.9.0",
    "jasmine-spec-reporter": "^4.2.1",
    "karma": "^1.5.0",
    "karma-chrome-launcher": "^2.2.0",
    "karma-coverage-istanbul-reporter": "^1.4.1",
    "karma-jasmine": "^1.1.1",
    "karma-jasmine-html-reporter": "^0.2.2",
    "karma-sourcemap-loader": "^0.3.7",
    "karma-webpack": "^2.0.9",
    "null-loader": "^0.1.1",
    "prettier": "^1.14.2",
    "protractor": "^5.3.0",
    "stylelint": "^9.1.3",
    "stylelint-config-standard": "^18.2.0",
    "ts-loader": "^3.5.0",
    "ts-node": "^5.0.0",
    "tslint-ionic-rules": "0.0.14",
    "typescript": "2.4.2",
    "webpack": "^3.0.0",
    "webpack-dev-server": "^2.0.0"
  }