Sentry-javascript: @ الحارس / حجم المتصفح

تم إنشاؤها على ٢٠ سبتمبر ٢٠١٨  ·  69تعليقات  ·  مصدر: getsentry/sentry-javascript

الحزمة + الإصدار

  • [x] @sentry/browser
  • [] @sentry/node
  • [] raven-js
  • [] raven-node _ (غراب للعقدة) _
  • [ ] آخر:

الإصدار:

4.0.2

وصف

حجم @ sentry / المتصفح أكبر بمرتين من حجم raven-js: 86 كيلوبايت مقابل 39 كيلوبايت (مصغر). في رأيي ، هذا بالتأكيد تراجع وسبب جدي لعدم التحديث إلى الإصدار الجديد.

Discussion Improvement

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

أعتقد أنه من العدل مقارنة أحجام حزمة gzip أولاً بدلاً من حجم الملف المصغر غير المضغوط:

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

لست متأكدًا من المكان الذي أخذت منه رقم < 1KB للنص CDN'ed. هل يمكن أن تتطور؟ عندما أفتح https://browser.sentry-cdn.com/4.0.4/bundle.min.js أرى حجمًا مضغوطًا بتنسيق gzip يبلغ 22 كيلوبايت.

يجب أن تدرك أن sdk sdk هو مجرد واحد من العديد من مكتبات مطوري البرامج.

ملاحظة: أنا أحب الحارس ، لقد كان مفيدًا للغاية بالنسبة لنا. أنا متحمس لأداء الويب. ؛)

ال 69 كومينتر

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

@sentry/browser هو 21.3799 كيلوبايت
raven-js 13.44 كيلوبايت

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

انظر: https://docs.sentry.io/quickstart/؟

البصمة والتأثير على وقت تحميل الصفحة لهذا البرنامج النصي <1KB gzipped مع الحفاظ على نفس الوظيفة.

لذلك TL ؛ د:
نحن على علم بذلك ، ونعلم أن هناك مجالًا للتحسين ولكنه ليس أولوية قصوى في الوقت الحالي.

أعتقد أنه من العدل مقارنة أحجام حزمة gzip أولاً بدلاً من حجم الملف المصغر غير المضغوط:

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

لست متأكدًا من المكان الذي أخذت منه رقم < 1KB للنص CDN'ed. هل يمكن أن تتطور؟ عندما أفتح https://browser.sentry-cdn.com/4.0.4/bundle.min.js أرى حجمًا مضغوطًا بتنسيق gzip يبلغ 22 كيلوبايت.

يجب أن تدرك أن sdk sdk هو مجرد واحد من العديد من مكتبات مطوري البرامج.

ملاحظة: أنا أحب الحارس ، لقد كان مفيدًا للغاية بالنسبة لنا. أنا متحمس لأداء الويب. ؛)

تضمين التغريدة
هههه ، لا تقلق 😅

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

عذرًا ، الرابط الذي نشرته من قبل قديم بالفعل 🙃
كنت أشير إلى _Loader_: https://docs.sentry.io/platforms/javascript/loader/
بينما يحتوي _Loader_ أيضًا على قيود بسبب طبيعته غير المتزامنة وفي النهاية ، فإنه لا يزال يجلب SDK ويحقنه (حتى لو كان غير متزامن) إنه بديل نقدمه لأن الأشخاص طلبوه.

HazAT آسف يا رفاق ، لكن هل يمكنك تقديم تاريخ إصدار الإصدار التالي؟
أعني ، هناك بعض التغييرات بالفعل في فرع #master ولكن لم يتم إصدارها بعد. هذا الشخص الذي يقرر أن الإصدار 4x قابل للاستخدام في مشاريع Angular5 + بالرغم من ذلك.

rayzru أصدر للتو 4.0.5 ، لكن يرجى الاحتفاظ بالمشاركات المتعلقة بالموضوع.

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

💯 كنت على وشك الترقية إلى أن لاحظت ما يلي:

capture d ecran 2018-10-03 a 15 07 27

حجم الحزمة أصغر على الأقل ، لكنني أعتقد أن ⚠️ +10 كيلوبايت من JavaScript مضغوط في حزمة أمر مهم. سننتظر ، استمروا في العمل الجيد :)

HazAT هل يمكن إنشاء ملفات esm. سيسمح لـ webpack بالحصول على نتيجة أفضل مع التسلسل واهتزاز الشجرة.

قد ترغب في إضافة بعض أدوات CI لتتبع حجم حزمة الحزمة لكل طلب دمج. منذ أن نمت هذه المشكلة بالفعل إلى 100 كيلو بايت ، راجع https://bundlephobia.com/result؟p=@sentry/browser @ 4.3.0

