دیباگ پروژه های جاوا اسکریپت با استفاده از Source Map ها
ﺯﻣﺎﻥ ﻣﻄﺎﻟﻌﻪ: 9 دقیقه

دیباگ پروژه های جاوا اسکریپت با استفاده از Source Map ها

پروژه های جاوا اسکریپت در حال تولید خود را با استفاده از Source Map ها دیباگ کنید

امروزه، کدی که برای برنامه خود می نویسید معمولا همان کدی نیست که در هنگام تولید استفاده می شود و توسط مرورگر ترجمه می شود. شاید کد خود را با زبانی می نویسید که بعدا به جاوا اسکریپت کامپایل می شود. مانند CoffeeScript، TypeScript یا آخرین نسخه تایید شده جاوا اسکریپت، یعنی ECMAScript 2015 (ES6). گاهی حتی کد خود را در جهت داشتن حجم کمتر، کوچک تر می کنید، که در این صورت به احتمال زیاد از ابزاری مثل Uglify یا Google Closure Compiler استفاده می کنید.

ابزار تغییر شکل این چنینی، معمولا به Transpiler معروفند. ابزاری که سورس کد را از یک زبان، به همان زبان، یا به زبانی مشابه و سطح بالا تغییر شکل می دهند. خروجی آنها کد های Transpile شده ای است که در کنار کار آمد بودن در همان محیط اولیه، (مثلا مرورگر) معمولا شباهت کمی به سورس کد اولیه دارند.

این باعث بروز یک مشکل می شود: در حالی که کد در مرورگر دیباگ می شود، یا Stack trace های ایجاد شده توسط ارور های موجود در برنامه شما بازرسی می شوند، معمولا در مقابل خود به جای کد های اصلی، کد های Transpile شده ای می بینید که خواندنشان نیز سخت است. این می تواند بررسی خطا های جاوا اسکریپت را مشکل ساز کند.

راه حل این مشکل، یک خاصیت در مرورگر است، به نام Source Map ها.

جدول محتویات:

  1. Source Map ها
  2. تولید Source Map
  3. Source Map های خصوصی
  4. Source Map ها و Sentry
  5. Sentry و Source Map های آفلاین
  6. جمع بندی

Source Map ها

Source Map ها فایل های JSON ای هستند، که اطلاعاتی درباره این که چگونه سورس کد های Transiple شده خود را به سورس کد های اصلی برگردانید را شامل می شوند. اگر تجربه برنامه نویسی با زبانی کامپایل شده مثل Objective-C را داشته باشید، می توانید آن ها را چیزی مانند نسخه جاوا اسکریپت علائم دیباگ (Debug Symbols) تصور کنید.

در زیر، مثالی از Source Map را می بینید:

{
    version : 3,
    file: "app.min.js",
    sourceRoot : "",
    sources: ["foo.js", "bar.js"],
    names: ["src", "maps", "are", "fun"],
    mappings: "AAgBC,SAAQ,CAAEA"
}

به احتمال زیاد هیچ وقت مجبور نمی شوید این فایل ها را خودتان بسازید، اما دانستن محتویات آن ها ضرری ندارد:

  • version : نسخه Source Map که این فایل ارائه می کند. (معمولا 3)
  • file : نام فایلی که Source Map در آن قرار دارد.
  • sourceRoot: URL ریشه ای که تمام منابع از طریق آن قابل دسترسی هستند. (این گزینه اختیاری است)
  • source : آرایه ای از URL ها که به فایل های منبع اصلی مرتبط می شود.
  • names : آرایه ای از نام های متغیر ها و متود های یافت شده در کد شما.
  • mappings : مسیر های سورس کد اصلی، بر پایه مقادیر base64-encoded VLQ

اگر به خاطر سپردن این موارد سخت است، نگران نباشید. در ادامه ابزاری برای ساخت این فایل ها برای شما را معرفی خواهیم کرد.

دستور العمل sourceMappingURL

برای این که به مرورگر بگوییم یک Source Map برای یک فایل Transpile شده موجود است، دستور العمل sourceMappingURL باید به انتهای فایل اضافه شود:

