Typescript: وفر طريقة لإضافة امتداد ملف ".js" إلى نهاية محددات الوحدة

تم إنشاؤها على ١٦ يونيو ٢٠١٧  ·  273تعليقات  ·  مصدر: microsoft/TypeScript

من أجل استخدام وحدات es6 في المتصفح ، تحتاج إلى امتداد ملف .js. لكن الإخراج لا يضيفه.

في ts:
import { ModalBackground } from './ModalBackground';
في إخراج ES2015:
import { ModalBackground } from './ModalBackground';

من الناحية المثالية ، أود أن يكون هذا ناتجًا
import { ModalBackground } from './ModalBackground.js';

بهذه الطريقة يمكنني استخدام الإخراج في Chrome 51

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Webpack boilerplate</title>
  <script type="module" src="index.js"></script>
</head>
<body></body>
</html>

image

متعلق بـ https://github.com/Microsoft/TypeScript/issues/13422

ES Modules Needs Proposal Suggestion

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

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

ال 273 كومينتر

لا يتعلق الأمر فقط بـ # 13422 ، إنها نفس المشكلة. لكن الردود كانت سلبية تمامًا ، على الرغم من حقيقة أنني أعتقد أنها قضية مهمة ، لذلك آمل أن يتم استقبال مشكلتك بشكل أفضل.

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

في الوقت الحالي ، لا يقوم TypeScript بإعادة كتابة المسارات. إنه أمر مزعج بالتأكيد ، ولكن يمكنك حاليًا إضافة الامتداد .js بنفسك.

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

شكرًا على النصيحة ، سأكتب برنامجًا نصيًا للقذيفة / العقدة للقيام بذلك.

DanielRosenwasser هل سيكون من المنطقي جمع مشكلات وحدة ES6 الأصلية تحت عنوان؟

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

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

لست متأكدًا من كيفية التعامل مع node_modules. عادةً ما تقوم حزمة الويب بتجميعها في الكود عبر أداة تحميل ts ولكن من الواضح أن المتصفح لا يفهم ذلك:

import { KeyCodes } from 'vanilla-typescript;
https://github.com/quantumjs/vanilla-typescript/blob/master/events/KeyCodes.ts#L3

إضافة امتداد js هنا لا معنى له.

أعتقد أنه يجب أن يكون هناك توسيع للمسار بواسطة الكتابة المطبوعة أو محلل عنوان url يعمل على الخادم.

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

لأي شخص قادم إلى هذا ويريد حلاً مؤقتًا ، قمت بكتابة نص برمجي لإضافة امتداد ملف js لاستيراد البيانات:

"use strict";

const FileHound = require('filehound');
const fs = require('fs');
const path = require('path');

const files = FileHound.create()
  .paths(__dirname + '/browserLoading')
  .discard('node_modules')
  .ext('js')
  .find();