جرب على سبيل المثال https://github.com/siddharthkp/bundlesize

ميزانية الأداء الافتراضية لنقطة دخول في Webpack هي 250 كيلو بايت للتأكد من حصولك على أداء لائق على أي جهاز وشبكة. يستهلك 100 كيلو بايت من Sentry قدرًا كبيرًا جدًا من تلك الميزانية.

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

نحن ندفع للعملاء واستثمرنا بشكل كبير في Sentry على كل من الواجهة الخلفية والأصلية والويب ، ولكن الترقية إلى أكثر من 3 أضعاف حجم المكتبة ([email protected] هو 31 كيلو بايت) ليس شيئًا يمكننا تبريره.

jacobrask يمكنك التمسك بالإصدار الأقدم من المكتبة ، وهذا ما نفعله على https://www.onepixel.com/ ، إنه يعمل بشكل جيد 👌.
dont-confuse-motion-with-progress

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

HazAT
يمكن تحسين حزمة مجموعة SDK لمتصفح Sentry. في ملف الحزمة min js ، هناك العديد من كود tslib تكرار. مثل __ Generator، __assign. في بيئة المتصفح ، من الأفضل مشاركة رمز واحد. بعد ذلك ، يستخدم مشروع المتصفح ملف حزم أخرى. ربما يتم تقليل حجم gzip من 23 كيلو إلى 16 كيلو بايت.

حجم الحزمة هو نفسه في 4.3.2
https://bundlephobia.com/result؟p=@sentry/browser @ 4.3.2 بغض النظر عن التغييرات من
https://github.com/getsentry/sentry-javascript/pull/1738 :(

vkrol كان علينا إعادة التغييرات التي أجراهاgaterking ، على الأقل لحزمة npm.
من ناحية أخرى ، يجب أن تكون الحزمة على CDN أصغر.

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

HazAT حسنًا ، شكرًا.

vkrol كان علينا إعادة التغييرات التي أجراهاgaterking ، على الأقل لحزمة npm.
من ناحية أخرى ، يجب أن تكون الحزمة على CDN أصغر.

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

نأمل في أقرب وقت ممكن.

gaterkingkamilogorek تم إصلاحه بالفعل https://github.com/getsentry/sentry-javascript/pull/1751
كان علينا فقط إجراء إصدار "عاجل" لهذا السبب قمنا بإعادته.

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

ما الذي تفعله هذه المكتبة أيضًا وهذا معقد جدًا؟

من الصعب حقًا فهم سبب احتياج مراسل الأخطاء الأبسط إلى مثل هذه البصمة الكبيرة 😐

@ mindplay-dk يرجع ذلك غالبًا إلى أن JavaScript والمتصفحات في حالة من الفوضى ^ ^
نحن بحاجة إلى القيام بالكثير من إصلاح آثار المكدس المكسورة / الخاطئة.
إن المهمة البسيطة المتمثلة في "اكتشاف الأخطاء فقط" هي أيضًا أكثر تعقيدًا مما تبدو عليه.

من الصعب حقًا فهم سبب احتياج مراسل الأخطاء الأبسط إلى مثل هذه البصمة الكبيرة 😐

@ mindplay-dk لأنها ليست بسيطة.

إليك رمز التقاط الأخطاء في جميع المتصفحات وتوحيدها في بنية بيانات قابلة للاستخدام: https://github.com/getsentry/sentry-javascript/blob/master/packages/browser/src/tracekit.ts

أحسنت في تخفيض الحجم الأخير ، موضع تقدير كبير. 👍

تظهر نظرة سريعة على الملف المرتبط رمزًا للتعامل مع أخطاء Opera 10 ، فهل هذا لا يزال مطلوبًا حقًا؟ لا تأخذ TraceKit أيضًا في الحسبان زيادة الحجم (حاليًا) بمقدار 2x من Raven ، والتي كانت كبيرة بالفعل.

بعض الاقتراحات:

