2017-10-31 1 views
5

最近、私はwebpackにあらゆる種類のものを世話するために使用されていたカスタムスクリプトからスクリプトを開始しました。私は、ブラウザでクライアントアプリケーションをバンドリングして提供することは、とても便利です。karma-webpackがロードされていませんAngularJS bundle

今、gulpを使用してバンドルされたapp.jsファイルに対してカルマテストを実行すると、gulpスクリプトはまずapp.jsファイルをバンドルし、distフォルダに吐き出します。このファイルはカルマがテストを実行するために使用します。私のgulpテストタスクはまた、テストファイルの変更やバンドルファイルの変更を監視し、それに基づいてテストを再実行します。

webpackでは、このdist/app.jsがディスクに書き込まれるのではなく、メモリ内に存在することを理解しています(少なくとも設定方法は同じです)。その問題は、私のバンドルされたアプリ(webpack-dev-server --openでうまく配信されている)が何らかの理由でカルマによって読み込まれず、パズルの欠けている部分が何であるか把握できないようだということです。

これは、(私が問題に関連する可能性があり、単に最も基本的なものを左)のように、私のフォルダ構造がどのように見えるかです:

package.json 
webpack.config.js 
karma.conf.js 
src/ 
--app/ 
----[other files/subfolders] 
----app.ts 
----index.ts 
--boot.ts 
--index.html 
tests/ 
--common/ 
----services/ 
------account.service.spec.js 

これは私のwebpack.config.js

var path = require("path"); 

const webpack = require("webpack"); 

const HtmlWebpackPlugin = require("html-webpack-plugin"); 
const CleanWebpackPlugin = require("clean-webpack-plugin"); 
const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin"); 

module.exports = { 
    context: path.join(__dirname), 
    entry: "./src/boot.ts", 
    plugins: [ 
    new webpack.HotModuleReplacementPlugin(), 
    new ForkTsCheckerWebpackPlugin(), 
    new CleanWebpackPlugin(["dist"]), 
    new HtmlWebpackPlugin({ 
     template: "./src/index.html" 
    }) 
    ], 
    module: { 
    rules: [ 
     { 
     test: /\.scss$/, 
     use: [{ 
      loader: "style-loader" 
     }, { 
      loader: "css-loader" 
     }, { 
      loader: "sass-loader" 
     }] 
     }, 
     { 
     test: /\.tsx?$/, 
     use: [{ 
      loader: "ts-loader", 
      options: { 
      transpileOnly: true, 
      exclude: /node_modules/ 
      } 
     }] 
     }, 
     { 
     test: /\.html$/, 
     loaders: "html-loader", 
     options: { 
      attrs: [":data-src"], 
      minimize: true 
     } 
     } 
    ] 
    }, 
    resolve: { 
    extensions: [".tsx", ".ts", ".js"], 
    alias: { 
     "common": path.resolve(__dirname, "src/app/common"), 
     "common/*": path.resolve(__dirname, "src/app/common/*"), 
     "modules": path.resolve(__dirname, "src/app/modules"), 
     "modules/*": path.resolve(__dirname, "src/app/modules/*"), 
    } 
    }, 
    output: { 
    filename: "app.js", 
    path: path.resolve(__dirname, "dist") 
    }, 
    devtool: "inline-source-map", 
    devServer: { 
    historyApiFallback: true, 
    hot: false, 
    contentBase: path.resolve(__dirname, "dist") 
    } 
}; 
です

これは私のkarma.conf.js

const webpackConfig = require("./webpack.config"); 

