(これは、 dojo ビルド システムを使用する wirejs および dojo と同じ質問ですが、問題と試行された解決策についての詳細が記載されています。これはコメントで提案されたため、重複する質問が作成されます)。
Wire を使用する Dojo アプリケーションをビルドすると、Dojo ローダーは「./lib/context」に対してエラーをスローしますが、undefinedModule
これを取り除くことはできません。
wire
私は、git サブモジュールを使用して、大規模な作業中の dojo プロジェクトに追加しました。cujojswhen
と cujojsmeld
も必要であることがわかりました。それらもgitサブモジュールとして追加しました。
このプロジェクトでは、ライブラリはアプリケーション フォルダ ( ) の隣ではなくsrc/app
、1 レベル深い にありsrc/lib
ます。、 、 、 などがあります。ライブラリは、src/lib/wire
、src/lib/when
、src/lib/meld
の2 レベルの深さです。src/lib/dgrid
dojo
src/lib/dojo/dojo
src/lib/dojo/dijit
src/lib/dojo/dojox
src/lib/dojo/util
バージョン:
- 道場 1.10.4
- ワイヤー 0.10.9
- 3.7.2のとき
- メルド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
エントリを追加する必要があることに注意してください。これにより、たとえば、cujojs コードが内部的に行う の代わりに、依存関係リスト内でwhen/when.js
asを参照することが可能になります。"when"
"when/when"
したがって、これは開発モードで機能します。
次に、ビルドを機能させようとしました。
にbuild.profile.js
、パッケージ参照を再度追加しました。ビルドは、さまざまな方法でそのように失敗します。
まず、パッケージの場合、Dojo ビルダーは、パッケージのビルド構成を本質的に定義するファイルまたはファイルを参照する、ファイルdojoBuild
内のプロパティを予期します。ほとんどの場合、このビルド構成は (すべてのパッケージに含まれています) 単なるオブジェクトであり、どのファイルがパッケージ内の AMD リソースであるか、どのファイルがテストであるか、およびどのファイルをそのままコピーする必要があるかを定義する関数を備えています。package.json
<mypackage>.profile.js
package.js
resourceTags
cujojs パッケージには、dojo ビルダーで使用できるそのようなビルド定義はありません。
ビルダーは、最初にこれらのパッケージのビルド構成がないこと、次にリソースが AMD リソースとしてフラグ付けされていないことを訴えます (これがこのビルド構成ファイルの主な理由です)。
使用している外部ライブラリのファイルを変更したくないのでdojoBuild
、cujojs パッケージにプロパティとビルド構成ファイルを追加する気はなく、回避策を探しました。
package.json
Dojo ビルダー コードをステップ実行した後、ビルダーはファイルにプロパティがないことを訴えていることがわかりました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
のパッケージ定義の追加のプロパティに注意してください。私は物事を「シンプル」に保ち、1 つの一般的なオブジェクトを使用して 3 つのケースすべてを処理しました。これは、すぐに説明するを除いて、かなり標準的な設定です。wire
when
meld
generalResourceTags
resourceTags
isGivingTroubleButUnused
https://github.com/cujojs/when/wiki/Using-with-Dojoで明示的に言及されているソリューションを試してみましたがwhen
、うまくいきませんでした。
このようにして、dojo ビルダーからかなり適切なレポートを取得できますが、不足しているリソースについて言及されています。たとえば、一部のモジュールには jquery が必要です。ただし、これらのモジュールはこのプロジェクトでは使用されません。
Wirejs および dojo using the dojo build systemで言及されているソリューション、ピギーバッキングのpackageJson
方が優れている可能性があることに注意してください。私はそれをテストしていません。
isGivingTroubleButUnused
とにかく使用しないため、これらのモジュールを処理せずにコピーするために を導入することになりました。問題の 1 つは にあることに注意してくださいwhen/generator
。Closure コンパイラはそこで構文エラーを検出します ( https://github.com/cujojs/when/issues/429を参照)。
このセットアップの最終的な結果は、エラーのないビルドです。
そして、これをテストしたいのですが...失敗します。最初に表示されるエラーは、確かに dojo ローダーが for をスローしたundefinedModule
Error
ことです"./lib/context"
。これが実際に発生する唯一の場所は、 の 23 行目ですwire/wire.js
。
createContext = require('./lib/context');
これは に解決されることを意図してwire/lib/context.js
おり、明らかにこれは開発 (アンビルド) モードで機能します。
いずれにせよ、require
モジュール参照は相対的であるため、コンテキスト依存の require (dojotoolkit.org /documentation/tutorials/1.10/modules_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) Missing dependency. module: MY_MODULE; dependency: wire!SOME_PACKAGE/_wire-serverRequests
)。
それでも、ブラウザは同じ場所で同じエラーを出します: undefinedModule
Error
for "./lib/context"
.
この時点での作業仮説はwire
、名前の下でによって使用される関数require
は、ビルド バージョンでは状況依存の require ではなく、アンビルド バージョンでは要求されるというものです。
本当じゃない。まず、wire
コードまたはテストを読み取りに変更しました
createContext = require('wire/lib/context');
参照を絶対にする。同じ問題。
次に、sourceMaps ( useSourceMaps = true
) を使用してデバッグを試みました。これは悪夢だrequire
。
多分「プリロード」は機能しますか?そのため、トップの HTML ページでは、すべてのコードを
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.");
(error
ビルドで他のメッセージが取り除かれるため、 を使用)。
アンビルド バージョンでは、すべてのメッセージが表示されます。ビルド版では、エラーが発生する前に「Defining context」しか表示されません。したがって、問題は "loading"wire/lib/context
ではなく、それを定義することであり、おそらくロードまたは定義することwhen
です!
だから、私は同じトリックに適用しましたwhen
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
when = require('when');
これは、「コンテキストの定義」のロギングの後に実行されます。
ビルドバージョンでは、まだ取得できるのは
Defining context
エラーになる前に!この動作は明らかに異なります。
次に、プリロード コードを削除しました。アンビルド コードでは同じ出力が得られますが、ビルド コードではエラーが発生する前にメッセージが表示されなくなりました。
したがって、いずれにせよ、このwire
コードは、読み込み中に予期せず理解できないことを行っています。
この余分な詳細が、誰かが私たちを正しい軌道に乗せるきっかけになることを願っています...