2017-10-31 22 views
5

Gần đây tôi đã bắt đầu di chuyển từ tập lệnh gulp tùy chỉnh được sử dụng để quản lý tất cả các loại nội dung cho webpack. Tôi có nó làm việc đến một điểm mà transpiling, bundling và phục vụ các ứng dụng khách hàng trong trình duyệt hoạt động tuyệt vời.karma-webpack không tải gói AngularJS

Bây giờ, khi tôi dùng gulp để chạy thử nghiệm nghiệp của mình dựa vào tệp app.js đi kèm, tập lệnh gulp trước tiên sẽ gộp tệp app.js và sau đó nhổ nó vào thư mục dist. Tập tin này sau đó sẽ được sử dụng bởi nghiệp để chạy các bài kiểm tra chống lại nó. Nhiệm vụ kiểm tra gulp của tôi cũng sẽ xem xét bất kỳ thay đổi tệp thử nghiệm nào hoặc cho thay đổi tệp bó và chạy lại các thử nghiệm dựa trên đó.

Với webpack, tôi hiểu dist/app.js này nằm trong bộ nhớ, thay vì được ghi vào đĩa (ít nhất đó là cách tôi thiết lập nó). Vấn đề với điều đó là dường như ứng dụng đi kèm của tôi (được phục vụ tốt với webpack-dev-server --open) không được tải bởi nghiệp vì một lý do nào đó và tôi không thể tìm ra phần còn thiếu của câu đố là gì.

Đây là cách cấu trúc thư mục của tôi trông như thế (tôi rời chỉ những thứ cơ bản nhất mà có thể có liên quan đến vấn đề này):

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 

Đây là webpack.config.js tôi

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") 
    } 
}; 

Đây là karma.conf.js tôi

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 
    }); 
}; 

Đây là boot.ts mà về cơ bản là điểm mấu chốt để t ông 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"); 

Đây là app.ts (mà sau đó tham chiếu bất cứ điều gì dưới nó:

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); 

Và cuối cùng, đây là 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\"#$%(#/$\"#$/(=/#$=!\")(\")(")); 
     }) 
    }); 
    }); 
}); 

Và đây là đầu ra của việc chạy 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]_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) 

Xin lưu ý một số nơi mà tôi để lại console.logs mà không bao giờ được kích hoạt. Đó là cách tôi biết ứng dụng không được tải. Điều đó và thực tế là hoa nhài không thể tiêm dịch vụ mà tôi muốn thử nghiệm.

Tôi đang sử dụng:

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

Bất kỳ ý tưởng? Tôi đang làm gì sai? Tôi đang theo ấn tượng rằng webpack.config.js của tôi là nghĩa vụ phải gói ứng dụng AngularJS/TS của tôi và sau đó về cơ bản ăn nó để nghiệp, nhưng vì lý do gì, điều đó dường như không hoạt động. Hay tôi có một số quan niệm sai lầm cơ bản về cách thức hoạt động của nó?

Cảm ơn bạn.

Tôi đã trích xuất một vài tệp vào một ứng dụng đơn giản và đặt nó vào github để sự cố có thể được sao chép dễ dàng.

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

Edit:

tôi quản lý để thực hiện các bài kiểm tra chạy bằng cách thay thế:

"dist/app.js" 

trong thiết lập nghiệp với

"src/boot.ts" 

nhưng điều đó wouldn' t đi sâu hoặc tải/i mport phần còn lại của ứng dụng. Sau đó, tôi đã thử chỉ nhập lớp mà tôi muốn kiểm tra thông số kỹ thuật nhưng sau đó tôi không thể thử bất kỳ dịch vụ DI-tiêm nào mà lớp tôi đang thử đang sử dụng. Dù sao, tôi khá nhiều đã từ bỏ điều này ở giai đoạn này và ngừng cố gắng tìm ra cách để làm điều này, chuyển sang ang2 +.