module.exports = function (config) { 
    config.set({ 
    frameworks: ["jasmine"], 

    files: [ 
     "node_modules/angular/angular.js", 
     "node_modules/angular-mocks/angular-mocks.js", 
     "dist/app.js", // not sure about this 
     "tests/common/*.spec.js", 
     "tests/common/**/*.spec.js" 
    ], 

    preprocessors: { 
     "dist/app.js": ["webpack", "sourcemap"], // not sure about this either 
     "tests/common/*.spec.js": ["webpack", "sourcemap"], 
     "tests/common/**/*.spec.js": ["webpack", "sourcemap"] 
    }, 

    webpack: webpackConfig, 

    webpackMiddleware: { 
     noInfo: true, 
     stats: { 
     chunks: false 
     } 
    }, 

    reporters: ["progress", "coverage"], // , "teamcity"], 

    coverageReporter: { 
     dir: "coverage", 
     reporters: [ 
     { type: "html", subdir: "html" }, 
     { type: "text-summary" } 
     ] 
    }, 

    port: 9876, 
    colors: true, 
    logLevel: config.LOG_INFO, 
    autoWatch: true, 
    browsers: [ 
     "PhantomJS" 
     //"Chrome" 
    ], 
    singleRun: false, 
    concurrency: Infinity, 
    browserNoActivityTimeout: 100000 
    }); 
}; 

これは、基本的にはトンへのエントリポイントであるboot.tsです彼はAPP:

import * as app from "./app/app"; 
import "./styles/app.scss"; 

// This never gets written to the console 
// so I know it never gets loaded by karma 
console.log("I NEVER OUTPUT TO CONSOLE"); 

