Typescript: ضع في اعتبارك السماح بالوصول إلى UMD globals من الوحدات النمطية

تم إنشاؤها على ٥ أغسطس ٢٠١٦  ·  73تعليقات  ·  مصدر: microsoft/TypeScript

تشير التعليقات الواردة من # 7125 إلى أن بعض الأشخاص يقومون بالفعل بخلط ومطابقة مكتبات UMD العالمية والمستوردة ، وهو ما لم نعتبره سيناريو محتملًا عند تنفيذ الميزة.

ثلاثة خيارات معقولة:

  1. افعل ما نفعله اليوم - سيء لأنه لا يوجد حل جيد
  2. السماح لبعض بناء الجملة أو التكوين ليقول "هذا UMD العالمي متاح بالفعل على مستوى العالم" - معقد إلى حد ما ، ولكن يمكن تنفيذه
  3. السماح بالوصول إلى جميع UMD globals بغض النظر عن السياق - يخطئ الأشخاص حيث ينسون استيراد UMD العالمي في ملف. من المفترض أن تكون هذه نادرة إلى حد ما ، لكن سيكون من الغباء تفويتها

يبدو أنه سيعمل ولكن من المحتمل ألا:

  1. وضع علامة على وحدات UMD النمطية المستوردة على أنها "غير متوفرة للعامة" - سيئة لأنه سيتم استيراد وحدات UMD النمطية في ملفات التصريح أثناء زيادة الوحدة النمطية. سيكون من الغريب أن يكون لديك سلوك مختلف للواردات من ملفات التنفيذ مقابل ملفات التصريح.

أنا أميل إلى الخيار 3 من أجل البساطة ، ولكن يمكنني رؤية الخيار 2 إذا كان هناك بعض التركيب أو التكوين الجيد إلى حد معقول يمكننا استخدامه في مكان منطقي. سيكون اكتشاف استخدام UMD global في قاعدة TSLint أمرًا سهلاً إذا أراد شخص ما القيام بذلك.

قد يكون أحد المسارات إلى الأمام هو تنفيذ الخيار 3 وإذا اتضح أن الأشخاص يرتكبون خطأ "نسيت الاستيراد" في كثير من الأحيان ، أضف خيار tsconfig globals: [] الذي يحدد صراحة أي UMD globals مسموح به.

Add a Flag Committed Suggestion good first issue help wanted

التعليق الأكثر فائدة

+1 على هذا. كنت أحاول فقط استخدام React مع SystemJS ، وبما أن React لا تجمع جيدًا ، فأنا أحملها مباشرة من CDN في علامة نصية ، وبالتالي فإن كائنات React / ReactDOM متاحة عالميًا.

أنا أكتب التعليمات البرمجية كوحدات نمطية كأفضل ممارسة ، ولكن سيتم تجميعها (مجموعة التحديثات) في برنامج نصي واحد لوقت التشغيل يتم تنفيذه عند التحميل. إنه لأمر مؤلم (وكذبة) أن تضطر إلى رد فعل / رد فعل على import from ، ثم قم بتكوين أداة التحميل ليقول "ليس حقًا ، هذه هي globals" (على غرار مثال تهيئة WebPack الواردة في https: / /www.typescriptlang.org/docs/handbook/react-&-webpack.html). سيكون من الأسهل (والأكثر دقة) توفيرها ببساطة على شكل كرات أرضية في الوحدات الخاصة بي. الخطوات التي جربتها ، كما بدت بديهية ، كانت:

  1. npm install --save-dev @types/react @types/react-dom
  2. في ملف tsconfig.json الخاص بي: "jsx": "react", "types": ["react", "react-dom"]
  3. في الوحدة النمطية الخاصة بي: export function MyComponent() { return <div>{"Hello, world"}</div>; }
  4. وبالمثل: ReactDOM.render(...)

لكن ينتج عن هذا الخطأ React refers to a UMD global, but the current file is a module. Consider adding an import instead .

إذا نجح هذا الأمر للتو ، فسيكون هذا أبسط بكثير من التظاهر في الكود بأنه وحدة نمطية ، ثم تكوين المحمل / المجمع على أنه ليس كذلك. (أو بدلاً من ذلك ، تمكنت من القيام بما كنت أتوقعه عن طريق إضافة ملف يحتوي على ما يلي. الآن يمكن للوحدات النمطية الخاصة بي استخدام React & ReactDOM مثل globals بدون أخطاء ، ولكنها نوعًا ما قبيحة / متسللة - على الرغم من أنه قد يكون هناك طريقة أبسط. لقد فاتته):

import * as ReactObj from "react";
import * as ReactDOMObj from "react-dom";

declare global {
    var React: typeof ReactObj;
    var ReactDOM: typeof ReactDOMObj;
}

ال 73 كومينتر

بدلاً من السماح بالوصول إلى جميع UMD globals بغض النظر عن السياق ، ألن يكون من الأسهل السماح فقط بالوصول إلى UMD العالمي إذا تمت الإشارة إلى وحدة UMD بشكل صريح (غير مستورد) عبر إما بناء الجملة ///<reference types=<>> ، أو عبر تكوين types في tsconfig.json؟

بمعنى آخر ، لماذا لا نسمح فقط باستخدام ///<reference types=<>> داخل الوحدة النمطية؟

إذا قلنا أن /// <reference type="x" /> يعني أن x كان متاحًا عالميًا _ في كل مكان_ ، فعادةً ما تكون الحالة أن بعض ملفات d.ts في مكان ما تشير بشكل غير صحيح إلى أشياء ليست عالمية حقًا ( أستطيع أن أخبرك بهذا لأنني كنت أقوم بصيانة فرع 2.0 من DefinitelyTyped وهو خطأ شائع للغاية).

على العكس من ذلك ، إذا كان متاحًا فقط _ في هذا الملف_ ، فسيتعين عليك نسخ ولصق التوجيهات المرجعية في كل مكان ، وهو أمر مزعج حقًا. عادةً ما تكون هذه التوجيهات معطلة ، لذا فإن تقديم سلوك خاص بالملف أمر غريب.

أنا أرى. حسنًا ، إذا لم يؤثر ذلك على أي شخص آخر ، فربما يكون من الأفضل الحفاظ على السلوك الحالي. سأحتاج فقط إلى الانتقال بالكامل نحو استيراد الأشياء كوحدات نمطية.

تحرير: يسعدني أن أرى أن هذا يؤثر على العديد من الأشخاص غير نفسي.

النظرية الحالية هي أن تطلب من الناس الهجرة إلى استخدام الوحدات أو لا. إذا واجه أشخاص آخرون هذا ، فالرجاء ترك تعليق مع المكتبات التي كنت تستخدمها بالضبط حتى نتمكن من التحقيق أكثر.

أنا أستخدم اللوداش ، الذي لا يأتي بطابعات خاصة به. لدي أيضًا موقف يكون فيه من الأسهل في بيئة وقت التشغيل استخدام عبارات استيراد المسار النسبي. لذلك ، لدي مجموعة من بيانات الاستيراد مع المسارات النسبية المحلية وأقارب المجلدات (". / foo" بالإضافة إلى "N / bar").

إذا قمت بنسخ @types/lodash/index.d.ts يدويًا إلى node_modules/lodash/ يمكنني الحصول على الأشياء لفحصها كتابة.

حتى الآن كان الحل البديل الخاص بي يستخدم ///<amd-dependency path='../lodash' name="_"> (وليس كشف حساب import ). باستخدام هذا التحرير والسرد ، يمكن للمترجم رؤية تعريفات @ types / Lodash "عالميًا" وسيظل المسار النسبي الصحيح ( ../lodash ) في JS المنبعث.

آمل أن يكون هذا السيناريو قريبًا بدرجة كافية من هذه المشكلة؟

يمكنك توضيح

لدي أيضًا موقف يكون فيه من الأسهل في بيئة وقت التشغيل استخدام عبارات استيراد المسار النسبي.

و

إذا قمت بنسخ @types/lodash/index.d.ts يدويًا إلى node_modules/lodash/ يمكنني الحصول على الأشياء لفحصها كتابة.

رجاء؟ لست معتادًا على هذا السيناريو ، فما هو الغرض منه ولماذا هو مفيد؟

اهلا ياجماعة،

أنا في عملية البحث عن حل للالحالية @types/bluebird إعلان المشكلة (يرجى عدم قضاء وقت القراءة). لقد وجدت أنه يمكن حل المشكلة عن طريق إضافة export as namespace Promise; إلى ملف d.ts ، ولكن بعد ذلك واجهت المشكلة التي وصفتها مشكلة github هذه.

