(这是与wirejs and dojo using the dojo build system相同的问题,但有关于问题和尝试解决方案的详细信息。创建了重复的问题,因为这是在评论中提出的。)
在构建使用wire的dojo应用程序时,dojo加载程序会为" ./ lib / context"抛出undefinedModule
错误。我们无法摆脱。
我使用git子模块将wire
添加到一个正在运行的大型dojo项目中。事实证明,cujojs when
和cujojs meld
也是必需的。我也将它们添加为git子模块。
在这个项目中,库不在应用程序文件夹(src/app
)的旁边,而是在src/lib
中的一个深层。我有src/lib/wire
,src/lib/when
,src/lib/meld
,src/lib/dgrid
旁边等等。dojo
图书馆深度为2级:src/lib/dojo/dojo
,{{ 1}},src/lib/dojo/dijit
和src/lib/dojo/dojox
。
版本:
一旦我将以下包定义添加到src/lib/dojo/util
,事情就在开发中工作(unbuild):
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"
中,我再次添加了包引用。构建以多种方式失败。
首先,对于包,dojo构建器期望build.profile.js
文件中的dojoBuild
属性引用package.json
或<mypackage>.profile.js
文件,该文件基本上定义了构建包的配置。
这个构建配置最常见(它在我们所有的包中)只是一个package.js
对象,其中的函数定义了包中的哪些文件是AMD资源,哪些文件是测试,哪些应该按原样复制。< / p>
cujojs包没有可用于dojo构建器的构建定义。
构建器首先抱怨这些软件包没有构建配置,其次资源没有被标记为AMD资源(这是构建配置文件的主要原因)。
由于我不想更改我使用的外部库的文件,我不倾向于在cujojs包中添加resourceTags
属性和构建配置文件,所以我寻求一种解决方法。
在单步执行dojo构建器代码之后,我发现构建器抱怨dojoBuild
文件没有package.json
属性,但最后只是查看内部包定义结构以获取{{ 1}}对象。内部包定义结构从主构建概要文件中的包定义开始。所以,我最终捎带了一个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,
[...]
}
};
和resourceTags
的包定义中的额外wire
属性。我保持简单&#34;,并且只使用一个通用对象来处理所有3个案例when
。这是一个非常标准的meld
设置,除了generalResourceTags
,我马上就可以了。
请注意,我在resourceTags
isGivingTroubleButUnused
尝试了明确提及的解决方案,并且无效。
这样,我们从dojo构建器获得了相当不错的报告,但它提到了一些缺少的资源。例如,一些模块需要jquery。但是,这些模块并没有在这个项目中使用。
请注意https://github.com/cujojs/when/wiki/Using-with-Dojo中提到的解决方案,捎带when
可能会更好。我还没有测试过它。
我最后介绍packageJson
来复制这些模块而不处理它们,因为我们无论如何也不会使用它们。请注意,其中一个问题位于isGivingTroubleButUnused
。 Closure编译器在那里看到语法错误(参见wirejs and dojo using the dojo build system)。
此设置的最终结果是构建没有错误。
然后,我们要测试这个......但它失败了。我们得到的第一个错误确实是dojo加载器为when/generator
抛出undefinedModule
Error
。确实发生在"./lib/context"
的第23行的唯一地方:
wire/wire.js
这是为了解析createContext = require('./lib/context');
,显然这适用于开发(unbuild)模式。
在任何情况下,wire/lib/context.js
都是一个上下文敏感的要求(参见dojotoolkit.org /documentation/tutorials/1.10/modules_advanced/,"有条件地要求模块&#34;),模块引用是相对的。但是,这应该没有理由为什么它可以解开,并且不会构建。
接下来,我尝试复制所有require
,wire
和when
资源。如果资源未包含在图层的dojo构建中,则它会回退到异步加载。所以,这可能有效:
meld
构建现在通过,并复制所需的内容。当然,还有更多错误,应用代码引用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) Missing dependency. module: MY_MODULE; dependency: wire!SOME_PACKAGE/_wire-serverRequests
undefinedModule
Error
。
此时的工作假设"./lib/context"
在名称wire
下使用的函数在构建版本中不是上下文敏感的需求,但是在unbuild版本中。
事实并非如此。首先,我将require
代码或测试更改为
wire
使参考绝对。同样的问题。
然后,我尝试使用sourceMaps(createContext = require('wire/lib/context');
)进行调试。这是一场噩梦,但我相信我看到使用的useSourceMaps = true
是相同的,是上下文相关的要求。
也许&#34;预加载&#34;作品?因此,在顶部HTML页面中,我使用
编写所有代码require
这可确保在我们执行任何其他操作之前加载require(["wire/lib/context"], function() {
[...]
});
。同样的错误。
接下来,我将记录添加到context
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.");
,因为在构建中剥离了其他消息。
在unbuild版本中,我看到所有消息。在构建版本中,我只看到&#34;定义上下文&#34;在错误发生之前。所以问题不在于#34; loading&#34; error
,但在定义它时,可能在加载或定义wire/lib/context
!
所以,我将相同的技巧应用于when
when
现在 unbuild 版本出人意料。输出是:
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
定义之前开始。这很奇怪,因为我看到没有代码可以告诉加载器context
在行之前需要when
context
执行,在记录&#34;定义上下文&#34;
之后执行。在构建版本中,我们仍然只能获得
when = require('when');
发生错误之前!这种行为明显不同!
接下来,我删除了预加载代码。 Unbuild代码提供相同的输出,构建代码现在在错误发生之前有 no 消息。
因此,无论如何,这个Defining context
代码正在执行我在加载过程中无法预料和理解的事情。
我希望这个额外的细节会引发某人让我们走上正轨......