// app.min.js
$(function () {
    // your application ...
});
//# sourceMappingURL=/path/to/app.min.js.map

وقتی که مرورگر های مدرن دستور العمل sourceMappingURL را می بینند، Source Map را از مکان ارائه شده دانلود می کنند و از اطلاعات موجود برای تایید کد های در حال اجرا استفاده می کنند. وقتی که با استفاده از Firefox کد ES6 + JSX اصلی Sentry را با استفاده از Source Map ها اجرا می کنیم، چنین چیزی مشاهده می کنیم. (نکته: مرورگر ها فقط وقتی که Developer Tools باز است، Source Map ها را دانلود کرده و اعمال می کنند. این اتفاق هیچ تاثیری در کارایی برنامه برای کاربران معمولی ندارد.)

دیباگ پروژه های جاوا اسکریپت با استفاده از Source Map ها

تولید Source Map :

حال می دانیم که Source Map ها چگونه کار می کنند و چگونه مرورگر ها را وادار به دانلود و استفاده از آنها کنیم. اما چگونه آنها را بسازیم و در فایل های Transiple شده خود قرار دهیم؟

نکته خوب این است که اکثر Transpiler ها مدرن جاوا اسکریپت گزینه ای برای ایجاد یک Source Map دارند. بیایید نگاهی به چند گزینه مشترک بیندازیم.

UglifyJS

UglifyJS ابزار معروفی برای کوتاه تر کردن سورس کد محصولتان است. این ابزار می تواند با حذف کردن Space های اضافه، باز نویسی نام متغیر ها، حذف کردن شاخه های بی استفاده کد و... حجم فایل های شما را کمتر کند.

اگر در حال استفاده از UglifyJS برای کوتاه تر کردن کد های خود هستید، دستور زیر در UglifyJS 3.3x، یک Source Map ایجاد می کند که کد کوتاه شده را به کد اصلی ارتباط می دهد:

uglifyjs app.js -o app.min.js --source-map

اگر نگاهی به فایل خروجی، یعنی app.min.js داشته باشید، می بینید که خط آخر شامل دستور العمل sourceMappingURL می شود که به Source Map تازه ایجاد شده شما اشاره می کند.

//# sourceMappingURL=app.min.js.map

دقت کنید که این یک URL از نوع Relative است. در جهت این که مرورگر Source Map مربوطه را دانلود کند، باید این Source Map در شاخه ای که فایل تولید شده توسط UglifyJS، یعنی app.min.js در آن قرار دارد، کپی شود. این به این معنی است که فایل app.min.js در آدرس http://example.org/static/app.min.js قرار دارد، پس Source Map شما نیز باید در همین آدرس قرار داشته باشد.

URL های نوع Relative ها تنها راه برای مشخص کردن sourceMappingURL نیستند. می توانید با استفاده از گزینه --source-map-url <url> به Uglify یک URL مطلق بدهید. یا حتی می توانید کد Source Map را به صورت Inline بنویسید، که البته این روش پیشنهاد نمی شود. برای اطلاعات بیشتر، نگاهی به گزینه های دستوری Uglify داشته باشید.

Webpack

Webpack یک ابزار قدرتمند است که Module های جاوا اسکریپت شما را به فایل های مناسبی برای اجرا در مرورگر Resolve کرده و متصل می کند. حتی خود پروژه Sentry نیز از Webpack (در کنار Babel) برای جمع کردن و Transpile کردن کد های ES6 + JSX خود به کد های جاوا اسکریپت مطابق با مرورگر استفاده می کند.

تولید Source Map ها با استفاده از Webpack آسان تر است. در Webpack 4، می توانید به این صورت ویژگی devtool را در پیکربندی های خود مشخص کنید:

// webpack.config.js
module.exports = {
    // ...
    entry: {
      "app": "src/app.js"
    },
    output: {
      path: path.join(__dirname, 'dist'),
      filename: "[name].js",
      sourceMapFilename: "[name].js.map"
    },
    devtool: "source-map"
    // ...
};