باختصار ، أود أن يعمل ما يلي:

  1. git clone -b vanilla-es5-umd-restriction-problem https://github.com/d-ph/typescript-bluebird-as-global-promise.git
  2. cd typescript-bluebird-as-global-promise
  3. npm install
  4. قم بتحرير node_modules/@types/bluebird/index.d.ts بإضافة export as namespace Promise; أعلى سطر export = Bluebird; .
  5. npm run tsc

النتيجة الحالية:
زوجان من أخطاء 'Promise' refers to a UMD global, but the current file is a module. Consider adding an import instead. .

نتيجة متوقعة:
التجميع ينجح.

هذه المشكلة صعبة بشكل خاص ، لأنها ناجمة عن استخدام Promise في كلٍّ من كود المطوِّر ورمز الجهة الخارجية (RxJS في هذه الحالة). يفترض الأخير أن Promise هو عالمي (يتم توفيره بواسطة معيار JS) ، لذلك لن يتغير أبدًا لاستخدام مثل import Promise from std; // (not that "std" is a thing) .

سأقدر حقًا طريقة لاستخدام وحدات UMD كوحدات قابلة للاستيراد وكجلوبالس.

شكر.

----------------------------- تحديث

انتهى بي الأمر إلى حل هذه المشكلة بشكل مختلف (أي عن طريق Promise و PromiseConstructor زيادة الواجهات).

يبدو أن الخيار "globals": [] tsconfig هو الأفضل لجعلها مرئية في كل مكان. مع إعلان UMD الذي أصبح هو القاعدة ، فإن احتمالات النسيان العرضي لاستيراد وحدة ما تكون عالية. يرجى النظر في الاحتفاظ بالسلوك الحالي. يجب أن يكون هذا خطأ.

أتذكر رواياتي عندما أزالت لحظة متغيرها العالمي window.moment في إصدار نقطة. اعتقدنا أننا كنا نستوردها بحكمة في كل مكان ، لكننا نسينا حوالي 5 أماكن.

بالطبع ستتوفر حزمة UMD في النطاق العام في وقت التشغيل ، ولكن عندما تصبح متوفرة ، يعتمد ذلك على الترتيب الذي يتم به تحميل الوحدات النمطية الأخرى.

+1 على هذا. كنت أحاول فقط استخدام React مع SystemJS ، وبما أن React لا تجمع جيدًا ، فأنا أحملها مباشرة من CDN في علامة نصية ، وبالتالي فإن كائنات React / ReactDOM متاحة عالميًا.

أنا أكتب التعليمات البرمجية كوحدات نمطية كأفضل ممارسة ، ولكن سيتم تجميعها (مجموعة التحديثات) في برنامج نصي واحد لوقت التشغيل يتم تنفيذه عند التحميل. إنه لأمر مؤلم (وكذبة) أن تضطر إلى رد فعل / رد فعل على import from ، ثم قم بتكوين أداة التحميل ليقول "ليس حقًا ، هذه هي globals" (على غرار مثال تهيئة WebPack الواردة في https: / /www.typescriptlang.org/docs/handbook/react-&-webpack.html). سيكون من الأسهل (والأكثر دقة) توفيرها ببساطة على شكل كرات أرضية في الوحدات الخاصة بي. الخطوات التي جربتها ، كما بدت بديهية ، كانت:

  1. npm install --save-dev @types/react @types/react-dom
  2. في ملف tsconfig.json الخاص بي: "jsx": "react", "types": ["react", "react-dom"]
  3. في الوحدة النمطية الخاصة بي: export function MyComponent() { return <div>{"Hello, world"}</div>; }
  4. وبالمثل: ReactDOM.render(...)

لكن ينتج عن هذا الخطأ React refers to a UMD global, but the current file is a module. Consider adding an import instead .

إذا نجح هذا الأمر للتو ، فسيكون هذا أبسط بكثير من التظاهر في الكود بأنه وحدة نمطية ، ثم تكوين المحمل / المجمع على أنه ليس كذلك. (أو بدلاً من ذلك ، تمكنت من القيام بما كنت أتوقعه عن طريق إضافة ملف يحتوي على ما يلي. الآن يمكن للوحدات النمطية الخاصة بي استخدام React & ReactDOM مثل globals بدون أخطاء ، ولكنها نوعًا ما قبيحة / متسللة - على الرغم من أنه قد يكون هناك طريقة أبسط. لقد فاتته):

import * as ReactObj from "react";
import * as ReactDOMObj from "react-dom";

declare global {
    var React: typeof ReactObj;
    var ReactDOM: typeof ReactDOMObj;
}

أتفق أيضًا مع الخيارات الثلاثة بالإضافة إلى الكرة الأرضية: [] النسخ الاحتياطي. يبدو هذا بديهيًا جدًا للمستخدمين الجدد والقدامى وسيعطي الوظائف الدقيقة التي يحتاجها الأشخاص.

أنا لست متخصصًا في الكود ، لذا لا يمكنني حقًا تحديد ما إذا كان الرقم 2 سيكون أفضل أم لا ، لكنني أعتقد أنه سيكون أيضًا بديهيًا نظرًا لأن التكوين الخاص به واضح ومباشر.

إذا كنت أرغب في النظر في المساعدة في تنفيذ أي من هذه ، فأين أذهب؟

هذا حقا يجب أن يكون وراء العلم. إنها مخاطر إعادة بناء ديون ضخمة. حتى لو تم تحديد العلم بشكل افتراضي. أعتقد أن هذا يجب أن يستمر في العمل في السيناريو الأصلي وإلا فإننا نفقد الميزة الأساسية لإعلانات UMD.

لا يتم تجميع React جيدًا

@ هل يمكنك التفصيل؟

إنه لأمر مؤلم (وكذبة) أن تضطر إلى رد فعل / رد فعل على import from ، ثم تكوين أداة التحميل ليقول "ليس حقًا ، هذه كرات أرضية"

السبب الوحيد الذي كتبته في البرنامج التعليمي هو أن استخدام externals يقلل من وقت الحزمة. إذا كنت تستخدم المتغير العالمي React بدون استيراد ، فلا يمكنك التبديل بسهولة إلى الوحدات لاحقًا ، بينما تمنحك الواردات المرونة في استخدام أيٍّ من المحمل الخاص بك.

راجع هذه المشكلة (https://github.com/rollup/rollup/issues/855) للحصول على مثال واحد حول كيفية محاولتهم تحسين التجميع والأحجام التي تمت ملاحظتها. بشكل فعال في الإعداد الخاص بي (باستخدام Rollup) ، رأيت مكاسب صغيرة الحجم تجمع React ، لذلك أفضل تقديمها من CDN. بالنسبة لي ، فإن هذا له فوائد:

أ) طلبات أقل (وعرض النطاق الترددي) إلى موقعي.
ب) وقت أقل للتجميع في سلسلة البناء الخاصة بي.
ج) رمز أقل لإعادة تنزيله على العميل في كل مرة أدفع فيها تغييرًا (حيث أن الكود الخاص بي فقط موجود في الحزمة التي يتم إعادة تنزيلها ، ولا يزال React في ذاكرة التخزين المؤقت للعميل غير معدل - وبالتالي يحصل على 304 ثانية).

بالبحث في Chrome Dev Tools عند تحميل الموقع ، فإن React و React-dom (الإصدارات المصغرة) ، على اتصال GZipped HTTP ، هي فقط 47 كيلو بايت من حركة مرور الشبكة ، وهو أقل من معظم الصور على الموقع ، لذا فأنا لست كذلك قلقًا بشأن محاولة تقليل ذلك كثيرًا على أي حال ، إلا إذا كانت هناك مكاسب كبيرة يمكن تحقيقها (على سبيل المثال تخفيض بنسبة 50٪).

كملحق: أود أن أشير أيضًا إلى أنه بدون هذا الخيار ، فإنك تجبر الأشخاص أيضًا على استخدام مُجمِّع يتجاهل هذه الواردات ، نظرًا لأن مُجمِّع TypeScript نفسه ليس لديه تهيئة للقول "هذه الوحدة هي حقًا وحدة عالمية" ، وبالتالي يصدر عمليات استيراد (أو يتطلب ، أو يحدد) للوحدات التي لا يمكن حلها في وقت التشغيل.

billti SystemJS لديه دعم كامل لهذا السيناريو. يمكنك التبديل بين استخدام حزمة مثبتة محليًا أثناء التطوير واستخدام CDN في الإنتاج. كما أن لديها دعمًا كاملاً للبيانات الوصفية التي تحدد أن جميع الواردات يجب أن تشير بالفعل إلى مراجع لمتغير عالمي سيتم جلبه مرة واحدة وإرفاقه بكائن النافذة عند الحاجة لأول مرة ، في الإنتاج يمكن أن يأتي هذا من CDN. لم أفعل هذا مع رد الفعل لكنني فعلت ذلك باستخدام الزاوية 1.x