هل هناك بعض الرموز المشتركة ( app:///${base} في Rewriteframes.ts) في حزم أخرى مثل الحزمة / الأساسية؟ لا يتم استخدامها من قبل العميل ، ولكن يتم استخدامها بواسطة العقدة.

لأنها ليست بسيطة.

kamilogorek yikes ، من الواضح أنك على حق ... أدركت أن JavaScript كان في حالة من الفوضى - أعتقد أنني لم أتعمق في هذا المجال من قبل ، لم أدرك مدى سوء ذلك. أعتقد أنه لا توجد حقًا طريقة بسيطة للتعامل مع تتبع المكدس في JS. فقط. ييكيس. 😐

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

قلل من استخدام غير المتزامن / انتظار ، فهو يجمع بشكل سيء إلى ES5. قارن https://github.com/getsentry/sentry-javascript/blob/master/packages/core/src/baseclient.ts#L307 -L378 بكود الإخراج (ابحث عن "processEvent" في حزمة الإنتاج). يصبح هذا الملف بأكمله ضخمًا في حزمة الإنتاج.

هذه هي الطريقة الخاطئة ، فبدلاً من التحسين الإضافي لـ ES5 ، من الأهمية بمكان التحسين لـ 80.07% الذين يستخدمون متصفحات حديثة.

لكل من يحتاج إلى دعم المتصفحات القديمة:
يتم دعم الوظائف غير المتزامنة بواسطة أي متصفح يدعم <script type="module"> (caniuse: esm ، async ) لذلك يحتاج مستخدمو المتصفحات القديمة فقط إلى الانتظار لفترة أطول (يستغرق الأمر وقتًا أطول بالنسبة لهم على أي حال)

دليل:
160 كيلوبايت (es5 ، مجمعة)> 119 كيلوبايت (esm ، ملفات عادية)

لذا يرجى تجميع ملف esm (أيضًا) ، فهو سهل مثل تغيير الإعداد module و target في /tsconfig.esm.json (الذي يمتد tsconfig.build.json ) إلى esnext ، إضافة ملفات tsconfig.esm.json مشابهة لملفات tsconfig.build.json إلى الحزم ، قم بإضافتها إلى البنية والحزمة وحدد إدخال الوحدة النمطية في package.json

إذا كنت تريد ، يمكنني إضافة علاقات عامة لذلك.

إذا كنت تريد ، يمكنني إضافة علاقات عامة لذلك.

أحب أن cromefire :)

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

أو حتى أفضل إذا كان يمكن أن يعمل مثل webpack env ، بحيث يمكن للمستخدم تحديد دعم المتصفح المطلوب. Ofc ، هذه ليست ميزة سهلة ، ولكن أردت فقط التخلص منها :)

منتج رائع!

باستخدام هذا الإصدار الجديد ، يمكنك تكوين babel ولكنك تريد دعم المتصفحات التي تحتاجها فقط

حجم @ sentry / المتصفح أكبر بمرتين من حجم raven-js: 86 كيلوبايت مقابل 39 كيلوبايت (مصغر).

لمعلوماتك: تم زيادة حجم أحدث إصدار من @sentry/browser إلى 91.8 كيلوبايت . المصدر: https://bundlephobia.com/result؟p=@sentry/browser @ 4.5.0.

cromefire نشكرك على عملك في تحسين حجم المكتبة!

لقد حاولت للتو استخدام بنية esm الجديدة من الإصدار v4.5.0 ولكن حصلت على الكثير من الأخطاء. تم تشغيل كل منهم لأنه تعذر حل الوحدات النمطية من @sentry/utils/esm .

في الحقيقة لم أجد المجلدات في node_modules بعد yarn install جديد. (انظر لقطة الشاشة)

قائمة الأخطاء الكاملة

