جاوااسکریپت - ایجاد یک ماژول AMD واحد از چندین کلاس TypeScript که به صورت ماژولهای AMD کامپایل شدهاند؟


من در حال تلاش برای ایجاد یک فایل کتابخانه AMD واحد (ماژول) هستم که از بسیاری از فایلهای کوچک (فایلهای TypeScript که به ماژولهای JavaScript-AMD کامپایل شدهاند) ساخته شده باشد.

مشکل این است:

  1. من وابستگیهای چرخشی بین کلاسها دارم. (والد نیاز دارد فرزند را بشناسد و فرزند نیاز دارد والد را بشناسد)
  2. میخواهم از همهٔ فراخوانیهای define() و require() خلاص شوم، به جز define اصلی برای "myLibrary"

دلایل اصلی برای ایجاد یک فایل واحد:

  1. زمانهای بارگذاری (نباید از requirejs برای ارجاع به همه فایلهای کوچک استفاده شود)
  2. وابستگیهای چرخهای که نمیتوانند(?) توسط ماژولهای AMD حل شوند

سؤال اصلی من این است:

  • آیا ابزاری برای انجام این کار وجود دارد؟ r.js (grunt-contrib-requirejs) مرا ناامید کرد زیرا تمام فراخوانیهای داخلی تابع define() را باقی گذاشت.

چیدمان پروژه فعلی من مشابه مثال زیر است:

root
|-- myLibrary
|   |-- packageA
|   |   |-- ClassA1.ts
|   |   +-- ClassA2.ts
|   |-- packageB
|   |   |-- ClassB1.ts
|   |   +-- ClassB2.ts
|   |-- packageA.ts
|   +-- packageB.ts
+-- myLibrary.ts

کد myLibrary.ts به سادگی به این صورت است:

export import packageA = require("./packageA");
export import packageB = require("./packageB");

که به سادگی به یک ماژول AMD مثل این کامپایل میشود:

define(["require", "exports", "./myLibrary/packageA", "./myLibrary/packageB"], function (require, exports, packageA, packageB) {
    exports.packageA = packageA;
    exports.packageB = packageB;
});

فایلهای بسته به همان روش سازماندهی شدهاند. برای مثال، packageA.ts به این شکل است:

// Typescript source:
export * from "./packageA/ClassA1";
export * from "./packageA/ClassA2";

// Compiled as Javascript:
define(["require", "exports", "./packageA/ClassA1", "./packageA/ClassA2"], function (require, exports, ClassA1_1, ClassA2_1) {
    function __export(m) {
        for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
    }
    __export(ClassA1_1);
    __export(ClassA1_2);
});

در حال حاضر چه گرفته میشود:

define("myLibrary/packageA/ClassA1",["require", "exports"], function(require, exports) {
    var MyClassA1 = (function() {
        // The content of the class ...
    })();
    exports.MyClassA1 = MyClassA1;
});
define("myLibrary/packageA/ClassA2", ...

// The other stuff ...    

define(["require", "exports", "./myLibrary/packageA", "./myLibrary/packageB"], function (require, exports, packageA, packageB) {
    exports.packageA = packageA;
    exports.packageB = packageB;
});

آنچه من میخواهم:

define(["require", "exports"], function(require, exports) {
    //... The entire code of packageA without define or require.
    var packageA = ...;
    //...
    export.packageA = packageA;
    export.packageB = packageB;
});

پاسخ شماره ۱

آنها قبلاً یک بستهبندی ماژول را در نقشه راه خود دارند.

از آنجایی که در زمان نوشتن این متن ما در TypeScript 1.6 هستیم و گفته میشود که این ویژگی در نسخه 1.7 پیادهسازی خواهد شد، شما باید منتظر vnext بمانید، که باید به زودی منتشر شود.

پاسخ شماره ۲

مشخص کردن --outFile همراه با --module amd یا --module system تمام ماژولها را در کامپایل به یک فایل خروجی واحد که شامل چندین بسته ماژول است، متصل خواهد کرد.

فایل خروجی را ببینید + amd.