试图了解pathMappings

时间:2015-12-04 23:35:43

标签: web-component-tester

我有一个Polymer项目,我正在研究

的(部分)结构
app/
app/elements/my-element/my-element.html
bower_components/

编写my-element.html编码时,我希望其html导入引用../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:本地运行它们我会收到大量报告404的奇怪网址。他们是这样的

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/elementsbower_components

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

1 个答案:

答案 0 :(得分: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,它们就会被压平成一个瀑布&#34;数组,因此数组的每个索引中的每个键都变成一个具有两个键prefixtarget的对象,并且这个瀑布数组很重要,因为它是有序的。因此,各种pathMappings源合并在一起也很重要,这可能比判断更幸运。

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

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

好的,非常适合背景,现在是解决方案。 如果你想做一些复杂的事情,你可以在wct-conf.js文件中定义一个registerHook函数,然后在其中完全重新定义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。我实际上看不到这个是必需的。