1

我有一个聚合物项目,我正在使用(部分)结构

app/
app/elements/my-element/my-element.html
bower_components/

在编写 my-element.html 时,我希望它的 html 导入引用表单的 url ../polymer/polymer.html。这意味着我需要将 app/elements 和 bower_components 都映射到同一个 url(如果它们存在,则优先转到 app/elements,否则它应该回退到在 bower_components 目录中查找它们。

我试图设置我的wct-conf.js文件这样做。在玩了很多调试器之后,我到了这一点,我认为可以做到这一点,

var ret = {
  'suites': ['app/elements/**/test'],
  'plugins': ['local'],
  'webserver': {

    'pathMappings': [
      {'/components/<basename>/components': 'app/elements'},
      {'/components/<basename>/components': 'bower_components'},
      {'/components/<basename>/api': 'server/mock/fake.js'},
      {'/components/<basename>':'app'}
    ]
  }
};

module.exports = ret;

但是,一旦我运行 gulp test:local 来运行它们,我就会收到大量报告 404 的奇怪 url。他们是这样的

404 GET /components/pasv5/app/elements/bower_components/webcomponentsjs/webcomponents.min.js
404 GET /components/pasv5/app/elements/bower_components/test-fixture/test-fixture-mocha.js
404 GET /components/pasv5/app/elements/bower_components/test-fixture/test-fixture-mocha.js

它设法以某种奇怪的方式app/elements合并bower_components

我做错了什么,我该怎么做?

4

1 回答 1

1

我现在找到了答案。有两种可能的方法,但首先让我解释一下我对 pathMappings 的发现。

首先,虽然它们是从 url 到文件偏移量的映射数组,但它不是一个简单的数组。每个数组元素实际上是一个我有许多键的对象,每个键是一个可能的 url 前缀,并且该键的每个值都是一个路径,相对于该键所代表的项目根目录。Web 组件测试器使用一个名为的节点模块serve-waterfall,它实际上定义了自己的一些条目,具体来说:-

  WEB_COMPONENT: [
    {'/components/<basename>': '.'},
    {'/components': 'bower_components'},
    {'/components': '..'},
    {'/': '.'},
  ],

在配置阶段,您通过 wct-conf.js 中的模块导出提供的任何数组(您可以在主目录或项目根目录或两者中找到此文件)与上述列表合并,其中对象位于同一数组中使用您提供的键扩充索引。

最后,Web Component Tester 添加了自己的路径:-

{'/components': path.join(WCT_ROOT, 'bower_components')},

其中 WCT_ROOT 是 WCT 在您的 node_modules 目录中的位置,尽管它在最后被推送到数组中。这确保了 mocha、chai 和 sinon 可用于测试。

一旦构建了 pathMappings,它们就会被展平为一个“瀑布”数组,因此数组的每个索引中的每个键都成为一个具有两个键的对象,prefix并且target这个瀑布数组很重要,因为它是有序的。因此,如何将各种路径映射源合并在一起也很重要,这可能比判断更幸运。

Web 组件测试启动 Express Web 服务器,服务器根位于项目根目录。

当 web 服务器正在运行时,并且当存在 web-component-tester 单独负责的 url(例如 web runner 组件)时,这由 app.get() 调用提供服务。如果它没有被它捕获,那么 serve-waterfall 组件将作为中间件使用 app.use() 启动。以一种相当复杂的方式,这一步通过“瀑布”数组尝试每个匹配的前缀,并根据 Express 服务器根目录和您尝试检索的目标文件组成一个url 。如果此尝试生成“404”错误,它会捕获它,并尝试下一个匹配的瀑布数组条目。

好的,背景介绍了这么多,现在是解决方案。 如果你想做一些复杂的事情,你可以registerHook在 wct-conf.js 文件中定义一个函数,并在其中完全重新定义 pathMappings。

类似于以下内容:-

var ret = {
  'suites': ['app/elements/**/test'],
  'plugins': ['local'],
  'registerHooks' : function(context) {
    var existingMapping = context.options.webserver.pathMappings;
    var pathMappings = [
      {'/components/<basename>/bower_components': 'app/elements'},
      {'/components/<basename>/app/elements': 'bower_components'},
    ]
    pathMappings = pathMappings.concat(existingMapping);
    context.options.webserver.pathMappings = pathMappings;
  }

};

module.exports = ret;

但是对于我上面提出的问题,以下内容也可以完成这项工作......

var ret = {
  'suites': ['app/elements/**/test'],
  'plugins': ['local'],
  'webserver': {
    'pathMappings': [
      {'/components/<basename>/bower_components': 'app/elements'},
      {'/components/<basename>/app/elements': 'bower_components'},
    ]

  }
};

module.exports = ret;

这里简要解释一下它的作用。该suites参数定义了查找测试的文件列表,并请求了对 url /components/<basename>/app/elements/xxx/test/xxx-test.html(或类似)的请求。这从瀑布数组的第一个元素成功。

毫无疑问,测试工具会尝试导入../xxx.html,这会变成请求/component/<basename>/app/elements/xxx.html并再次从数组的第一个元素成功。

接下来被测元素将尝试和 html 导入..\polymer\polymer.html

wct 再次将其转换为对 的请求/components/<basename>/app/elements/polymer/polymer.html,但这失败了,因此检查了瀑布数组中的下一项。唯一匹配的是带有前缀的/components/<basename>/app/elements,并且变成了/components/<basename>/bower_components/polymer/polymer.html. 它有效。

使用我提供的配置,您还可以映射另一种方式,瀑布数组中的第一项将失败,/components/<basename>/bower_components/xxx/xxx.html之后唯一匹配的前缀就是那个/components/<basename>/app/elements。我实际上看不出需要这个。

于 2015-12-05T17:54:54.017 回答