Использование html -loader с angularJS (v1) шаблонами и Jest не работает - PullRequest
2 голосов
/ 01 апреля 2020

У меня есть приложение AngularJS (v.1.7), обслуживаемое Rails. Я только что перешел из Sprockets в Webpack. При попытке перенести мои тесты Жасмин на 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)

Я следовал рекомендациям в этом сообщении SO и этом npm пакете html -loader-jest . В моем package.json я добавил следующее jest config

  "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? Есть ли способ получить шутку, чтобы обеспечить эту ценность? Или это не тот способ, которым htmlLoader должен вызываться вне реального конвейера Webpack.

Эта проблема возникает, только когда я запускаю через 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();
  })
});

1 Ответ

0 голосов
/ 03 апреля 2020

Ну, я понял это. Кажется, что когда 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.

Надеюсь, это спасет кого-то еще от копания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...