خطأ في ./node_modules/@sentry/core/esm/baseclient.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / async" في "./node_modules/@sentry/core/esm"
خطأ في ./node_modules/@sentry/browser/esm/backend.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / هو" في "./node_modules/@sentry/browser/esm '
خطأ في ./node_modules/@sentry/browser/esm/tracekit.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / هو" في "./node_modules/@sentry/browser/esm '
خطأ في ./node_modules/@sentry/browser/esm/integrations/breadcrumbs.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / هو" في "./node_modules/@sentry/browser/esm/integrations '
خطأ في ./node_modules/@sentry/browser/esm/integrations/helpers.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / هو" في "./node_modules/@sentry/browser/esm/integrations '
خطأ في ./node_modules/@sentry/browser/esm/integrations/pluggable/vue.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / هو" في "./node_modules/@sentry/browser/esm/integrations/pluggable '
خطأ في ./node_modules/@sentry/core/esm/baseclient.js
لم يتم العثور على الوحدة النمطية: خطأ: لا يمكن حل "@ sentry / utils / esm / هو" في "./node_modules/@sentry/core/esm"
خطأ في ./node_modules/@sentry/core/esm/dsn.js
لم يتم العثور على الوحدة النمطية: خطأ: لا يمكن حل "@ sentry / utils / esm / هو" في "./node_modules/@sentry/core/esm"
خطأ في ./node_modules/@sentry/core/esm/integrations/inboundfilters.js
لم يتم العثور على الوحدة النمطية: خطأ: لا يمكن حل "@ sentry / utils / esm / هو" في "./node_modules/@sentry/core/esm/integrations '
خطأ في ./node_modules/@sentry/core/esm/integrations/extraerrordata.js
لم يتم العثور على الوحدة النمطية: خطأ: لا يمكن حل "@ sentry / utils / esm / هو" في "./node_modules/@sentry/core/esm/integrations '
خطأ في ./node_modules/@sentry/browser/esm/integrations/globalhandlers.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / logger" في "./node_modules/@sentry/browser/esm/integrations"
خطأ في ./node_modules/@sentry/browser/esm/integrations/breadcrumbs.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / logger" في "./node_modules/@sentry/browser/esm/integrations"
خطأ في ./node_modules/@sentry/core/esm/baseclient.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / logger" في "./node_modules/@sentry/core/esm"
خطأ في ./node_modules/@sentry/core/esm/basebackend.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / logger" في "./node_modules/@sentry/core/esm"
خطأ في ./node_modules/@sentry/core/esm/sdk.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / logger" في "./node_modules/@sentry/core/esm"
خطأ في ./node_modules/@sentry/core/esm/integration.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / logger" في "./node_modules/@sentry/core/esm"
خطأ في ./node_modules/@sentry/core/esm/integrations/dedupe.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / logger" في "./node_modules/@sentry/core/esm/integrations"
خطأ في ./node_modules/@sentry/core/esm/integrations/sdkinformation.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / logger" في "./node_modules/@sentry/core/esm/integrations"
خطأ في ./node_modules/@sentry/core/esm/integrations/inboundfilters.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / logger" في "./node_modules/@sentry/core/esm/integrations"
خطأ في ./node_modules/@sentry/hub/esm/hub.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / logger" في "./node_modules/@sentry/hub/esm"
خطأ في ./node_modules/@sentry/browser/esm/client.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / misc" في "./node_modules/@sentry/browser/esm"
خطأ في ./node_modules/@sentry/browser/esm/tracekit.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / misc" في "./node_modules/@sentry/browser/esm"
خطأ في ./node_modules/@sentry/browser/esm/integrations/useragent.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / misc" في "./node_modules/@sentry/browser/esm/integrations"
خطأ في ./node_modules/@sentry/browser/esm/integrations/breadcrumbs.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / misc" في "./node_modules/@sentry/browser/esm/integrations"
خطأ في ./node_modules/@sentry/browser/esm/integrations/trycatch.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / misc" في "./node_modules/@sentry/browser/esm/integrations"
خطأ في ./node_modules/@sentry/browser/esm/integrations/helpers.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / misc" في "./node_modules/@sentry/browser/esm/integrations"
خطأ في ./node_modules/@sentry/browser/esm/integrations/pluggable/reportingobserver.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / misc" في "./node_modules/@sentry/browser/esm/integrations/pluggable"
خطأ في ./node_modules/@sentry/browser/esm/integrations/pluggable/vue.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / misc" في "./node_modules/@sentry/browser/esm/integrations/pluggable"
خطأ في ./node_modules/@sentry/browser/esm/integrations/pluggable/ember.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / misc" في "./node_modules/@sentry/browser/esm/integrations/pluggable"
خطأ في ./node_modules/@sentry/browser/esm/transports/beacon.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / misc" في "./node_modules/@sentry/browser/esm/transports"
خطأ في ./node_modules/@sentry/browser/esm/transports/fetch.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / misc" في "./node_modules/@sentry/browser/esm/transports"
خطأ في ./node_modules/@sentry/core/esm/baseclient.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / misc" في "./node_modules/@sentry/core/esm"
خطأ في ./node_modules/@sentry/core/esm/integrations/dedupe.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / misc" في "./node_modules/@sentry/core/esm/integrations"
خطأ في ./node_modules/@sentry/core/esm/integrations/inboundfilters.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / misc" في "./node_modules/@sentry/core/esm/integrations"
خطأ في ./node_modules/@sentry/hub/esm/scope.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / misc" في "./node_modules/@sentry/hub/esm"
خطأ في ./node_modules/@sentry/hub/esm/hub.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / misc" في "./node_modules/@sentry/hub/esm"
خطأ في ./node_modules/@sentry/browser/esm/parsers.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / object" في "./node_modules/@sentry/browser/esm"
خطأ في ./node_modules/@sentry/browser/esm/integrations/breadcrumbs.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / object" في "./node_modules/@sentry/browser/esm/integrations"
خطأ في ./node_modules/@sentry/browser/esm/integrations/trycatch.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / object" في "./node_modules/@sentry/browser/esm/integrations"
خطأ في ./node_modules/@sentry/browser/esm/integrations/helpers.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / object" في "./node_modules/@sentry/browser/esm/integrations"
خطأ في ./node_modules/@sentry/core/esm/api.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / object" في "./node_modules/@sentry/core/esm"
خطأ في ./node_modules/@sentry/core/esm/basebackend.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / object" في "./node_modules/@sentry/core/esm"
خطأ في ./node_modules/@sentry/core/esm/dsn.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / object" في "./node_modules/@sentry/core/esm"
خطأ في ./node_modules/@sentry/hub/esm/scope.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / object" في "./node_modules/@sentry/hub/esm"
خطأ في ./node_modules/@sentry/core/esm/integrations/pluggable/rewriteframes.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / path" في "./node_modules/@sentry/core/esm/integrations/pluggable"
خطأ في ./node_modules/@sentry/browser/esm/parsers.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / string" في "./node_modules/@sentry/browser/esm"
خطأ في ./node_modules/@sentry/browser/esm/integrations/breadcrumbs.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / string" في "./node_modules/@sentry/browser/esm/integrations"
خطأ في ./node_modules/@sentry/core/esm/baseclient.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / string" في "./node_modules/@sentry/core/esm"
خطأ في ./node_modules/@sentry/core/esm/integrations/inboundfilters.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / string" في "./node_modules/@sentry/core/esm/integrations"
خطأ في ./node_modules/@sentry/browser/esm/backend.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / support" في "./node_modules/@sentry/browser/esm"
خطأ في ./node_modules/@sentry/browser/esm/integrations/breadcrumbs.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / support" في "./node_modules/@sentry/browser/esm/integrations"
خطأ في ./node_modules/@sentry/browser/esm/integrations/pluggable/reportingobserver.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / support" في "./node_modules/@sentry/browser/esm/integrations/pluggable '
خطأ في ./node_modules/@sentry/browser/esm/transports/fetch.js
الوحدة غير موجودة: خطأ: لا يمكن حل "@ sentry / utils / esm / support" في "./node_modules/@sentry/browser/esm/transports"