شكرا @ aluanhaddad . مثير للاهتمام ... كنت أحاول فعلاً الحصول على عمل مشابه قادني إلى هذا الحاجز ، ولم أستطع معرفة ذلك ، لذلك طرحت هذا الصباح السؤال على SystemJS repo. إذا كان بإمكانك الإجابة عن كيفية تحقيق https://github.com/systemjs/systemjs/issues/1510 ، فسيكون ذلك مفيدًا حقًا :-)

ملاحظة: تعليقي الآخر لا يزال قائماً ، أن إصدار TypeScript نفسه لا يمكن استخدامه بدون ذلك ، لأنك تحتاج إلى شيء مثل SystemJS / WebPack / Rollup وما إلى ذلك ... لتعيين الواردات إلى globals لتشغيل الكود.

سألقي نظرة وأرى ما إذا كان بإمكاني تقديم مثال عملي ، لم أفعل ذلك منذ فترة طويلة ولا يمكنني الوصول إلى الكود المصدري الذي كان لدي في ذلك الوقت ، لكنني متأكد تمامًا انه ممكن.

بالنسبة إلى النقطة الثانية ، هذا بالضبط ما يفعله SystemJS. ستقوم بتعيين هذه الواردات إلى العالمية وتدرك أنه تم طلب العالمية بالفعل وتم تحميلها بالفعل. الإخراج بالتأكيد صالح للاستخدام

لمعلوماتك: لقد حصلت على هذا العمل في SystemJS باستخدام واجهة برمجة تطبيقات SystemJS وأضفت الحل الخاص بي على https://github.com/systemjs/systemjs/issues/1510 . شكر.

إعادة نقطتي الثانية: نعم ، أعلم أن هذا بالضبط ما يمكن أن يفعله اللوادر. هذه وجهة نظري ، يمكنهم تعيين وحدة نمطية مستوردة إلى وحدة عالمية ، لكن لا يمكن لـ TypeScript - لذلك عليك استخدام أداة تحميل لجعل الكود الخاص بك صالحًا في وقت التشغيل. إذن ، إنها مشكلة 22 مع هذه المشكلة الأصلية ، حيث لا يمكنك التصريح بأن العام (في هذه الحالة React) متاح في الوحدة ، يجب عليك استيرادها كما لو كانت وحدة (وهي ليست كذلك) .

تعليقي الآخر لا يزال قائماً ، أن إصدار TypeScript نفسه لا يمكن استخدامه بدون هذا ، لأنك تحتاج إلى شيء مثل SystemJS / WebPack / Rollup وما إلى ذلك ... لتعيين الواردات إلى globals لتشغيل الكود.

@ بيلتي أنا لا أفهم. ما هو السيناريو الذي يكون خيارك الوحيد فيه هو استخدام الإصدار العام من الوحدة النمطية ، لكن TypeScript لا يسمح لك بفعل ذلك؟ رأيت فقط سيناريوهات حيث تتوفر على حد سواء العالمية ووحدة مكتبة.

DanielRosenwasser أعتقد أنه يقصد أن React هو في الواقع عالمي في وقت التشغيل كما هو الحال في عضو في الكائن العام ، بسبب كيفية تحميله.

Billti رائع أنك حصلت عليه تعمل.

أعد نقطتك الثانية: أرى ما تعنيه.

أفترض أن شعوري هو أنه ، في سيناريو المتصفح ، لأنك تحتاج إما إلى استخدام أداة تحميل مثل RequireJS أو حزمة مثل Webpack لأنه لا يوجد متصفح يدعم الوحدات النمطية ومع ذلك لا يحدث أي فرق. (سمعت أن شقرا متوفرة خلف العلم). لذلك لا توجد طريقة لتشغيل الكود على الإطلاق بدون أداة إضافية. إنه نوع من الدلالة الضمنية للمخرجات التي تحتوي على define أو require أو System.register أن كود JavaScript_ المنبعث من غير المحتمل أن يكون محمولًا. ومع ذلك ، أرى أهمية تمييز "وحدة مقابل ليست وحدة".

يمكنك استخدام هذا الحل البديل للإشارة إلى "الوحدة النمطية" مرة واحدة على الأقل.

_ الحشوات. d.ts_

import __React from 'react';

declare global {
  const React: typeof __React;
}

ثم يمكنك استخدامه في أي مكان آخر دون استيراده.
هذا أيضًا صريح بشكل جيد ، إذا كان قليلًا ، لأنك تقول أن React أصبحت عالمية وهذا أيضًا سبب أنك لست مضطرًا لاستيرادها بعد الآن.

أعد الحشوات الخاصة بك. d.ts ، إذا صعدت بضع مشاركات ، سترى أن هذا ما فعلته الآن (العقول العظيمة تفكر على حد سواء) ؛-)

يمكنني تشغيله بإحدى الطرق العديدة الآن ، هذا ليس الهدف. نحاول أن نجعل من السهل اعتماد TypeScript ، وجعل المستخدمين يسقطون في حفرة النجاح ، وليس اليأس. مع أخذ ذلك في الاعتبار ، غالبًا ما أطرح على نفسي سؤالين عند محاولة استخدام TypeScript ومشكلات الضرب: أ) هل هذا الرمز صالح ، و ب) هل سيحاول العملاء القيام بذلك.

نظرًا لأنني حصلت على إصدار (ليس من نوع TypeScript) وهو يفعل ما أريده في Babel تقريبًا في الوقت الذي استغرقته في كتابته ، أعتقد أنه من العدل أن أقول إن الكود صالح. نظرًا لأن صفحة تثبيت مستندات React تُظهر كيفية استخدام علامات البرنامج النصي من CDN لتضمين React ، أعتقد أن عددًا من الأشخاص سيحاولون ذلك أيضًا. (FWIW: لقد قضيت وقتًا أكثر مما يهمني أن أتذكر العمل مع وحدات JS ومحملات مختلفة ، لذلك ليس الأمر كما لو أنني لست على علم بها ، أردت فقط كتابة الكود الخاص بي بهذه الطريقة).

إذا كانت TypeScript لا تدعم أنماطًا معينة صالحة لكتابة التعليمات البرمجية ، فيجب أن نحاول جعل ذلك واضحًا على الفور وتوجيه الأشخاص بشكل صحيح (وهو تحدٍ يجب القيام به في رسائل الخطأ أو المستندات المختصرة). لكن شخصيًا ، لا أعتقد أن TypeScript يجب ألا تدعم الأنماط لأننا لا نعتقد أنها "أفضل الممارسات" أو "الأساسية". إذا كانت الشفرة صالحة ، وقد يرغب بعض مطوري JavaScript في كتابتها ، فيجب على TypeScript محاولة دعمها. كلما طلبنا منهم تغيير الكود الخاص بهم وإعادة تكوين خط أنابيب البناء الخاص بهم لتشغيل TypeScript (كما هو موصى به هنا لترحيل تطبيقي التافه) ، فحينئذٍ سينتقل عدد أقل من المطورين.

فيما يتعلق بالحل ... مجرد spit balling هنا ، ولكن ربما خيار مترجم "lib" ، الذي يحدد بالفعل بشكل فعال ما هي واجهات برمجة التطبيقات المتاحة خلال المشروع ، يمكن أن يأخذ أيضًا قيم تنسيق @types/name للمكتبات لإضافتها عالميًا (وحتى دعم المسارات النسبية ربما).

نحاول أن نجعل من السهل اعتماد TypeScript ، وجعل المستخدمين يسقطون في حفرة النجاح ، وليس اليأس.

أعتقد أن نحاول أن يقود المستخدمين إلى حفرة من النجاح في الوقت الحالي. إذا كانت الوحدة تعرف فقط بشكل مشروط عام ، فأنت بذلك تقوم عن طريق الخطأ بتوجيه المستخدمين لاستخدام شيء غير موجود. لذلك أرى بعض الخيارات المختلفة:

  1. قم بإنشاء بناء export as namespace foo معزز يكون مرئيًا فقط إذا لم يتم استيراده بواسطة وحدة نمطية.
  2. لا تفعل شيئًا ، واستمر في دفع الأشخاص لاستخدام الاستيراد - هذا جيد إلى حد ما في رأيي ، لأننا جعلنا رسالة الخطأ إلزامية بشكل معقول على أي حال.
  3. اسمح للناس باستخدام UMD من كل مكان - أنا بصراحة لست كبيرًا في هذه الفكرة.

تضمين التغريدة

أعد الحشوات الخاصة بك. d.ts ، إذا صعدت بضع مشاركات ، سترى أن هذا ما فعلته الآن (العقول العظيمة تفكر على حد سواء) ؛-)

آسف ، فاتني ذلك ، جميل جدًا ؛)

لا أعتقد أن TypeScript يجب ألا تدعم الأنماط لأننا لا نعتقد أنها "أفضل الممارسات" أو "المتعارف عليها"

لا أعتقد أن TypeScript محرمة هنا ، أعتقد أنها تقوم بما تدعي ، تخبرني أن لدي خطأ. تحتوي الكثير من المكتبات على عروض توضيحية ودروس حيث يتم تحميل نفسها "على هيئة جلوبال" ثم تتابع لاستخدام بناء جملة وحدة ES. لا أعتقد أنهم يصبحون أعظم المواطنين من خلال القيام بذلك ، لكن هذه مناقشة أخرى.

ومع ذلك ، إذا تم استخدام الوحدات بشكل أساسي كسكر نحوي متصور على الكرة الأرضية ، فإن فشلها في متناول اليد لأنها ليست سكرًا نحويًا على الإطلاق. إذا كان أي شيء عبارة عن ملح نحوي (ربما ضريبة؟) نستهلكه من أجل فوائد مثل عزل الكود الحقيقي ، والتحرر من علامة البرنامج النصي ، وإعلان التبعية الصريح ، والهروب من جحيم مساحة الاسم العالمية ، ومزايا أخرى. إن بناء جملة الوحدات ليس مريحًا ، فهو مطول في أحسن الأحوال ، لكن دلالات الوحدات هي التي تجعلها جديرة بالاهتمام.

أعتقد أنه إذا استخدم الناس TypeScript ، في ملفات .ts على الأقل ، أفترض أنهم يريدون الحصول على فوائد تحليل الكود الثابت القوي. لا يفعل بابل هذا ، بافتراض وجود React ولكن ليس لديها معرفة بها. هذا صحيح على الرغم من أن وحدات ES قد تم تحديدها عمدا لتكون قابلة للتحليل الثابت.

تضمين التغريدة

قم بإنشاء تصدير معزز على هيئة مساحة اسم foo التي تكون مرئية فقط إذا لم يتم استيرادها بواسطة وحدة نمطية.

يبدو أن أفضل طريقة لحل هذا.

إليك حالة أخرى تسبب فيها هذا في حدوث مشكلات:

في المشروع الذي أعمل عليه حاليًا ، نمزج العناصر المحلية (غالبًا لأسباب تاريخية) مع وحدات npm. في النهاية ، يتم ضم كل شيء باستخدام Rollup أو Browserify ، لذلك لا بأس بذلك.

أستخدم ملف .js من مشروع emojione الذي نسخته ببساطة في قاعدة الكود. أضفت لاحقًا بيانات النوع الخاصة به إلى DefinitelyTyped: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/13293 أعتقد أنه يمكنني الآن ببساطة تحميل الأنواع وسيعمل كل شيء. ولكن لا يبدو أن هذا هو الحال ، لأن TypeScript لن يسمح لي بالوصول إلى الملف العام.

سبب عدم انتقالي إلى الوحدة النمطية npm هو أن الوحدة النمطية npm تجمع أيضًا عدة ميغا بايت من الرموز المتحركة و PNG. أنا فقط بحاجة إلى برنامج نصي واحد بحجم 200 كيلوبايت. مع إقرارات النوع.

مع AngularJS ، كان الحل هو declare var angular: ng.IAngularStatic . لكن هذا لا يعمل مع مساحات الأسماء ، أليس كذلك؟

dbrgn أنت تواجه مشكلة مختلفة. إذا كانت الوحدة النمطية عمومية بالفعل ، فإن تعريف النوع الخاص بك غير صحيح. لا تعلن عن إعلان عالمي ، ولا إعلان نمط UMD (هذا يتعلق بإعلانات نمط UMD) ، إنها تعلن في الواقع وحدة ES نقية فقط.

إذا كانت الوحدة النمطية تمثل وحدة عامة ، فلا تقم بالتصدير في المستوى الأعلى من الملف ، فهذا يجعلها وحدة نمطية.

مع AngularJS ، كان الحل هو إعلان var angular: ng.IAngularStatic. لكن هذا لا يعمل مع مساحات الأسماء ، أليس كذلك؟

إنه يعمل مع مساحات الأسماء.

كانت نتيجة المناقشة في اجتماع التصميم الخاص بنا هي أننا نفكر دائمًا في السماح لـ UMD ، وإضافة علامة تفرض التقييد الحالي. سيتم أيضًا تمديد القيد للعمل على الوصول إلى أنواع من UMD عالمي.

بعد التفكير في هذا الأمر أكثر ، ما زلت أعتقد أن أفضل شيء يجب فعله هو إنشاء نوع إعلان جديد. هذه العلامة أقل قابلية للاكتشاف من الصيغة الجديدة ، والتي تحتاج فقط إلى أن يكتبها مؤلف ملف التصريح مرة واحدة.

هذا مطلوب بشدة للكود والأدوات الموجودة. حتى هذا الوقت يتوقف Javascript عن اللعب بسرعة وتفقد مع أنظمة الوحدات ، نحتاج إلى المرونة للعمل مع الكود كما هو موجود أرسل تحذيرًا ، لكن لا تفشل في البناء. لقد أهدرت أيامًا في التعامل مع جعل الكود القديم يلعب بشكل لطيف مع العرض التراكمي والطباعة المطبوعة.

قرف.

أعلم أن هناك الكثير من الأشخاص الذين يحبون الضحك على Java ، لكن وحدات جافا الأساسية تعمل على الأقل. الجرار تعمل

لست مضطرًا إلى احتواء 14 معيارًا مختلفًا للوحدة المخصصة ، أو محاولة تجميع وحدة js من ملفات المصدر بالتنسيق الذي ستستهلكه أداة التجميع / التجميع في اليوم دون التبرز ، كما ستنشئ تنسيق وحدة ستلعب بشكل جيد مع عبارات الاستيراد / التصدير من Typescript وملفات d.ts التابعة لجهات خارجية حتى يقرر TSC بالفعل إنشاء الكود بدلاً من التذمر بشأن شيء ما ستنتقل إليه "فقط استخدم DARN IMPORT ، سيكون الأمر عالميًا في مدة العرض".

اختراق shims.d.ts يعمل بشكل جيد. لكن لاف.

حل مؤقت لمن يستخدمون Webpack https://github.com/Microsoft/TypeScript/issues/11108#issuecomment -285356313

أضف externals إلى webpack.config.js مع الكرات الأرضية UMD المطلوبة.

    externals: {
        'angular': 'angular',
        'jquery': 'jquery'
        "react": "React",
        "react-dom": "ReactDOM"
    }

أعتقد أن هذا يجب أن يكون ممكنًا لتسهيل ترحيل الأكواد البرمجية الموجودة.

لديّ مشروع تم تنفيذه باستخدام يتطلب jQuery حيث يتم تضمين jQuery باعتباره عامًا ، نظرًا لوجود بعض المكونات الإضافية التي توسع jQuery فقط إذا تم العثور عليها كعالمية.

تعتمد الشفرة في بعض الوحدات النمطية على تلك المكونات الإضافية ، والتي لن تكون متاحة إذا تم استيراد jQuery كوحدة نمطية. لإنجاز هذا العمل ، سيتعين علي تعديل جميع المكونات الإضافية للعمل مع jQuery المحملة كوحدة نمطية ، وتحميلها أيضًا كوحدات (تخمين عند الضرورة).

إلى جانب ذلك ، هناك أيضًا صفحات تستخدم جافا سكريبت بدون برامج تحميل الوحدات. لذلك ، يجب أن تعمل المكونات الإضافية مع كل من الكرات الأرضية والوحدات النمطية.

بصرف النظر عن jQuery ، هناك نصوص أخرى بها نفس المشكلة مثل الضربة القاضية وغيرها. هذا يجعل ترحيل المشروع أمرًا صعبًا. أو ، من وجهة نظر واقعية ، غير قابل للتنفيذ.

بالطبع ، هذا ليس أفضل نمط ، ولن أستخدمه في مشروع جديد. لكنني لا أعتقد أنني الوحيد الذي يعاني من هذه المشكلة

هل يعقل استخدام types في tsconfig.json لهذا؟ على سبيل المثال ، بدون types set ، تحصل على السلوك الضمني الحالي ومع مجموعة types ، فأنت تقول حرفياً "هذه الأشياء هي globals" ويمكن أن تفرض مساحة اسم UMD على الظهور بشكل عام. هذا نوع من السلوك الموجود اليوم على أي حال (مطروحًا منه القوة العالمية). هذا يعارض تقديم خيار globals .

أعتقد أن هذه فكرة جيدة. في حالتي ، هناك نصوص تستخدم مكتبة UMD كعالمية ، وأخرى كوحدة نمطية. يمكنني حل هذه المشكلة باستخدام ملفين مختلفين من tsconfig.json يعالجان كل حالة. حقا مستقيم للأمام.