files.then((filePaths) => {

  filePaths.forEach((filepath) => {
    fs.readFile(filepath, 'utf8', (err, data) => {


      if (!data.match(/import .* from/g)) {
        return
      }
      let newData = data.replace(/(import .* from\s+['"])(.*)(?=['"])/g, '$1$2.js')
      if (err) throw err;

      console.log(`writing to ${filepath}`)
      fs.writeFile(filepath, newData, function (err) {
        if (err) {
          throw err;
        }
        console.log('complete');
      });
    })

  })
});

قد أجعل هذا في أداة cli ..

تعليق justinfagnani يضرب المسمار في الرأس.

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

عندما تكتب

import { KeyCodes } from 'vanilla-typescript';

أو لهذه المسألة

import { KeyCodes } from 'vanilla-javascript';

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

إذا كنت تكتب تطبيقًا NodeJS ، فستحاول خوارزمية NodeJS Require حلولًا مختلفة ، ولكن من المحتمل ألا تحاول حلها إلى 'vanilla-typescript.js' لأنها تشير إلى اسم مجرد ، وسيتم حلها حسب الاصطلاح والتكوين ( ربما عبر محاولات مختلفة) إلى شيء مثل '../../../node_modules/vanilla_typescript/index.js' .

البيئات الأخرى ، مثل AMD لها اختلافات في كيفية تنفيذ هذا القرار ولكن هناك شيء واحد تشترك فيه كل هذه البيئات وهو فكرة معينة عن محدد وحدة مجردة.

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

قد يكون هذا بعيد المنال ، ولكن كما تكتشف ، ليس من الواقعي أن تكتب إلى هذا (بأدب) دليلًا على تنفيذ المفهوم الذي قدمناه لنا.

علاوة على ذلك ، لا أرى كيف يمكن أن تساعد TypeScript هنا لأن المشكلة تتعلق بالبيئة.

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

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

مرة أخرى ، تمتلك NodeJS و RequireJS AMD و Dojo AMD و Sea Package Manager و CommonJS و Browserify و Webpack و SystemJS طرقًا مختلفة للقيام بالأشياء ولكنها توفر جميعها دقة اسم مجردة. يجب عليهم تقديمه لأنه _ أساسي_.

شكرا لك على قراءة خرفتي.

لست متأكدًا من إصدار TS الذي أضافه ، ولكن عمليات الاستيراد مثل ' ./file.js' تعمل الآن (حتى إذا كان الملف هو file.ts بالفعل).
يقوم TypeScript بحل مشكلة الملف ، وإخراج استيراد .js الكامل إلى الهدف.
lit-html استخدمه: https://github.com/PolymerLabs/lit-html/blob/master/src/lib/repeat.ts#L15

إنه ممكن منذ TS 2.0. لكن أدوات مثل حزمة الويب لا تدعمها ، لذا فهي في النهاية غير مجدية.

لا فائدة من استخدام أداة تحميل ts في المصادر (حالة الاستخدام الأكثر شيوعًا).
لا يزال من الممكن تجميع الهدف (عادةً مجلد "dist") ، حيث يوجد ملف js الفعلي هناك ويمكن العثور عليه من خلال عملية الحل.

أتساءل عما إذا كان بإمكاني تنفيذ تحول سريع في ts-loader الذي يزيل امتدادات .js من الكود المستهدف ، مما يسمح للمرء بالتجميع مباشرة من المصادر.

لا تتردد في القيام بذلك ، سيكون ذلك رائعًا. لقد قمت بنشر المشكلة على لوادر webpack ts الرئيسية ، مثل ts-loader ، منذ بضعة أشهر ، وقد تم استقبالي بشكل سيء للغاية ...

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

أخفقت في معرفة ما يفعله هذا حتى تدعم تطبيقات أداة تحميل المستعرض ومواصفات محمل WGATWG على الأقل _ بعض التكوينات لأن معظم التبعيات لن يتم تحميلها بشكل صحيح.

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

حتى ذلك الحين سنظل معتمدين على أدوات مثل SystemJS و Webpack.

لقد أنشأت محولًا صغيرًا يزيل ".js" من بيانات الاستيراد / التصدير.
لقد استخدمت حراسًا من النوع tsutils ، لذلك yarn add tsutils --dev . (عادةً ما يتم تثبيت الحزمة على أي حال إذا كان لديك tslint في مشروعك ، لذلك تبعية إضافية)

https://gist.github.com/AviVahl/40e031bd72c7264890f349020d04130a

باستخدام هذا ، يمكن للمرء تجميع ملفات ts التي تحتوي على واردات من ملفات تنتهي بـ .js (باستخدام webpack و ts-loader ) ، ولا يزال تحويل المصادر إلى وحدات esm التي يمكن تحميلها المتصفح (باستخدام tsc ).

ربما يكون هناك عدد محدود من حالات الاستخدام حيث يكون ذلك مفيدًا.

تحرير: لقد قمت بتحديث الجوهر للعمل مع الصادرات أيضًا. إنها ساذجة وغير محسّنة ، لكنها تعمل.

أي تحرك في هذا الموضوع؟

مسألة التمديد هذه تعود بنا إلى بداية TypeScript ولماذا كانت هناك حاجة tsconfig.json ولماذا تمت إضافة خيار module إلى إعداد compilerOptions .

نظرًا لأن الأمر يتعلق بامتداد extension إلا لـ ES2015 + حيث أن الطلب قادر على حلها جيدًا ، دع المترجم يضيفها عندما يكون الرمز المستهدف هو ES2015 +.

  1. .js مقابل .ts
  2. .jsx مقابل .tsx

مرحبًا ، أنا قادم في هذا الوقت متأخرًا ولكني أرغب في المساعدة. أواجه مشكلة في فهم المشكلة هنا. من مثال OP هو:

import { ModalBackground } from './ModalBackground';

هل المشكلة أننا لا نعرف ما هو './ModalBackground' ؟ يمكن أن يكون مجلد أو أي شيء آخر؟

إذا قمنا بتشغيل tsc على المشروع بأكمله وعرفنا أن ModalBackground.ts موجود ، فسنعلم أنه من الآمن إضافة الامتداد ، أليس كذلك؟

هذه المشكلة أيضًا أمر يهتم به مجتمع RxJS بشدة. ما هو الجدول الزمني لحل هذا الأمر؟ هل هي حتى ذات الأولوية؟ هل هناك أي تحولات من طرف ثالث من شأنها أن تساعد؟

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

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

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

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

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

justinfagnani تم تفسيرهم بالفعل برأي متضارب. ينتج TS ملف JS لا يشير إليه كود JS الذي ينتجه. ES6 هو أقرب شيء إلى الطريقة الصحيحة رسميًا للقيام بـ JavaScript ، لذلك إذا كان كود ES6 الذي تم إنتاجه بواسطة TypesScript خاطئًا ، فهذا خطأ بسيط وبسيط. ليست هناك حاجة لانتظار أي دعايات وما إلى ذلك ، فقط أصلح خطأ TypeScript. لكن الناس اليوم يشعرون أنهم إذا لم يجدوا خطأً في شيء ما ووضعوه في 10 طبقات من الاقتراح قبل التصرف ، فإنهم لا يتصرفون بطريقة فكرية. أعطني إستراحة.

aluanhaddad صحيح أن العديد من المشاريع لن تستفيد ، ولكن هناك بعض المشاريع التي لا تستخدم تبعيات npm (أو التي تكون قادرة على التعامل مع تبعيات npm بطريقة ما) ، لذلك ستستفيد هذه المشاريع.

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

justinfagnani لم يتم توحيدها أو تنفيذها بعد ، ولكن هناك اقتراح لجعل حزم npm تعمل في المتصفح.

يمكن إنشاء خريطة اسم الحزمة تلقائيًا بواسطة مترجم TypeScript أو بواسطة أداة أخرى.

لذلك أنا أعيد النظر في هذا مرة أخرى ، هل كان هناك أي حل لطيف لهذا ، بصرف النظر عن البرنامج النصي الخاص بالعقدة؟

كنت أستخدم هذا الحل:
https://github.com/Microsoft/TypeScript/issues/16577#issuecomment -343610106

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

أي حركة على هذا؟

ربما https://github.com/Microsoft/TypeScript/pull/25073 يمكنه حل هذا؟

Kingwl هل ستدعم بعض امتدادات الملفات الأخرى؟ مثل .mjs .es .esm .

ربما لا ، فهذه ميزة أخرى

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

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

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

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

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

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

لا يهم أي من وحدات المتصفح.

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

تنصل:

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

راجع للشغل ، أثناء البحث في مصدر TypeScript ، أرى importModuleSpecifierEnding - هل يمكن استخدام هذا (ab) لجعل الباعث يستخدم .js endings؟

ربما هريسة هذا الاقتراح مع مخطط tsconfig؟ https://github.com/domenic/package-name-maps

في هذه المرحلة ، سأكون سعيدًا إذا كان بإمكان TypeScript إعادة كتابة الواردات تلقائيًا فقط باستخدام paths المحدد في tsconfig. حتى بدون دعم المتصفح الذي من المحتمل أن يحل معظم نقاط الألم بالنسبة لي.

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

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

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

بعد ذلك ، ربما يقبل مترجم Typescript خيارًا لإضافة الامتدادات أم لا. ربما يمكنه حتى قبول مجموعة من regex من أجل إضافة (أو عدم) الامتداد ، مثل خيار التضمين (https://www.typescriptlang.org/docs/handbook/tsconfig-json.html).

نعم ، لقد تم اقتراحه مرة واحدة على الأقل من قبل ، فلماذا لا تأخذ ذلك في الاعتبار؟ يحتوي TS بالفعل على بعض الميزات التجريبية التي قد تتغير في المستقبل بمجرد تنفيذها في المتصفح ، لكن TS لديها بالفعل علامات لتلك المواصفات غير المستقرة. لماذا لا يكون لديك مجرد علم تجريبي addImportsExtensions حيث يمكن أن يؤدي فقط module += '.js' ، هذا كل شيء! لا منطق غير تقليدي ، ولا ميزات إضافية. قد يكون هدفًا مختلفًا إذا كنت تفضل الاحتفاظ به كهدف منفصل. أكثر من ذلك ، إذا قبلت أيًا مما سبق ، فسأبحث شخصيًا في كود tsc وأقوم بعمل علاقات عامة لذلك ، فقط لا أريد أن أضيع وقتي إذا لم يتم قبوله على أي حال.

يمكنك ببساطة استخدام تحويل مخصص لإعادة كتابة الواردات في الكود المنبعث (إضافة ".js" أو استخدام المسار الذي تم حله لاستيراد الوحدة النمطية).

كيفية كتابة تحويل TypeScript
ttypescript: غلاف لـ tsc يطبق عمليات التحويل أثناء التحويل البرمجي

ربما يوجد بالفعل تحويل موجود يقوم بما تحتاجه.

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

ajafff ​​قد يكون هذا حلاً ، لكنني أعتقد أن المشكلة الرئيسية هي التالية: يُنشئ ناسخ الأنواع كود مصدر خاطئ في المتصفحات. من الجيد إجراء تحويلات ، لكنني أرى ذلك كحل بديل. أتساءل عما إذا كان عليّ الاهتمام بتفاصيل الترجمة وأحتاج إلى تنفيذ التحويل الخاص بي أم أنه شيء يجب أن يديره المترجم.

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

نعم ، لقد تم اقتراحه مرة واحدة على الأقل من قبل ، فلماذا لا تأخذ ذلك في الاعتبار؟ TS لديها بالفعل بعض الميزات التجريبية

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

يُنشئ ناسخ التنضيد شفرة مصدر خاطئة في المستعرضات

أتفهم توقعاتك ، ولكن نظرًا لأن المترجم لا يعيد كتابة المسارات التي كتبتها ، فأنا مندهش من أنك لا تعتبر أن واردات الكود الخاص بك "خاطئة". 😉

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

  1. هل فريق الطباعة على استعداد لشحن هذه الميزة؟
  2. إذا كانت الإجابة بنعم ، فهل تقبل العلاقات العامة؟
  3. إذا كانت الإجابة "لا" ، فمتى تخطط للإفراج عن هذا؟

إذا كانت إجابة السؤال الأول هي "لا" ، من فضلك ، أغلق هذه المشكلة مع الإعلان رسميًا عن عدم رغبتك في شحن هذه الميزة ، ولا تجعل الآخرين ينتظرون إذا لم يأتوا.

نعم ، لقد تم اقتراحه مرة واحدة على الأقل من قبل ، فلماذا لا تأخذ ذلك في الاعتبار؟ TS لديها بالفعل بعض الميزات التجريبية

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

يُنشئ ناسخ التنضيد شفرة مصدر خاطئة في المستعرضات

أتفهم توقعاتك ، ولكن نظرًا لأن المترجم لا يعيد كتابة المسارات التي كتبتها ، فأنا مندهش من أنك لا تعتبر أن واردات الكود الخاص بك "خاطئة". 😉

إنها نقطة جيدة DanielRosenwasser ، لقد اعتبرت الكود الخاص بي صحيحًا لأنه يبدو أنه من الصحيح قراءة مواصفات Typescript (https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#11.3).

أنا متأكد من أنك قرأت مواصفات ECMAScript. في المواصفات ، لم يتم تحديد ما إذا كان يجب أن تنتهي الوحدة بامتداد أم لا. في المواصفات ، يتم حل استيراد الوحدات النمطية باستخدام خوارزمية HostResolveImportedModule ، لكن التعريف غامض. المشكلة ليست مواصفات ECMAScript. تكمن المشكلة في أن المتصفحات تحل الوحدات كما لو أن [ModuleRequest] كما هو محدد في المواصفات كان مسارًا إلى الموارد.

مع وضع ذلك في الاعتبار ، ما عليك سوى الانتقال إلى الصفحة الرئيسية للغة: https://www.typescriptlang.org/ .

يمكنك قراءة الأسطر التالية في تذييل الصفحة:

يبدأ وينتهي بـ JavaScript

يبدأ TypeScript بنفس بناء الجملة والدلالات التي يعرفها الملايين من مطوري JavaScript اليوم. استخدم كود JavaScript الموجود ، وادمج مكتبات JavaScript الشائعة ، واستدع كود TypeScript من JavaScript.

يقوم TypeScript بتجميع تعليمات JavaScript البرمجية النظيفة والبسيطة التي يتم تشغيلها على أي متصفح ، في Node.js ، أو في أي محرك JavaScript يدعم ECMAScript 3 (أو أحدث).


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

كما يشير Draccoz ، نريد فقط أن نعرف ماذا تفعل مع هذه المشكلة. لكن من المحبط بعض الشيء أن تقرأ شيئًا واحدًا في صفحتك الرئيسية والعكس في هذه المشكلة.

لا ، لسنا على استعداد لشحن أي شيء متعلق بهذا حتى يكون هناك وضوح على الأقل حول أشياء مثل ES interop في Node واستراتيجية معقولة لشحن التبعيات المتعدية التي تستخدمها من npm في المقام الأول. إذا لم تكن تستخدم TypeScript ، فستواجه نفس المشكلة فيما يتعلق بإدارة التبعية والقرار ، لذلك ليس من المنطقي بالنسبة لنا أن نبتكر شيئًا قد يطوره نظام JS البيئي بشكل عام بشكل مستقل. ولكن حتى لو تم حل هذه المشكلات ، لا يمكنني تقديم ضمانات بإجراء أي تغيير هنا.

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

أعتقد أن هذا التفسير حرفي للغاية. var fs = require('fs') لا يعمل عند تشغيله في المتصفح ، HTMLDivElement غير معرّف في Node ، و String.prototype.startsWith لا يعمل على المتصفحات الأقدم. لحل هذه المشكلة ، أنشأ الأشخاص أدوات ومكتبات / ملفات متعددة خارج TypeScript لأنها تنطبق على نظام JavaScript البيئي الأوسع.

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

DanielRosenwasser شكرًا لك على ردك السريع ، وأنا أقدر ذلك حقًا. أعتقد أنه اختيار حكيم.

أعتقد أن هذا التفسير حرفي للغاية. var fs = يتطلب ('fs') لا يعمل عند تشغيله في المتصفح ، ولا يتم تعريف HTMLDivElement في Node ، ولا يعمل String.prototype.startsWith على المتصفحات القديمة. لحل هذه المشكلة ، أنشأ الأشخاص أدوات ومكتبات / ملفات متعددة خارج TypeScript لأنها تنطبق على نظام JavaScript البيئي الأوسع.

بالطبع هو كذلك ، ولكن ¿ما الذي يمكن أن يعتقده أي شخص لا يعرف شيئًا عن الكتابة المطبوعة؟ حقيقة أن تفسيري حرفي للغاية هي حقيقة حقيقة أن هذا النص يمكن أن "يربك" أي شخص لا يعرف شيئًا عن كتاب الطباعة 😉.

ربما يمكنك تحديث مستنداتك (https://www.typescriptlang.org/docs/handbook/modules.html) لتعكس السلوك الفعلي.

DanielRosenwasser أشكرك مرة أخرى على ردك. لقد كنت أنتظر شيئًا مشابهًا لمدة عام.

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

بالنسبة للأشخاص مثلي الذين يبحثون عن حل للقدرة على استخدام وحدات ES و TypeScript في المتصفح اليوم ، وجدت https://github.com/guybedford/es-module-shims. إنه بمثابة نوع من polyfill لخرائط اسم الحزمة بينما ننتظر إنهاء المواصفات وتنفيذ المتصفح. إنه يحل مشكلة QuantumInformation المتمثلة في عدم استخدام أي أدوات بناء (مشكلتي أيضًا) عند تأليف تطبيق ويب بسيط في TypeScript (بصرف النظر عن مترجم TS).

import 'knockout'

export class MyViewModel {
    greeting: KnockoutObservable<string>
    target: KnockoutObservable<string>
    constructor() {
        this.greeting = ko.observable('hello')
        this.target = ko.observable('world')
    }
}
<!DOCTYPE html>


md5-f28d4b503a1603c40bfeb342f341bfbe


<main>
    <span data-bind='text: `${greeting()} ${target()}`'></span>
    <script type='module-shim'>
        import 'knockout'
        import { MyViewModel } from 'index'
        ko.applyBindings(new MyViewModel())
    </script>
</main>

من الناحية النظرية ، بمجرد أن يتم دعم خرائط اسم الحزمة بواسطة المتصفحات ، يمكنك فقط العثور على / استبدال type='module-shim' بـ type='module' في ملفات HTML الخاصة بك وتغيير البرنامج النصي الخاص بخريطة الحزمة إلى أي شيء ينتهي به الأمر لإدراج packagemap في المواصفات.

من الجدير بالذكر أيضًا أن الامتداد .js غير مطلوب من قبل المتصفحات أو أي شيء آخر - يمكنك دائمًا تكوين خادم الويب الخاص بك ليكون أكثر من unpkg -like وتقديم ملفات .js من طلب عناوين URL غير القابلة للتمديد. كل شيء قابل للتكوين من جانب خادم الويب.

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

بالمناسبة ، لا تمنع هذه المشكلة الوحدات النمطية التي تم إنشاؤها بواسطة TypeScript من استخدامها في المتصفحات اليوم. فقط قم دائمًا باستيراد الملفات بامتداد .js . tsc يفعل الشيء الصحيح ويحل الأنواع من ملف .ts ، وستحصل على توافق المتصفح.

weswigham ضع في اعتبارك أن هناك مواقف تقدم فيها ملفات دون الوصول إلى خادم الويب. GitHub Pages و IPFS و S3 وما إلى ذلك .. مع ظهور أطر عمل التطبيق ذات الصفحة الواحدة ، أصبح من الشائع أكثر فأكثر تشغيل "بدون خادم" (حيث يعني عدم وجود خادم هنا بدون خادم تتحكم فيه / تهيئته لخدمة أصولك) ، لذلك أنت لا يمكن الاعتماد على عوامل التصفية من جانب الخادم لخدمة apple.js عند تقديم طلب للحصول على apple .

يجب أن تتأكد من أنك تشير إلى ملف بنفس الطريقة تمامًا عند كل استيراد.

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

فقط قم دائمًا باستيراد الملفات ذات الامتداد .js

يا ، هذا يعمل بشكل جيد أيضًا.

QuantumInformation هل المقتطف المستخدم هنا للاستخدام المفتوح؟ هل يمكنني استخدامه في مشروع؟ 😃

distante نعم يمكنك استخدامه

لمعلوماتك إذا كنت تستخدم Jest للاختبار والتغيير إلى الامتدادات إلى .js في المصدر - فإنها تنكسر
ولكن يمكنك إضافة ما يلي إلى تهيئة jest لإصلاح ذلك

  "jest": {
    ...
    "moduleNameMapper": {
      "(.*)\\.js": "$1"
    }
  }

مرحبا @ MrAntix ،

أعتقد أن Jest هي المكتبة التي يجب أن تتكيف مع TypeScript ، وليس العكس.

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

https://github.com/microsoft/TypeScript/issues/16577#issuecomment -452312753

كحل بديل ، يمكنك القيام بذلك على هذا النحو (على الرغم من أنه ملف ts وليس js) 😢

Screenshot 2019-06-05 at 22 47 49

إذا أراد أي شخص تجربته:
https://github.com/QuantumInformation/web-gen-bot

ومع ذلك ، لا يمكنني الحصول على تصحيح أخطاء المصدر للعمل مع tsconfig الحالي ، وسوف يعود التقرير.

في النهاية عدت إلى webpack ، كانت node_modules هي القاتل عند محاولة الابتعاد عن أدوات البناء في المتصفح.

إنها ليست مجرد Jest - إذا كنت تستخدم tsc لترجمة TypeScript قبل النشر ، فإن أي وحدة JS تستورد الحزمة الناتجة ستتعطل بسبب الاختلافات في دقة الوحدة.

يبدو أن المناقشة هنا قد انقسمت قليلاً إلى مسألتين مترابطتين ولكن منفصلتين في النهاية:

  • يجب أن يُنشئ تنضيد الملفات ملفات يمكن تحميلها أصليًا في المستعرض
  • يجب أن تحل الكتابة المطبوعة حقيقة أن مسارات وحدة العقدة ليست دائمًا عناوين URL صالحة.

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

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

في رأيي ، يتلخص الموضوع في هذا:

إذا كان تشغيل tsc ينتج ملفًا بامتداد .js ثم ملف آخر يستورد أول ملف .js ، فلا يوجد غموض حول الامتداد الذي يجب استخدامه ، ويجب أن يكون هناك خيار لتضمين التمديد.

بالنسبة لجميع عبارات الاستيراد التي تشير إلى ملفات أخرى غير الملفات التي تنشئها Typescript ، أعتقد أنه من الجيد ترك تلك البيانات دون تغيير (كما يفعل Typescript اليوم).

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

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

أقول هذا لأنه إذا كنت أستخدم حزمة الويب ، فأنا لا أريد إضافة .js إلى الواردات لأن webpack يعتني بتجميع الوحدات.

يتعامل Webpack مع الامتداد .js بشكل جيد تمامًا ، لذلك لا يوجد فرق.

في الواقع ، من الضروري أحيانًا استخدام .js مع Webpack (في المواقف التي توجد فيها ملفات متعددة بنفس الاسم ولكن بامتدادات مختلفة).

هل يمكنك أن تشرح المزيد عن سبب عدم رغبتك في استيراد .js باستخدام Webpack؟

عندما أقول I don't want أعني أنني لست بحاجة إلى حالات الاستخدام الخاصة بي.

لا أرى سببًا مقنعًا لعدم كونه السلوك الافتراضي بعد ذلك (ممانع دائمًا في إضافة علامة تكوين أخرى ...)

يؤدي تعيين عمليات الاستيراد على .js إلى توقف ts-node عن العمل بشكل صحيح للملف. هذا لأن ts-node يجمع ملفًا واحدًا فقط في كل مرة وإذا انتهى الأمر بمحتويات الملف المنبعث بـ require('./foo.js') فعندئذ عندما يعالج nodejs هذا الملف ، سيحاول تحميل ./foo.js وهو غير موجود في أي مكان على القرص وبالتالي سوف تفشل. عندما يتطلب الكود ( ./foo ) من ناحية أخرى ، سيتم استدعاء معالج ts-node وعند هذه النقطة يمكنه تجميع ./foo.ts في JS وإرجاع ذلك.

إذا قامت TypeScript بإصدار امتدادات .js في جميع الحالات ، فستواجه ts-node نفس المشكلة. ومع ذلك ، إذا كان هناك خيار للتبديل بين إضافة الامتدادات تلقائيًا أم لا ، فيمكن عندئذٍ ts-node ضبط خيار المترجم على إيقاف التشغيل ، مما سيسمح للنظام الحالي بمواصلة العمل.

نظرًا لأن Node.js --experimental-modules يتطلب امتدادات ملفات إلزامية ، فإن واجهة برمجة التطبيقات الخاصة بذلك واضحة ومباشرة دون الحاجة إلى تحليل التبعية - يمكن لخيار مثل --jsext إعادة كتابة أي امتداد .ts إلى .js تمديد .ts مثل import 'npmpkg.ts' . هذه الحالة نادرة للغاية ، ولكن للتعامل معها بشكل شامل في الدقة ، يمكن أن تكون القاعدة هي إجراء استثناء لـ _bare Specifiers_ على غرار - إذا كان المحدد المجرد (ليس عنوان URL أو المسار النسبي) هو اسم حزمة npm صالح ( مطابقة /^(@[-_\.a-zA-Z\d]+\/)?[-_\.a-zA-Z\d]+$/ ، من https://github.com/npm/validate-npm-package-name) ، ثم تجاهل امتدادات .ts في إعادة الكتابة.

لقد قمت بإنشاء محول مترجم TypeScript والذي سيلحق بامتداد ملف .js بأي مسار استيراد نسبي. هذا يعني أنه إذا كان ملفك .ts يحتوي على import { Foo } from './foo' فسيصدر import { Foo } from './foo.js' . إنه متاح على NPM ، ويمكن العثور على إرشادات حول كيفية استخدامه في الملف التمهيدي للمشروع.

https://github.com/Zoltu/typescript-transformer-append-js-extension

إذا تم دمج شيء من هذا القبيل في مترجم TypeScript (كخيار مترجم) ، فمن المحتمل أن يكون أكثر ذكاءً في تحديد وقت إلحاق الامتداد .js ومتى لا يتم ذلك. يبحث الآن عن أي مسار يبدأ بـ ./ أو ../ ولا يحتوي على . في أي مكان آخر في المسار. هذا يعني أنه لن يفعل الشيء الصحيح في عدد من سيناريوهات الحالة المتطورة ، على الرغم من أنني أتساءل عما إذا كان أي شخص _ في الواقع _ سيواجه تلك الحالات الحافة أم لا.

MicahZoltu رائع لرؤية حلول userland لهذا. أعتقد أنه من المهم جدًا أن يشتمل النموذج العقلي دائمًا على امتدادات الملفات ، بحيث يمكن أن يصبح خيار امتداد TypeScript _t turn. يؤدي ذلك إلى تجنب حالات حافة الحل ، تاركًا فقط حالة أسماء حزم npm التي تنتهي بـ ".ts" ، والتي يمكن معالجتها كما ناقشت في تعليقي السابق.

guybedford بما في ذلك امتداد .js في ملف .ts يجعله لذلك لا يمكن تنفيذ الملف في ts-node. حل المشكلة في ts-node ليس بالأمر السهل نظرًا للطريقة التي يقوم بها NodeJS بتحليل الملف. هذا يعني أنك إذا نشرت مكتبة بامتدادات .js مشفرة ، فلن تعمل المكتبة لأي شخص يستخدم ts-node. راجع المناقشة حول هذا في https://github.com/TypeStrong/ts-node/issues/783.

MicahZoltu أعني تضمين امتداد .ts في ملف .ts بدلاً من ذلك.

guybedford بما في ذلك الامتداد .js في ملف .ts يجعله لذلك لا يمكن تنفيذ الملف في ts-node.

هذا سبب آخر يجعل تنفيذ TypeScript تلقائيًا في العقدة والمتصفحات فكرة سيئة.

MicahZoltu أعني تضمين امتداد ts في ملف .ts بدلاً من ذلك.

أعتقد أن المشكلة في هذا هو أنه يكسر التكافؤ بين ملف .ts # $ وزوج .js / .d.ts . هذا يعني أنه إذا كنت تقوم باستيراد ملف تم تجميعه مع المشروع الحالي ، فإنك تستخدم .ts ، وإذا قمت بنقل الملف إلى مشروع مختلف ، فستحتاج إلى تغيير عمليات الاستيراد إليه لاستخدام .js .

هذا يعني أيضًا أن الإخراج لا يعمل في البيئات القياسية بدون المحول. نظرًا لعدم وجود طريقة لتثبيت محول من ملف .tsconfig ، فهذا يعني أنه يتعين عليك دائمًا استخدام مترجم مخصص. هذا عائق كبير جدًا يجب وضعه من أجل فائدة صغيرة تتمثل في استخدام .ts بدلاً من .js .

هذا يعني أنك إذا كنت تقوم باستيراد ملف تم تجميعه باستخدام المشروع الحالي ، فإنك تستخدم .ts ، وإذا قمت بنقل الملف إلى مشروع مختلف ، فستحتاج إلى تغيير عمليات الاستيراد إليه لاستخدام .js.

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

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

بينما يمكن أن يساعدنا المحول في استكشاف هذا الأمر ، هناك حاجة ماسة إلى علامة / خيار مترجم --ts-to-js أو ما شابه ذلك لحل هذه المشكلة.

guybedford لقد أقنعتني أن وضع .ts هو الشيء الصحيح الذي يجب القيام به للمكوِّن الإضافي. ومع ذلك ، عند محاولة تنفيذه ، علمت أن TypeScript لا تسمح بذلك بالفعل!

// foo.ts
export function foo() { console.log('foo') }
// bar.ts
import { foo } from './foo.ts' // Error: An import path cannot end with a '.ts' extension. Consider importing './foo' instead
foo()

مرحبا ماذا عن هذا؟


إدخال:

// src/lib.js.ts
export const result = 42;
// src/index.js.ts
import { result } from "./lib.js";

console.log(result);

انتاج:

// build/lib.js
export const result = 42;
// build/index.js
import { result } from "./lib.js";

console.log(result);

العدد 30076

يبدو أن الامتداد الوحيد .ts في ملف TypeScript هو الأنسب بالنسبة لي. غالبًا ما لا تعرف حتى وقت التجميع ما هو الهدف. على سبيل المثال ، في العديد من مشاريع مكتبتي لدي عدة ملفات tsconfig.json تستهدف بيئات مختلفة ، مثل استهداف المتصفحات الحديثة التي يجب أن ترسل ملفات .js وتعيين مسارات الاستيراد إلى .js ، أو استهداف Node الحديثة ، والتي يجب أن ترسل ملفات .mjs وتعيين مسارات استيراد إلى .mjs .

MicahZoltu أن استيراد الملفات المنتهية بـ .ts قد يكون خطأ في صالحنا في الواقع. لأن هذا يعني أنه يمكن إضافة امتداد .ts إلى .js عند إعادة كتابة الترجمة كلما تم استخدام ملحقات .ts دون الحاجة إلى علامة :)

ربما تكون العلاقات العامة لتمكين ملحقات .ts اللاحقة التي يتم دعمها وإعادة كتابتها إلى امتدادات .js (ربما تكون تحت علامة لتمكين هذه الميزة ، ولكن العلامة التي يمكن إزالتها في الوقت المناسب) ستكون طريقة رائعة للبدء في هذا الطريق.

// ccDanielRosenwasser

هذه المشكلة طويلة بالفعل ، لذا ربما قال شخص ما هذا بالفعل ، لذا فأنت معرض لخطر تكرار ما قيل بالفعل:

يجب أن تسمح TypeScript للمطورين بتحديد الامتدادات في import s لأنها لغة JavaScript صالحة. وهذا لا يتعلق بتمديد JS / TS فقط! في ESM ، يكون أي ملحق صالحًا طالما أن نوع MIME صحيح.

import actuallyCode from './lookLikeAnImage.png';

… يجب أن يكون صالحًا طالما أن الخادم يخدم JavaScript صالحًا في ذلك الملف ويعين نوع MIME الصحيح. يذهب هذا إلى أبعد من ذلك لأن الأمر نفسه يمكن أن يكون صحيحًا بالنسبة لـ TS! يمكن أن يكون ملف TS عبارة عن رمز مصدر JS يتم تقديمه مع نوع JS MIME وبالتالي فهو مسار صالح لاستيراد وحدة ESM.

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

عذرًا ، إذا لم يكن هذا هو المكان المناسب لإثارة هذا ، فقد رأيت بعض المشكلات الأخرى: # 18971 ، # 16640 ، # 16640 ولكن يبدو أن المشكلات المتعلقة بهذا الموضوع يتم إغلاقها من اليسار واليمين ، لذا أفترض أن هذا هو المشكلة "الرئيسية" منذ أن سمح لها بالبقاء مفتوحة.

اللعب مع NodeJS v12.7.0

salathiel@salathiel-genese-pc:~/${PATH_TO_PROJECT}$ node --experimental-modules dist/spec/src/ioc
(node:15907) ExperimentalWarning: The ESM module loader is experimental.
internal/modules/esm/default_resolve.js:59
  let url = moduleWrapResolve(specifier, parentURL);
            ^

Error: Cannot find module '${PROJECT_ROOT}/dist/spec/src/ioc' imported from ${PROJECT_ROOT}/
    at Loader.resolve [as _resolve] (internal/modules/esm/default_resolve.js:59:13)
    at Loader.resolve (internal/modules/esm/loader.js:73:33)
    at Loader.getModuleJob (internal/modules/esm/loader.js:149:40)
    at Loader.import (internal/modules/esm/loader.js:133:28)
    at internal/modules/cjs/loader.js:830:27
    at processTicksAndRejections (internal/process/task_queues.js:85:5) {
  code: 'ERR_MODULE_NOT_FOUND'
}
salathiel@salathiel-genese-pc:~/${PATH_TO_PROJECT}$ node --experimental-modules dist/spec/src/ioc.js
(node:16155) ExperimentalWarning: The ESM module loader is experimental.
internal/modules/esm/default_resolve.js:59
  let url = moduleWrapResolve(specifier, parentURL);
            ^

Error: Cannot find module '${PROJECT_ROOT}/dist/spec/src/observe' imported from ${PROJECT_ROOT}/dist/spec/src/ioc.js
    at Loader.resolve [as _resolve] (internal/modules/esm/default_resolve.js:59:13)
    at Loader.resolve (internal/modules/esm/loader.js:73:33)
    at Loader.getModuleJob (internal/modules/esm/loader.js:149:40)
    at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:43:40)
    at link (internal/modules/esm/module_job.js:42:36) {
  code: 'ERR_MODULE_NOT_FOUND'
}

الآن ، لست متأكدًا من سبب إزعاج هذا ...

في الوقت الحالي ، لا يقوم TypeScript بإعادة كتابة المسارات. إنه أمر مزعج بالتأكيد ، ولكن يمكنك حاليًا إضافة الامتداد .js بنفسك.

DanielRosenwasser https://github.com/microsoft/TypeScript/issues/16577#issuecomment -309169829

ماذا عن التنفيذ وراء خيار؟ مثل --rewrite-paths ( rewritePaths: true

@ viT-1 هنا حل بديل في الوقت الحالي: https://github.com/microsoft/TypeScript/issues/16577#issuecomment -507504210

MicahZoltu لقد حللت للتو حالة الاستخدام الخاصة بي عن طريق تجميع SystemJS (خيار tsconfig outFile)

لم أقرأ كل تعليق كتبه الناس حول هذا ، لكنني لا أعرف لماذا يجب أن أكتب .js a gazillion مرة. أريد أن يقوم الكمبيوتر بذلك من أجلي.

richardkazuomiller كلنا نفعل ذلك ، لكن DanielRosenwasser صرح في https://github.com/microsoft/TypeScript/issues/16577#issuecomment -448747209 أنهم ليسوا على استعداد للقيام بذلك في الوقت الحالي (أنا مندهش من أن هذه المشكلة لا تزال مفتوحة بشكل مضلل لفترة طويلة بعد البيان أعلاه). إذا كنت تريد أن يقوم الكمبيوتر بذلك نيابةً عنك ، ففكر في استخدام أداة تجميع أو بعض أدوات الطرف الثالث للتعامل مع إعادة كتابة مسارات الاستيراد.

من يريد مني إغلاق هذه القضية؟

من فضلك لا تغلق ، ما زلت أنتظر لمعرفة كيف سيستجيب فريق TypeScript لكيفية التعامل مع عمليات استيراد ESM التي تسمح باستخدام أي امتداد والاعتماد على نوع MIME بدلاً من ذلك. هذا ممكن في الوقت الحالي في JavaScript ولكن ليس في TypeScript. (يرجى الاطلاع على تعليقي السابق للحصول على التفاصيل.)

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

كما قيل سابقًا:

لست متأكدًا من إصدار TS الذي أضافه ، ولكن عمليات الاستيراد مثل ' ./file.js' تعمل الآن (حتى إذا كان الملف هو file.ts بالفعل).
يقوم TypeScript بحل مشكلة الملف ، وإخراج استيراد .js الكامل إلى الهدف.

هذا منطقي لأن أي JavaScript صالح هو TypeScript صالح. حيث يمكنك القيام بما يلي:

import foo from './bar.js'

... في JS ، يجب أن تكون قادرًا على القيام بذلك في TS أيضًا. إذا قمت بذلك ، فإنك تحل مشكلة استخدام وحدات ES6 الأصلية لأنك حصلت على امتداداتك بشكل صحيح.


دعونا أيضًا لا ننسى أنه عندما يرى المتصفح استيرادًا لـ ./foo/bar ، فإنه في الواقع يقدم طلبًا لذلك. حقيقة أنه لم يتم تقديم أي شيء كان بسبب الخادم. يمكنك تكوينه بطريقة تجعل طلبات /foo/bar راضية عن /foo/bar.js . عدم القول إن هذا حل جيد ، أو حتى فكرة جيدة ، لكنه سيعمل من الناحية الفنية.

علامة في ملف التكوين ، فقد تشير إلى أن جميع عمليات الاستيراد التي لا تحتوي على امتدادات يجب أن تحتوي على امتداد

هذا من شأنه أن يحل الغالبية العظمى من الحالات. هل سيكون فريق TypeScript على استعداد للنظر في العلاقات العامة لخيار التكوين هذا؟

NodeJS الآن _ افتراضيًا_ يتصرف بنفس الطريقة التي تتصرف بها المتصفحات عندما يتعلق الأمر بدقة وحدة المسار النسبية. لن تستنتج بعد الآن امتداد .js افتراضيًا. هذا يعني أن السلوك الحالي لـ TSC ينتج عنه إصدار JS غير صالح في جميع سياقات وقت التشغيل. يبدو أنه يجب معالجة هذه المشكلة الآن نظرًا لوجود وضوح في كل من المتصفح وسلوك NodeJS لـ ESM.

https://nodejs.org/api/esm.html#esm_customizing_esm_specifier_resolution_algorithm

يحتاج المحلل الجديد لـ esm إلى وضع دقة جديد - moduleResolution: node هو في الحقيقة مجرد محلل cjs لما يمكنني تسميته الآن "الإصدارات القديمة من العقدة". إذا كنت تنوي استهداف محلل esm الجديد ، فسنحتاج إلى وضع دقة جديد لمطابقة أكثر ملاءمة. خاصة وأن العقدة لا تزال تدعم المحلل القديم بشكل كامل في جميع التكوينات الحالية. (يرجى ملاحظة: إنشاء مثل هذا المحلل الجديد _ الافتراضي الخاص بك_ سيكون صعبًا)

على أية حال! على الرغم من وجود _ خلاف_ حول هذا الموضوع و _ سيختار بعض الأشخاص إبداء الرأي على أنه حقيقة _ ، لا يزال هناك علامة --es-module-specifier-resolution=node تعرض سلوك الامتداد المتوقع وقد تظل هي الوضع الافتراضي - كما تقول المستندات ، على الرغم من عدم الإشارة إليها ، الوحدات النمطية في العقدة _لا تزال تجريبية بطبيعتها_.

أيضًا ، كتذكير للطلب الأصلي: نحن لا نعيد كتابة عمليات الاستيراد. أي وقت مضى. على الاطلاق. المحدد في === المحدد خارج. تصف المحددات النية الهيكلية ، وليس هدفنا أن نربط ضمنيًا من هيكل مقصود إلى آخر. يمكنك أيضًا التفكير في الأمر بهذه الطريقة: إذا كتبت const varFoo = "./Foo"; import(varFoo) فهل سنضيف الامتداد هناك بطريقة ما ، إذا لزم الأمر؟ لا - هذا مثير للسخرية - للتعامل مع جميع أشكال المدخلات الديناميكية التي سنحتاجها إلى التفاف الاستيراد الديناميكي في وقت التشغيل ، وفجأة أصبحنا محمل وحدة خاص بنا ، طبقة فوق محمل النظام الأساسي المدمج. بدلاً من ذلك ، سنوفر وضع محلل يخطئ بشكل مناسب عند حذف الامتداد (والذي ، من دون شك ، يمكنك العثور بالفعل على قواعد الوبر الخاصة به).

إذا وجدت هذا الموضوع وكنت تريد حقًا ألا تحتوي مصادر الإدخال الخاصة بك على امتدادات ، وتحتاج بالفعل إلى أن تظل مخرجاتك تعمل مع ذلك عند استهداف وحدات (عقدة) ، فيجب عليك تقديم ملاحظات على https://github.com/ nodejs / modules / issues / 323 مع الأساس المنطقي الخاص بك ، حتى تتمكن من العمل بهذه الطريقة في النظام الأساسي الهدف نفسه ، لأن هذا في النهاية ما نؤجله.

فجأة أصبحنا محمل وحدة خاص بنا

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

تتصرف NodeJS الآن بشكل افتراضي بنفس طريقة المتصفحات عندما يتعلق الأمر بدقة وحدة المسار النسبية. لن يستنتج بعد ذلك امتداد .js افتراضيًا. هذا يعني أن السلوك الحالي لـ TSC ينتج عنه إصدار JS غير صالح في جميع سياقات وقت التشغيل.

أليس هذا سببًا آخر لاستخدام امتدادات الملفات .js في المحددات مثل TypeScript التي تدعمها بالفعل؟ هذا يحل كل شيء باستثناء أنه سيكون رائعًا إذا حدث خطأ tsc في الواردات بدون امتداد.

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

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

ألا يجب أن تكون tsc محمل وحدة وظيفية مهما كان الأمر؟

ليس في وقت التشغيل. يحتاج tsc إلى فهم كيفية قيام وقت التشغيل المختار بحل المحددات وتنفيذ ذلك في وقت الإنشاء ، ولكن وقت التشغيل متروك تمامًا للبيئة.

يمكنك أيضًا التفكير في الأمر بهذه الطريقة: إذا كتبت const varFoo = "./Foo"؛ استيراد (varFoo) هل نضيف الامتداد هناك بطريقة ما ، إذا لزم الأمر؟

weswigham هذه حجة قوية فيما يتعلق بالواردات الديناميكية ، لكنني لا أعتقد أنه يمكنك فعل ذلك باستخدام الواردات الثابتة؟ يمكنني أن أقدر الحجة القائلة بأن الإستراتيجية يجب أن تكون هي نفسها لكليهما ، لكنني أعتقد أنه من الجدير بالذكر أن الواردات الثابتة تؤدي دورًا مختلفًا تمامًا عن الواردات الديناميكية ولا أعتقد أنه من غير المعقول تمامًا أن يكون لديك استراتيجية مختلفة للثابت. استيراد إعادة الكتابة وإعادة كتابة الاستيراد الديناميكي.

أليس هذا سببًا آخر لاستخدام امتدادات ملفات .js في المحددات مثل TypeScript التي تدعمها بالفعل؟ هذا يحل كل شيء باستثناء أنه سيكون رائعًا إذا حدث خطأ tsc في الواردات غير القابلة للتمديد.

justinfagnani هناك مشكلتان في ذلك:

  1. سيفشل وقت التشغيل الذي ينفذ TS محليًا (مثل TS-Node) في العمل إذا حددت ملحقات .js على وارداتك.
  2. أنت تكذب على المترجم (IMO) إذا قمت بتضمين امتدادات .js في وارداتك.

بخصوص (2) ، إذا كان لدي ملفي TS a.ts و b.ts و a.ts يفعل import ... from './b.js' ، فأنا أخبر المترجم "لدي ملف شقيق اسمه b.js . هذه العبارة غير صحيحة. لجعل الأمور أسوأ ، إذا كان لديك .b.ts و b.js (والتي قد لا تكون في الواقع مشتقات لبعضها البعض) ، يصبح الآن غامضًا بشأن أي واحد تشير إليه _ على الرغم من أنك قمت بتضمين ملحق _ بشكل صريح.

أنا أرى أنه يجب على المستخدم إخبار المترجم بما يريده بالفعل (كمستخدم) وهذا إما "استيراد أي ملف باسم X وأي امتداد" (في حالة import ... from './foo' ) أو "استيراد هذا الملف تحديدًا" (في حالة import ... from './foo.ext' ). إذا اكتشف المترجم أنك تقوم باستيراد ملف TS ، واستمر المترجم في إرسال ملف .js ، فأعتقد أنه يجب على المترجم تحديث الاستيراد لاستيراد الملف المناسب بشكل صحيح. قد يعني هذا تغيير .ts إلى .js في بيان الاستيراد.

justinfagnani هناك مشكلتان في ذلك:

  1. سيفشل وقت التشغيل الذي ينفذ TS محليًا (مثل TS-Node) في العمل إذا حددت امتدادات .js على وارداتك.

هذا خطأ في TS-Node. لا يتطابق مع سلوك tsc .

  1. أنت تكذب على المترجم (IMO) إذا قمت بتضمين امتدادات .js في وارداتك.

إنه في الواقع عكس ذلك - فأنت تقول الحقيقة حول ما سيتم استيراده بالفعل. لن يتم استيراد ملف .ts ، ولكن ملف .js . يجب أيضًا ألا يكون هناك فرق واضح بين زوج .d.ts / .js .ts . إنها قابلة للتبديل. الطريقة الصحيحة الوحيدة لإنجاز ذلك هي استيراد ملف .js - ما سيكون الملف .ts بعد التحويل البرمجي.

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

يجب أيضًا ألا يكون هناك فرق واضح بين زوج .d.ts / .js وملف .ts

هذا ليس صحيحا دائما. يمكنك تكوين الخادم الخاص بك لخدمة جميع JS و TS و DTS بنوع JS MIME ثم استيرادها جميعًا بشكل منفصل في JavaScript وسيقوم وقت التشغيل بتنفيذها جميعًا على أنها JS. لا تهتم ESM بالملحقات على الإطلاق.

لهذا السبب أعتقد أنه يجب إجبار مستخدمي TS فعليًا على تضمين امتداد .ts ولن يكون الامتداد خطأ ما لم يتم استيراد ملف بدون امتداد أو هذا الاسم. وسيقوم TS بإعادة كتابة الواردات إلى .js في المخرجات. وفي حالة وجود ملف JS (ليس ملفًا تم إنشاؤه بواسطة TS) ، فسيكون ذلك أيضًا خطأ.

هذا خطأ في TS-Node. إنه لا يتطابق مع سلوك tsc.

إنه تقييد لمحمل NodeJS ، وليس خطأ في TS-Node: https://github.com/TypeStrong/ts-node/issues/783#issuecomment -507437929

هذا ليس صحيحا دائما. يمكنك تكوين الخادم الخاص بك لخدمة جميع JS و TS و DTS بنوع JS MIME ثم استيرادها جميعًا بشكل منفصل في JavaScript وسيقوم وقت التشغيل بتنفيذها جميعًا على أنها JS. لا تهتم ESM بالملحقات على الإطلاق.

أنا أدرك ذلك جيدًا ، لكن المتصفح أيضًا لن يقوم بتنفيذ TypeScript. يكاد يكون من الصحيح عالميًا أن الملف الذي تقوم البيئة بتحميله بالفعل هو ملف JavaScript.

وجهة نظري هي أنه إذا كان لديك زوج .js / .d.ts بالفعل ، لنقل من حزمة طرف ثالث ، وقم باستيراد ملف .js ، فإن tsc سوف شاهد ملف .d.ts وقم بتحميل الأنواع. على سبيل المثال ، زوج .js / .d.ts _acts_ مثل ملف .ts ، وهذا ما يجب أن يكون عليه الأمر ، لأن هذه هي الطريقة التي يمكنك من خلالها النقل بشفافية من JavaScript إلى TypeScript دون تغيير استيراد الملفات التي تم نقلها.

هذا خطأ في TS-Node. إنه لا يتطابق مع سلوك tsc.

إنه تقييد لمحمل NodeJS ، وليس خطأ في TS-Node: TypeStrong / ts-node # 783 (تعليق)

لا يزال خطأ أن TS-Node تبتعد عن سلوك tsc . هذا يجعل ملفات .ts التي لا تعمل في كل من tsc و TS-Node ، وأنا أعتبر بشدة tsc كمعيار قياسي يجب أن تتبعه TS-Node .

وجهة نظري هي أنه إذا كان لديك زوج .js / .d.ts بالفعل ، لنقل من حزمة طرف ثالث ، وقمت باستيراد ملف .js ، فسوف يرى tsc ملف .d.ts ويحمل الأنواع. على سبيل المثال ، يعمل زوج .js / .d.ts مثل ملف .ts ، وهذا ما يجب أن يكون عليه الأمر ، لأن هذه هي الطريقة التي يمكنك بها النقل بشفافية من JavaScript إلى TypeScript دون تغيير استيراد الملفات التي تم نقلها.

إذا قمت بتحميل _package_ خارجي ، فستحتاج إلى أداة تحميل حزمة وقت التشغيل من نوع ما (على سبيل المثال ، خرائط استيراد مسماة في المستعرض) تقوم بتعيين الوحدة النمطية المسماة إلى ملف نقطة الدخول. ومع ذلك ، أعتقد أن وجهة نظرك ثابتة بشكل عام ، في حالة وجود زوج .js / .d.ts قريب. أنا على الحياد سواء في هذه الحالة يجب أن تفعل import ... from './foo.d.ts' أو import ... from './foo.js' .

الملف .d.ts هو في الأساس رأس يصف الهيكل الذي لا يحتوي على معلومات حول الامتداد الذي يتم تعيينه منه (الافتراض أنه بشكل عام لا يجب أن يكون لديك ملفات متعددة بنفس الاسم ولكن امتدادات مختلفة في نفس المكان ، و نحن نخطئ في الإنشاء إذا فعلت ذلك) - حتى اليوم ، يمكن أن يكون "المصدر" المرتبط بوقت التشغيل .js أو .jsx (باستخدام jsx: preserve ). لا يمكنك ، بشكل عام ، استبدال مرجع .d.ts بـ .js في استيراد في وقت الإرسال وافترض أنه يعمل ...

من المهم بالضبط ألا يكون TSC شديد الرأي على نطاق أوسع
بناء ودقة الافتراضات.

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

كان هناك جهد مدروس للغاية لعدم فضح تغييرات القرار كما
جزء من عملية تجميع tsc - وهذا في حد ذاته يفرض الرأي على
المستخدمين ويسبب الاحتكاك في سير عملهم.

يوم الأربعاء 27 نوفمبر 2019 الساعة 16:48 Wesley Wigham [email protected]
كتب:

يعد ملف .d.ts أساسًا عنوانًا يصف البنية التي تحتوي على
لا توجد معلومات عن الامتداد الذي يرسمه (الافتراض هو ذلك
بشكل عام لا يجب أن يكون لديك عدة ملفات بنفس الاسم ولكن
مختلفة في نفس المكان) - حتى اليوم ، المرتبطة
يمكن أن يكون "المصدر" لوقت التشغيل هو .js أو .jsx (باستخدام jsx: save). يمكنك
لا ، على نطاق واسع ، استبدال مرجع .d.ts بـ .js في استيراد وقت الإرسال
وافترض أنه يعمل ...

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/microsoft/TypeScript/issues/16577؟email_source=notifications&email_token=AAESFSQS2DQ23RR5KN3RTZ3QV3TLXA5CNFSM4DPRQTY2YY3PNVWWK3TUL52HS4DFVREXG43V59
أو إلغاء الاشتراك
https://github.com/notifications/unsubscribe-auth/AAESFSUAP2YO23ZFHCOWVQLQV3TLXANCNFSM4DPRQTYQ
.

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

لدي خريطة استيراد مثل هذه في ملف html الخاص بي:

<script type="importmap-shim">
      {
        "imports": {
          "@root/":"../../../",
         }
      }
</script>

ولدي ملف ts حيث أقوم باستيراد ملف مثل هذا:

import '@root/components/page-main/page-main.js';

الآن ، هذا الإعداد يعمل بشكل جيد في المتصفح. ولكن ، كيف سأتمكن من التنقل / استخدامه في VSCode؟ أعني ، أريد ctrl + النقر فوق الاستيراد والانتقال إلى الملف ، والحصول على الإكمال التلقائي ، واكتب def ، وما إلى ذلك.

أيضًا ، مع الأخذ في الاعتبار أن tsc لا تعيد كتابة ملحقات الاستيراد من .ts إلى .js ، فهل هناك أي أداة / حزمة أخرى موصى بها يمكنني استخدامها لفعل الشيء نفسه في وقت الإنشاء؟ شكرا.

(أنا أستخدم https://github.com/guybedford/es-module-shims لوحدات ES وخرائط الاستيراد)

ولكن ، كيف سأتمكن من التنقل / استخدامه في VSCode؟

ابحث عن خيار المترجم paths .

أيضًا ، مع الأخذ في الاعتبار أن tsc لا تعيد كتابة ملحقات الاستيراد من .ts إلى .js ، فهل هناك أي أداة / حزمة أخرى موصى بها يمكنني استخدامها لفعل الشيء نفسه في وقت الإنشاء؟ شكرا.

فقط استخدم .js وسيعمل بشكل جيد ، حتى إذا كنت تشير إلى ملف .ts في وقت الإنشاء.

tvvignesh https://github.com/Zoltu/typescript-transformer-append-js-extension/ لإعادة كتابة الواردات غير القابلة للتمديد إلى .js في وقت الترجمة. أنا لست معجبًا شخصيًا بـ "ضع فقط .js في ملفات TS" لأن شفرتك لن تعمل في ts-node إذا فعلت ذلك. إذا لم تكن بحاجة إلى تشغيل التعليمات البرمجية الخاصة بك في ts-node ، فسيعمل استخدام .js.

ولكن ، كيف سأتمكن من التنقل / استخدامه في VSCode؟

ابحث عن خيار المترجم paths .

أيضًا ، مع الأخذ في الاعتبار أن tsc لا تعيد كتابة ملحقات الاستيراد من .ts إلى .js ، فهل هناك أي أداة / حزمة أخرى موصى بها يمكنني استخدامها لفعل الشيء نفسه في وقت الإنشاء؟ شكرا.

فقط استخدم .js وسيعمل بشكل جيد ، حتى إذا كنت تشير إلى ملف .ts في وقت الإنشاء.

شكرا على ردك السريع. لقد قمت بالفعل بتعيين خيار المسارات في tsconfig.json ولكنني ما زلت غير قادر على التنقل عن طريق ctrl + click.

هذا هو خيار مساراتي في tsconfig.json

"paths": {
            "*": ["www/node_modules/*"],
            "@modules/*": ["www/node_modules/*"],
            "@root/*": ["www/*"]
        }

فقط استخدم .js وسيعمل بشكل جيد ، حتى إذا كنت تشير إلى ملف .ts في وقت الإنشاء.

هذا غير عملي تمامًا عندما يكون هناك الآلاف من الواردات.

تكمن المشكلة في "استخدام .js " فقط في أنه إذا كان TypeScript يرسل ملفات .mjs فإن برنامجك لا يعمل. هذا يعني أنك ستنتهي في موقف تكتب فيه TypeScript حيث يعمل _either_ في المتصفح _ أو يعمل في NodeJS. لم يعد بإمكانك كتابة TypeScript التي تعمل في كليهما.

أعتقد أن الحجة هنا هي ، "هذا ليس خطأ TypeScript ، هذا هو المتصفح و NodeJS متباعدان".

يدعم العقدة 13.2 ملحقات .js بشكل جيد.

@ justinfagnani للوحدات ES؟ اعتقدت أن NodeJS لن يقوم بتحميل وحدات ES إلا إذا كان لديهم امتداد .mjs ، وإلا تم التعامل مع الملفات على أنها CommonJS؟

أشعر أن هذا الموضوع برمته مضلل بعض الشيء. من شأن كتابة امتداد الملف بشكل صريح أن يحل هذه المشكلة برمتها. إذا كنت تقوم باستيراد ملف JavaScript ، فاكتب الامتداد .js. إذا كنت تقوم باستيراد ملف TypeScript ، فاكتب امتداد ts. هذا مسموح به في المعيار ويفهم مترجم TypeScript كل ذلك جيدًا. المشكلة الوحيدة هي أن المترجم ينص على أن امتدادات .ts هي أخطاء. هذا لا يؤثر على النح الخالص ، ولكنه مجرد خطأ في النوع. يجب أن يقوم TypeScript بإصلاح هذا الأمر ، حيث من الواضح أن امتداد الملف .ts صالح ، نظرًا لأننا نقوم بالتأليف في TypeScript. للتغلب على هذه المشكلة ، لدى Deno.js امتداد VS Code: https://marketplace.visualstudio.com/items ؟

مع ظهور WebAssembly ، ستبدأ تطبيقات الويب في استيراد المزيد والمزيد من أنواع الملفات. سيصبح من المهم بشكل متزايد تحديد ما إذا كنت تستورد ملف .wasm ، .js ، .ts ، .rs ، .c ، إلخ.

هل استخدم أحد البرنامج النصي الذي كتبته بالفعل؟

https://github.com/microsoft/TypeScript/issues/16577#issuecomment -310426634

أي ملاحظات إذا كان الأمر كذلك؟

QuantumInformation لم أستخدم البرنامج النصي الخاص بك ، لكن ملحق محول TypeScript الإضافي الذي كتبته يقوم بنفس الشيء بشكل أساسي. 😊 https://github.com/Zoltu/typescript-transformer-append-js-extension/

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

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

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

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

Draccoz أعتقد أن النقطة التي يتم توضيحها هي أنه إذا كتب شخص ما TypeScript مثل import { ... } from './foo' ثم نشر ذلك كحزمة NPM ، فلا يمكن للمستخدم استخدام هذه المكتبة مباشرة في المستعرض حتى لو كانت تستهدف وحدات ES. أعتقد أن حجة Microsoft هنا هي أن الحزمة خاطئة إذا كانت توزع كودًا كهذا مع توقع أنها تعمل في متصفح.

يمكنك كتابة امتداد الملف الموجود في node_modules. import * as stuff from 'rxjs/path/to/file.js'; إذا كان ملف JavaScript ، و import * as stuff from 'rxjs/path/to/file.ts'; إذا قاموا بتوزيع ملف TypeScript. هذا يعمل الآن إذا لم أكن مخطئا

lastmjs نعم ، ولكن ماذا لو كان rxjs/path/to/file.ts يحتوي على import foo from './bar' ؟ لا يمكنك تغيير ذلك ، حيث لا يمكنك تعديل الملف ، لأنه مكتبة تابعة لجهة خارجية.

لهذا السبب يجب علينا الضغط لاستخدام الامتدادات الصريحة في كل مكان ، لكن نعم أرى وجهة نظرك. تقوم أداتي (https://github.com/lastmjs/zwitterion) بإعادة الكتابة كحل مؤقت لتلك الملفات التي تركت الامتدادات.

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

نعم ولكن من الواضح أن الأمل لا يزال مفيدًا لكثير من الناس

image

ومع ذلك ، فقد قيل عدة مرات من خلال تلك التعليقات أنه لن يتم تنفيذه ، فلماذا يبقيه مفتوحًا؟

إذا كتب شخص ما TypeScript مثل import {...} من "./foo" ثم نشر ذلك كحزمة NPM

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

هل هناك اتفاقية لنشر TS غير المجمعة إلى NPM؟ إذا كان الأمر كذلك ، فهل هذا موثق في مكان ما؟ لقد فهمت أن هذا يتجول OT من الإصدار الأصلي ولكني أعتقد أنه وثيق الصلة بالإجابة ، لأننا نحتاج إلى معرفة ما إذا كانت "الحزم" TypeScript التابعة لجهة خارجية هي حالة / هدف استخدام مدعوم.

@ thw0rted آسف لعدم الوضوح ، قصدته:

... إذا كتب شخص ما TypeScript مثل import { ... } from './foo' ثم قام بنقل ذلك إلى JS باستخدام TSC اليوم ونشر JS كحزمة NPM ...

إذا لم يتم تنفيذه ، فسأترك الأمر لـ MS لإغلاق المشكلة الآن.

آه ، فهمت الآن. نعم ، عندما أقوم بالترجمة (باستخدام target: ES2018 ) يترك JS المنبعث الامتداد خارج بيان الاستيراد ، ولكنه يعمل بالنسبة لي لأن المستهلك يضع كل شيء من خلال webpack / babel ويجب أن يملأ الامتداد المفقود لي. أنا على دراية بالسرعة الآن. لم يخطر ببالي حتى أن "الحزمة" الخاصة بي لن تعمل أصلاً في المتصفح بدون الانتقال عبر webpack أولاً.

نعم ، هذا صعب.

@ thw0rted أنا لا أستخدم webpack / babel ، وبالتالي فإن حل .js من المربع يمثل مشكلة بالنسبة لي.
بعض الحلول / الحل البديل هو تكوين خادم الويب لمصادر الحل الافتراضية .

آسف إذا كنت أكرر ما قاله الآخرون ، لكن هذا شيء أتعامل معه كل يوم ، لذا أود أن أرمي سنتًا أخرى من سنتي غير المرغوب فيها.

أعلم أن TypeScript ليس مضطرًا لتلبية احتياجات أي بيئة معينة (Node.js ، Webpack ، وما إلى ذلك) ولكن الحقيقة هي أن هناك الكثير من البيئات التي يكون فيها الامتداد ضروريًا دائمًا ، ما لم يتم تكوينه بشكل خاص ، لذلك لا أفعل لا أعتقد أنه ينبغي تجاهلها. لم تعد الواردات خلف علامة في Node بعد الآن ويجب أن يتطابق مسار الاستيراد مع اسم مسار URL على الويب. على الرغم من عدم وجود حاجة فنية لوجود .js في نهاية عنوان URL ، فهذا هو المعيار الفعلي.

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

في غضون ذلك ، هل يعرف أي شخص أي مكونات إضافية لـ VSCode تعمل على إصلاح هذا؟ إن إضافة الاستيراد / الامتدادات إلى eslint هو أفضل ما تمكنت من القيام به للتعامل مع هذا الأمر.

أكتب حاليًا خطوطًا import بدون امتداد .js ، ثم استخدم sed لإضافة امتداد .js في ملفات الإخراج.
https://github.com/yoursunny/NDNts/blob/9f50fcec245b33c7649fa815bbb3dd404eee160e/mk/build.sh#L12 -L14
لا بد لي من حذف SourceMaps أثناء بناء الإنتاج ، لأنها لن تتطابق بعد تعديل ملفات الإخراج.

لا يمكنني كتابة امتداد .js في ملفات المصدر .ts لأنه يكسر ts-jest .
في حين أنه من الممكن تشغيل Jest على ملفات .js المترجمة ، فإنه يكسر Coveralls .

yoursunny نعم ، sed متغير (لقد استخدمته أيضًا ولكني أفضل استبدال الملف بسبب التكوين الذي يمكن تهيئته عن طريق تعيين ملف خريطة الاستيراد) لاستبدال السلاسل في ملفات js التي تم إنشاؤها ، ولكن رائحتها ليست جيدة =) قد يكون ستكون إضافة الإضافات ميزة / خيارًا مفيدًا لـ ttypescript مع البرنامج المساعد للتحويل (على سبيل المثال ، typecript -transform-paths byMicahZoltu).

richardkazuomiller هذا الجزء غير صحيح:

إذا كان الأشخاص اللطفاء في Microsoft يريدون حقًا عدم وجود امتداد للملف ، يكون الخيار الافتراضي

TypeScript فقط:

  1. يسمح بدقة الوحدة النمطية التي تتطلب نمط Node (يجب أن يوسعوا هذا للسماح بنمط Node-import-style ، والذي يتطلب امتدادات الملفات).
  2. في نفس وحدة الترجمة ، يحل ملفات .js إلى زوج .js / .d.ts حتى قبل أن يتم إنشاؤها بواسطة المترجم.
  3. لا يقوم بتعديل محددات الاستيراد - على الإطلاق -.

لذا فإن الحل لكل هذا هو استيراد ملفات .js بامتداد .js . سيعمل TypeScript على حل ملف .ts الأيمن ولن يعدل محدد الاستيراد ، لذلك ستعمل الأشياء فقط في المتصفحات و Node> = 13.2.

yoursunny هل رفعت خطأ ضد ts-jest ؟ إنهم يختلفون عن معيار TypeScript القياسي هنا. يبدو أيضًا أنه خطأ في Coveralls إذا لم يكن بإمكانه استخدام خرائط المصدر على ملفات .js.

هل رفعت خطأ ضد ts-jest ؟ إنهم يختلفون عن معيار TypeScript القياسي هنا.

لا ، لأنني لا أفهم تمامًا كيف يعمل حل ts-jest.

يبدو أيضًا أنه خطأ في Coveralls إذا لم يكن بإمكانه استخدام خرائط المصدر على ملفات .js.

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

العصر الجديد هنا!

تدعم Node.js v13 التي تم إصدارها حديثًا وجميع المتصفحات الرئيسية وحدات ES الأصلية خارج الصندوق ، وسيكون من الرائع أن تدعم TypeScript هذه البيئات بطريقة بسيطة.

إن أبسط حل لمعظم حالات الاستخدام الأساسية (موقع ويب يتم تقديمه من خلال خادم ملفات ثابت بسيط) هو إضافة خيار مترجم جديد مثل "appendJsExtension": true أو ما شابه.

mjbvz المشكلة التي أغلقتها في ريبو VS Code مختلفة قليلاً: إنها تتعلق باستخدام الإكمال التلقائي لإضافة عبارات الاستيراد تلقائيًا ؛ عندما يقوم VS Code بإضافة جملة الاستيراد بدون امتداد .js ، ومن السهل التغاضي عن ذلك حتى فشل وقت التشغيل.

ومع ذلك ، إذا أضافت TypeScript خيارًا مثل "appendJsExtension": true أو خيارًا مشابهًا ، فلن يهم كثيرًا ، وسنكون قادرين على كتابة رمز TS بدون .js في المصدر.

ربما يجب أن يحتوي المكون الإضافي VS Code على خيار لتمكين / تعطيل الإضافة التلقائية لملحقات .js في بيانات الاستيراد المكتملة تلقائيًا؟

mjbvz تعتبر مشكلة VS Code / Intellisense ذات صلة ، ولكن لا يجب إغلاقها كمخادعة. إذا تم إغلاق هذه المشكلة في النهاية باسم WONTFIX ، فسيؤدي ذلك في الواقع إلى زيادة أهمية مشكلة رمز VS.

أرى أنه تم التغاضي عن نقطة واحدة ولا أفهم كيف ستحل الحلول التي يكون فيها امتداد JS بغلاف خاص: بالنسبة لـ ESM ، لا يوجد ملحق له حالة خاصة ، حتى الملفات غير الملحقة تكون جيدة تمامًا طالما أن الخادم يقدمها إلى المتصفح باستخدام النص المناسب / نوع جافا سكريبت MIME. هذا يعني أن الرمز مثل:

import something from './javascript-code.png';
import something2 from './javascript-code2.js';
import something3 from './javascript-code3.ts';

كل هذا صالح طالما أن الملفات (بغض النظر عن امتداداتها) تحتوي على كود JavaScript ويتم تقديمها إلى المتصفح بنوع JavaScript MIME.

نظرًا لأن TypeScript يجب أن تكون مجموعة شاملة من النوع الآمن لجافا سكريبت ، لا أرى طريقة حول السماح بالواردات مثل تلك المذكورة أعلاه ، نظرًا لأن الشفرة صالحة لـ JavaScript وإذا لم تقبلها TypeScript ، فلن تكون مجموعة شاملة آمنة من JavaScript ، أليس هذا صحيحًا؟

إذن الحلول التي يكون فيها امتداد JS إما ضمنيًا أو الوحيد المسموح به والذي لا أعتقد أنه يمكنه قطع هذا؟ علاوة على ذلك ، حتى امتدادات TS و DTS IMO لا يمكن أن تكون مغلفة بشكل خاص ، لأنه في حين أن هذا ليس هو الحال عادة ، يمكن أن تحتوي على كود JavaScript ، وليس رمز TypeScript وخادم إلى المتصفح على هذا النحو دون أي مشكلة على الإطلاق فيما يتعلق بـ ESM ، نظرًا لأنه يتم تقديمها مع نوع MIME الصحيح.

هل أفتقد شيئًا على هذه الجبهة؟ هل من الممكن أن لا تنفذ TypeScript دعم الامتدادات التعسفية (بما في ذلك المفقودة) في عمليات استيراد الكود ، وهل من الممكن أن تستمر TypeScript في افتراض امتدادات TS في واردات الوحدة النمطية ، بالنظر إلى أن file.ts و file (بدون تمديد) من شأنه أن يؤدي إلى تعارض؟

يحصل عمال الويب والخدمة أيضًا على دعم لاستيراد / تصدير وحدة ES .

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

يرجى النظر في هذا كخيار للمترجم Typescript. <3

هل يعرف أي شخص طريقة يمكنك من خلالها تشغيل ملفات js الفردية المترجمة في متصفح بدون webpack أو --outFile ، باستخدام أي نوع من نظام الوحدات النمطية؟

مشكلتي هي: يستغرق مشروع TypeScript الكبير إلى حد ما الذي أعمل معه حوالي 35 ثانية ليتم تجميعه باستخدام حزمة الويب في ملف js مجمع باستخدام ts-loader .
الطريقة الوحيدة التي يمكنني بها تحسين ذلك كانت باستخدام transpileOnly مما قلل من وقت الترجمة إلى 20 ثانية ولكن هذا لا يزال بطيئًا وأنا أفقد التحقق من الكتابة.
للتخلص من حزمة الويب ، يمكنني الوصول إلى حوالي 14 ثانية باستخدام outFile ولكن هذا لا يزال بطيئًا جدًا بالنسبة لي. استخدام incremental لم يحدث أي فرق.

كانت الطريقة الوحيدة التي يمكنني من خلالها الوصول إلى بضع ثوانٍ من وقت الترجمة هي إرسال ملف js واحد لكل ملف ts ، واستخدام العلم incremental . في هذه الحالة أتخيل أن ts يكتشف ويجمع فقط الملفات التي تغيرت بالفعل. المشكلة هي أنني لم أتمكن من تشغيل هذا في متصفح في أي من أهداف الوحدة التي جربتها: system ، amd ، es6.
أنا أستخدم تعيين paths في tsconfig.json وفي ملفات js المجمعة ، ترتبط الأخطاء التي أحصل عليها في الغالب بعدم القدرة على حل هذه الأسماء المستعارة.

هل هناك أي طريقة لتحقيق ذلك؟

andrewvarga أقوم حاليًا بتشغيل كل ما عندي من TypeScript المترجمة مباشرة في المتصفح دون تجميع أو تجميع ملف واحد. أسهل طريقة للقيام بذلك هي:

  1. تأكد من أن جميع الواردات في ملفات TypeScript لها الامتداد .js .
  2. قم بتشغيل خادم dev الذي يحل استيراد أسماء حزم npm للتبعيات ، إذا لزم الأمر. أبسط ما أعرفه هو es-dev-server .
  3. قم بتشغيل tsc --watch (تأكد من أن الوحدة هي esnext في tsconfig الخاص بك)

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

justinfagnani mate ، لقد نسيت أهم معلومة - يجب أن تكون الأنواع بتنسيق jsdoc ، وأي تجريد مطبوع على JavaScript الأصلي سيؤدي إلى فشل المحلل اللغوي.

Draccoz tsc سينتج JavaScript وليس TypeScript.

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

andrewvarga أستخدم https://github.com/Zoltu/typescript-transformer-append-js-extension/ واستهدف وحدات ES الأصلية التي يتم تحميلها في جميع المتصفحات الحديثة (باستثناء Safari ، متصفح IE الجديد).

إذا كانت تبعيات NPM الخاصة بوقت التشغيل محدودة جدًا ، فيمكنك تحميلها باستخدام es-modules-shim دون أي تجميع. يمكنك رؤية نموذج التفاعل الذي قمت بإنشائه والذي يوضح كل هذا العمل معًا: https://github.com/Zoltu/react-es2015-template

لدىMicahZoltu Safari دعم الوحدة النمطية ES ، وأنا أعلم أنه في الحقيقة ، بناءً على التجربة الشخصية والتجربة الشخصية: https://caniuse.com/#search = modules

justinfagnani awww آسف ، غاب عن جزء "TypeScript المترجمة" ، أعتقد أنك تتحدث عن jsdoc مطبوعة.

شكرا لكم جميعا على النصائح المختلفة!

ما وجدته هو أنه باستخدام الوحدة النمطية hard-source-webpack-plugin npm لـ webpack و transpileOnly: true في خيارات ts-loader ، قلل وقت الإنشاء إلى حوالي 4-5 ثوانٍ.
سيتجاهل هذا بالطبع أخطاء الكتابة المطبوعة ، لذا فهو مفيد فقط للتكرار السريع للبناء ، والمحاولة في المتصفح ، والاعتماد على IDE لأية أخطاء محتملة ، لكنني أعتقد أنه مفيد جدًا أثناء التطوير.

للحصول على كل من أخطاء TS والتجميع السريع ، ما زلت أعتقد أن الطريقة الوحيدة هي تشغيل الوحدات في المتصفح ، لكن نقص الدعم لخرائط الاستيراد وامتدادات js جعل ذلك صعبًا.
justinfagnaniMicahZoltu شكرا لك ، سأحاول تلك الخيارات. بشكل عام ، أفضل تجنب استخدام وحدة npm أخرى ولكن يبدو أنها لا مفر منها.

حاولت أن أجعله يعمل باستخدام systemjs أيضًا ولكني تعثرت مع خرائط الاستيراد ..

andrewvarga يمكنك تجربة SystemJs من خلال المثال الخفيف الخاص بي باستخدام importmap.
يمكنك أيضًا تجربة المثال الثقيل الخاص بي - بديل systemjs و esm ، لكن خرائط استيراد esm غير مدعومة من قِبل أصلي ، ويجب علينا حل الوحدات يدويًا (gulp-replace) ، أو يمكنك تجربة es-module-shims .

لذلك ، إذا كنت أستخدم tsc كمترجمي الوحيد ، فقم باستهداف esnext أو es2015 كنوع الوحدة الخاصة بي. هل هناك أي طريقة يمكنني من خلالها استخدام الإخراج مباشرة في المتصفح الخاص بي؟

https://github.com/alshdavid-sandbox/typescript-only-compiler

إذا فهمت بقية هذا الموضوع بشكل صحيح ، فمن المفترض أن يكون Typescript سعيدًا تمامًا لتجميع الكود الخاص بك إذا قمت بتغيير هذا السطر ليقول from "./module.js" . بعد ذلك ، سيحتوي index.js المترجم على بيان استيراد ES6 صالح ويجب أن يعمل جميعًا.

هذا ما لم تقم باستيراد بعض المكتبات التي إما لا تعرف كيفية استيراد ES أو لا تهتم: P.

لقد أنشأت مكوّنًا إضافيًا لـ Gulp يضيف .js لاستيراد مسارات الملفات. (أيضا قرار مسار مكافأة نهاية الخبر).

لقد استخدمت Gulp لأنني لا أعرف أي عداء مهام آخر من شأنه أن يسمح لي بشكل أساسي بإرفاق خطوة ما بعد المعالجة البسيطة بالمترجم tsc (كل من الساعة والوضع العادي). حزمة Webpack و rollup كلاهما حزمة حصرية ، وأريد إرسال وحدات es.

إنه يعمل ولكنه بطيء في المشاهدة حيث يبدو أنه يعيد بناء كل شيء.

https://github.com/alshdavid-sandbox/typescript-only-compiler/tree/gulp

تزداد أهمية هذا الأمر عندما قرر فريق العقدة عدم استخدام عمليات الاستيراد غير القابلة للتمديد
https://github.com/nodejs/modules/issues/444

إضافة خرائط الاستيراد المقررة أيضًا ضد الواردات غير القابلة للتمديد
https://github.com/WICG/import-maps/issues/194

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

chyzwar مرة أخرى ، إذا قمت ببساطة بكتابة الامتدادات .js في مصدر TypeScript ، فسيكون للمخرجات المجمعة الامتدادات الصحيحة وستعمل الوحدات النمطية في المتصفحات و Node. لا تحتاج إلى أدوات تحويل إضافية أو للحصول على tsc للقيام بأي شيء من أجلك.

من الأسهل للمطور القيام بما يلي: إذا كان ملف مصدر TypeScript ، فاكتب امتداد ts. إذا كان ملف JavaScript مصدرًا ، فاكتب امتداد .js. سيؤدي ذلك أيضًا إلى تجميع وتشغيل بشكل صحيح في المتصفح (ستحتاج .ts إلى تطبيق / نوع جافا سكريبت MIME). يجب أن يتطابق الامتداد مع نوع الملف المصدر. يمكن للوحدات النمطية tsc و ES التعامل مع ذلك (على الأقل وحدات ES في المتصفح ، ونأمل أن يتبع Node.js نفس الشيء)

@ justinfagnani tsc سعيد بهذا ، ومن العدل أن نقول "ليست مشكلتنا" هنا ولكن يبدو أنه لا يوجد إجماع هنا حول ما هو صحيح ،

بين tsc و vscode و webpack و ts-node ، لا يمكن أن يوافق أي شيء بشكل جيد على المعيار الذي أصبح متاحًا الآن (متصفح وعقدة متاحان الآن).

مثال 1

أريد أن أكتب حزمة جافا سكريبت حديثة ، وأقوم بتأليفها بنسخة مطبوعة ، ثم قم بإخراج الأنواع للتوزيع كوحدة نمطية ecmascript (مع الاحتفاظ ببيانات الاستيراد والتصدير).

مثال 2

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

في هذه الحالات ، يمكن لـ tsc التعامل مع هذا الأمر ، وحتى تصدير ملفات الواصف التي تدعم ثم استهلاك توزيع الوحدة النمطية es من الكتابة المطبوعة بكتابات كاملة (رائع).

ولكن إذا كنت أرغب في تشغيل كود اختبار مقابل المصدر ، فيمكنني استخدام ts-node ولكن هنا ts-node ليست سعيدة.

وبالمثل ، فإن حقيقة أن tsc و vscode و webpack قد تطورت للقيام بما يلي:

  1. استيراد السيارات vscode بدون ملحق
  2. سيسعد tsc بإعادة كتابة الواردات إلى ملف js بمعنى ملف ts
  3. يقوم webpack بالعديد من السحر هنا للإضافات الافتراضية للبحث عنها

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

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

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

أرغب في أن تكون tsc هي التبعية الوحيدة لدي ، لكن بعض الأشياء لن تحدث وستبقى كحلم.

لا بد أنني رأيت العشرات من التعليقات شبه المتطابقة التي امتدت لعدة سنوات في # 3469 ، بما في ذلك بعض التعليقات من فريق Typescript. "إنه فاحص نوع ، من المفترض أن يقوم بشيء واحد جيدًا ، لا تتوقع منه أن يحل محل سلسلة أدواتك بالكامل ..." استغرق الأمر 3 سنوات ، لكنهم ما زالوا يضيفون وضع الإنشاء ، لأنه تم إثبات أنه الاتجاه الصحيح للذهاب.

حزمة Webpack و rollup كلاهما حزمة حصرية ، وأريد إرسال وحدات es.

قد يعمل alshdavid Rollup من أجلك إذا قمت بتعيين تنسيق الإخراج على esm وقمت بتعيين preserveModules إلى true : https://rollupjs.org/guide/en/#preservemodules

ربما كانت الواردات "بدون امتداد" خطيئة أصلية ، ولا تتوافق مع طريقة عمل المتصفحات

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

لذلك ربما كان عدم التمديد عيبًا في شفرة المصدر كانت أدواتنا القديمة تعوضه

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

مثال أساسي

src/index.ts
src/foo.ts
test/index.ts

src / foo.ts

export default (a: number) => a + 100;

src / index.ts

// okay, editor (without ESLint) doesn't report error here
import foo from './foo.js';

export default () => {
  console.log(foo(123));
}

اختبار / index.ts

// errm... ts or js ext?! .ts should be the one that make sense
// and that's how the testing too will expect it to be, otherwise will throw
// but then it will detect some weird `.js` ext in the source files...
// which again won't be able to resolve... complete bullshit. 
import main from '../src/index.ts';
import foo from '../src/foo.ts';

test('some boolshit', () => {
  main();
});

test('about foo', () => {
  foo(20);
});

آسف لاستخدام "هراء" ، ولكن هذه هي الحقيقة.

لا أعتقد أنه من الصعب تنفيذ الخيار الأساسي عندما يرى المترجم امتدادًا ( .ts ) في الواردات لتحويله إلى .js (أو حتى السماح اختياريًا بتحديد ما هو الإخراج الممتد إلى يكون). عندما لا يكون هناك امتداد ، لا تحتفظ بالامتدادات (سلوك شبه حالي؟).

كتابة امتداد .js في عمليات الاستيراد في كود المصدر المطبوع هو محض هراء. إنه يعمل ، ويحافظ على الامتداد في الإخراج ، ولكن من المحتمل أن يفشل مع أخطاء "تعذر حل الملف" في قواعد ESLint (أو TypeScript) في VSCode أو أي محرر تستخدمه.

هذا ليس صحيحًا. ESLint و TypeScript و VS Code وكل أداة أخرى مرتبطة بـ TypeScript استخدمتها _ فقط العمل_ بهذه الطريقة. إنه ليس اختراقًا ، وله سبب منطقي جدًا حوله: أن الملف الذي تستورده في الواقع _ هو _ الملف .js ، وأن امتداداتك لا يجب أن تتغير لمجرد أن الملف المستورد جزء من الملف المحلي مشروع ، أو تم تجميعه مسبقًا كجزء من حزمة جهة خارجية.

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

لا ليس كذلك. على الأقل في الحالة الأكثر شيوعًا حيث يكون دليل المخرجات dist أو build أو lib وما إلى ذلك. الملفات المترجمة ليست في نفس الدليل ، فهي غير موجودة أبدًا هناك ( src/ ) - لا أثناء الاختبار ولا أثناء الترميز في المحرر.

إن الحصول على / رؤية واستيراد ./foo.js في src/index.ts أعلاه ليس له أي معنى بالنسبة لي - ما لم تكن بالطبع تقصد استيراد ملف js / json ، وهو أمر جيد تمامًا. لكن كتابة ./foo.js عندما تقصد حقًا ملف مصدر مطبوع آخر ( ./foo.ts ) هو ... أمر وحشي. إنه مضلل ومربك ، وخاطئ بالتأكيد.

أنا متأكد تقريبًا إذا قمت بتشغيل test/index.ts أعلاه مع Jest ، فسوف يفشل مع خطأ أنه لا يمكنه العثور على / حل ./foo.js لأنه لا يوجد سوى ./foo.ts .

إذا تركنا كل شيء جانبًا ، فلماذا يُسمح بامتداد .js ولكن ليس .ts واحد (ts report error in the editor)؟ إنه تناقض أساسي وبسيط وغبي. مثل العديد من المشاكل الأخرى "لمجرد" في TypeScript.

لقد فقدت في الواقع المنطق وراء تسمية هذه المشكلة بهذه الطريقة في حين أنه من الممكن بالفعل أن تنتهي بامتداد .js . أعتقد أن المشكلة هي العكس تمامًا - لا يمكن أن تنتهي بـ .ts (بدءًا من 3.7+)

لماذا تم حظر تمديد الواردات .ts تمامًا ؟!

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

TypeScript هي مجموعة شاملة من JavaScript ولكنها ليست JavaScript. JavaScript هو هدف ترجمة لـ TypeScript.

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

تفترض كتابة .js عند محاولة استيراد ملف .ts معرفة نوع التحويل البرمجي الهدف وتفترض أن هدف التحويل هو JavaScript دائمًا.

ماذا لو قمنا بترجمة TypeScript إلى ثنائي لتجميع الويب أو قمنا بتشغيل كود TypeScript باستخدام وقت تشغيل بديل مثل Deno أو ts-node.

بيانات الاستيراد التي تنتهي بـ .js لا معنى لها في مثل هذه السياقات.

أفضل أن أجبر على كتابة .ts للخارج في مسارات الاستيراد الخاصة بي أو لا أمتلك أي ملحق محدد بافتراض وجود ملف مصدر TypeScript.

إنه لأمر محزن أن المخطوطة المطبوعة اخترعت امتدادها الخاص بدلاً من أن تكون مجرد تركيب مثل السكر.

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

يبدو أن هذه المشكلة (الأكبر من TypeScript) تمنع التحسس الذكي لبرنامج Visual Studio Code من العمل في متصفحات الويب والعقدة - الأمر الذي يتطلب مسارات ملفات كاملة (نسبية) في محددات الاستيراد. بدون ذلك ، فإن عبارات import التي تم إنشاؤها تعمل فقط مع المحولات والمجمعات ، مثل WebPack و TypeScript نفسها.

كان رد فريق VSCode هو أنه يجب إضافة الامتدادات بواسطة الكود الذي يوفر اقتراحات الاستيراد التلقائي. أظن أن هذا هو خادم لغة TypeScript (وليس tsc ، الذي دار حوله النقاش هنا).

هل يمكن لشخص يعرف الأشياء بالفعل أن يؤكد (أو يصحح) أن VSCode يحصل على اقتراحات استيراد تلقائي من TypeScript Language Server؟

الموقف معقد ودقيق بعض الشيء ، لذا في حين أن امتدادات ".js" تتعارض في البداية مع حدس ومثل العديد من الأشخاص الأنيقة ، فقد يكون من غير الحكمة والمربك أن تنحرف الكتابة المطبوعة كثيرًا عن معايير المتصفح المعتمدة والتطبيقات المشحونة

لذلك ربما نعتبر النموذج الحالي كما يلي:
تصف عمليات الاستيراد المطبوعة ما يتم استيراده في وقت التشغيل - أي ، يتم تنفيذ عمليات الاستيراد الخاصة بك في دليل "dist" ، وليس "src" - مثل مكالمات fetch والباقي - إذا استطعنا تحمل هذه الفكرة ، فسيصبح الباقي بسيطة ومتسقة

يبدو بالتأكيد فكرة سيئة أن تقوم بإرفاق ".js" بشكل أعمى بالواردات التي لا تحتوي على امتداد كما تفعل العقدة مع Commonjs (من الجدير بالذكر أن دعم node esm يتطلب ".js" بنفس طريقة الكتابة المطبوعة اليوم) - إرفاق أعمى لـ ".js" قد يؤدي إلى حدوث مشكلات جديدة ، مثل استيراد ملفات جافا سكريبت بدون امتداد حقًا ، أو حتى أنواع ملفات أخرى مثل css أو json - سيجعل الامتدادات ذات مغزى وتتطلب منطقًا خاصًا للتحليل ، مما يخلق فرقًا صارخًا بين المتصفح ودلالات الكتابة المطبوعة - ومن الواضح أننا لن نذهب لإعادة كتابة مكالمات fetch بنفس الطريقة ، فربما يظل import متشابهًا؟

ومع ذلك ، فأنا أتساءل - هل من غير الضار نسبيًا أن تقوم الحروف المطبوعة بتحويل امتدادات ".ts" إلى ".js"؟

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

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

🥃 مطاردة

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

يبدو أن هذه المشكلة (الأكبر من TypeScript) تمنع التحسس الذكي لبرنامج Visual Studio Code من العمل في متصفحات الويب والعقدة - الأمر الذي يتطلب مسارات ملفات كاملة (نسبية) في محددات الاستيراد. بدون ذلك ، فإن عبارات الاستيراد التي تم إنشاؤها تعمل فقط مع المحولات والحزم ، مثل WebPack و TypeScript نفسها.

أعتقد أن هناك بعض الالتباس هنا - من الممكن جدًا اليوم إنشاء مكتبة أو تطبيق مطبوع يعمل بشكل رائع مع vscode و intellisense ، والذي يعمل في المتصفحات والعقدة ، ويعمل في esm أو commonjs - أصبح الحل الشامل حقًا ممكنًا اليوم

لقد كنت أعمل على عدد قليل من المكتبات المفتوحة التي تعرض هذا - renraku ، cynic ، redcrypto ، السلطوية

أرسل لي بريدًا إلكترونيًا وسأكون سعيدًا بتوضيح المزيد

: موجة: مطاردة

نقطة أخرى هي أنه ينتج عنه ارتباك في الملف الذي تصل إليه. يوجد بالفعل غموض فيما يبدو عليه tsc بعد دقة الوحدة عندما يكون لديك ملف .js و .ts جنبًا إلى جنب.

/folder
  a.ts
  a.js
  index.ts

إذا كانت في index.ts ، عند استخدام moduleResolution: 'node'

// points to a.ts
import * as a from './a` 

// points to a.ts
import * as a from './a.js` 

// compiler emits error
import * as a from './a.ts` 

يوجد بالفعل غموض بشأن ما ينظر إليه tsc بعد دقة الوحدة عندما يكون لديك ملف .js و. ts جنبًا إلى جنب.

حسنًا ، بالتأكيد ، نوعًا ما ، ولكن إذا كان a.js أي شيء سوى النسخة المنقولة من a.ts ، فهذا يعني أن شيئًا ما قد حدث خطأ كارثي وليس خطأ TypeScript.

@ thw0rted إذا كنت تقوم بالترجمة إلى ملف حزمة JS واحد ، فلن يقوم TypeScript بإنشاء نظائر JS لملفات TypeScript المدخلة ، فقط ملف الحزمة الفردي. في هذه الحالة ، من القانوني تمامًا أن يكون لديك ملف JS وملف TS يحمل نفس الاسم ولا يتوافقان بأي شكل من الأشكال.

هذا ليس "غير قانوني" لكن هذا لا يعني أنها فكرة جيدة. هل لديك مثال ملموس على المكان الذي تريده بالفعل؟

سيكون من الجيد ببساطة استخدام TypeScript بدون حزم ، ومحمل وبطريقة تنبعث منها JavaScript والتي يمكن استخدامها مباشرة من قبل المتصفحات الحديثة.

كمثال:
https://github.com/alshdavid/tsc-website

لكني أشعر بألم المشكلة. لا يرغب فريق TypeScript في تنفيذ دقة الوحدة النمطية. هذا هو نفس السبب في أن برنامج التحويل البرمجي TypeScript لا يمكنه تحويل paths إلى المسارات النسبية الفعلية في وقت الترجمة.

تحويل استيراد من .ts إلى .js ، أو إضافة .js إلى استيراد بدون ملحق يعني أن فريق TypeScript سيقوم بتنفيذ حل الوحدة النمطية وهذا خارج النطاق.

حل لذلك هو أن يوفر فريق TypeScript طريقة لتقديم ملحقات حتى نتمكن من تنفيذ هذه الأشياء.

حل لذلك هو أن يوفر فريق TypeScript طريقة لتقديم ملحقات حتى نتمكن من تنفيذ هذه الأشياء.

يفعلون ذلك ، لا يتم الكشف عنها عبر tsc (فقط من خلال الاستدعاء البرمجي للمترجم). لحسن الحظ ، قام شخص ما ببناء غلاف حول المترجم الأساسي يعمل _ بالضبط _ مثل tsc باستثناء أنه يدعم الامتدادات عبر التكوين. باستخدام غلاف tsc هذا ، يمكنك استخدام امتداد مثل https://github.com/Zoltu/typescript-transformer-append-js-extension/ لإضافة الامتداد .js تلقائيًا.

alshdavid يعمل المثال الخاص بك في GitHub في المتصفحات بدون حزمة إذا قمت فقط بتضمين الامتداد .js على الواردات. لقد تقدمت بعلاقات عامة لإصلاحها.

alshdavid قد تكون مهتمًا بمشروع عينة (esm للحديث و IE11 مع SystemJS).
لكنني مجبر على حل وحدات ESM يدويًا = (

ليس لدي أي مشكلة من حيث المبدأ في وضع .js في كل import s الخاصة بي ، ولكن لسوء الحظ فإن ذلك يعرض تفاعلًا ضعيفًا مع بعض الأدوات. على سبيل المثال ، اختناقات ts-node: https://github.com/TypeStrong/ts-node/issues/783. لا يبدو أن هناك اتفاقًا واضحًا على من تقع مسؤوليته - TypeScript لإرسال الامتداد .js (في بعض الظروف) أو كل أداة تستهلك مصادر TypeScript للقيام بالترجمة. وطالما أن الجميع يتخطى المسؤولية ، يعاني المستخدمون من مكونات إضافية موثقة بشكل سيئ أو عمال خدمة محرجين للتغلب على حالات عدم توافق التشغيل المتداخل.

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

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

وإذا لم أكن أنا حقًا ، فأنا لا أفهم لماذا لم يتم إصلاح هذه المشكلة منذ 3 سنوات ...

لقد أكملت مؤخرًا البرنامج التعليمي المطبوع على الحروف ، ثم عندما حاولت إنشاء بعض ملفات ts ، جئت حول هذه المشكلة. أنا جديد تمامًا على عالم js-ts ، لذا اعذرني إذا كان هناك أي شيء خاطئ أو مضلل / مضلل.

ما فعلته كان أثناء الاستيراد

لقد قمت فقط بوضع امتداد .js في ملف ts ، ثم عندما راجعت intellisense ، عملت أيضًا عندما قمت بنقلها باستخدام tsc ، أضافت الامتداد .js أيضًا إلى ملف الإخراج الذي تم إنشاؤه.

فيما يلي ما فعلته.
tsc -p tsconfig.json

{
"compilerOptions": {
// "وحدة": "amd"،
"الوحدة النمطية": "es6"،
"الهدف": "es6"،
"noImplicitAny": خطأ ،
"removeComments": صحيح ،
"saveConstEnums": خطأ ،
// "outFile": "js"،
"outDir": "js"،
"sourceMap": خطأ
} ،
"تتضمن": [
"testcript.ts"
]
}

على الرغم من أنها عملت بالنسبة لي.

أشك في أنه نظرًا لعدم وجود svgwrapper.js للاستيراد منه
لماذا / كيف عملت؟ (أفترض أنه لا يعتبر التمديد)

أنا أرفق لقطة الشاشة كمرجع.

ts-js-ext-issue

yogeshjog هذا هو بالضبط كيف يعمل tsc ويفترض أن يعمل. تقوم باستيراد الوحدة النمطية مع اسم الملف الذي سيتم إنشاؤه. ما إذا كانت الوحدة التي تم استيرادها مكتوبة في الأصل كملف .ts أو .d.ts / .js زوج لا يجب ملاحظته من وحدة الاستيراد.

yogeshjog هذا هو بالضبط كيف يعمل tsc ويفترض أن يعمل. تقوم باستيراد الوحدة النمطية مع اسم الملف الذي سيتم إنشاؤه. ما إذا كانت الوحدة التي تم استيرادها مكتوبة في الأصل كملف .ts أو .d.ts / .js زوج لا يجب ملاحظته من وحدة الاستيراد.

شكرا! @ justinfagnani للتوضيح 👍

تقوم باستيراد الوحدة النمطية مع اسم الملف الذي سيتم إنشاؤه.

لكن TypeScript يسمح أيضًا بحذف الامتداد ، وهو أمر غير مسموح به وفقًا لـ ECMAScript. حتى أنه يتجاهل الامتداد عند استخدام ميزة الاستيراد التلقائي في VSCode وهو الأمر الأكثر إزعاجًا. تكتب بعض JS ويقول TS إنه على ما يرام ثم يتعطل في وقت التشغيل.

لكن TypeScript يسمح أيضًا بحذف الامتداد

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

وهو غير مسموح به وفقًا لـ ECMAScript.

لا يذكر ECMAScript أي شيء عن محددات الاستيراد. هذا متروك للبيئات المضيفة مثل HTML و Node. يدعم TypeScript دقة العقدة عند تحميل الوحدات النمطية ، ويفسر الدقة مقابل _output_ للمجمع وليس المترجم _input_. بهذه الطريقة تعمل المحددات بعد التجميع وتعمل بغض النظر عما إذا كنت تحاول استيراد وحدة مترجمة أم لا.

نظرًا لأن TypeScript يستخدم دقة العقدة التي ستقوم ببحث المسار لتحويل './foo' info './foo.js' ، فإن './foo' صالح. لكن تحليل العقدة لن يحول './foo.ts' إلى './foo.js' ، لذا فإن './foo.ts' غير صالح.

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

نأمل أن يتم تسوية دعم الوحدة النمطية الأصلية بشكل كافٍ الآن لـ TypeScript لإضافة إعداد دقة آخر.

leontepe لست بحاجة إلى أداة تجميع / محمل. يمكنك إما استخدام https://github.com/Zoltu/typescript-transformer-append-js-extension/ (الحل المفضل لدي) أو يمكنك إلحاق .js لجميع بيانات الاستيراد الخاصة بك (احذر: هذه الإرادة اجعل شفرتك تفشل في ts-node ).

leontepe لست بحاجة إلى أداة تجميع / محمل. يمكنك إما استخدام https://github.com/Zoltu/typescript-transformer-append-js-extension/ (الحل المفضل لدي) أو يمكنك إلحاق .js لجميع بيانات الاستيراد الخاصة بك (احذر: هذه الإرادة اجعل شفرتك تفشل في ts-node ).

MicahZoltu حسنًا ، شكرًا لك ، لكن لا يزال محبطًا نوعًا ما لأنه لا يعمل فقط "خارج الصندوق". كما قال phaux ، يقترح VSCode على مستخدميه عمل بيانات استيراد بدون الامتداد وهذا ببساطة لا يعمل في وقت التشغيل. أشكك بجدية في كفاءة فريق TypeScript هنا أو أخطأت طوال الوقت وأنا مجرد غبي. لكن من يعلم...

تحرير: التفكير بجدية في إسقاط TypeScript لـ JavaScript + Babel في هذه المرحلة.

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

ربما حان الوقت لإضافة دقة وحدة جديدة إلى TS؟ تتمتع Node.js بدعم ESM أصلي الآن ، ولكن بدون امتدادات صريحة في المسارات النسبية ، فإنها تفرض استخدام علامة --experimental-specifier-resolution=node ، وهو أمر مزعج نوعًا ما. هناك أيضا دينو والمتصفحات. من الناحية المثالية ، يجب أن يكون هناك شيء من هذا القبيل:
tsconfig.json:

{
    "compilerOptions": {
        "moduleResolution": "explicit",
        "strict": true
    }
}

ثم مطبوعة:

import foo from './foo.ts'; // no ts(2691) here

يجمع إلى جافا سكريبت:

import foo from './foo.js';

"صارم": صحيح يعني الكثير من العمل!
2020 ، لم يتم إصلاحه بعد ، سخيف.

مجرد رنين للقول بأن هذه المشكلة تمنع فريقنا أيضًا 😢

نود حقًا أن نكون قادرين على الحصول على مصدر واحد يتناسب مع الوحدات الأصلية ويمكن أيضًا استهلاكه في العقدة ومع حزمة الويب. يبدو أن Webpack تواجه مشكلة إذا أدخلت .js يدويًا في الواردات في كود TS الخاص بك. ومع ذلك ، يمكنك نوعًا ما تشغيل حزمة الويب إذا قمت بوضع امتداد الملف .ts في الواردات الخاصة بك ، ولكن بالطبع هناك شكوى مطبوعة. عدم وجود امتداد الملف يؤدي إلى عدم وجود وحدات أصلية. لذلك ، لا يبدو أن أي مجموعة ترضي المتصفح والحزم. إذا تمكنا من كتابة .ts في وارداتنا وجعلها .js في الإخراج ، فسيتم حل المشكلة على ما أعتقد (وستحصل أيضًا على deno توافق). شيء مثل @ evg656e يقترح يبدو أنه يجب أن يعمل.

EisenbergEffect هل هناك خطأ تم رفعه ضد WebPack لهذا الغرض؟ يبدو حقًا أن مشكلة WebPack تبتعد عن tsc العادي.

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

EisenbergEffect إذا كان مُحمل WebPack's TypeScript لا يسمح لك باستيراد ملفات TypeScript عبر امتداد .js مثل tsc ، فهذا خطأ. كما قلت ، يمنع السلوك وجود نفس المصدر مع WebPack و tsc .

ربما حان الوقت لإضافة دقة وحدة جديدة إلى TS؟ تتمتع Node.js بدعم ESM أصلي الآن ، ولكن بدون امتدادات صريحة في المسارات النسبية ، فإنها تفرض استخدام علامة --experimental-specifier-resolution=node ، وهو أمر مزعج نوعًا ما. هناك أيضا دينو والمتصفحات. من الناحية المثالية ، يجب أن يكون هناك شيء من هذا القبيل:
tsconfig.json:

{
    "compilerOptions": {
        "moduleResolution": "explicit",
        "strict": true
    }
}

ثم مطبوعة:

import foo from './foo.ts'; // no ts(2691) here

يجمع إلى جافا سكريبت:

import foo from './foo.js';

يحب الناس (على سبيل المثال ، أنا) السماح لقطعة واحدة من التعليمات البرمجية بالعمل بين Node.js و Deno والويب في نفس الوقت. أعتقد أن هذا سيكون معلمًا رائعًا لبرمجة TypeScript / JavaScript.

إذا كنت تستخدم vscode وتحتاج إلى حل مؤقت ، فإن إضافة هذا إلى settings.json يبدو أنه يحل المشكلات:

"typescript.preferences.importModuleSpecifierEnding": "js"

سيؤدي ذلك إلى إلحاق .js بمسارات الاستيراد الخاصة بك (والتي ستحل ملفات *.ts في src بدون أخطاء ، ولكنها تحتفظ بـ .js عند التحويل). إنه مفيد عند استخدام tsc بدون مجمّع.

بينما ننتظر حل tsc ، فإن الإصلاح منخفض التقنية لهذا هو

  1. انسخ جميع ملفات المصدر إلى مجلد مؤقت
  2. قم بإزالة الامتداد للواردات والصادرات قبل الإنشاء

كنت أرغب في مشاركة هذا الخط الواحد في حال كان بإمكان الآخرين استخدامه. يقوم بنسخ المجلد / src إلى tmp / وتغيير الملفات هناك.

npx shx cp -r ./src/ ./tmp/ && npx rexreplace "(^§s*?(?:import|export).*?from§s+?(['\"]).*?)§.ts§2" €1€2 './tmp/**/*.{ts,js,tsx,jsx}'

كجزء من نص برمجي في package.json (بعد عمل yarn add --dev shx rexreplace ) قد يبدو هكذا

"scripts":{
  "build": "yarn build-esm && yarn build-tsc",
  "buil-esm": "...Whatever you normally do...",
  "build-tsc": "shx mkdir -p tmp && shx cp -r ./src/* ./tmp && rexreplace \"(^§s*?(?:import|export).*?from§s+?(['\\\"]).*?)§.ts§2\" €1€2 './tmp/**/*.{ts,js,tsx,jsx}' && tsc src/index.ts && shx rm -r ./tmp"
}

أنا حاليًا أبقي .js بعيدًا عن مسارات الاستيراد في مصادر TypeScript ، لإرضاء Jest.
بعد ذلك ، لدي خطوة معالجة ما بعد لإضافة .js .
خرائط المصدر غير مدعومة بهذه الطريقة.

tsc -b tsconfig-solution.json -w --listEmittedFiles \
  | node mk/build-post.js

يقوم سكربت معالجة ما بعد build-post.js بما يلي.

إلحاق .js بالمسارات النسبية import و export

علي سبيل المثال،

export { X } from "./first";
import { Y } from "./second";

يصبح

export { X } from "./first.js";
import { Y } from "./second.js";

لاحظ أنني لا أستخدم index.ts في أي مكان ، ولكن بدلاً من ذلك استخدم mod.ts بعد اصطلاح Deno. وبالتالي ، لست بحاجة إلى النظر في حالة إلحاق /index.js .

قم بتغيير import إلى require لحزم CommonJS

يعمل الكود الخاص بي على العقدة ^ 12.17 و ^ 14.1 ، في وضع الوحدات النمطية. أنا أنشر فقط وحدات ES.
ومع ذلك ، لا تزال العديد من التبعيات تحتوي على CommonJS في حقل "main" الخاص بهم.
وبالتالي ، يجب أن أغير هذه إلى CommonJS ، باستثناء الوحدات النمطية المدمجة في NodeJS.

علي سبيل المثال،

import { Server as WsServer } from "ws";

يصبح

import { createRequire } from "module";
const require = createRequire(import.meta.url);
const { __importDefault } = require("tslib");

const { Server: WsServer } = require("ws");

ولكن بعد ذلك ، حزمة الويب غير راضية عن هذه require s ، لذلك يجب علي استخدام:

/// #if false
import { createRequire } from "module";
const require = createRequire(import.meta.url);
const { __importDefault } = require("tslib");
/// #endif

/// #if false
const { Server: WsServer } = require("ws");
/*
/// #else
import { Server as WsServer } from "ws";
/// #endif
/// #if false
*/
/// #endif

في حزمة الويب ، يجب أن تستخدم أي حزمة تقوم باستيراد مشروعي ifdef-loader ، وبعد ذلك ستظهر حزمة الويب سطر import الأصلي.

لقد أصابنا هذا أيضًا ولا يمكنني أن أفهم كيف لم يتم إصلاح ذلك بعد 3 سنوات من الإبلاغ عنه.
نحن نستخدم WebStorm لذا لن يعمل الإعداد المحدد لـ VSCode.
يعد استخدام برنامج نصي منفصل لإصلاح الإخراج أمرًا سخيفًا.
يجب أن يعمل هذا دون الحاجة إلى استخدام أدوات الجهات الخارجية.

+1

هذا هو الحل البديل الخاص بي باستخدام موقع asp.net core 3.1 (ربما يعمل على إصدارات أقل)
في ملف startup.cs:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            var rewriteOptions = new RewriteOptions();
            rewriteOptions.AddRewrite(@"^js/(.+)", "js/$1.js", skipRemainingRules: true);

            app.UseRewriter(rewriteOptions);

            app.UseStaticFiles();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGet("/", async context =>
                {
                    await context.Response.WriteAsync("Hello World!");
                });
            });
        }

ستضيف البرامج الوسيطة المعاد كتابتها الامتداد ".js" إلى أي طلب يستهدف المجلد / js.
تحذير: ترتيب البرامج الوسيطة مهم هنا ، يجب وضع UseStaticFiles بعد UseRewriter وإلا فلن يعمل.

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

ربما حان الوقت لإضافة دقة وحدة جديدة إلى TS؟ تتمتع Node.js بدعم ESM أصلي الآن ، ولكن بدون امتدادات صريحة في المسارات النسبية ، فإنها تفرض استخدام علامة --experimental-specifier-resolution=node ، وهو أمر مزعج نوعًا ما. هناك أيضا دينو والمتصفحات. من الناحية المثالية ، يجب أن يكون هناك شيء من هذا القبيل:
tsconfig.json:

{
    "compilerOptions": {
        "moduleResolution": "explicit",
        "strict": true
    }
}

ثم مطبوعة:

import foo from './foo.ts'; // no ts(2691) here

يجمع إلى جافا سكريبت:

import foo from './foo.js';

قمت بإعداد قاعدة node/file-extension-in-import في eslint-plugin-node لتكوين الفحص مع فكرة إضافة الامتداد يدويًا لاستيراد البيانات (لأنه من الأفضل بهذه الطريقة) و "moduleResolution": "node" في TypeScript config وكل ما يمكنني رؤيته هو ts(2691) .

نأمل أن يكون ما قاله @ evg656e يستحق التنفيذ.

لا أستطيع أن أصدق أن هذه لا تزال مشكلة.

عندما تستخدم
"baseUrl": ".", "paths": { "/*": ["./*"] },

يمكنك القيام باستيراد وحدة absoulte مثل:
"استيراد ws من" / مرحباً / اتصال "؛

ولكن عند إضافة الامتداد ".js" ، فجأة لم يعد المترجم يجد إعلان connection.ts ويقول:

Could not find a declaration file for module '/hey/connection'. '/home/tobi/Documents/JITcom/Code/Libs/Test_Browser/hey/connection.js' implicitly has an 'any' type.

باستخدام مسار نسبي كل شيء يعمل بشكل جيد.

الرجاء إصلاح هذا

أنا أيضا أريد إصلاح لهذا.

شكرا لك.

من السخف أن تظل هذه مشكلة! : 00

لقد قررت أخيرًا التبديل إلى TypeScript وكانت هذه إحدى المشكلات الأولى التي واجهتها. إنه يكسر دقة الوحدة في التنفيذ الأصلي لـ Node ، وقد تمكنت فقط من الالتفاف حوله إما باستخدام حزمة esm التي تبدو أكثر مرونة في قبول الأسماء بدون ملحقات ، أو (بشكل غريب) باستخدام امتدادات .js في مسارات الاستيراد داخل ملفات .ts الخاصة بي حتى عندما يشير الاستيراد إلى ملف .ts أو .tsx. لست متأكدًا من سبب قبول برنامج التحويل البرمجي TypeScript لذلك ، ولكن على الأقل ناتج البناء يتضمن الامتداد .js. حل مبتذل رهيب بالرغم من ذلك.

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

أترك الامتداد في سطور الاستيراد ، لإرضاء Jest و Webpack.
عندما أقوم بالتجميع ، أقوم باستدعاء tsc --listEmittedFiles وأرسل الإخراج إلى برنامج نصي للمعالجة اللاحقة. يضيف هذا النص البرمجي الامتدادات .js ، لجعل Node (في وضع الوحدة النمطية) سعيدة.
https://github.com/yoursunny/NDNts/blob/fa6b2eb68a9f32a6a2e24e5475275f803236b8f8/mk/build-post.js

kj

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

إنه ليس غريبًا وبالتأكيد ليس اختراقًا ، ويعمل بشكل مثالي مع المستعرض ودقة الوحدة الأصلية Node.

المورد الذي تستورده _is_ ملف .js. يمكن أن يكون النوع إما في ملف .ts أو في ملف .d.ts. لا يحتاج ملف .d.ts إلى أن يكون شقيقًا لوحدة .js ، ولا يلزم وجود علاقة 1 إلى 1 بين ملفات .d.ts وملفات .js.

يعد استيراد الوحدة النمطية .js هو الخيار الأكثر موثوقية واستقرارًا والذي يمكن أن يختاره tsc. وإلا فستكون هناك حالات حيث تقوم باستيراد الأنواع ولا يعرف tsc الطريقة الصحيحة لإعادة كتابتها في مسار وحدة فعلي.

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

المورد الذي تستورده _is_ ملف .js

أنت تشير إلى الوحدة المبنية هنا ، أليس كذلك؟ ليس ملف .js في الدليل المصدر ، ولكن الإصدار المبني من وحدة .ts؟

ألا يمكن أن يكون الأمر كذلك إذا قمت بتحديد الامتداد .ts أو .tsx صراحة في مسار الوحدة النمطية ، فإن الإخراج سيحل محل .js؟

أعتقد أنه قد يكون هناك سوء فهم لما يحدث علىkj. عند تحديد امتداد .ts دون تجميع التعليمات البرمجية الخاصة بك ، فإنه يشير إلى ملف ts. ولكن عند التحويل البرمجي باستخدام tsc ، فإنه يحول محتويات ملف ts إلى ملف js قابل للتنفيذ في البيئة التي تتواجد فيها (عقدة أو متصفح).

أفهم أن @ mkay581 ، لكن أقول إن لدي هذا السطر في ملف foo.ts:

import { Component } from './Component.js';

إن "Component.js" الذي أشير إليه هو في الواقع "Component.tsx" على نظام الملفات (لا يوجد ملف .js ، ما لم يفهم TypeScript أن هذا يشير إلى النسخة النهائية من الملف؟) ، حتى الآن يقبل TypeScript هذا بشكل جيد ويوجد نفس سطر الاستيراد بعد ذلك في الإخراج (بامتداد .js الذي يعمل بعد ذلك مع Node أو المستعرض).

تتمثل طريقة TypeScript التقليدية (AFAIK) في تحديد سطر الاستيراد هذا بدون الامتداد ، على النحو التالي:

import { Component } from './Component';

من الواضح أن هذا يجمع جيدًا أيضًا ، باستثناء سطر الاستيراد في ملف .js المنقول لا يتضمن الامتداد .js على "./Component" ، وهو أمر مطلوب من قبل بيئات معينة (وربما يبدو مثل المواصفات ، على الرغم من أنني لم أفعل ذلك. ر قراءته للتأكد).

من ناحية أخرى ، إذا قمت بتحديد السطر الذي يحتوي على اسم الملف الفعلي للملف المصدر:

import { Component } from './Component.tsx';

ثم لا يتعرف TypeScript على المسار ويقترح أن أجرب سطر الاستيراد بدون امتداد الملف (إذا كنت أتذكر ، فأنا لست على جهاز الكمبيوتر الخاص بي الآن).

لذا ، يبدو المثال الأول غريبًا بعض الشيء بالنسبة لي ، فأنا أكتب TypeScript أتوقع أن أكون قادرًا على الاستيراد بامتداد .ts أو .tsx ، لكنه يقبل فقط المسار بدون امتداد (والذي يبدو أنه خلافًا للتطبيقات الأخرى لنظام الوحدة النمطية ES) أو بامتداد .js الذي يمكن أن يشير فقط إلى ملف الإخراج حيث لا يوجد لدي مثل هذا الملف المصدر.

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

المورد الذي تستورده _is_ ملف .js.

لا أعرف كيف يعمل tsc ولكن هذا لا يبدو صحيحًا بالنسبة لي. عندما تكتب الرمز الخاص بك ، لا يوجد ملف .js حتى الآن. إن مهمة المترجم هي إنشائها.

يعمل TS كطبقة تجريد أعلى JS وملفات .js هي ناتج خطوة الترجمة. يبدو أن الاعتماد على وجودهم مع هذا الامتداد المحدد يكسر التجريد ، IMO.

بعبارة أخرى ، عندما تستخدم C أو C ++ ، فأنت لا تستخدم #include .o الملفات في شفرتك ، فأنت تقوم بتضمين .h أو على الأكثر .c أو .cpp .

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

kj

إنه ليس غريبًا وبالتأكيد ليس اختراقًا

لا أوافق بشدة. بالنسبة لي ، هذا هو تعريف الغريب والمتسلل. 😛 ما تفعله هنا هو الرجوع إلى ملف افتراضي. ملف ليس مضمونًا في الوجود. (على سبيل المثال ، عند تجميع التعليمات البرمجية ، باستخدام AssemblyScript ، أو deno) أنت تفترض تنسيق الإخراج. ولكن عند كتابة تعليمات برمجية حيادية (مثل وحدات الطرف الثالث) ، فإن هذا أمر "خطير" يجب افتراضه.

borfastfrzi نعم هذا هو ما شعرت به حيال ذلك ، ويسعدني أن أرى أنني لست الوحيد الذي لا يشعر بالراحة مع هذا. أنا أحاول فقط عدم وضع الكثير من الافتراضات لكوني جديدًا جدًا على TypeScript!

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

ما تفعله هنا هو الرجوع إلى ملف افتراضي. ملف ليس مضمونًا في الوجود

ليس افتراضيًا ، يعلم فريق الدعم أنه سينشئه. إنه مضمون في الوجود ، عند استخدام tsc.

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

عند تجميع الكود

Bundlers تعمل بعد TSC

ذكرkj ملفات .tsx ، وهم يدفعون وجهة نظري إلى المنزل أكثر. يوجد .tsx فقط للإشارة إلى مترجم تلك الوحدة ، _locally_ ، بأن الوحدة تحتوي على JSX. لا يحتاج مستوردي الوحدة إلى معرفة وجود JSX في الملف ، ولا يمكنهم معرفة ذلك بعد التجميع. يمكن نقل الملفات بسلاسة بين أزواج .tsx و .ts و .js / .d.ts.

لنفترض أنك تقوم باستيراد ملف .ts:

import {Component} from './component.ts';

ثم تريد استخدام JSX للمكون ، لذلك يمكنك إعادة تسميته إلى component.tsx. هل يجب أن تفشل جميع الواردات؟ لنفترض أنك قمت بالترحيل من .ts إلى .js / .d.ts ، فهل يجب أن تفشل عمليات الاستيراد مرة أخرى؟

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

يعمل TS كطبقة تجريد أعلى JS وملفات .js هي ناتج خطوة الترجمة. يبدو أن الاعتماد على وجودهم مع هذا الامتداد المحدد يكسر التجريد ، IMO.

التجريد ليس كاملاً كما تشير إليه هنا. يمكنك استيراد ملفات .js من داخل أو خارج مشروع TS الخاص بك. يمكنك إضافة أنواع إلى ملف .js باستخدام ملف .d.ts الذي يوجد في أي مكان في مشروعك. ملفات .js هي ما هو حقيقي بعد التجميع. كل شيء آخر يساعد المترجم فقط.

justinfagnani لقد فقدت بعض الشيء مع ما تقوله ، ولكن لماذا لا تفترض TypeScript فقط أنه إذا أعطيتها مسار استيراد بامتداد .ts أو .tsx ، فإنها ستنشئ ملف .js لتلك الوحدة و لذلك ينبغي استبدال الامتداد الأخير في الإخراج؟

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

ليست افتراضية ، tsc _knows_ سوف تولدها. إنه مضمون في الوجود ، عند استخدام tsc.

ولكن هناك تناظر ضمني هنا أنك لا تعترف به.

هذا "الضمان" الذي ذكرته يحمل كلا الاتجاهين. إذا كان ، كما قلت ، "tsc _knows_ ستنشئ [ملفات js]" ، فحينئذٍ يكون طرح سؤال صحيح بنفس القدر: "حسنًا ، فلماذا لا تتصرف tsc على هذا الضمان وتطبيق امتدادات .js التي _ تعرفها_ هي في عداد المفقودين من js المترجمة؟ "

تفسير حقيقة أن "tsc تضمن ملفات js" يسير في كلا الاتجاهين.

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

في النهاية ، يدور هذا الجدل حول "قرار جمالي وليس منطقي". وآمل أن يتم استخدام نبرة الصوت المكبرة والمتوافقة - كما هو مناسب للرأي_ الجمالي (وليس الاستنتاج المنطقي) - للتأثير على هذه المسألة من قبل منتقديها.

باختصار ، يرجى الاعتراف بأن سؤال OP هو تفسير صحيح تمامًا - ربما مع تفسيرك الخاص. لا حاجة لمناقشات قاسية.

شكرا لك

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

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

بالطبع لن يحدث ذلك ، تمامًا مثل ملف .h لا يتم توزيعه مع الملف التنفيذي لبرنامج C. هذه هي النقطة بالضبط: تخبر المترجم بتضمين الملفات المصدر ، وليس الملفات المترجمة .

حسنًا ، تلقيت رسائل غير مرغوب فيها أكثر من اللازم في هذه المحادثة بحيث لا يمكنني تجاهلها أكثر.
العبارة import ليست جزءًا من الكتابة المطبوعة ، إنها جزء من بيئة JavaScript التي نفذتها. الآن ، الكلمة الأساسية هنا هي بيئة JavaScript ، حيث أن هذا هو ما يحل المسارات. أرني تطبيقًا واحدًا يقوم في وقت التشغيل باستيراد ملفات .ts وينفذها (بالتأكيد ، قد يكون هناك بعض منها ، لكنها ما يمكن أن أسميه الاختراق).
يسمح TypeScript بإضافة امتدادات .js لأنه يسمح باستخدام JavaScript أصلي داخل ملفات المصدر الخاصة به. لن يقوم أي من مستعرضات node.js بتنفيذ ملف .ts ، حتى ts-node نقل ملفات .ts أثناء التنقل ، فقط يحتفظ بالنتيجة في الذاكرة بدلاً من كتابتها على القرص الصلب (ليس اختراقًا على الإطلاق بشكل صحيح ؟).

الآن ، سيكون إصلاح tsc المناسب هو:

  • لدينا ملف .ts
  • نشير إليه في ملف آخر
  • يقوم tsc بنقل هذا الملف .ts إلى ملف .js
  • يقوم tsc بإعادة كتابة جميع المراجع المباشرة إلى ملف .ts بملف .js (يعرف بالضبط كيف يتم نقله حتى يتمكن من تحديثه بشكل صحيح)

المشكلة: "مطور الويب الحديث" ليس مطور ويب حقيقيًا ويستخدم طريقة node.js للاستيراد وتخطي الامتداد (ومسار الملف بالكامل). tsc الآن لم يعد يعرف ما هو الناتج ، حيث أن استيراد my-awesome-module/test يمكن أن يكون أي شيء ، بدءًا من ملف test.js في node-modules/my-awesome-module ، من خلال index.js ملف داخل مجلد test في node-modules/my-awesome-module ، تنتهي ببعض عمليات إعادة الكتابة المحلية مع ملفات غير js مثل ./local-mocks/my-awesome-module/mock.json .

هذا هو المكان الذي تبرز فيه المشكلة: كيف يمكن لـ tsc معرفة ما هو غير تقليدي webpack / rollup / super-awesome-new-and-shiny-bundler config لمشروعك المحدد؟

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

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

كيف يمكنك القيام بذلك في مشروع بسيط بدون webpack ، فقط مع tsc أعني؟

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

عندما تشير ملفات المصدر .ts إلى ملفات .js ، فقد بدأت المشكلة بالفعل.

تم إنشاء Typescript لتشغيل ~ تجميع ملفات المصدر .ts - وليس ملفات .js. إذا أراد أحد المطورين استخدام TypeScript في مشروعهم ، فيجب عليهم تحويل مشروعهم _entire_ إلى نص مطبوع وعدم ترك ملفات .js المعزولة ومحاولة الرجوع إليها. وإذا لم يكن لديك الوقت لتغيير المحتويات في ملفات js إلى بناء جملة Typescript ، فما عليك سوى إعادة تسمية ملفات js إلى ملفات ts (أو استخدم تعيين مسار TS لتعيين الواردات إلى ملفات .js). تم حل المشكلة. : man_shrugging:

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

@ mkay581 لم يكن المقصود من TypeScript مطلقًا تشغيل أي شيء ، فقط لإخراج ملفات JS.

valeriob من المحتمل أن يحتوي المشروع البسيط على ملفات قليلة على الأكثر ، والتي لا تحتاج إلى تجميعها. تحتوي المتصفحات في الوقت الحاضر على واردات مضمنة ، ولا داعي للالتفاف حول ذلك. بعد ذلك ، سيكون الأمر بسيطًا مثل الاستماع إلى أحداث التنقل في المتصفح ، ثم تعيين كل حدث للمسار المطابق ، ويمكن لكل مسار استيراد البيانات بـ fetch وبمجرد إرجاعه يمكن عرضه بمحركات قوالب غير مجمعة (مضاءة- html أو HyperHTML أو أقدم مثل Moustache و Handlebars و Pug وما إلى ذلك). تم ، لا حاجة إلى حزمة ويب خيالية أو إطار عمل أو أي مكتبات أدوات مساعدة ، فقط حتى المستمعين و regexp و fetch والوعود ومحرك نموذج js بسيط.

شكرًا Draccoz ، مما يمكنك أن تخبرني كيف أجعل هذا السيناريو البسيط يعمل؟ https://github.com/valeriob/Typescript_Non_SPA
إنه ملف .ts بسيط يشير إلى مكتبة JS (كمثال rxjs) وأريد أن أستهلكه كوحدة نمطية في صفحة html.

valeriob هذا ليس تافهًا كما ينبغي. معظم مكتبات الجهات الخارجية حتى عندما تعلن أنها متوافقة مع وحدات ES ، فهي ليست في عالم المتصفحات.
RxJS هو شيء كنت مهتمًا به في الغالب عند إحضاره إلى التدفق الأصلي ، لكنهم ينتظرون حل هذه التذكرة قبل أن يقرروا تنفيذها بأنفسهم (مضحك ...).
في الهندسة المعمارية التي كنت أصممها ، استخدمت في البداية sed لإصلاح جميع الواردات ، ولكن بعد ذلك غيرت رأيي لاستخدام خادم dev بسيط مع إعادة كتابة المسار. مفهومي هو عدم وجود تبعيات خارجية في تطبيقاتي بصرف النظر عن rxjs و typecript و lit-html (node_modules مع 4 مجلدات واختبارات / تصميمات ULTRA fast CI). إذا أعاد TS كتابة المسارات ، فسيؤدي ذلك إلى التخلص من الحاجة إلى الخادم الخاص بي ، على الرغم من وجود حوالي 90 سطرًا من التعليمات البرمجية على أي حال. إنه مفتوح المصدر ، إذا كان أي شخص يريد رابطًا فقط اسأل أو تحقق من المؤسسات في ملفي الشخصي.

بالنسبة للصفحات البسيطة ، كنت أشير إلى تلك التي لا تحتاج حقًا إلى أي مكتبة ، مثل الضغط على عنوان url -> جلب البيانات -> عرضها -> كرر.

إن عدم الحاجة إلى استخدام أي مكتبة في Js هو خيال خالص لأن Js لا تحتوي على مكتبة أساسية.

السيناريو البسيط هو الذي ربطته ، وهو لا يعمل. إنه أيضًا السيناريو الأكثر شيوعًا لـ ppl الذي لا يريد الغوص في عالم webpack / التجميع المجنون الذي يعقد الأشياء بدون فائدة حقيقية ، ويحد من خياراتك كثيرًا ، ويجعل المطورين يحاربون الأدوات أكثر من كتابة التطبيق الخاص بك ، ويبطئ التطوير الخاص بك حلقه.

هناك العديد من التمارين الذهنية التي تجري هنا لإنكار وجود هذه المشكلة وأنها مصدر قلق مهم لكثير من إنتاجية المطورين.

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

إذا كان المستخدمون يصورون tsc كمترجم شبيه بـ C ، وفقًا لـborfast ، فهذا هو الوضع العقلي المميز الذي يجب مواءمته ، على الرغم من تفاصيل تنفيذ tsc.

يحتوي سؤال OP على 200+ إعجاب ، أكثر من جميع المشكلات الأخرى في الريبو.

هذه القضية تستحق تصويت المجتمع. يرجى النظر في بدء الاستطلاع.

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

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

weoreference إذا حددت بطريقة واضحة (وليس كتابة التعليمات البرمجية ، فقط التصميم) كيف يجب أن تعيد كتابة المسارات بالضبط ، مع مراعاة البيئات المتعددة (node.js ، المتصفح) ، إمكانيات تكوينات الحزم المتعددة (التحقيق في جميع الميزات الحالية والمخطط لها والمستقبلية المحتملة webpack و rollup و parcel وأي حزم أخرى) بالتأكيد ، إذن أعتقد أن فريق TypeScript سيكون ممتلئًا بجانبك.

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

Draccoz ، تريد أن تغير سيارتك التروس حتى تتمكن من قيادتها أسرع من 10 كم / ساعة ، لكنني متأكد من أنك لم تطلب من الشركة المصنعة أبدًا معرفة كيفية عمل قطار التروس ، ناهيك عن تصميم واحد.

أما بالنسبة لمسألة الحزم وماذا ، فلماذا هذا مانع لذلك؟

انظر ، أريد فقط استخدام وحدات ES ، ولا أريد التعامل مع كل جنون Babel و Webpack. لماذا لا يكون هذا خيار مترجم اختياريًا يقوم ببساطة بتغيير امتداد الملف إلى .js؟ إذا كان هذا السلوك يتعارض مع خيارات التكوين الأخرى التي حددها المستخدم ، فيجب تعطيله تلقائيًا ، أو يجب إظهار تحذير / خطأ وإيقاف التجميع عند تنفيذ tsc ، حتى يعرف المستخدم أنه بحاجة إلى تغيير التكوين.

أنا حقًا لا أفهم لماذا هذا مستحيل.

Draccoz مرحبا :) حسنًا ، كما أراها ، أنت تسأل شيئين:

  1. كيف يمكن تنفيذه

  2. كيف يمكنني ، المطور ، إرسال إشارة إلى tsc أنني أريد إعادة تسمية الواردات بطريقة معينة ، لبيئتي الخاصة

ها هي أفكاري.

  1. يرجى الاطلاع على رد borfast ؛ إنها إجابة "عالية المستوى" ، لكنها موجزة :)

  2. ربما يمكنني تمرير علامة إلى tsc / tsconfig ، مثل "renameImports": true ، أو بعض الإشارات الأخرى التي يتم التقاطها بواسطة tsc. إذا كانت هناك حاجة إلى مزيد من الدقة ، فربما لا ينبغي أن يكون العلم منطقيًا بل يجب أن يأخذ سلسلة ، ربما شيء من هذا القبيل:

StandardImportExtension: 'js'

لذلك يتم استيراد جميع عمليات الاستيراد بدون امتدادات الملفات افتراضيًا إلى .js

خاتمة:
يبدو أن هذه الوظيفة صعبة التنفيذ فقط لأنك تفترض أن Q2 (نظام إعادة تسمية الاستيراد) يحتاج إلى معرفته مسبقًا بحلول Q1 (أي بواسطة tsc). لكن في الواقع ، لا. أنا ، المطور البشري ، يمكنني بسهولة توفير "المعرفة العالمية" هذه إلى tsc دون الحاجة إلى معرفة كيفية عمل webpack / المتصفحات / إلخ. كل هذا بعلم بسيط.

لم يسأل مستخدم borfast Transmission ، لقد تم تزويده بسيارة من قبل الشركة المصنعة ، وافق المستخدم للتو على أنها ميزة جديدة وبدأ في استخدامها - آسف ، هذه ليست حجة مناسبة. مقارنة بمثال المستخدم - الشركة المصنعة للسيارة لك ، فإن الأمر أشبه بـ "أريد أن تكون سيارتي سيارة كهربائية بالكامل بمدى 100 ألف ميل وسرعة قصوى تصل إلى سرعة طائرة. لا يهمني كيفية تحقيق ذلك ، أريد ذلك و هذا كل شيء - فترة.
weoreference بت سوء فهم في أسئلتي. كنت أسأل: كيف أجعل tsc يفهم ما يشير إليه المسار؟ هل هو ملف js مباشرة؟ أم أنه مجلد بداخله index.ts ؟ أم أنها وحدة نمطية بها package.json تحتوي على حقل main ؟ أو مجال esnext؟ أو أي شيء آخر غير قياسي؟ أم أنه مسار تمت إعادة كتابته بواسطة webpack؟ أو تراكمي؟ إذا كان الأمر كذلك ، أين التكوين؟ هل هو مجمع آخر ربما؟ بعض أقل شهرة؟ وما هي حالات الاستخدام الأخرى التي لم أفكر بها في الجملة أعلاه؟

ربما يمكنني تمرير علامة إلى tsc / tsconfig ، مثل "renameImports": true ، أو بعض الإشارات الأخرى التي يتم التقاطها بواسطة tsc.

weoreference ألا يمكنك فعل ذلك بالفعل مع تعيين المسار ؟ يمنحنا الخيار paths في ملف TSconfig التحكم في تعيين مسارات الاستيراد إلى ملفات JS. آسف إذا كنت أفسر بشكل غير صحيح.

Draccoz شكرا لك على ردك ، واسمحوا لي أن أوضح

وما هي حالات الاستخدام الأخرى التي لم أفكر بها في الجملة أعلاه؟

أوه نعم ، سيكون من الصعب جدًا على tsc الحصول على معرفة بكل مجموعات أدوات البيئة / البناء هذه.

ولكن يمكن أن يكون لـ tsc أداة مساعدة بسيطة تساعد المطورين على تغطية _ most__ حالات الاستخدام ، وهذه هي قيمة التكوين "standardImportExtension" التي شرحتها.

طبعا هنا تأتي مشكلة "الضمان". في وقت سابق من هذا الموضوع ، قيل أن tsc يجب أن "تضمن" أن js المترجمة ستعمل في الواقع [في بعض البيئات].

حسنًا ... ربما كان هذا التزامًا صعبًا للغاية. في الواقع ، من الصعب جدًا على tsc ضمان تشغيل js [في بعض البيئات] ، لأنه ، كما وصفت للتو ، من الصعب جدًا تحديد هذه البيئة في المشهد js الحالي.

لكن أداة العلم البسيطة التي اقترحها borfast تحل _ most_ من أخطاء استيراد js التي واجهها المستخدمون الجدد الذين يحاولون tsc.

الاستخدام المتقدم ، والذي يتكون كما ذكرت من كل هذه الاعتبارات —-

هل هو ملف js مباشرة؟ أم أنه مجلد بداخله index.ts؟ أم أنها وحدة مع package.json تحتوي على المجال الرئيسي؟ أو مجال esnext؟ أو أي شيء آخر غير قياسي؟ أم أنه مسار تمت إعادة كتابته بواسطة webpack؟ أو تراكمي؟ إذا كان الأمر كذلك ، أين التكوين؟ هل هو مجمع آخر ربما؟

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

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

وأسهل حالة هي إضافة امتداد .js للواردات ؛ التي يمكننا حلها ويجب حلها.

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

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

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

ليس افتراضيًا ، يعلم فريق الدعم أنه سينشئه. إنه مضمون في الوجود ، عند استخدام tsc.

ولكن هناك تناظر ضمني هنا أنك لا تعترف به.

هذا "الضمان" الذي ذكرته يحمل كلا الاتجاهين. إذا كان ، كما قلت ، "tsc يعلم أنه سينشئ [ملفات js]" ، إذن فمن الصحيح طرح سؤال: "حسنًا ، فلماذا لا تتصرف tsc على هذا الضمان وتطبق امتدادات .js التي تعرف أنها في عداد المفقودين من js المترجمة؟ "

التناظر لا يصمد في الواقع. الأمر ليس بهذه البساطة مثل "تطبيق امتداد .js" - سيتعين على tsc حل المحدد وإعادة كتابته ، وقد يعتمد القرار على تعريفات النوع. يدعم TypeScript و Babel أوضاع الترجمة أحادية الوحدة (وحدات معزولة لـ tsc) وفي هذه الحالة إذا قمت باستيراد أنواع بدلاً من JavaScript ، فسيتعين على tsc تحميل تعريفات النوع لتحديد مكان ملف .js المقابل ، من أجل إعادة كتابة محدد. للحفاظ على اتساق الأشياء وعدم وجود حالات حافة ، فمن الأسهل دعم استيراد ملفات .js الموجودة قبل التجميع أو التي تعتبر نتيجة معروفة للمشروع الحالي.

تضمين التغريدة حسنًا ، نعم أفهم.

تعليقي الأخير: "فقط لأن القضايا الصعبة لا يمكن حلها لا يعني أننا لا نستطيع حل القضايا السهلة".

شكرا لك

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

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

تحرير: أعتقد أنه قد يكون هذا القسم من المواصفات هو الذي يبدو أنه يحدد أن دقة الوحدة "معرّفة من قبل المضيف"؟

kj ، نص المواصفات ذي الصلة موجود في مواصفات HTML: https://html.spec.whatwg.org/multipage/webappapis.html#resolve -a-module-specifier

تقول أن محددات الاستيراد يجب أن تكون عناوين URL كاملة أو مسارات مطلقة أو نسبية. إذا لم يتم تحليل المحدد كعنوان URL (يبدأ عادةً بـ http:// أو https:// ) أو يبدأ بـ / ، ./ ، أو ../ ، حدث خطأ. يتم حل محددات المسار مقابل عنوان URL الأساسي للمستوردين.

لم يتم البحث عن مسار أو حل آخر. هذا يعني أن المحدد يجب أن يحل عنوان URL الكامل للوحدة النمطية ويجب عليك تضمين الامتداد إذا طلب الخادم ذلك. تمتلك الخوادم خيار إرجاع الاستجابات لعناوين URL التي لا تحتوي على امتداد.

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

أخيرًا ، يعمل دعم tsc للاستيراد باستخدام امتدادات .js بشكل مثالي في كل من Node ومتصفحات الويب. إنها في الواقع عمليات الاستيراد غير القابلة للتمديد التي تسبب مشاكل بدون أدوات إضافية. عادةً ما تستخدم الأدوات التي تدعم دقة العقدة لأسماء الحزم فئة تتطلب دقة نمط () وحل المسارات النسبية وإضافة امتداداتها أيضًا. هذا ما يفعله es-dev-server .

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

تحرير: في الوقت الحالي ، سيكون هذا كافيًا بالنسبة لي (خاصة بالنظر إلى التفسيرات أعلاه ، أشعر براحة أكبر معها):

https://nodejs.org/api/esm.html#esm_customizing_esm_specifier_resolution_algorithm

لست متأكدًا مما إذا كان هذا الخيار قد تمت الإشارة إليه في وثائق TypeScript ، ولكن إذا لم يكن كذلك ، فربما يجب أن يكون لتجنب الالتباس. لا يبدو الأمر كذلك ، حيث يتم البحث عن " site: typescriptlang.org specifier-Resolution" أو " site: staging-typescript.org specifier-Resolution". على الرغم من أن هذا لا يزال جديدًا في Node ، فهذا ليس مفاجئًا للغاية.

justinfagnani أوافق على أن الامتداد .js يعمل فقط في معظم الحالات ، باستثناء الحالات التي يتخذ فيها شخص ما موقفًا أيديولوجيًا - ضده (على سبيل المثال https://github.com/TypeStrong/ts-node/issues/783 ، التي تعرفها).

لقد صنعت نسخة خالية من التبعية من نصquantuminformation هنا . يحتوي هذا الإصدار أيضًا على regex الذي سيحل فقط محل الوحدات التي لا تنتهي بـ .js بالفعل.

نفس الحاجة

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

يبدو أن السبب الرئيسي لعدم تطوير هذه الميزة يرجع إلى صعوبة / استحالة التوافق مع الحزم المختلفة ، لكن Node.js والمجمعات طوروا مخططات الوحدات الخاصة بهم في غياب دعم الوحدات في ECMAScript. الآن بعد أن أصبح لدينا ESM ، على الرغم من أن البعض قد يعتبرها غير كافية ، فهذا هو الطريق إلى الأمام. مع تطوير المزيد من التعليمات البرمجية في ESM ومكونات الويب ، سينخفض ​​استخدام الحزم ، وستؤدي نقطة الألم هذه بين TS و ESM إلى مزيد من الاحتكاك. سيكون من الجيد ، حتى لو كان الدعم الأولي عربات التي تجرها الدواب ولا يأخذ في الاعتبار جميع حالات الاستخدام ، إذا كان يمكن البدء في دعمه.

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

تكوين الحزمة الخاصة بك. json:

  ..
    "scripts": {
        "build": "node build.js",
   ...

//build.js
import { execSync} from "child_process"
import * as util from "util"
import * as fs from "fs"
import * as path from "path"

//function to recurse dirs finding files
function fromDir(startPath, filter, callback) {

    //console.log('Starting from dir '+startPath+'/');

    if (!fs.existsSync(startPath)) {
        console.log("no dir ", startPath);
        return;
    }

    var files = fs.readdirSync(startPath);
    for (var i = 0; i < files.length; i++) {
        var filename = path.join(startPath, files[i]);
        var stat = fs.lstatSync(filename);
        if (stat.isDirectory()) {
            fromDir(filename, filter, callback); //recurse
        }
        else if (filter.test(filename)) callback(filename);
    };
};

//this add .js to lines like:  import .* from "\.  <-- only imports from ./ or ../ are touched
function addDotJsToLocalImports(filename) {
    var buf = fs.readFileSync(filename);
    let replaced = buf.toString().replace(/(import .* from\s+['"])(?!.*\.js['"])(\..*?)(?=['"])/g, '$1$2.js')
    if (replaced !== buf.toString()) {
        fs.writeFileSync(filename, replaced)
        console.log("fixed imports at "+filename )
    }
}

//------------------------
//---BUILD TASK START 
//------------------------

execSync("npx tsc --build -verbose", { stdio: 'inherit' })

//add .js to generated imports so tsconfig.json module:"ES2020" works with node
//see: https://github.com/microsoft/TypeScript/issues/16577
fromDir("./dist", /\.js$/, addDotJsToLocalImports)

بناءً على https://github.com/microsoft/TypeScript/issues/16577#issuecomment -310426634

هل يمكن لأي شخص أن يتذكر ما كان يفعله قبل 3 سنوات عندما تم فتح هذه القضية؟

الحل غير المجمع هو كتابة مشاريع موزعة على الويب باستخدام .js كملحق.

هذا 100٪ يعمل. تكمن المشكلة الأكبر في محاولة كتابة وحدات تستهدف الويب و Node.js ، لكن هذه مشكلة لـ JS بشكل عام.

إذا كان هناك شيء يجب القيام به ، فسيتم إضافة --moduleResolution=web ، لكن هذا ليس نطاق هذه المشكلة هنا.

اضطررت إلى كتابة هذا البرنامج النصي بعد الإنشاء لإضافة الامتداد .js.

fix-ts-imports

#!/usr/bin/env sh

# Fixes JavaScript module imports generated by TypeScript without extension.
# Converts
# import {} from './module'
# into
# import {} from './module.js'
#
# EXAMPLE
# ./fix-ts-imports

ProjectDir="$(cd "$(dirname "$0")/.." && pwd)"

fix() {(
        local pkg="$1"
        shift

        find "$pkg" -type f -iname '*.js' -not -ipath '*/node_modules/*' -print0 \
        | while read -r -d '' file; do
                sed -i '' -E 's|(import .+ from ['\''"]\.?\./.+[^.][^j][^s])(['\''"])|\1.js\2|g' "$file"
        done
)}

if test $# -eq 0; then
        set -- "$ProjectDir"
fi

for pkg; do
        fix "$pkg"
done

لدي نص برمجي مشابه في JavaScript:
https://github.com/yoursunny/NDNts/blob/743644226fe18d48e599181e87ad571a2708a773/mk/build-post.js

تم استدعاؤه كـ:

tsc -b mk/tsconfig-solution.json -w --listEmittedFiles \
  | node mk/build-post.js

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

باستخدام الأدوات الحديثة و .js في المصدر ، كل شيء يعمل بشكل ممتاز في العقدة والمتصفحات

  • مطبوعة
  • وحدات وفاق
  • تراكمي

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

- ربما يقع اللوم على webpack ...

وهكذا - القط خارج الحقيبة.

باستخدام الأدوات الحديثة و .js في المصدر ، كل شيء يعمل بشكل ممتاز في العقدة والمتصفحات

_ معظم_ الأشياء تعمل بشكل ممتاز ، وأنا أوافق على أن جميع الملفات المصدر يجب أن تحتوي على ملحقات .js في صادراتها. في تجربتي ، الشيء الوحيد الذي لا يعمل بشكل جيد مع هذا هو ts-node ، بسبب رفضهم العنيد لدعم ملحقات .js . نعم ، يمكنك إضافة خطوة التحويل المسبق قبل تشغيل العقدة ، وستعمل الواردات .js ، ولكن إذا كنت تريد تشغيل كود .ts أو اختبارات مباشرة مع العقدة وأيضًا في المتصفح ، أنت حاليًا غير محظوظ في الغالب. (للتوضيح ، أعتقد أن هذا خطأ ts-node ، وليس خطأ TypeScript).

شكرا @ تشيس موسكال.

أعدت بناء الريبو وملف tsconfig ، والآن
import {something} from './something.js'
لا يرمي
typescript force overwrite error TS5055: Cannot write file because it would overwrite input file
بعد الآن ، ولست بحاجة إلى اختراق fix-ts-imports بعد الآن.

في أكثر من 250 تعليقًا ، كان هناك القليل جدًا من الوضوح. كي تختصر:

خلفية

وحدات المتصفح

تقوم المستعرضات بتحليل وحدات EcmaScript وفقًا لعنوان URL ، بما في ذلك عناوين URL النسبية. ( WHATWG )

وحدات Node.js

يحل Node.js الوحدات (كل من EcmaScript و CommonJS الخاصة بـ Node.js) عبر خوارزمية أكثر تعقيدًا تتضمن العديد من الإجراءات الاحتياطية وتحليل ملفات package.json. ( Node.js ) يمكن تخصيص ذلك ، على سبيل المثال باستخدام --experimental-specifier-resolution=explicit والذي يتطلب مسارًا كاملاً.

وحدات TypeScript النمطية

يحتوي TypeScript على العديد من خوارزميات دقة الوحدة المتاحة ومجموعة متنوعة من الخيارات لتخصيصها بشكل أكبر. ( TypeScript ) القصد هو أن يكتب المستخدمون نفس محددات الوحدة النمطية المستخدمة في الإخراج الناتج ، مع ضبط دقة tsc بخيارات مثل baseUrl و pathMappings.

في الممارسة العملية ، يستخدم معظم المستخدمين وحدة العقدة moduleResolution ، التي تستهدف بيئة Node.js أو الحزم المتوافق. يركز هذا الطلب على المستخدمين الذين يستهدفون المتصفحات بدون حزمة.

قرار وحدة ts- عقدة

على ما يبدو ، لا تدعم ts-node معرفات الوحدات النمطية ذات الامتدادات. على الرغم من عدم وضوح السبب ، نظرًا لأن كلا من Node.js و TypeScript يعملان ، و ts-node هو ظاهريًا اندماج هؤلاء.

حقائق

الحقيقة 1: يمكنك استخدام امتدادات .js

لتوافق أوسع (أي المتصفحات) ، يمكنك استخدام امتدادات .js اليوم. مع استثناء فردي لعقد ts-node (خطأ IMO) ، يعمل كل شيء الآن من خلال تحديد المسار الكامل (أي بما في ذلك الامتداد).

الحقيقة 2: الأمر ليس بهذه البساطة "إضافة ملحق"

يتم تلخيص هذا الطلب بشكل أفضل على أنه "تحويل معرف الوحدة النمطية إلى مسار الملف." على سبيل المثال ، يصبح $ ./example ./example/index.js و 'lodash' يصبح '.node_modules/lodash/index.js' .

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

declare module "lodash" {
}

ربما تقتصر إعادة كتابة الوحدة على وحدات TS في المشروع / التجميع الحالي.

على أي حال ، نحن الآن ننتهك أحد معامِلات تصميم TS ، وهي أن الوحدات الأخرى تؤثر على مخرجات المعامل الحالي.

خاتمة

من الممكن استخدام المسار لمعرفات الوحدة النمطية التي تعمل للويب. (على سبيل المثال ، ./foo/index.js بدلاً من ./foo .)

(على الرغم من أنه من الناحية العملية ، فمن المحتمل أن ترغب في الحصول على متصفحات مستهدفة على أي حال. أي إذا تم استخدام حزم npm.)

pauldraper هناك مشكلة مهمة في "الحقيقة 2":

يتم تلخيص هذا الطلب بشكل أفضل على أنه "تحويل معرف الوحدة النمطية إلى مسار الملف." على سبيل المثال ، يصبح /example ./example/index.js ويصبح "Lodash" "node_modules / Lodash / index.js".

أنت لا تريد حقًا حل المحددات خارج الحزمة الخاصة بك في وقت الترجمة ، لأن هذه قد لا تكون المسارات المتاحة عند تثبيت الحزمة في مكان آخر. تحتاج إلى تشغيل دقة وحدة العقدة في كل تثبيت حزمة فريدة. وإلا يمكننا كتابة ونشر import {} from './node_modules/lodash/index.js' والانتهاء من ذلك.

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

يتم تلخيص هذا الطلب بشكل أفضل على أنه "تحويل معرف الوحدة النمطية إلى مسار الملف." على سبيل المثال ، يصبح /example ./example/index.js ويصبح "Lodash" ".node_modules / Lodash / index.js".
لاحظ أنه في بعض الأحيان لا يوجد حتى مسار ملف تم حله ، كما هو الحال مع إعلانات الوحدة النمطية المحيطة.

هذا ليس ما يدور حوله هذا الطلب. يتعلق الأمر بإضافة امتداد عند إرسال رمز. نريد كتابة وحدات متوافقة مع النوع: "module" بدون خطوة بناء إضافية. ستستمر الوحدات الخارجية مثل لوداش في العمل حتى بدون .js لأنها من نوع CommonJs.

مثال:

// ./src/moduleA.ts
export const test = 2;
// ./src/moduleB.ts
import {test} from './moduleA'



md5-ec0300a1c6d92a03c70699d0e52c0072



```js
// ./lib/moduleB.js
import {test} from './moduleA.js'

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

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

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

ستستمر الوحدات الخارجية مثل لوداش في العمل حتى بدون .js لأنها من نوع CommonJs.

إلا إذا لم يكونوا كذلك.

عندما تنبعث.

قد يكون ./moduleA.js . أو قد يكون ./moduleA/index.js ، أليس كذلك؟ يسمح دقة وحدة Node.js بعدد من المسارات.

إلا إذا لم يكونوا كذلك.

هل يمكنك إعطاء مثال عندما لا تعمل هذه؟ حصل Node.js للتو على دعم لاستيراد تصدير مسمى من CommonJS.
https://nodejs.org/api/esm.html#esm_import_statements

قد يكون ./moduleA.js. أو قد يكون ./moduleA/index.js ، أليس كذلك؟ يسمح دقة وحدة Node.js بعدد من المسارات.

ليس في وضع ESM. لن يتم دعم index.js كما هو الآن. ستقرأ أداة تحميل ESM "الصادرات" و "النوع" للبيانات الوصفية لـ package.json.
https://nodejs.org/api/esm.html#esm_mandatory_file_extensions

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

تمت إزالة تحرير ارتباط العقدة PR لأنه كان مضللاً.

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