使用dojo构建系统的wirejs和dojo(2)

使用dojo构建系统的wirejs和dojo(2),dojo,wirejs,cujojs,Dojo,Wirejs,Cujojs,(这是与相同的问题,但有关于问题的更多细节和尝试过的解决方案。创建重复问题是因为这是在评论中提出的) 在构建使用wire的dojo应用程序时,dojo加载程序会为“/lib/context”抛出一个我们无法摆脱的undfinedmodule错误 我使用git子模块将wire添加到一个大型的、可工作的dojo项目中。事实证明,当需要cujojs和cujojsmeld时,也需要cujojs。我也将它们添加为git子模块 在这个项目中,库不是在应用程序文件夹(src/app)的旁边,而是在src/li

(这是与相同的问题,但有关于问题的更多细节和尝试过的解决方案。创建重复问题是因为这是在评论中提出的)

在构建使用wire的dojo应用程序时,dojo加载程序会为“/lib/context”抛出一个我们无法摆脱的
undfinedmodule
错误

我使用git子模块将
wire
添加到一个大型的、可工作的dojo项目中。事实证明,当需要cujojs
和cujojs
meld
时,也需要cujojs
。我也将它们添加为git子模块

在这个项目中,库不是在应用程序文件夹(
src/app
)的旁边,而是在
src/lib
的一个层次上。所以我有
src/lib/wire
src/lib/when
src/lib/meld
,紧挨着
src/lib/dgrid
,等等。
dojo
库有两层深度:
src/lib/dojo/dojo
src/lib/dojo/dojo/dijit
src/lib/dojo/util>

版本:

  • dojo 1.10.4
  • 导线0.10.9
  • 当3.7.2
  • meld 1.3.1
一旦我将以下包定义添加到
dojoConfig
,开发(未构建)中的事情就会起作用:

var dojoConfig = (function() {

  [...]

  return {

    [...]

    packages: [

      [...]

      {name: "wire", location: "../../wire", main: "wire"},
      {name: "when", location: "../../when", main: "when" },
      {name: "meld", location: "../../meld", main: "meld" },

      [...]

    ],

    [...]
  };

})();
请注意,有必要添加
main
条目。例如,这使得在依赖项列表中将
when/when.js
作为
“when”
引用成为可能,而不是cujojs代码内部执行的
“when/when”

所以,这在开发模式下工作

接下来,我试着让构建工作起来

build.profile.js
中,我再次添加了包引用。构建以多种方式失败

首先,对于包,dojo构建器希望
package.json
文件中有一个
dojoBuild
属性,它引用一个
.profile.js
package.js
文件,该文件基本上定义了包的构建配置。 这个构建配置通常(在我们所有的包中)只是一个
resourceTags
对象,其函数定义了包中哪些文件是AMD资源,哪些文件是测试,哪些文件应该按原样复制

cujojs包没有可用于dojo builder的此类构建定义

构建者首先抱怨这些包没有构建配置,其次抱怨资源没有标记为AMD资源(这是构建配置文件的主要原因)

因为我不想更改我使用的外部库的文件,所以我不想将
dojoBuild
属性和构建配置文件添加到cujojs包中,所以我寻求了一种解决方法

在遍历dojo builder代码之后,我发现生成器抱怨
package.json
文件没有
dojoBuild
属性,但最后只查看内部包定义结构以获取
resourceTags
对象。内部包定义结构从主构建概要文件中的包定义开始。因此,我最终在那里支持了一个
resourceTags
对象:

[...]

/*
 wire, when and meld don't have a good build profile set up.
 Here, we doctor a resourceTags (i.e., the core of a build profile). We set it on the package definition.
 This is an unsupported hack. The builder will still complain about there not being a build profile, but
 it will use these definitions when building those packages.

 Note: // see https://github.com/cujojs/when/wiki/Using-with-Dojo does not work!
*/
var generalResourceTags = (function () {

  function isTest(filename, mid) {
    return filename.indexOf("test/") >= 0;
  }

  function isCopyOnly(filename, mid) {
    return filename.indexOf(".html") >= 0;
  }

  function isAmd(filename, mid) {
    return filename.indexOf(".json") < 0 && filename.indexOf(".js") >= 0 && filename.indexOf(".profile.js") < 0;
  }

  function isGivingTroubleButUnused(filename, mid) {
    return /^wire\/jquery\//.test(mid) ||
           mid === "wire/sizzle" ||
           /^when\/build\//.test(mid) ||
           /^when\/es6-shim\//.test(mid) ||
           mid === "when/generator"; // see https://github.com/cujojs/when/issues/429
  }

  return {
    test: function (filename, mid) {
      return isTest(filename, mid);
    },

    copyOnly: function (filename, mid) {
      return isCopyOnly(filename, mid) || isGivingTroubleButUnused(filename, mid);
    },

    amd: function (filename, mid) {
      return !isTest(filename, mid) && !isCopyOnly(filename, mid) && isAmd(filename, mid) && !isGivingTroubleButUnused(filename, mid);
    }
  }
})();