blakeembrey على الرغم من أن استخدام types أمر منطقي ، إلا أنني لست شديد الحرص على فكرة التحميل الزائد عليه نظرًا لأنه يعاني بالفعل من مشاكل. على سبيل المثال ، يحتوي البناء <reference types="package" /> بالفعل على قيود أنه لا يدعم "paths" . يجب أن يشير "package" إلى اسم مجلد في @types

أواجه صعوبة في متابعة هذه المحادثة. هل كانت هناك أي تحديثات أو قرارات مخطط لها لهذا؟ يبدو أن هذا شيء يمكن أن يكون مفيدًا في سيناريوهات مثل عندما يكون لوداش جزءًا لا يتجزأ من تطبيق ما ، أو عندما تتحول المزيد من مكتبات الطرف الثالث إلى بنية أكثر نمطية بدلاً من الاعتماد فقط على وجودها على النافذة.

هل هناك طريقة مخططة لمعالجة هذا أو على الأقل لتوثيق كيفية حل هذا مع الإصدار الحالي المتاح؟

مرحبًا mochawich ، تلقيت الخطأ التالي باستخدام تعريف declare global :

TS2686: 'React' refers to a UMD global, but the current file is a module. Consider adding an import instead.

cantux TypeScript لا يقرأ تكوين Webpack. إذا جعلت React متاحًا عالميًا ، فيمكنك declare ذلك ، ولكن لماذا لا تستخدم الوحدات؟

aluanhaddad في الغالب لأنني كنت مرتبكًا مع العمل المنجز من خلال مكالمة الاستيراد. لقد تلاعبت ببعض ، فهل العبارات التالية صحيحة؟

نحن ندفع رسومًا رمزية لتقديم طلب عندما نستورد وحدة. هذا يضمن أن ما نستخدمه متاح في الذاكرة ، إذا تم طلبه مسبقًا ، يتم تحميل الوحدة من ذاكرة التخزين المؤقت ، وإذا لم تكن الوحدة موجودة ، يتم جلبها. إذا كنت ترغب في التحايل على هذا الطلب ، فأنت تقوم فقط بتعريف شيء ما على أنه عام ويثق برنامج Typescript بشكل أعمى في توفره (وإذا كنت تستخدم عبارات استيراد الحزم الذكية ، فيمكن استبدالها / إزالتها).

إذا كانت هذه صحيحة ، فيمكننا إزالة التعليقات للإيجاز ، فالخيط عملاق كما هو.

كما سأل codymullins أعلاه ، هل يمكن لشخص ما تلخيص الحل الحالي لهذه المشكلة؟ لقد قمت للتو بتحديث تعريف نوع Lodash وحصلت على الكثير من أخطاء TS2686.

كان الحل البديل الذي أجريته هو اختراق ملف typedef ليتوافق مع معيار العمل القديم ، لكن هذا غير قابل للتطبيق إذا بدأ المزيد من ملفات typedef في التعطل.

السيناريو الخاص بي هو كما يلي:

  • في تطبيقاتي ذات الصفحة الواحدة ، أستورد عددًا من المكتبات (بما في ذلك Lodash) في ملف

يعمل مثال shim المذكور أعلاه ، على الرغم من أن vscode يبرزه كخطأ (على الرغم من أنه لا يزال يقوم بالإكمال بشكل صحيح!)

من فضلك من فضلك لا تعطي أخطاء عند الوصول إلى UMD globals في الوحدات. ويتم هذا المشروع الضخم وأنا أعمل على في AngularJS ونحن نستخدم نسخة مطبوعة على الآلة الكاتبة للتطبيق، ولكن بالطبع نحتاج نسخة مطبوعة على الآلة الكاتبة لمعرفته حول angular UMD أنواع العالمية والزاوي من @types/angular . كنت تعتقد أنه سيكون سهلاً مثل إضافة "angular" إلى types في tsconfig.json ، لكن لأي سبب من الأسباب ، لم يكن الأمر كذلك ، و TSC يصرخ في وجهي. بقدر ما كنت أتمنى أن تكون جميع حزم NPM عبارة عن نسخة مطبوعة خالصة ، فإن معظمها عبارة عن JS عادي وستظل لفترة طويلة جدًا. أنا حقًا لا أفهم لماذا لا يمكن لـ TSC أن يصمت عندما نستورد d.ts قائلًا أن UMD عالمي موجود. هذا الموقف أكثر من شيوعًا - كل مشروع من مشاريع الأنواع التي عملت عليها في أي وقت مضى يستخدم مكتبة JS واحدة على الأقل يجب أن أقوم بتجميعها بنفسي والإشارة إليها باستخدام تعريفات النوع.

هل هناك أي تحديث على ذلك؟

حالة الاستخدام الخاصة بي: أعمل على قاعدة بيانات كبيرة موجودة والتي تستخدم بشكل مكثف شبكات CDN. يتم استيراد الأدوات المساعدة الشائعة عبر علامات البرنامج النصي عبر العديد من الصفحات (مثل clipboardjs و Lodash). أود الإشارة إلى تلك المتغيرات العالمية لأنها متوفرة على الصفحة. بدون استخدام الوحدات النمطية ، يكون من السهل الحصول على ترجمة مطبوعة باستخدام /// <reference type="$name" /> في الجزء العلوي من الملفات المصدر ذات الصلة. لكن هذا يتوقف عن العمل عند محاولة إنشاء وحدات.

يبدو أنه تم اقتراح طريقتين في الموضوع:

  1. اجعل رموز الاستيراد /// <reference type="$name" /> في مساحة اسم الملف الحالي فقط.

  2. متغير تكوين / خيار مترجم في tsconfig.json (مثل "globals" ، "types" )

أعتقد أن كلا النهجين جيدان. بينما أتفق مع انتقادات الخيار الأول بواسطة RyanCavanaugh :

على العكس من ذلك ، إذا كان متاحًا فقط في هذا الملف ، فسيتعين عليك نسخ ولصق التوجيهات المرجعية في كل مكان ، وهو أمر مزعج حقًا.

أعتقد أنه أمر مزعج للغاية أنه لا يمكنك استخدام الوحدات مع UMD globals على الإطلاق بسبب السلوك الحالي. بعض الحلول أفضل من لا شيء.

هل هذه القضية لا تزال معلقة؟ وإذا كان الأمر كذلك ، فما الحل الحالي؟

إذا قمت بتثبيت الحزمة @types ، فإن تلك الحزم التي لم يتم استيرادها كوحدات نمطية ، يتم توفيرها على شكل globals.

على سبيل المثال ، إذا كنت npm install -D @types/underscore في جذر مشروعي ، فيمكنني كتابة وحدات لا تستورد أي شيء من شرطة سفلية ، ومع ذلك فإن _ global متاح (انظر أدناه).

types-ref

هل هذا ما تبحث عنه؟

billti ربما أكون أسيء الفهم ، لكن

الحد الأدنى اللازم لإعادة:

js / foo.ts:

// <reference types="js-cookie">

import { Bar } from "./bar";

const Foo = {
    set: function() {
        Cookies.set("foo", "bar");
    },
    get: function() {
        console.log(Cookies.get("foo"));
    }
};

window.onload = function() {
    console.log(Cookies);
}

js / bar.ts

const Bar = {
    x: 3
};

export { Bar };

package.json:

{
  "name": "foo",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "private": true,
  "devDependencies": {
    "@types/js-cookie": "^2.1.0",
    "typescript": "^2.7.1"
  },
  "dependencies": {
    "http-server": "^0.11.1"
  }
}

tsconfig.json

{
    "compilerOptions": {
        "module": "system"
    },
    "files": [
        "js/foo.ts"
    ]
}

رسائل خاطئة:

js / foo.ts (7،3): خطأ TS2686: تشير "ملفات تعريف الارتباط" إلى UMD عمومي ، لكن الملف الحالي عبارة عن وحدة نمطية. ضع في اعتبارك إضافة استيراد بدلاً من ذلك.
js / foo.ts (10،15): خطأ TS2686: تشير "ملفات تعريف الارتباط" إلى UMD عالمي ، لكن الملف الحالي عبارة عن وحدة نمطية. ضع في اعتبارك إضافة استيراد بدلاً من ذلك.
js / foo.ts (15،14): خطأ TS2686: تشير "ملفات تعريف الارتباط" إلى UMD عالمي ، لكن الملف الحالي عبارة عن وحدة نمطية. ضع في اعتبارك إضافة استيراد بدلاً من ذلك.

يعتمد السلوك الذي تحصل عليه على ما إذا كانت الوحدة التي تم استيرادها قد تمت كتابتها كوحدة نمطية "مناسبة" لـ UMD (هذا هو السلوك مع "ملفات تعريف الارتباط") أو الوحدة النمطية "تعمل بكلا الطريقتين في نفس الوقت" (وهي كيفية كتابة لوداش) .