screenshot 2019-01-10 at 4 37 45 pm

pascaliske esm build لا يزال في مرحلة التجريب ولم نقم بتوثيقه علنًا حتى الآن. سنفعل ذلك بمجرد اختبار كل شيء طوال الوقت وسننشر نتائجنا هنا.

kamilogorek نعم ، أعرف. أردت فقط إخبارك بهذه الأخطاء. 🙂

شكرا ، نقدر ذلك pascaliske! سنحاول تقديم دعم ESM في أقرب وقت ممكن :)

pascaliske جرب yarn build أولاً

cromefire لا هذا لن يساعد على ما أعتقد. لقد قمت للتو بتنزيل الحزمة من npm لذلك لا توجد بيئة بناء متاحة. 🙂

لقد بحثت قليلاً من خلال الكود المصدري وقارنت @sentry/browser بـ @sentry/utils . أعتقد أن هذه هي المشكلة: الحزم / utils / tsconfig.build.json # L5 مقابل الحزم / المتصفح / tsconfig.build.json # L5 . هل من الممكن أن يحل ناتج البناء العادي محل إخراج esm build؟ 🤔

داخل مجلد node_modules الخاص بي ، تحتوي الحزمة browser على إخراج بناء من كل من العادي و esm. لكن الحزمة utils تحتوي فقط على مخرجات بناء عادية في المجلد الجذر.

هل صدر بالفعل؟

لقد بحثت قليلاً في الكود المصدري وقارنت @ sentry / browser مع @ sentry / utils. أعتقد أن هذه هي المشكلة: الحزم / utils / tsconfig.build.json # L5 مقابل الحزم / المتصفح / tsconfig.build.json # L5. هل من الممكن أن يحل ناتج البناء العادي محل إخراج esm build؟ 🤔

لا ، عليك أن تنظر إلى esm tsconfig

سوف ننظر إليها غدا

مرحبا جميعا! نحن أيضًا ندرس بعض أحجام الحزم في Sentry ، ووجدنا هذا: https://github.com/getsentry/sentry-javascript/blob/master/packages/minimal/package.json#L20

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

كما أنه من غير الواضح بالنسبة لي سبب احتياج @sentry/types إلى تبعية _runtime_ ، وعدم تحديده في devDependencies ...

evocateur لجميع مستخدمي الكتابة المطبوعة هذا ضروري. المطبوع يحسن كل شيء.
(ولكن قد تكون مطلوبة لملفات .d.ts )

IanMitchell لا يتم استخدامه لبناء esm ، ولكن للأغراض العادية

يحتوي bundle.js 4.5.0 على الكثير من التعليمات البرمجية المكررة ، مثل Severity و htmlElementAsString و htmlElementAsString و uuid4 و parseUrl وما إلى ذلك. هذا لا يمكن أن يقصد!

يحدث نفس الشيء عندما أقوم بعمل حزمة عبر import * as Sentry from '@sentry/browser'; (كالسطر الوحيد في الملف) باستخدام WebPack + Babel 7 ، فإن الحجم المجمع هو 326 كيلوبايت. انظر: sentry.bundle.js.txt
نحن نستخدم نفس التكوين لحزمنا الأخرى أيضًا ، ولكن Sentry هو الحزمة الوحيدة التي تحتوي على هذه المشكلة.

لا يحتوي bundle.min.js على كود مكرر بالداخل ، والذي قد يكون نتيجة اهتزاز الشجرة مع التجميع.

لذلك ، الحل المؤقت هو استخدام import '@sentry/browser/build/bundle.min.js';

يحتوي bundle.js 4.5.0 على الكثير من التعليمات البرمجية المكررة ، مثل Severity و htmlElementAsString و htmlElementAsString و uuid4 و parseUrl وما إلى ذلك. هذا لا يمكن أن يقصد!

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

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

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

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

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

للمقارنة:

جئت عبر TrackJS ، الذي يتمتع بإمكانيات مماثلة (تتبع مكدس عبر المستعرضات مع خرائط المصدر) في حزمة ~ 10 كيلوبايت.

يبلغ حجم TraceKit الأصلي حوالي 3 كيلو بايت + gz.

لقد وجدت هذه المكتبة التي يمكنها عمل بت خريطة المصدر (من جانب العميل) في حوالي 8 كيلو بايت دقيقة + gz أو ~ 10 كيلو بايت مع polyfills x-browser.

علاوة على ذلك ، فإن الأمر يتعلق بجمع أجزاء قليلة من معلومات المتصفح ، ولفها بتنسيق JSON المتوقع ، ونشرها - والتي لا ينبغي أن تكون أكثر من بضعة كيلو بايت min + gz. ينبغي له؟

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

أعلم أنه من الشائع نشر ميغا بايت من JS هذه الأيام ، لكن لدينا سياسات محتوى صارمة في العمل ، لضمان شحن المشاريع التي يتم تحميلها بسرعة على الهواتف المحمولة ، ولا يمكنني تبرير إنفاق أكثر من نصف ميزانية JS الخاصة بنا على الخطأ- تسجيل الدخول - ربما يكون أعلى بنسبة 10٪ ، لذلك يبدو أن شيئًا مثل ~ 15-20 كيلوبايت يبدو معقولاً.

أنا أحب منتجك ، لكن لا يمكنني نشر هذا العميل 😐

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

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

cromefire فكرة مثيرة للاهتمام. أتساءل عما إذا كان هذا ما يفعله على سبيل المثال TrackJS للحفاظ على الحجم منخفضًا؟ (عميلهم مملوك - لا يتوفر سوى المصدر المصغر ، لذلك من الصعب تحديد ما يفعلونه. لنفترض أنه يمكنني تثبيته ومعرفة ما ينتقل عبر السلك ...)

إليك حزمة أبسط لحل خرائط المصدر في المتصفح: حل خريطة المصدر عند حوالي 2 كيلو بايت دقيقة + gz ... هذا بدون polyfills ، ولكن (إذا نجح ذلك) أعتقد أننا يجب أن نكون قادرين على الوصول إلى ~ 10 كيلو بايت من أجل المتصفحات الحديثة التي لا تحتاج إلى polyfill.

هذا بدون بوليفيل

لا ينبغي أن يكون Polyfills في الإصدار esm ، لذلك يمكن أن يعمل ذلك أيضًا ، ولكن في bachend سيكون أقل من ذلك

يجب أن يكون الإصدارcromefire ESM متاحًا في 4.5.1 الآن. لم يتم توثيقه بعد لأننا نريد التأكد من أنه تم اختباره في المعركة ، ولكنه جيد حتى الآن. لقد تحققت من تصميم webpack العادي باستخدام أداة تحميل babel وهو يعمل مثل السحر.

علاوة على ذلك ، فإن الأمر يتعلق بجمع أجزاء قليلة من معلومات المتصفح ، ولفها بتنسيق JSON المتوقع ، ونشرها - والتي لا ينبغي أن تكون أكثر من بضعة كيلو بايت min + gz. ينبغي له؟

@ mindplay-dk ، لا نقوم بأي حل لتتبع المكدس من جانب العميل. يتم كل ذلك على الخادم ، ولهذا السبب تحتاج إلى تحميل خرائط المصدر في المقام الأول للحصول على الدعم لها.

لكن ما نفعله هو:

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

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

أعلم أنه من الشائع نشر ميغا بايت من JS هذه الأيام ، لكن لدينا سياسات محتوى صارمة في العمل ، لضمان شحن المشاريع التي يتم تحميلها بسرعة على الهواتف المحمولة ، ولا يمكنني تبرير إنفاق أكثر من نصف ميزانية JS الخاصة بنا على الخطأ- تسجيل الدخول - ربما يكون أعلى بنسبة 10٪ ، لذلك يبدو أن شيئًا مثل ~ 15-20 كيلوبايت يبدو معقولاً.

يمكنك استخدام أداة التحميل الخاصة بنا بعد ذلك - https://docs.sentry.io/platforms/javascript/loader/ :)

يمكنك استخدام أداة التحميل الخاصة بنا بعد ذلك - https://docs.sentry.io/platforms/javascript/loader/ :)

ولكن للأسف لا يوجد حل لـ webpack

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

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

ولكن للأسف لا يوجد حل لـ webpack

ماذا تقصد بالضبط؟ هل لديك حزمة يمكن أن تتواجد مع المحمل ، والتي يمكن استيرادها وتجميعها ، ولكن بعد ذلك يتم الاتصال مع SDK الذي تم تحميله بشكل غير متزامن بمجرد حدوث خطأ أو استدعاء captureException؟

ماذا تقصد بالضبط؟ هل لديك حزمة يمكن أن تتواجد مع المحمل ، والتي يمكن استيرادها وتجميعها ، ولكن بعد ذلك يتم الاتصال مع SDK الذي تم تحميله بشكل غير متزامن بمجرد حدوث خطأ أو استدعاء captureException؟

نعم ، إذا قمت بالتلخيص بشكل صحيح ، فلن يكون المُحمل متاحًا إلا عبر cdn

cromefire نعم ، لأنه من المفترض استخدامه كـ "مقتطف". ومع ذلك يمكنك العثور على الكود هنا https://github.com/getsentry/sentry-javascript/blob/master/packages/browser/src/loader.js

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

لدينا حل قادم يتيح لك استخدام loader بجانب minimal وسيضيف فعليًا بضعة كيلوبايت فقط إلى حزمتك النهائية.

لا ينبغي أن يكون من الصعب كتابة محمل يحمل ذلك في أقل من 1 كيلوبايت ، فلماذا لا ، سأحاول كتابة واحدة سريعة

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

على سبيل المثال ، يمكن أن يكون الحد الأدنى الجميل هو:

  • تتبع مكدس الخطأ الأصلي (لا تهتم أنه ليس الأمثل في بعض المتصفحات)
  • وكيل المستخدم
  • الطابع الزمني
  • URL
  • تطابق مع خرائط المصدر على الخادم

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

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

sentry.js

import * as Sentry from '@sentry/browser';
Sentry.init({
  ...
  integrations: integrations => {
    return integrations.filter(integration => integration.name !== 'GlobalHandlers');
  },
});
export const logError = error => Sentry.captureException(error);

errors.js

const captureError = async error => {
 const { logError } await import(/* webpackChunkName: "sentry" */ './sentry');
 logError(error);
}
window.onerror = (message, url, line, column, error) => captureError(error);
window.onunhandledrejection = event => captureError(event.reason);

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

هذا إلى حد ما ما نفذته في # 1846

قد يكون مفيدًا للآخرين:
لقد استخدمت إصدار ESM مع حزمة الويب ( 4.29.5 ) بواسطة:

  • إضافة اسم مستعار لحزمة الويب لاستخدام إصدار ESM بدلاً من الإصدار القياسي نظرًا لعدم وجود إعلان module في package.json
resolve: {
    alias: {
        // use sentry ESM build which is not declared in the @sentry/browser package.json
        '@sentry/browser': path.resolve(
            __dirname,
            'node_modules/@sentry/browser/esm',
        ),
    }
  • إضافة استثناء إلى sentry/.+/esm إلى التهيئة الخاصة بنا babel-loader ، حيث يبدو أن إصدار ESM يتضمن ميزات أحدث من ES2015.
{
    test: /\.m?jsx?$/,
    loader: 'babel-loader',
    // compile sentry as the ESM build is new and ships modern features which break our supported browsers
    exclude: /(node_modules\/(?!(@sentry\/[^/]+\/esm))|bower_components)\//,
}

ملحوظات:

  • استخدمنا الأسماء المستعارة لذلك لا داعي للقلق بشأن التجميع عند استخدامها في الكود (نقوم بعمل مماثل مقابل lodash-es بين أشياء أخرى)

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

يمكنك فقط إعادة التوجيه إلى @sentry/browser/esm :

resolve: {
    alias: {
        // use sentry ESM build which is not declared in the @sentry/browser package.json
        '@sentry/browser': '@sentry/browser/esm'
    }

لكنك لست بحاجة إلى إضافة اسم مستعار ، ما عليك سوى استيراد @sentry/browser/esm

بالنسبة للمحمل ، من الأسهل كتابته على النحو التالي:

  • إذا كان لديك أشياء أخرى في بابل:
{
    test: /other_things/,
    include: [/@sentry\/.+\/esm/],
    exclude: /node_modules/,
    // config
}
  • إذا لم تقم بما يلي:
{
    test: /@sentry\/.+\/esm/,
    exclude: /node_modules/,
    // config
}

تذكر أيضًا تخصيص تهيئة babel لاحتياجاتك: babel docs ، وإلا فلا يستحق استخدام إصدار esm

تحديث: سنصدر قريبًا إصدارًا رئيسيًا جديدًا من SDK مما يقلل من حجم الحزمة بشكل كبير.

26.1 kB - https://bundlephobia.com/result؟p=@sentry/browser @ 4.6.4
ضد.
17.2 kB - https://bundlephobia.com/result؟p=@sentry/browser @ 5.0.0-rc.1

تُظهر إصدارات CDN المُنشأة مسبقًا نتائج أفضل (لست متأكدًا من كيفية قياس رهاب الحزم للأشياء)

ES6:  14.3535 kB
ES5:  15.6846 kB

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

ملاحظة حول الترقية: إنها عثرة كبيرة نظرًا لوجود العديد من التغييرات الداخلية في SDK. يجب ألا يكون هناك أي تغييرات ضرورية في التعليمات البرمجية من جانبك. نقوم حاليًا باختبار الإصدار الجديد بأنفسنا على sentry.io لنرى كيف يتصرف. المرجع: https://github.com/getsentry/sentry/pull/12492

إخلاء المسؤولية: لا تستخدم 5.0.0-rc.x في الإنتاج حتى الآن كما نفعل 🙈

HazAT شكرا لك على أخذ هذا الأمر على محمل الجد! هذه خطوة كبيرة للأمام - أنا بالفعل أقل قلقًا بشأن نشر هذا الآن :-)

image

kamilogorek بدافع الفضول ، هل يمكنك إضافة الإصدار الأخير من فرع 3.x للمقارنة؟

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

كملاحظة سريعة ، نود حقًا فقط مقارنة حجم "الحزمة" لدينا ، نظرًا لأن اعتمادًا على الحزم الذي تستخدمه قد يختلف ، لذلك إليك رقم حزمة CDN التي نشحنها (ped):

| الحزمة | الإصدار | الحجم بالبايت | الحجم بالكيلو بايت | ارتباط |
| ----------------- | --------- | --------------- | ----- ------- | ------------------------------------------ ---------- |
| الغراب شبيبة | 3.27.0 | 13741 بايت | ~ 13.4 كيلو بايت | https://cdn.ravenjs.com/3.27.0/raven.min.js |
| @ الحارس / المتصفح | 4.6.6 | 22607 بايت | ~ 22.1 كيلو بايت | https://browser.sentry-cdn.com/4.6.6/bundle.min.js |
| @ الحارس / المتصفح | 5.0.3 | 16059 بايت | ~ 15.7 كيلو بايت | https://browser.sentry-cdn.com/5.0.3/bundle.min.js |

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

شكرا لكم جميعا على صبركم 🙇

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

Limess هل لا يزال من المناسب استخدام هذا اليوم: @sentry/browser/esm بدلاً من @sentry/browser ؟

تم استيراده مثل import * as Sentry from "@sentry/browser/esm"; ومُجمَّع بـ webpack -p لكني لا أرى فرقًا في أحجام الحزم. لدي أيضًا webpack.config.js بدون مكونات إضافية أو لوادر.

@ 0xbkt لا يحدث فرقًا في حجم الحزمة ، على الأقل الآن عند استخدام تطبيق التجميع إلى الحزمة.

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