+0

Tôi đã thử nhân bản ứng dụng của bạn và lệnh đang chạy 'npm run serve: dev' bạn gặp lỗi trong bảng điều khiển và bạn sẽ thấy' Ứng dụng hiển thị tốt' vì đó là html cơ sở của ứng dụng của bạn. Lỗi 'ts-loader đã được cung cấp với tùy chọn trình tải không mong đợi' đang đến. – varit05

+0

@ varit05 - xin lỗi, tôi không thể repro điều đó. :/Tôi đã thử nó trên một máy tính riêng biệt mà tôi không có bất cứ thứ gì được thiết lập trước đó và ứng dụng bắt đầu bình thường trong lần thử đầu tiên (tôi cũng nhận được kết quả dự kiến ​​trong giao diện điều khiển trong devtools mà tôi cho rằng bạn không nhận được?) . – pootzko

+1

tất cả điều này là sai hoặc ít nhất là hoàn toàn khác với những gì chúng tôi có với karma + webpack + góc cạnh. Để bắt đầu, bạn không cần bất cứ điều gì ngoại trừ 'npm run test' để chạy thử nghiệm. Bạn cần bao gồm app.ts/js của mình trong tệp thử nghiệm, không phải trong cấu hình nghiệp. Vv v.v. Bạn đã thử bất kỳ công cụ nào có sẵn trên các thiết lập web cho webpack + karma + webpack chưa? –

Trả lời

1

Tôi gặp phải sự cố tương tự trong khi chuyển dự án AngularJS của dự án từ Grunt sang Webpack và thử 2 cách tiếp cận khác nhau.

1. Webpack và Karma dưới dạng hai quy trình riêng biệt. Tôi đã tạo một tập lệnh npm chạy webpackkarma song song. Nó trông giống như

"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\"" 

Thay vì concurrently bạn có thể làm bất cứ điều gì khác, hoặc thậm chí npm-run-all&. Trong cấu hình đó Karma không có bất kỳ thứ gì trong Webpack, cô ấy chỉ xem thư mục ./temp để xây dựng và phân phối độc lập, tự chạy lại mỗi lần kiểm tra hoặc phân phối đã bị thay đổi. Webpack đã được bắt đầu trong chế độ dev (thông qua "dev-build" script), ông đã xem thư mục ./src và biên dịch phân phối vào thư mục ./temp. Khi ông cập nhật ./temp, Karma bắt đầu thử nghiệm chạy lại.

Nó hoạt động, bất chấp những vấn đề của Karma đầu tiên thất bại. Karma bắt đầu kiểm tra trước khi biên dịch Webpack đầu tiên đã được hoàn thành. Nó không quan trọng. Ngoài ra, việc chơi với cài đặt restartOnFileChange có thể giúp ... Có thể có một cách giải quyết khác tốt. Tôi đã không hoàn thành câu chuyện này, tôi chuyển sang tùy chọn 2, mà tôi tin rằng phù hợp với Webpack-way nhiều hơn một chút so với mô tả một.

2. Karma là quá trình duy nhất sử dụng Webpack. Tôi từ chối thư mục ./temp và quyết định rằng đối với chế độ dev, tất cả các thao tác phải nằm trong bộ nhớ. Dev-mode Webpack có sau cài đặt (./webpack/development.js):

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-mode Karma (./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 

này cũng yêu cầu cài đặt hai gói npm: karma-webpackkarma-sourcemap-loader. Tùy chọn đầu tiên trông quen thuộc hơn sau Grunt/gulp, nhưng tùy chọn này đơn giản hơn, ngắn hơn và ổn định hơn.

+0

Cảm ơn bạn đã trả lời. Thật không may tôi sẽ không thể thử nó cho đến tuần tới, nhưng tôi sẽ thử nó sau đó và lấy lại cho bạn. Chúc mừng! – pootzko

Các vấn đề liên quan