最近,我开始了从一个习惯的吞咽脚本,过去负责各种事情,webpack。我让它的工作到了一个点,在浏览器中转换、捆绑和服务客户端应用程序是非常有效的。
现在,当我使用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,它基本上是应用程序的入口点:
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("YYyy22!@"));
expectValidPassword(_AccountService.validatePassword("Ma#38Hr$"));
expectValidPassword(_AccountService.validatePassword("aA1\"#$%(#/$\"#$/(=/#$=!\")(\")("));
})
});
});
});这是运行karma start的输出
> npm test
> myapp@1.0.0 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 typescript@2.4.2 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
forEach@node_modules/angular/angular.js:410:24
loadModules@node_modules/angular/angular.js:4917:12
createInjector@node_modules/angular/angular.js:4839:30
WorkFn@node_modules/angular-mocks/angular-mocks.js:3172:60
loaded@http://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
loaded@http://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
forEach@node_modules/angular/angular.js:410:24
loadModules@node_modules/angular/angular.js:4917:12
createInjector@node_modules/angular/angular.js:4839:30
WorkFn@node_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编辑:
通过替换以下命令,我成功地运行了测试:
"dist/app.js"在因果报应中
"src/boot.ts"但这不会向下钻,也不会加载/导入应用程序的其余部分。然后,我尝试只将我想要测试的类导入到规范中,但之后我无法模拟我正在测试的类所使用的任何注入DI的服务。无论如何,在这个阶段,我几乎放弃了这一点,不再想办法解决这个问题,搬到ang2+。
发布于 2017-11-14 10:57:34
在将我的AngularJS项目建设从Grunt转移到Webpack的过程中,我遇到了一个类似的问题,我尝试了两种不同的方法。
1. Webpack和Karma作为两个独立的过程。I制作了一个并行运行webpack和karma的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-build“脚本),他观看了./src文件夹,并将发行版编译到./temp文件夹中。当他更新./temp时,Karma开始重新运行测试。
尽管第一次因果报应失败了,它还是起了作用。在Webpack第一次编译完成之前,Karma就开始了测试。这不是关键。同时,使用restartOnFileChange设置可以帮助.也许还有另一个好的解决办法。我没有写完这个故事,我转向了选项2,我认为它比刚才描述的更适合Webpack。
2. Karma是唯一使用Webpack的进程,i拒绝了./temp文件夹,并决定对于开发模式,所有操作都应该在内存中。发展模式Webpack得到以下设置(.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发展模式Karma (./test/karma.Development.conjs):
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这还需要安装两个npm包:karma-webpack和karma-sourcemap-loader。第一个选项在Grunt/gulp之后看起来比较熟悉,但这个选项更简单、更短、更稳定。
https://stackoverflow.com/questions/47045159
复制相似问题