将 html-loader 与 angularJS (v1) 模板和 Jest 一起使用失败
Using html-loader with angularJS (v1) templates and Jest is failing
我有一个由 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 and from 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 提供这种价值?或者这不是应该在实际 Webpack 管道之外调用 htmlLoader
的方式。
只有当我通过 jest
运行 时才会出现此问题。 webpack
正确编译应用程序的所有资产。
库版本
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};`
}
};
这基本上是 returns 模板作为导出模板的 js 模块。 replace
似乎在处理换行符。
我希望这可以为其他人节省一些挖掘工作。
我有一个由 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 and from 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 提供这种价值?或者这不是应该在实际 Webpack 管道之外调用 htmlLoader
的方式。
只有当我通过 jest
运行 时才会出现此问题。 webpack
正确编译应用程序的所有资产。
库版本
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};`
}
};
这基本上是 returns 模板作为导出模板的 js 模块。 replace
似乎在处理换行符。
我希望这可以为其他人节省一些挖掘工作。