これは、その後、その下に何かを参照しapp.ts(です:

import * as ng from "angular"; 
import * as _ from "lodash"; 

import "@uirouter/angularjs"; 
import "angular-cookies"; 
import "angular-material" 
import "angular-local-storage"; 
import "angular-sanitize"; 
import "angular-messages"; 
import "angular-file-saver"; 
import "angular-loading-bar"; 
import "satellizer"; 

export * from "./index"; 

import * as Module from "common/module"; 
import * as AuthModule from "modules/auth/module"; 
import * as UserModule from "modules/user/module"; 

import { MyAppConfig } from "./app.config"; 
import { MyAppRun } from "./app.run"; 

export default ng.module("MyApp", [ 
    "ngCookies", 
    "ngSanitize", 
    "ngMessages", 
    "ngFileSaver", 
    "LocalStorageModule", 
    "ui.router", 
    "ngMaterial", 
    "satellizer", 
    "angular-loading-bar", 
    Module.name, 
    AuthModule.name, 
    UserModule.name 
]) 
.config(MyAppConfig) 
.run(MyAppRun); 

そして最後に、これはaccount.service.spec.js

describe("Account service", function() { 
    // SETUP 

    var _AccountService; 

    beforeEach(angular.mock.module("MyApp.Common")); 
    beforeEach(angular.mock.inject(function (_AccountService_) { 
    // CODE NEVER GETS IN HERE EITHER 
    console.log("I NEVER OUTPUT TO CONSOLE"); 
    _AccountService = _AccountService_; 
    })); 

    function expectValidPassword(result) { 
    expect(result).toEqual({ 
     minCharacters: true, 
     lowercase: true, 
     uppercase: true, 
     digits: true, 
     isValid: true 
    }); 
    } 

    // TESTS 

    describe(".validatePassword()", function() { 
    describe("on valid password", function() { 
     it("returns valid true state", function() { 
     expectValidPassword(_AccountService.validatePassword("asdfASDF123")); 
     expectValidPassword(_AccountService.validatePassword("as#dfAS!DF123%")); 
     expectValidPassword(_AccountService.validatePassword("aA1234%$2")); 
     expectValidPassword(_AccountService.validatePassword("[email protected]")); 
     expectValidPassword(_AccountService.validatePassword("Ma#38Hr$")); 
     expectValidPassword(_AccountService.validatePassword("aA1\"#$%(#/$\"#$/(=/#$=!\")(\")(")); 
     }) 
    }); 
    }); 
}); 
です

これは、実行の出力ですkarma start

> npm test 

> [email protected] test E:\projects\Whatever 
> karma start 

clean-webpack-plugin: E:\projects\Whatever\dist has been removed. 
Starting type checking service... 
Using 1 worker with 2048MB memory limit 
31 10 2017 21:47:23.372:WARN [watcher]: Pattern "E:/projects/Whatever/dist/app.js" does not match any file. 
31 10 2017 21:47:23.376:WARN [watcher]: Pattern "E:/projects/Whatever/tests/common/*.spec.js" does not match any file. 
ts-loader: Using [email protected] and E:\projects\Whatever\tsconfig.json 
No type errors found 
Version: typescript 2.4.2 
Time: 2468ms 
31 10 2017 21:47:31.991:WARN [karma]: No captured browser, open http://localhost:9876/ 
31 10 2017 21:47:32.004:INFO [karma]: Karma v1.7.1 server started at http://0.0.0.0:9876/ 
31 10 2017 21:47:32.004:INFO [launcher]: Launching browser PhantomJS with unlimited concurrency 
31 10 2017 21:47:32.010:INFO [launcher]: Starting browser PhantomJS 
31 10 2017 21:47:35.142:INFO [PhantomJS 2.1.1 (Windows 8 0.0.0)]: Connected on socket PT-pno0eF3hlcdNEAAAA with id 71358105 
PhantomJS 2.1.1 (Windows 8 0.0.0) Account service .validatePassword() on valid password returns valid true state FAILED 
     [email protected]ode_modules/angular/angular.js:410:24 
     [email protected]_modules/angular/angular.js:4917:12 
     [email protected]_modules/angular/angular.js:4839:30 
     [email protected]_modules/angular-mocks/angular-mocks.js:3172:60 
     [email protected]://localhost:9876/context.js:162:17 
     node_modules/angular/angular.js:4958:53 
     TypeError: undefined is not an object (evaluating '_AccountService.validatePassword') in tests/common/services/account.service.spec.js (line 742) 
     webpack:///tests/common/services/account.service.spec.js:27:0 <- tests/common/services/account.service.spec.js:742:44 
     [email protected]://localhost:9876/context.js:162:17 
PhantomJS 2.1.1 (Windows 8 0.0.0) Account service .validatePassword() on valid amount of characters returns minCharacters true FAILED 
     [email protected]_modules/angular/angular.js:410:24 
     [email protected]_modules/angular/angular.js:4917:12 
     [email protected]_modules/angular/angular.js:4839:30 
     [email protected]_modules/angular-mocks/angular-mocks.js:3172:60 
     node_modules/angular/angular.js:4958:53 
     TypeError: undefined is not an object (evaluating '_AccountService.validatePassword') in tests/common/services/account.service.spec.js (line 753) 
     webpack:///tests/common/services/account.service.spec.js:38:0 <- tests/common/services/account.service.spec.js:753:37 
PhantomJS 2.1.1 (Windows 8 0.0.0): Executed 2 of 2 (2 FAILED) ERROR (0.017 secs/0.015 secs) 

私がconsole.logsを出た場所はほとんどありません。それは私がアプリが読み込まれないことを知っている方法です。それとジャスミンは私がテストしたいサービスを注入できないという事実。

私が使用しています:

karma v1.7.1 
karma-webpack v2.0.5 
webpack v3.3.0 

任意のアイデア?私は間違って何をしていますか?私の印象は、私のwebpack.config.jsがAngularJS/TSアプリをバンドルして、それを本質的にカルマにフィードすることになっているという印象を受けていますが、何らかの理由でそれはうまくいかないようです。あるいは、私はこれがどのように機能するのかという基本的な誤解をいくつか持っていますか?

ありがとうございます。

シンプルなアプリケーションにいくつかのファイルを抽出し、それをgithubに入れて、問題を簡単に再現できるようにしました。

npm install # install deps 
npm run serve:dev # run the app - works 
npm run test # run karma tests - doesn't work 

編集:

"src/boot.ts" 

それwouldn」でカルマのセットアップに

"dist/app.js" 

は私が交換することによって実行テストを行うために管理しましたドリルダウンまたはロード/ i残りのアプリをmportします。テストしたいクラスだけを仕様にインポートしようとしましたが、テストしているクラスが使用しているDI注入サービスを模擬することができませんでした。とにかく、私はこの段階でこれをあきらめて、これをどうやって行うかを考えずに、ang2 +に移動しました。

+0

私はあなたのアプリケーションと実行中のコマンド 'npm run serve:dev'をクローンしてみましたが、あなたはコンソールでエラーを受け取りました。あなたのアプリの基本的なHTMLであるため、' App renders fine'が表示されます。 'ts-loaderが予期しないローダーオプションで提供されました。 'というエラーが表示されます。 – varit05

+0

@ varit05 - 申し訳ありませんが、私はそれをreproできません。 :/私はこれまで何もセットアップしていない別のコンピュータで試してみたところ、アプリケーションは最初の試行で正常に起動しました(devtoolsのコンソールで期待通りの出力が得られましたか? 。 – pootzko

+1

これはすべて間違っているか、少なくともkarma + webpack + angularとは異なるものです。まず、テストを実行するために 'npm run test'以外のものは必要ありません。あなたは、カルマの設定ではなく、テストファイルにあなたのapp.ts/jsを含める必要があります。あなたは角度+カルマ+ウェブパックのWeb設定で利用可能なものを試しましたか? –

答えて

1

私はAnguntJSプロジェクトの建物をグランツからウェブパックに移しているときに同様の問題に直面し、2つの異なるアプローチを試みました。

1.ウェブパックとカルマは2つの別個のプロセスとして。webpackkarmaを同時に実行するnpmスクリプトを作成しました。それは

"dev-build": "webpack --config webpack/development.js", 
"dev-test": "karma start test/karma.development.conf.js", 
"test": "concurrently --kill-others --raw \"npm run dev-build\" \"npm run dev-test\"" 

代わりのconcurrentlyあなたが何かを行うことができ、npm-run-allあるいは&のように見えました。その構成では、KarmaにはWebpackのものはありませんでした。彼女はビルドされたディストリビューションの./tempフォルダを監視し、テストやディストリビューションが変更されるたびに自分自身を再実行しました。 Webpackはdev-mode( "dev-build"スクリプト経由)で起動し、./srcフォルダを見て、./tempフォルダにコンパイルされたディストリビューションを見ました。彼が./tempを更新したとき、Karmaは再テストを開始しました。

最初のカルマの問題にもかかわらず、それはうまくいった。 KarmaはWebpackの最初のコンパイルが完了する前にテストを開始しました。それは重要ではない。また、restartOnFileChangeの設定で遊んでも助けになるかもしれません。別の良い回避策があるかもしれません。私はこの話を終えていませんでした。私はオプション2に切り替えました。これは、Webpackのやり方にちょうどちょっと説明されたものよりも適していると思います。

2. KarmaはWebpackを使用する唯一のプロセスです。私は./tempフォルダを拒否し、dev-modeではすべての操作がメモリ内であることに決めました。

entry: { 'ui-scroll': path.resolve(__dirname, '../src/ui-scroll.js') }, 
output: { filename: '[name].js' }, // + path to ./dist in prod 
devtool: 'inline-source-map', // 'source-map' in prod 
compressing: false, 
watch: true 

のDevモードカルマ(./test/karma.development.conf.js):

files: [ 
    // external libs 
    // tests specs 
    '../src/ui-scroll.js' // ../dist in prod 
], 
preprocessors: { // no preprocessors in prod 
    '../src/ui-scroll.js': ['webpack', 'sourcemap'] 
}, 
webpack: require('../webpack/development.js'), // no webpack in prod 
autoWatch: true, 
keepalive: true, 
singleRun: false 

デベロッパーモードのWebPACKは設定(./webpack/development.js)を以下ましたまた、インストールするには2つのnpmパッケージが必要です:karma-webpackkarma-sourcemap-loader。最初のオプションは、Grunt/gulpの後でもっとよく似ていますが、これは単純で短く安定しています。

+0

お返事ありがとうございます。残念ながら、来週まで試してみることはできませんが、試してみることにします。乾杯! – pootzko

関連する問題