Rollup-plugin-typescript2: تم إنشاء ملف الكتابة في مجلد خاطئ داخل الكائن كتجميع `إدخال`

تم إنشاؤها على ٥ فبراير ٢٠١٩  ·  33تعليقات  ·  مصدر: ezolenko/rollup-plugin-typescript2

ماذا يحدث ولماذا هو خطأ

من المحتمل أن يكون هذا خطأ في التكوين من جهتي ، لكنه يبدو وكأنه خطأ. عند استخدام object كخاصية input لتكوين المجموعة ، يتم إنشاء ملف الكتابة لملفات الإدخال في المجلد الجذر لملف الريبو (نفس المجلد مثل ملف التكوين التراكمي) و ليس دليل الإخراج الهدف (هنا ، ./dist ) مع ملف JS المجمع.

إصدارات

  • مطبوعة: 3.2.4
  • تراكم: 1.1.2
  • rollup-plugin-typescript2: 0.19.2

rollup.config.js

{
    ...
    input: {
        Lib1: './src/Lib1.tsx',
        Lib2: './src/Lib2.tsx'
    },
    output: {
        dir: './dist',
        format: 'cjs',
        sourcemap: true,
        entryFileNames: '[name].js'
    }
}

tsconfig.json

{
  ...
  "compilerOptions": {
    "outDir": "./dist"
  },
}

نتيجة:

// These files are created
./Lib1.d.ts
./Lib2.d.ts

// instead of (expected):
./dist/Lib1.d.ts
./dist/Lib2.d.ts

من الغريب أنك إذا قمت بإدخال entryFileNames: 'dist/[name].js' فإنه يقوم بإنشاء مجلد فرعي غير ضروري يسمى dist داخل المجلد dist ويقوم بإنشائها هناك.

bug more info needed

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

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

  1. "تحقق من النوع وتحويل كل هذه الوحدات الفردية إلى JavaScript" واسمحوا لي (أي Rollup) بالقيام بعملية التجميع والكتابة على القرص.
  2. "قم بعمل كافة التصريحات الخاصة بمجلد مشروع TS هذا وقم بتفريغها هناك."

نتائج 1 و 2 لا ، ولا يمكن أن تتطابق عند استخدام "خريطة الإدخال" وتقسيم الشفرة ، وما إلى ذلك - AFAICT.

... ما لم تجعل المكون الإضافي التراكمي أكثر انخراطًا في عملية إنشاء إعلان النوع.

ال 33 كومينتر

يعد خيار المكون الإضافي useTsconfigDeclarationDir حلاً مؤقتًا في الوقت الحالي.

قد يتم إصلاح ذلك بواسطة # 142 ، الذي تم إصداره في 0.20.0

مرحبًا ezolenkom و @ jakearchibald ، لا حظ في أي منهما في الواقع.

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

benkeen عند استخدام خيار المكون الإضافي useTsconfigDeclarationDir: true تحتاج أيضًا إلى الحصول على declarationDir في tsconfig.json

لدي مشكلة مماثلة ، تخطيط مشروعي مثل هذا:

export default [ 
  {
    input: 'src/subFolder1/one.ts,
    output: [
                    {
                      file: 'dist/one.js'
                      .....                      
                     }
    ],
    plugins: [
           typescript({
                typescript: require('typescript'),
            }),
    ]
  },
      input: 'src/subFolder2/two.ts,
      output: [
                    {
                      file: 'dist/two.js'
                      .....                      
                     }
    ],
     ...
  },
]

كمخرج لدي:

  |---subFolder1
  |          |--------one.d.ts
  |
  |---subFolder2
  |          |---------two.d.ts
  |-----one.js
  |-----two.js

يعمل بالنسبة لي على 0.20.1 مع ملفات useTsconfigDeclarationDir: false - d.ts تذهب إلى المجلدات المحددة في output.[].dir . benkeen هل يمكنك المحاولة مرة أخرى؟

AntonPilyak هذا حسب التصميم - إذا كانت d.ts تنتقل إلى مجلد واحد بدون مسارات فرعية ، فعندئذٍ إذا كان لديك subFolder1/one.ts و subFolder2/one.ts ، فسيتم استبدال أحدهما بآخر.

ezolenko : أعتقد أن هذه الميزة تخلق المزيد من الإزعاج بدلاً من حل مشكلة حقيقية (نظرًا

AntonPilyak ، قد تتمكن من استخدام الخيار useTsconfigDeclarationDir: true ، إعداد declarationDir في tsconfig ، يجب أن يسمح هذا للطباعة نفسها بمعالجة مسارات إخراج الكتابة.

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

عادةً إذا كنت تريد كتابات جميلة ، فستحتاج إلى دمجها في ملف واحد على أي حال (كانت هناك وحدة npm وأظل أنسى اسمها)

أنا أستخدم الإصدار 0.22.0 ولدي نفس المشكلة تمامًا مثل AntonPilyak

{
    ...
    input: {
        foo: 'src/lorem/foo.ts',
        bar: 'src/ipsum/bar.ts'
    },
    output: {
        dir: 'dist',
        format: 'cjs',
        sourcemap: true,
    }
}

وأنا أخرج هذا:

dist/
    lorem/
        foo.d.ts
    ipsum/
        bar.d.ts
    foo.js
    foo.js.map
    bar.js
    bar.js.map

من الواضح أنني أرغب في وضع ملفات *.d.ts بجانب ملفات *.js و *.js.map .

لقد حاولت العبث بـ useTsconfigDeclarationDir و declarationDir دون جدوى.

تنتهي ملفات التعريف دائمًا داخل مجلدات فرعية lorem و ipsum على التوالي ، وليس في قائمة ثابتة أبدًا.

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

dist/
    lorem/
        foo.d.ts
    ipsum/
        utils/
            bar-helper.d.ts
        bar.d.ts
     some_other_ts_file/
         not_imported_by/
             neither_foo_nor_bar/
                  wat.d.ts
    foo.js
    foo.js.map
    bar.js
    bar.js.map

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

هذا كله مربك بعض الشيء.

...

أعني ، إنه عادل بما يكفي إذا احتاج إلى إنشاء ملف إقرار utils/bar-helper.ts ولكن يجب ترك ما لا يقل عن wat.ts من كل شيء.

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

بالنسبة لمسار التعريفات ، أين تريد تعريف 'src/ipsum/foo.ts' في المثال الخاص بك؟

نظرًا لأنه تعريف لـ dist/foo.js فقد افترضت أنه سينتهي به الأمر بجواره - تمامًا مثل ملف الخريطة المصدر - أي في dist/foo.d.ts .

هل ستعرف TypeScript بإقران dist/foo.js و dist/lorem/foo.d.ts ؟

السيناريو الكامل الذي ينهار فيه هذا هو:
src / dir1 / foo.ts
src / dir2 / foo.ts

قام dir1 / foo.ts بتعييننا كمدخل تراكمي واستورد dir2 / foo.ts. ستنشئ Rollup حزمة dist / foo.js التي ستحتوي على الأجزاء ذات الصلة من كلا الملفين المصدرين ، ولكن يجب إنشاء ملفي تعريف نوعين يحملان الاسم نفسه في مكان ما.

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

ونعم ، ستعرف الكتابة المطبوعة مكان العثور على تعريفات النوع. لذا بصرف النظر عن كونها فوضوية بعض الشيء ، لا ينبغي أن تكون هذه مشكلة. إذا كنت ترغب في نشر الحزمة مع الأنواع على npm ، فقم بتعيين "types" في package.json إلى ملف d.ts لنقطة الدخول الخاصة بك. سيجد المطبوع أشياء من هناك.

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

ومع ذلك ، إذا كنت أقوم فقط بعرض / نشر وحدتين من الوحدات ، فلماذا أريد من TypeScript إنشاء ملفات *.d.ts لكل ملف ts واحد يواجهه؟ ألا توجد طريقة لحصرها على نقاط الدخول فقط؟

الشيء هو أنني أقوم بتصدير مجموعة من الوحدات المستقلة ( import tool1 from 'myTools/tool1'; إلخ ..) لذلك لا توجد نقطة دخول واحدة لاستخدامها في pkg.types . يجب أن يوجد كل ملف تعريف بجوار نظيره *.js لـ VSCode لاستلامه.

والأسوأ من ذلك ، إذا كان لدي

{
    ...
    input: {
        fooscript: 'src/foo/index.ts',
        barscript: 'src/bar/index.ts'
    },
    output: {
        dir: 'dist',
        format: 'cjs',
        sourcemap: true,
    }
}

انا حصلت:

dist/
    foo/
        index.d.ts
    bar/
        index.d.ts
    fooscript.js
    fooscript.js.map
    barscript.js
    barscript.js.map

والآن لا توجد طريقة لإقران TypeScript بين dist/fooscript.js و dist/foo/index.d.ts .

...

ألا توجد طريقة تمكن المكون الإضافي الخاص بك من تغذية TypeScript بمسار الوجهة / الإخراج لكل ملف حزمة JavaScript؟ يبدو أن tsc يتلقى اسم ملف الإدخال الأصلي ويتمسك به بشدة عند إنشاء الإعلانات.
... أو لكل ملف من ملفات الإدخال ، ابحث عن الملف المقابل *.d.ts وانقله + أعد تسميته إلى وجهة تعيين ملف الإدخال. (قد تلاحظ أنني أتحدث من مؤخرتي هنا ، لذلك ... ؛-)

هذا شيء لا بد لي من تجربته يدويًا بعد انتهاء Rollup - ولكن سيكون من الأجمل كثيرًا أن يتعامل البرنامج المساعد معه تلقائيًا.

لا ، يستخدم البرنامج المساعد LanguageServices (تستخدم نفس IDEs API المطبوع عادة) ، لذلك لدي بعض التحكم في ما أكتبه وأين.

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

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

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

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

كيف تستهلك هذه العبوة بعد إنشائها؟ إنه ليس شيئًا يمكنك نشره على npm واستيراده حسب اسم الحزمة ...

أنا أقوم بإعداد مجموعة من المرافق المستقلة. يحتوي المجلد الجذر للحزمة المنشورة / المثبتة على جميع ملفات الوحدة النمطية المضمنة في قائمة ثابتة.

(أنا أكتبها في TS / ES6 في بنية مجلد متداخلة ، مع خلط ملفات الاختبار ، والاعتماد على Rollup لتحويلها إلى قائمة ثابتة من ملفات CJS مع مزيج فعال من تقسيم الكود والتضمين لأي رمز مشترك.)

ثم أستهلك هذه الأدوات عن طريق استيرادها حسب اسم الملف - مثل:

import tool1 from 'myTools/tool1';
import tool2 from 'myTools/tool2';

الفكرة هي أنه من خلال عدم وجود نقطة دخول واحدة لمجموعة الأدوات بأكملها (بدون إدخال pkg.main أو pkg.module إدخالات) ، يمكنني أن أكون خاليًا من العناية لإضافة أدوات نادر الاستخدام ، وحتى تجريبية دون إضافة وزن / سخام للمستهلكين في المراحل النهائية (والتي قد لا يكون لها اهتزاز فعال للأشجار).

... لقد كنت ألعب مع tsc على سطر الأوامر قليلاً الآن ، وأعتقد أنني أرى الآن القيود التي تتعامل معها.

ومع ذلك ، لاحظت أنه إذا قمت بتشغيل tsc وقمت بتعيين تنسيق الوحدة / الإخراج إما على "amd" أو "system" ، فإنه ينشئ ملفًا واحدًا *.d.ts مع قائمة مرتبة من الكل كتل declare module "..." الضرورية مضمّنة.

أتساءل عما إذا كان يمكن استغلال هذا السلوك بطريقة أو بأخرى - من خلال إعادة تسمية / نقل الملف وإلغاء تغليف / إعادة كتابة إعلان الوحدة النمطية الأخيرة (الرئيسية)؟


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

أهلا مرة أخرى.
في الوقت الحالي ، أقوم بإعداد declarationDir مخصص لـ tsc لتفريغ كل *.d.ts في ، ثم تشغيل برنامج نصي مستقل يستورد نفس ملف الإدخال إلى- كائن ملف الإخراج أثناء تغذيتي به إلى Rollup ، ويقوم بإنشاء ملفات إقرار على مستوى الحزمة-الوجهة التي هي ببساطة export * from ملف الإقرار الفعلي.

بشكل أساسي ، أقوم بإنشاء dist/fooscript.d.ts والذي يحتوي فقط على:

export *  from './__types/foo/index';

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

أتساءل عما إذا كان بإمكان rollup-plugin-typescript2 فعل شيء مشابه؟

هذا من شأنه أن يعمل ، نعم.

لدي عدة أفكار (عندما أتطرق إليها) ، على سبيل المثال إنشاء <bundlename>.d.ts الذي يحتوي على مجموعة من /// <reference types=""/> لكل d.ts المعنية.

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

بعض الأفكار:

IMO ، الجزء الوحيد القبيح حقًا من الاختراق الخاص بي هو حقيقة أنه يقف بعيدًا عن عملية التجميع. الوسيط *.d.ts هو في الواقع طريقة أنيقة وعبارات للربط بين الحزم التي تم إنشاؤها من Rollup وتعريفات tsc .

نظرًا لأن ملفات التعريف التي تم إنشاؤها tsc تشير إلى بعضها البعض عبر المسارات النسبية ، فمن الأفضل ترك بنية الملف / المجلد بمفردها - لئلا ينتهي بك الأمر إلى إعادة تنفيذ أجزاء من وظيفة Rollup ، لبناء جملة لغة مخصصة.

وإذا عيّن rollup-plugin-typescript2 شيئًا مثل output.dir + '__types' كقيمة افتراضية declarationDir ، فإن أي فوضى ناتجة عن الحماس المفرط لـ tsc يتم التخلص منه بدقة. مشهد داخل مجلد واضح اسمه. بهذه الطريقة تصبح ملفات التعريف الدخيلة مصدر قلق ضئيل للغاية IMO.


FWIW ، هذا هو جوهر نصي:

const { makeInputMap, getEntrypoints, distFolder, srcFolder } = require('./buildHelpers');
const { writeFileSync } = require('fs');
const { relative } = require('path');

const srcPrefixRe = new RegExp('^' + srcFolder + '/');
const tsExtRe = /\.tsx?$/;

const declDirRelative = './' + relative(
  distFolder,
  require('../tsconfig.json').compilerOptions.declarationDir
);

const tsEntrypoints = getEntrypoints()
  .filter((fileName) => tsExtRe.test(fileName));

Object.entries(makeInputMap(tsEntrypoints))
  .forEach(([moduleName, sourcePath]) => {
    const tscDeclFile = sourcePath
      .replace(srcPrefixRe, declDirRelative + '/')
      .replace(tsExtRe, '');
    const outFile = distFolder + '/' + moduleName + '.d.ts';
    writeFileSync(
      outFile,
      [
        'export * from "' + tscDeclFile + '";',
        'import x from "' + tscDeclFile + '";',
        'export default x;',
        '',
      ].join('\n')
    );
  });

console.info('Created local declaration files for TypeScripted entrypoints.');

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

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

مرحبًا ، هل يجب حل هذه المشكلة في الإصدار 0.23.0؟

(... أتساءل عما إذا كان ينبغي أن أحاول تحديث مشروعي لإسقاط كل التخصيص المخصص)

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

البرنامج النصي المخصص للحل البديل الخاص بي (انظر أعلاه) يزحف تدريجياً إلى المزيد والمزيد من مشاريعي. o_O

لمعلوماتك: تم استئناف تطوير الحزمة الرسمية @ rollup / plugin-typecript منذ ذلك الحين ، وهي تتميز الآن بفحص النوع وإخراج ملفات التصريح ، لذلك أنا شخصياً أقوم بالتبديل لاستخدام ذلك.
القيود هي نفسها إلى حد كبير ، مع ذلك.

maranomynet هل ما زلت تعتمد على البرنامج النصي الخاص بك لنقل ملفات التصريح بعد أن يقوم التراكمي

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

  1. "تحقق من النوع وتحويل كل هذه الوحدات الفردية إلى JavaScript" واسمحوا لي (أي Rollup) بالقيام بعملية التجميع والكتابة على القرص.
  2. "قم بعمل كافة التصريحات الخاصة بمجلد مشروع TS هذا وقم بتفريغها هناك."

نتائج 1 و 2 لا ، ولا يمكن أن تتطابق عند استخدام "خريطة الإدخال" وتقسيم الشفرة ، وما إلى ذلك - AFAICT.

... ما لم تجعل المكون الإضافي التراكمي أكثر انخراطًا في عملية إنشاء إعلان النوع.

آه نعم ، هذا نوع ما كنت أحسبه ، شكرًا! أعطيتك 👍 لإجابتك المفيدة ، و هي ما أشعر به حيال ذلك.

أي حظ مع هذا؟

لأي روح تكافح بها نفس بنية مجلد src مثل maranomynet وأنا.

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

أنا أستخدم البرنامج المساعد التراكمي / typecript2 لذلك سأذهب مع التكوين الخاص به في هذه الإجابة:
حدد التصريح الخاص بك في ملف tsconfig.json الخاص بك حتى يتمكن مشروعك من تفريغ جميع ملفات * .d.ts في مساره الخاص في التوزيع المجمع. وتأكد من ضبط useTsConfigDeclusionDir على true في المكون الإضافي للنسخ المطبوعة في ملف التكوين التراكمي.
أيضًا ، عند تحديد مسارات الإخراج لحزم المكونات الفردية الخاصة بك في rollup.config.js (و package.json) ، قم بتغيير هذه المسارات لتكون مماثلة لـ "دليل التعريف" + "كيف يكون مسار مكون src الخاص بك". لذلك إذا كان المكون الخاص بك في src مثل:

src / homepage / foo.tsx

وإعلانك هو:

Dist / MyDeclusionDir

لذلك يجب أن يكون مسار الإخراج الخاص بك مثل:

dist / MyDeclusionDir / homepage / foo.js

بهذه الطريقة ، ستشمل المجموعة التراكمية الأنواع الخاصة بك في نفس الدليل مثل main.js المكون الخاص بك وسيقوم مشروع المستهلك TS الخاص بك بالتقاط الكتابة.

لذلك ستبدو الحزمة مثل:

توزيع /

    declarationDirPath/
                  component1/
                        foo.js/
                              foo.js
                              foo.map.js
                        foo.d.ts
                   component2/
                        bar.js/
                               bar.js
                               bar.map.js
                        bar.d.ts
هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات