我有一个由 Rails 提供的 AngularJS (v.1.7) 应用程序。我刚刚从 Sprockets 转移到了 Webpack。
在尝试将我的 Jasmine 测试迁移到 Jest 时。我遇到了 html-loader
的问题我用它来将我的指令模板导入到指令中。
对于我导入模板的一个简单指令,Jest 无法加载测试,因为 html-loader
因错误而失败
TypeError: Cannot read property 'query' of undefined
1 | const htmlLoader = require("html-loader");
2 | module.exports = {
> 3 | process: (src) => htmlLoader(src)
| ^
4 | };
5 |
at getOptions (node_modules/html-loader/node_modules/loader-utils/lib/getOptions.js:6:31)
我正在遵循建议 in this SO post来自 this npm package html-loader-jest .在我的
package.json
, 我添加了以下 jest
配置 "jest": {
"moduleFileExtensions": [
"js",
"html"
],
"transform": {
"^.+\\.js$": "babel-jest",
"^.+\\.html$": "<rootDir>/jest/support/html_loader.js"
},
...
}
和支持文件
// jest/support/html_loader.js
const htmlLoader = require("html-loader");
module.exports = {
process: (src) => htmlLoader(src)
};
堆栈跟踪将我指向
html-loader
(来自 node_modules)// node_modules/html-loader/node_modules/loader-utils/lib/getOptions.js
function getOptions(loaderContext) {
const query = loaderContext.query;
...
如果我在 Jest 运行期间追踪到这里,我会发现这个
loaderContext
未定义(如错误报告)。我的问题是......这是使用它的正确方法
htmlLoader
?如果是这样,我应该期待什么loaderContext
成为?有没有办法让开 Jest 来提供这种值(value)?或者这不是方式htmlLoader
应该在实际的 Webpack 管道之外调用。这个问题只发生在我通过
jest
运行时. webpack
正确编译应用程序的所有 Assets 。库版本
html-loader: 1.0.0
webpack: 4.42.1
jest: 25.2.4
代码(为了清晰起见)
// mailer.js
import angular from "angular";
import ngInject from "@js/ng-inject";
import template from "./index.html";
const mailer = ngInject(function () {
return {
restrict: "E",
scope: {
text: "@",
},
template: template,
};
});
angular.module("app-directives").directive("mailer", mailer);
<!-- index.html -->
<a>{{text}}</a>
// mailer.test.js
import expect from "expect";
import "./mailer";
describe("app-directives.mailer", function () {
it("works", () => {
expect(true).toBeTruthy();
})
});
最佳答案
嗯,我想通了。似乎当jest
运行,它没有传递正确的上下文(正如我在上面怀疑的那样)导致 getOptions
调用失败。
解决方案是为 jest
编写一个非常简单的加载器。不打扰 getOptions
.我能够更换我的 jest/support/html_loader.js
代码如下(基本上来自 webpack-contrib/raw-loader
。
// jest/support/html-loader.js
module.exports = {
process: (content, _path) => {
// escape newlines
const json = JSON.stringify(content)
.replace(/\u2028/g, '\\u2028')
.replace(/\u2029/g, '\\u2029');
return `module.exports = ${json};`
}
};
这基本上将模板返回为导出模板的 js 模块。
replace
.我希望这可以为其他人节省一些挖掘工作。
关于angularjs - 使用带有 angularJS (v1) 模板的 html-loader 和 Jest 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60962499/