var profile = {
  releaseName: releaseName,
  releaseDir: "../../../../release",
  action: 'release',
  cssOptimize: 'comments',
  mini: true,
  optimize: 'closure',
  layerOptimize: 'closure',
  stripConsole: 'normal',
  selectorEngine: 'acme',
  useSourceMaps: false,

  [...]  

  packages: [

    [...]

    {name: "wire", location: "../../wire", main: "wire", destLocation: "./lib/wire", resourceTags: generalResourceTags},
    {name: "when", location: "../../when", main: "when", destLocation: "./lib/when", resourceTags: generalResourceTags},
    {name: "meld", location: "../../meld", main: "meld", destLocation: "./lib/meld", resourceTags: generalResourceTags},

    [...]

  ],
  layers: {

    [...]

  },
  staticHasFeatures: {
    "config-publishRequireResult": false,
    "dijit-legacy-requires": false,
    "dojo-debug-messages": false,
    "dojo-firebug": false,
    "dojo-log-api": 0,
    "dojo-mobile-parser": false,
    "dojo-moduleUrl": false,
    "dojo-parser": true,
    "dojo-publish-privates": 0,
    "dojo-test-sniff": 0,
    "dojo-trace-api": 0,
    "dom-addeventlistener": true,
    "extend-dojo": true,
    "host-browser": true,
    "mvc-bindings-log-api": false,

    [...]

  }
};
这是为了解析为
wire/lib/context.js
,显然这是在开发(unbuild)模式下工作的

在任何情况下,
require
都是上下文相关的require(参见dojotoolkit.org/documentation/tutorials/1.10/modules\u advanced/,“有条件地要求模块”),因为模块参考是相对的。但这不应该成为它在未构建时工作、在构建时不工作的原因

接下来,我试图复制所有的
wire
when
meld
资源。如果一个层的dojo构建中不包含资源,它只会退回到异步加载。因此,这可能会起作用:

var generalResourceTags = (function () {

  function isTest(filename, mid) {
    return filename.indexOf("test/") >= 0;
  }

  [...]

  return {
    test: function (filename, mid) {
      return isTest(filename, mid);
    },

    copyOnly: function (filename, mid) {
      return !isTest(filename, mid);
    },

    amd: function (filename, mid) {
      return false;
    }
  }
})();
构建现在通过,并复制所需内容。当然,在应用程序代码引用
wire
的地方会出现更多错误,但这是意料之中的(
error(311)缺少依赖项。模块:MY\u模块;依赖项:wire!一些\u包/\u wire-serverRequests

然而,浏览器在相同的位置给出了相同的错误:对于
“/lib/context”
,一个
未定义的模块
错误

此时的工作假设是,
wire
使用的名为
require
的函数在生成版本中不是上下文敏感的require,而是在未生成版本中

事实并非如此。首先,我将
导线
代码或测试更改为读取

createContext = require('wire/lib/context');
使引用成为绝对引用。同样的问题

然后,我尝试使用sourceMaps(
useSourceMaps=true
)进行调试。这是一场噩梦,但我相信我看到使用的
require
是相同的,上下文相关的require

也许“预加载”有效?因此,在顶部的HTML页面中,我用

require(["wire/lib/context"], function() {

  [...]

});
这确保在执行任何其他操作之前加载
上下文。同样的错误

接下来,我在
wire/lib/context

console.error("Defining context");

var when, mixin, loaderAdapter, relativeLoader, Container, specUtils;

when = require('when');
console.error("Loaded when");
mixin = require('./object').mixin;
console.error("Loaded ./object");
loaderAdapter = require('./loader/adapter');
console.error("Loaded ./loader/adapter");
relativeLoader = require('./loader/relative');
console.error("Loaded ./loader/relative");
Container = require('./Container');
console.error("Loaded ./Container");
specUtils = require('./specUtils');

console.error("Defined context. Returning.");
(使用
错误
,因为其他消息在生成中被剥离)

在未构建版本中,我看到了所有消息。在构建版本中,我只看到错误发生之前的“定义上下文”。因此,问题不在于“加载”
wire/lib/context,而在于定义它,可能是在加载或定义

所以,当

console.error("Defining when");

var timed = require('./lib/decorators/timed');
console.error("Loaded lib/decorators/timed");
var array = require('./lib/decorators/array');
console.error("Loaded lib/decorators/array");
var flow = require('./lib/decorators/flow');
console.error("Loaded lib/decorators/flow");
var fold = require('./lib/decorators/fold');
console.error("Loaded lib/decorators/fold");
var inspect = require('./lib/decorators/inspect');
console.error("Loaded lib/decorators/inspect");
var generate = require('./lib/decorators/iterate');
console.error("Loaded lib/decorators/iterate");
var progress = require('./lib/decorators/progress');
console.error("Loaded lib/decorators/progress");
var withThis = require('./lib/decorators/with');
console.error("Loaded lib/decorators/with");
var unhandledRejection = require('./lib/decorators/unhandledRejection');
console.error("Loaded lib/decorators/unhandledRejection");
var TimeoutError = require('./lib/TimeoutError');
console.error("Loaded lib/TimeoutError");
[...]
现在,未构建版本中出现了一个惊喜。输出为:

Defining when
Loaded lib/decorators/timed
Loaded lib/decorators/array
Loaded lib/decorators/flow
Loaded lib/decorators/fold
Loaded lib/decorators/inspect
Loaded lib/decorators/iterate
Loaded lib/decorators/progress
Loaded lib/decorators/with
Loaded lib/decorators/unhandledRejection
Loaded lib/TimeoutError
Loaded lib/Promise
Loaded lib/apply
Defined when
Defining context
Loaded when
Loaded ./object
Loaded ./loader/adapter
Loaded ./loader/relative
Loaded ./Container
Defined context. Returning.
这意味着
定义在
上下文
定义之前开始时。这很奇怪,因为我看不到任何代码可以告诉加载程序在
上下文中需要
时,在行之前

when = require('when');
在“定义上下文”的日志记录之后执行

在构建版本中
when = require('when');
Defining context