إن عدم اتساق الأشخاص الذين يكتبون بشكل صحيح ملف .d.ts الذي يصف كيفية عمل الكائن في وقت التشغيل ، وغموض التجربة للمطورين ، هو السبب في أنني أميل بشدة في اتجاه "إزالة قيود UMD العالمية". يمكننا وضعه تحت --strict مع إلغاء الاشتراك في --noStrictUMD .

الشيء الآخر الذي صادفته هو التعامل مع محمل AMD المخصص في موناكو. إنهم يدعمون بعض المجموعات الفرعية من سلوك AMD (أدخل eyeroll الهائل) ولكنهم يضغطون على "المتطلبات" العالمية ، لذلك من الصعب حقًا استخدام وحدات UMD المناسبة معها نظرًا لأن هذه الوحدات تميل إلى رؤية "تتطلب" عالمية ثم تفشل في التحميل بشكل صحيح محمل وحدة موناكو. ينتهي بك الأمر بوضع UMD JS libs فوق علامة البرنامج النصي لمحمل Monaco ثم يشكو TS لأنك تصل إلى globals من وحدة نمطية (والتي يجب أن تكون لاستيراد واجهات برمجة تطبيقات Monaco).

تضمين التغريدة

الشيء الآخر الذي صادفته هو التعامل مع محمل AMD المخصص في موناكو. إنهم يدعمون بعض المجموعات الفرعية من سلوك AMD (أدخل eyeroll الهائل) لكنهم يضغطون على "المتطلبات" العالمية ، لذلك من الصعب حقًا استخدام وحدات UMD المناسبة معها نظرًا لأن هذه الوحدات تميل إلى رؤية "تتطلب" عالمية ثم تفشل في التحميل بشكل صحيح في محمل وحدة موناكو.

😁

أي فرصة لهم لإصلاح ذلك؟

كنت أفكر كثيرًا في التكلفة المعقدة للوحدات مؤخرًا. الكثير من اللوادر المترابطة والمتوافقة جزئيًا والمُجمِّعات والناقلات ومديرو الحزم والأطر تصل إلى قدر غير ضئيل حقًا من تعقيد الاعتماد. (أنا متأكد من أنك لست بحاجة إلى أي تذكير على الإطلاق 🙉).

بصفتنا مطورين ، فقد قبلنا سلاسل الأدوات التي تعتبر بأحجام كبيرة أكثر تعقيدًا مما كانت عليه قبل 5-6 سنوات ، وكان المصدر الأساسي للتعقيد هو الوحدات النمطية.

إذا استسلمنا وبدأنا في تحميل حزم UMD هذه على شكل جلوبال ، فماذا كان كل ذلك؟

ومع ذلك ... يفعل الناس ذلك بالضبط. هذا مريع!

أعني ، أن هذا Stack Overflow يحتوي على 61 👍s وكان يقترح جميع الأشياء الخاطئة لـ 99٪ من الحزم خلال نصف العام الماضي. (يرجى من المؤلف تحديثه ليذكر الوحدات كخيار _ لتبعيات UMD بسبب بعض التعليقات المقدمة هذا الصباح)

هذا لا يمكن أن يترك كل هذا في الوريد والعودة إلى الكرة الأرضية!

ومع ذلك ... يفعل الناس ذلك بالضبط. هذا مريع!

تكمن المشكلة في أن وحدات JS يتم تصميمها وتنفيذها بشكل سيء للغاية ، لذلك من الأفضل والأسهل العودة إلى استخدام globals. إذا تم تصميم الوحدات النمطية وتنفيذها بشكل صحيح من البداية ...

نحن نمزج ونطابق الوحدات النمطية و UMD globals لأنه من الصعب جدًا تحميل تبعياتنا كوحدات ذات مستويات متفاوتة من التوافق مع مختلف اللوادر وبعض اللوادر التي لا تدعم تجميع التبعية المباشرة وبدلاً من ذلك يتعين عليك استخدام المعالج المسبق الخاص بنا الذي يستغرق دقيقة للتشغيل.

تعني هذه "الميزة" أننا لا نستخدم دعم وحدة UMD الرسمية على الرغم من أننا بالفعل نستخدم وحدات UMD. نقوم فقط بالتصدير كملف عالمي من ملف d.ts ثم لدينا الوحدة النمطية الخاصة بنا بهذا الاسم والتي تعيد تصدير كل شيء يدويًا.

أي تحديث على هذا؟ أود حقًا أن يعمل الخيار 2:

السماح لبعض بناء الجملة أو التكوين ليقول "هذا UMD العالمي متاح بالفعل على مستوى العالم"

كما أنه لا يساعد في وجود الكثير من برامج js libs ذات الطراز القديم
هناك ، وإعادة كتابتها جميعًا أمر غير وارد. مجرد العمل بها
config للحصول على Rollup للتعامل معها جميعًا بشكل صحيح يضيع ساعات من وقتي.

يضحك الناس على "Enterprise Java" ، لكن جافا العادي يتم شحنها مع ملف
نظام الوحدة في 1.0. لم يكن مثاليًا ، لكن لم يكن فوضى كاملة.

نظرًا لأنه يجب أن يكون "السماح بأشكال الكرة الأرضية UMD" خيارًا بالتأكيد.

يوم الإثنين 2 أبريل 2018 الساعة 1:40 صباحًا Kagami Sascha Rosylight <
[email protected]> كتب:

اضطررت إلى حل بديل مع:

/ * الوحدة النمطية: es2015 * /
// js-yaml يدعم UMD لكن ليس ES2015 module!

-
أنت تتلقى هذا لأنك علقت.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/Microsoft/TypeScript/issues/10178#issuecomment-377885832 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe-auth/AA50ljAD33sr09EGFVAsURbu1x75X-lOks5tkeQCgaJpZM4Jd8jX
.

>

دانيال جويس

يرث الودعاء الأرض ، لأن الشجعان سيكونون بين النجوم.

أنا أستخدم three.js في مشروع Angular. أقوم باستيراده كـ

import * as THREE from "three";

import {Vector3} from "three"; يعمل أيضًا كما هو متوقع.

مع تثبيت حزم npm three و @types/three npm ، كل شيء يعمل بشكل جيد. تحت الغطاء ، أعتقد أن هذا يستخدم three/build/three.module.js . يستخدم الملف @types/three/index.d.ts الترميز export as namespace THREE ، والذي لست مرتاحًا تمامًا له ، لكن مهلا ، إنه يعمل.

في هذه الحالة بالذات ، تكمن المشكلة في وجود ملف آخر ذي صلة في نظام three.js يسمى OrbitControls.js (والذي يسمح لك بتدوير الصور ثلاثية الأبعاد بإصبعك أو الماوس ، بشكل أساسي). تكمن المشكلة في أنه على الرغم من أن هذه الوظيفة هي جزء شبه رسمي من توزيع three.js ، إلا أنها عبارة عن ملف JS قديم بسيط موجود في شجرة examples ويضع نفسه مباشرة على خاصية THREE من النافذة ، ويستخدم مباشرة واجهات برمجة التطبيقات الأخرى التي يتوقع أن تجدها موجودة على window.THREE . لذلك حتى إذا كنت "تطلب" الملف بامتداد

require("three/examples/js/controls/OrbitControls.js");

لا يمكن العثور على window.THREE لوضع نفسه ، أو للوصول إلى أجزاء أخرى من النظام الثلاثة الذي يستخدمه. يمكنني تضمين المكتبة بأكملها مباشرةً باستخدام خاصية Angular scripts في angular.json (ما يعادل تقريبًا علامة <script> قديمة الطراز) ، ولكن إذا لم أكن مخطئًا ، سيتم تحميل المكتبة مرتين.

لتجنب ذلك ، قمت بإزالة بيان import * as THREE from "three"; ، وما زال بإمكانه حل أنواع مثل foo: THREE.Vector3 ، لكن الاختناقات على المراجع مثل new THREE.Vector3() مع الشائنة

يشير "ثلاثة" إلى UMD عمومي ، لكن الملف الحالي عبارة عن وحدة نمطية. ضع في اعتبارك إضافة استيراد بدلاً من ذلك. [2686]

في هذه المرحلة ، أعتقد أنني سأضطر فقط إلى الحصول على ملف OrbitControls.js و ES6-ify و / أو TS-ify ، وهو ما يبدو أن أكثر من شخص آخر قام به بالفعل في شكل أشياء مثل `` orbit-controls-es6 ، لذا ربما ينبغي علي تبسيط حياتي واستخدام ذلك ، على الرغم من أنني أكره وضع حياتي في أيدي الآخرين بهذه الطريقة.