حال زمانی که خط دستور webpack را اجرا می کنید، Webpack فایل های شما را جمع آوری می کند، یک Source Map تولید می کند، و با استفاده از دستور العمل sourceMappingURL، سورس مپ های شما را به فایل های جاوا اسکریپت ساخته شده متصل می کند.

Source Map های خصوصی

تا به اینجا، تمام مثال های ما به گونه ای بودند که در آنه ها Source Map های شما برای عموم در دسترس هستند و به عنوان کد جاوا اسکریپت شما از سرور گرفته می شوند. در این صورت، هر توسعه دهنده ای می تواند از Source Map های شما استفاده کند و سورس کد های اصلی شما را به دست بیاورد.

برای جلوگیری از این اتفاق، به جای استفاده از یک sourceMappingURL عمومی، می توانید Source Map های خود را در سروری قرار دهید که فقط برای تیم توسعه شما قابل دسترسی هستند. به عنوان مثال، سروری که فقط از طریق VPN شرکت شما قابل دسترسی است.

دیباگ پروژه های جاوا اسکریپت با استفاده از Source Map ها

وقتی شخصی که عضو تیم شما نیست، Developer Tools خود را باز می گذارد و به برنامه شما سر می زند، برای دانلود این Source Map اقدام می کنند اما با ارور 404 (یا 403) HTTP مواجه می شوند، و Source Map اعمال نمی شود.

Source Map ها و Sentry

اگر از Sentry برای رهگیری Exception ها در برنامه جاوا اسکریپت سمت کاربر خود استفاده می کنید، اخبار خوبی برای شما داریم! Sentry به طور خودکار Source Map ها را گرفته و به Stack Trace های تولید شده توسط خطا ها اعمال می کند. این یعنی شما سورس کد اصلی خود را می بینید، نه نسخه کوتاه شده یا Transpile شده. Stack Trace کد کوتاه نشده شما در Sentry به این صورت خواهد بود:

 

اساسا، اگر مراحل موجود در این آموزش را دنبال کرده باشید و Source Map ها و فایل های Transpile شده خود را با استفاده از دستور العمل sourceMappingURL آپلود کرده باشید، کار دیگری برای انجام دادن وجود ندارد. Sentry باقی کار ها را انجام می دهد.

Sentry و Source Map های آفلاین

از سوی دیگر، می توانید به جای این که خودتان میزبان Source Map ها باشید، آن ها را مستقیما به Sentry آپلود کنید.

اما چرا باید این کار را انجام دهید؟ برخی دلایل در اینجا ذکر شده اند:

  • در صورتی که Sentry نمی تواند به سرور های شما دسترسی داشته باشد. (مثلا وقتی که Source Map ها بر روی یک VPN قرار دارند)
  • در صورتی که تاخیر هایی پیش می آیند. در این صورت Source Map ها اگر Exception ای پیش آمده باشد، داخل Sentry قرار دارند.
  • در صورتی که در حال توسعه برنامه ای هستید که تنها بر روی یک دستگاه اجرا می شود. (مثلا استفاده از React Native یا PhoneGap، که سور کد ها/Source Map های آن ها بر روی اینترنت قابل دسترسی نمی باشند.)
  • جلوگیری از بروز تداخل میان نسخه ها، زمانی که یک Source Map گرفته شده با کدی که خطا در آن بروز داده است، همخوانی ندارد.

جمع بندی

حال فهمیدید که چگونه Source Map ها با آسان کردن فرایند دیباگ کردن در طی تولید، می توانند شما را نجات دهند. از آنجایی که ابزار های مورد استفاده شما به احتمال زیاد تولید Source Map را پشتیبانی می کنند، پیکربندی آن ها زیاد طول نمی کشد، و نتیجه ای که میگیرید ارزش زحمات کشیده شده را خواهد داشت.

منبع

چه امتیازی برای این مقاله میدهید؟

خیلی بد
بد
متوسط
خوب
عالی
در انتظار ثبت رای

/@er79ka

دیدگاه و پرسش

برای ارسال دیدگاه لازم است وارد شده یا ثبت‌نام کنید ورود یا ثبت‌نام

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

در حال دریافت نظرات از سرور، لطفا منتظر بمانید