في ملاحظة غير ذات صلة ، هناك غرابة واحدة وهي أن @types/three يحدد أنواعًا لـ OrbitControls ، حتى من خلال الكود نفسه ليس في الوحدة النمطية three نفسها. ومع ذلك ، لا يمكنني معرفة كيفية ربط كل هذه الأنواع التي تحدد فئة تسمى OrbitControls بأي شيء - أود أن أعلن عن التصدير الافتراضي لـ orbit-controls-es6 المذكور أعلاه هذا النوع ، ولكن كيفية القيام بذلك بعيدًا عني.

الحل الذي توصلت إليه أخيرًا ، والذي أشعر بالخجل الشديد منه ، هو:

import * as THREE from "three";
Object.defineProperty(window, "THREE", {get() { return THREE; }});
require("three/examples/js/controls/OrbitControls.js");

إنه يعمل ، على الرغم من أنني مرتبك قليلاً لماذا. يحتوي الملف المطلوب على سطر مثل

THREE.OrbitControls = funtion() { };

والذي يبدو أنه سينتهي به الأمر بالتخصيص لثلاث "مساحة اسم" ناتجة عن عبارة import * as THREE from "three"; ، والتي لا ينبغي أن تعمل ، أليس كذلك؟

طلب مني RyanCavanaugh نسخ ملاحظاتي من # 26223 هنا:

أحتفظ بقاعدة شفرة TypeScript كبيرة نوعًا ما (monorepo الداخلي من Google) تحتوي على العديد من المكتبات المكتوبة التي يعتمد عليها الأشخاص. في الأصل ، كان المستخدمون يعتمدون فقط على الأنواع العامة للمكتبات مثل angular ، قبل أن يتم تحويل .d.ts إلى وحدات خارجية. ثم قمنا بعد ذلك بترحيل قاعدة التعليمات البرمجية لاستخدام الوحدات والواردات الصريحة. لقد توقعنا بالفعل أن تتطلب الكرات الأرضية UMD export as namespace d دائمًا استيرادًا صريحًا لاستخدام الرموز ، لكل من مراجع النوع والقيمة ، ولم نلاحظ ذلك مرة أخرى عندما قمنا بالترحيل (عفوًا).

يعد السماح بالاستخدام غير المستورد للكود مشكلة بالنسبة لنا بشكل عام:

  • هذا يعني أن الكود يعتمد على تعريفات أنواع "الخلفية" العالمية ، مما يجعل قراءة الكود أكثر صعوبة (خاصة في متصفحات الريبو أو مراجعة الكود بدون الانتقال إلى الرمز).

  • يحجب تبعيات الكود

  • إنه يتحايل على قيود "يجب أن يكون هناك اعتماد واضح على مستوى البناء على جميع الواردات" التي نطبقها في bazel ، والمعروفة أيضًا باسم "التقسيمات الصارمة".

    في قاعدة التعليمات البرمجية الكبيرة ، يجب أن تحتوي التعليمات البرمجية الخاصة بك على تبعيات صريحة ، وإلا يصبح الريبو غير قابل للإدارة. الآن إذا كان لديك تبعية تطارد A -> B -> C وأنواع عالمية ، فمن السهل أن يكون لديك رمز A مترجم لمجرد أن B يعتمد على C . إذا قام B لاحقًا بإزالة التبعية الخاصة به ، فإنه يكسر A ، مما يعني أن التغييرات لها تأثير مضاعف غير متوقع على المستودع ، مما يخالف عزل الكود.

  • يتسبب في قيام الكود باستيراد الوحدة النمطية بشكل غير متسق ببادئة واحدة للقيم واستخدام أنواعها مع بادئة أخرى (خاصة بالنسبة إلى AngularJS و ng vs angular)

يمكننا حل هذه المشكلة عن طريق إزالة بيانات export as namespace في نسخة البائع الخاصة بنا من DefinitelyTyped ، ولكن على الأقل بالنسبة لنا ، هذه الميزة تعمل ضد صيانة الكود وأهدافنا الهندسية. أعتقد أن المشاكل أكثر وضوحًا في حالة monorepo مثل Google ، ولكنها تنطبق أيضًا بشكل عام في قواعد الرموز الأصغر.

النقاط التي نشرتها غير مهمة على الإطلاق لموقفنا. نحن مجبرون على تنفيذ الكود الخاص بنا مع وحدات AMD وتزويد تبعياتنا بوحدات UMD نظرًا لظروف خارجة عن سيطرتنا على نطاق واسع (لكنني سألخصها لأن وحدات JS معيبة بشكل فظيع في كل من المفهوم والتنفيذ). ستسمح لنا هذه الميزة بتبسيط حياتنا بشكل كبير.

ربما مع TS3 يمكننا معرفة كيفية تجنب ذلك ، ولكن حتى لو فعلنا ذلك ، فمن المحتمل أن يستغرق الأمر عامين على الأقل قبل أن ننتهي من جميع التغييرات الضرورية ، لذلك ستظل هذه ميزة مفيدة للغاية بالنسبة لنا.

سؤال مفتوح: هل ستكون علامة عالمية واحدة لـ "السماح بالوصول إلى جميع وحدات UMD النمطية" كافية ، أم يحتاج الأشخاص حقًا إلى التحكم في الخطأ لكل وحدة نمطية؟

التصويت ❤️ لـ "علم واحد فقط"
التصويت لـ "التحكم في الحاجة لكل وحدة"

كنت أفكر أيضًا في ما إذا كان وجود قائمة صريحة في الخيار "types" في tsconfig.json لا ينبغي أن يسمح أيضًا باستخدام UMD في وحدة نمطية. إنه يدل على أن النوع موجود عمدا. (على الرغم من أنه من الواضح أنه لا يمنع الخطأ الذي نسيت استيراده).

أو بالمثل ، استخدام بناء /// <reference types="..." /> يجب أن يسمح باستخدام UMD لتلك الحزمة في الوحدة النمطية التي يتم استخدامها فيها (على سبيل المثال ، "التحكم لكل وحدة" المذكورة).

RyanCavanaugh هل سيكون هناك علم للعنوان # 26233 أيضًا؟

26233 يعتبر يعمل بشكل كامل على النحو المنشود ؛ الوصول إلى جانب النوع من UMD global من وحدة غير ضار شرعيًا

لست متأكدًا تمامًا مما إذا كانت "غير ضارة بشكل مشروع". استخدام @types/jquery كمثال. $ و jQuery JQueryStatic لواجهة $ و jQuery بدون استيراد. آمل أن أتمكن من تعطيل ذلك.

RyanCavanaugh نعم ، إنه غير ضار بمعنى أن انبعاثات TS لا تتأثر به. إنها مشكلة إذا كنت تريد تحكمًا دقيقًا في ما يمكن لكل مكتبة الوصول إليه @types - إنه يحول ما يشبه على الأقل أنواع الوحدات النمطية إلى أنواع عالمية. يمكن أن يمثل توسيع الوصول مشكلة أيضًا ، حتى إذا لم يتأثر الانبعاث.

في الواقع ، في حالة jQuery ، يتأثر الإرسال. ينبعث $() في وحدة نمطية بدون استيراد.

قبول العلاقات العامة للعلم الجديد الذي يسمح بالوصول إلى UMD globals من جميع الوحدات.

من ناحية التنفيذ ، إنه واضح تمامًا ... لكننا نحتاج إلى تسميته. لقد أطلقنا حوالي عشرة أسماء فظيعة في اجتماع مراجعة الاقتراحات وكرهناهم جميعًا ، لذا فإن الأمر متروك لكم جميعًا للتوصل إلى شيء مستساغ. من فضلك توقف.

ركلنا عشرات الأسماء الرهيبة في اجتماع مراجعة الاقتراح وكرهناهم جميعًا

ماذا كانوا؟

لذا فالأمر متروك لكم جميعًا لابتكار شيء مستساغ.

ربما umdUseGlobal أو شيء من هذا القبيل.

أود أن أقترح importAllNamespaces لاسم العلم العالمي UMD لأن الكرات الأرضية UMD عادة ما تكون export as namespace .

RyanCavanaugh هل ناقش الفريق مشكلة النوع؟

تضمين التغريدة

saschanaz سألت هذا بالفعل ، لكنني أشعر بالفضول أيضًا ... RyanCavanaugh هل تتذكر الأسماء الرهيبة التي تمت مناقشتها؟

أعتقد أن السلسلة ذهبت إلى شيء من هذا القبيل

  • allowUmdGlobalAccessFromModules - الأكثر دقة ولكن طويل جدًا
  • assumeGlobalUmd - لاف
  • allowModuleUmdGlobals - "globals" ؟؟
  • umdAlwaysGlobal - 🤢
  • allowUmdGlobals - لكن يمكنني ذلك بالفعل؟
  • allowUmdGlobalAccess - يتخطى جزء الوحدة ولكن ربما لا أحد يهتم؟

سأختار الأخير إذا أجبرت على ذلك

شكرا لك!

أنا أحب allowUmdGlobalAccessFromModules لأنه على الرغم من طوله ، إلا أن دقته تجعله أسهل في التذكر. أعتقد ، "ما هذا الخيار الذي يسمح بالوصول إلى UMD globals من الوحدات؟ أوه نعم ، إنه allowUmdGlobalAccessFromModules ، بالطبع!"

استخدام البادئة "allow" يطابق اصطلاح التسمية للخيارات الأخرى ، وهو أمر جيد.

بالإضافة إلى ذلك ... هناك خيارات أخرى طويلة تقريبًا :)

allowUmdGlobalAccessFromModules : 31 حرفًا

allowSyntheticDefaultImports : 28 حرفًا
strictPropertyInitialization 28 حرفًا
suppressExcessPropertyErrors 28 حرفًا
suppressImplicitAnyIndexErrors : 30 حرفًا
forceConsistentCasingInFileNames : 32 حرفًا

ما هو الحل الحالي؟ لقد كنت أبحث في Google خلال الساعة الماضية ولا يمكنني العثور على أي حلول عملية.
أفضل عدم الإرسال إلى "أي" أو الرجوع إلى إصدار واحد يعمل من نوع Typescript ولكن لا يمكنني العثور على أي خيارات أخرى.
هل هناك تصميم تجريبي في مكان ما به علامة مترجم يعمل على حل هذه المشكلة؟
(بالمناسبة ، "allowUmdGlobalAccessFromModules" هو اسم ممتاز ؛ ليس الأمر كما لو كنا نكتبه 50 مرة في اليوم :-))

نحن نستخدم tsc 3.2.2 مع Lodash المضمنة بشكل ثابت في ملف HTML العلوي ؛ مع need.js ؛ d.ts تم الحصول عليها من أحدث نوع DefinitelyTyped ؛ مثال على رمز فشل في التجميع:

/// <reference path="..." />

class Example<T extends IThingWithTitle<T>> {

    public test = (arg : T[]) : void => {
        _.sortBy(arg, (el : T) => { return el.title; }); // TS2686: '_' refers to a UMD global, but the current file is a module. Consider adding an import instead.
    };

}

export = Example;

(من فضلك لا تخبرني أنني بحاجة إلى قلب المشروع رأسًا على عقب ، فأنا أعلم أننا خلف المنحنى في بعض الجوانب)

تحديث: ((نافذة) ._) / * FIXME https://github.com/Microsoft/TypeScript/issues/10178 * /. sortBy (...) يعمل ولكن عزيزي الرب ، إنه قبيح :-P

Gilead ، الحل من هذا التعليق يعمل بشكل جيد في الوقت الحالي: https://github.com/Microsoft/TypeScript/issues/10178#issuecomment -263030856

هل هناك أي تقدم في هذا؟ لدي حالة لا يبدو أن الحل المذكور يعمل (باستخدام [email protected] ) لأنني أواجه هذه المشكلة.


أولاً حاولت هذا:

import 'firebase';

declare global {
  const firebase;
}

يعطي هذا ضمنيًا firebase النوع any ، ثم يطبق مساحة الاسم (بنفس الاسم) عليه. أولاً ، بدا أن هذا يعمل لأنه يظهر التلميحات المناسبة / التحسس المناسب لجميع مفاتيح المستوى الأعلى من firebase .

ومع ذلك ، فهو لا يعمل بالفعل (أفترض لأنه يتحول بعد ذلك إلى استخدامه كنوع any ، والذي قد يكون خطأ؟):


لذلك جربت الحل البديل المذكور هنا دون نجاح (رغم أنه يعمل مع الآخرين):

import _firebase from 'firebase'; // same with = require('firebase') 

declare global {
  const firebase: typeof _firebase;
}

=> تتم الإشارة إلى "firebase" بشكل مباشر أو غير مباشر في نوع التعليق التوضيحي الخاص به.
(على الرغم من أن مساحة الاسم مستعارة؟)


حاولت أيضا

import * as _firebase from 'firebase';

declare global {
  const firebase: typeof _firebase;
}

=> تعريف دائري للاسم المستعار للاستيراد "_firebase".
(ربما بسبب export = firebase; export as namespace firebase; في تعريفها ؟)


وأخيرًا ، إذا قمت بعمل import 'firebase' ، فقد عدت إلى

يشير مصطلح "firebase" إلى UMD global ، لكن الملف الحالي عبارة عن وحدة نمطية. [2686]


إذا كان لدى أي شخص حل لهذا ، فسيكون موضع تقدير كبير. بخلاف ذلك ، أي من الاقتراحات التي تم ذكرها حتى الآن لحل هذه المشكلة تبدو جيدة حقًا (علامة ، مرجع مائل ثلاثي ، types في tsconfig ، وجود كائن global أو external كائن في tsconfig).

رد تعليق aluanhaddad

هذا لا يمكن أن يترك كل هذا في الوريد والعودة إلى الكرة الأرضية!

لا أحاول العودة إلى الكرة الأرضية ، فأنا أحاول فقط تحميل بعض التبعيات الثقيلة بشكل منفصل عن حزمة تطبيقي ، مع الاستمرار في استخدام الوحدات النمطية لكل شيء آخر ، لأنه يجلب بعض الفوائد: يمكن تخزين التبعيات مؤقتًا بشكل صحيح لأنهم لا يتم تحديثهم كثيرًا مثل حزمة التطبيقات الخاصة بي ؛ لا ينفجر حجم الحزمة الخاصة بي (أحيانًا بسبب تقسيم الكود ، تتضمن الحزمة نفس التبعية عدة مرات) ، مما يعني تنزيلًا أقل لمستخدمي تطبيقي ؛ إعادة بناء حزمي أثناء التطوير أسرع بكثير.

هذا هو في الحقيقة ميزة سهلة جدا لإضافة. سيكون من الرائع أن يأخذه أحد أعضاء المجتمع.

RyanCavanaugh لقد بحثت في الأمر compiler/types.ts وتعديل الشيك العمومي umd في compiler/checker.ts ، وأعتقد أنني بحاجة إلى إضافته إلى compiler/commandLineParser.ts أيضًا ... لكنني أعتقد أن الأمر سيستغرق بعض الوقت لإنجازه لأنني لست على دراية بالمصدر على الإطلاق (مثل كيف يمكنني إضافة وصف لعلامة CLI دون كسر i18n) . في الوقت الحالي ، سأنتظر شخصًا آخر يعرف المصدر ليقوم بذلك بالفعل.

simonhaenisch يمكنك التصريح عنه في ملف إعلان غير وحدة نمطية ، ولتجنب المرجع الدائري ، يمكنك إعادة تصديره في إعلان وحدة UMD آخر. تم الإعلان عن firebase الأصلي كمساحة اسم ، ومن حسن حظنا أنه سيزيد من إعلاننا ، ولن يتسبب في حدوث خطأ.

// umd.d.ts
import firebase = require("firebase");
export import firebase = firebase;
export as namespace UMD;

// global.d.ts
declare const firebase: typeof UMD.firebase;

لسوء الحظ ، ما أعلناه هو قيمة وليس مساحة اسم ، لذلك لا يمكنك فعل شيء مثل let x: firebase.SomeInterface ، الطريقة الوحيدة لاسم مستعار لمساحة الاسم هي الإعلان عن الاستيراد ، لكن لا يمكنك declare import firebase = UMD.firebase; ، لأن مساحة الاسم لن تزيدها. بالتأكيد يمكننا استخدام اسم مختلف لـ namspace فقط باستخدام الكتابة ، ولكن هذا سيؤدي إلى حدوث ارتباك ، أفضل إسقاط بقية الكود الذي تحدثت عنه أعلاه ، وتعيينه إلى قيمة عامة في وقت التشغيل ، وجعل الاسم المستعار للاستيراد يعمل حقًا.

على غرار التعليق السابق ، نحن كسول التحميل hls.js (UMD) وأنواع المراجع وبالتالي:

في hls.d.ts :

import * as Hls from 'hls.js';
declare global {
    const Hls: typeof Hls;
}

في الملف .ts باستخدام وحدة UMD ذات التحميل البطيء:

/// <reference path="hls.d.ts" />
// now use it
if(Hls.isSupported()){
 ...
} 

تم اختباره في ترميز> = 3.0.1 و 3.4.1.

الأساس المنطقي هو دعم المتصفح غير الكامل لواردات الوحدة الديناميكية.

MatthiasHild هل يمكن أن يتم ذلك بدون التعليق /// <reference path="hls.d.ts" /> ؟

EDIT ، نعم يمكن ذلك ، طالما أن الإعلان ضمن ملف .d.ts مضمن ليس له نفس الاسم مثل ملف .ts ، بناءً على سؤال SO هذا (هذا ما كان يحصل علي ولماذا سألت).

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات