Frontend team leader @snappfood
استراتژی های assets name hashing در وب پک
قدیم ندیما، برای درست تنظیم کردن ورژن ها و درست آپدیت شدن اپلیکیشن های وب، بعد از هر ریلیز سعی میکردن به صورت دستی و استاتیک، به فایل های asset شون یه ورژن میزدن. مثلا
https://temp.com/main.chunk.js?v=0xasa0sdd
خب، مثل همه ی کارهای دستی دیگه، آدما دوس دارن یه چیز automatic بسازن. حالا نمیریم سراغ سیری که طی شد برای این کار. اما اتفاقی که این روزها میوفته و ابزاری که در دسترسمون هست، Module bundler هایی هستن که میتونید به وسیله اونها، این کار رو انجام بدین. من میخوام اینجا، از وب پک استفاده کنم و کارهایی که میشه در وب پک انجام داد رو بگم.
کاری که این روزها داره ازش استفاده میشه، اضافه شدن یک hash به صورت اتوماتیک به آدرس فایل های asset هست به شکل زیر:
https://temp.com/main.chunk.0xasa0sdd.js
برای اینکار، روی وب پک کار خاصی نیاز نیست انجام بدید، کافیه برای حالت پروداکشن، در قسمت output از مثال زیر استفاده کنید:
output: {
filename: 'app.bundle.[hash].js',
chunkFilename: '[id].[hash].js'
},
این کار باعث میشه، بعد از build شدن، به انتهای همه ی فایل های js شما، یک hash یکتا الصاق بشه. یعنی خروجی اسم فایل هاتون یه همچین چیزی میشه:
0.d0fb27baffad1379579c.js.gz
1.d0fb27baffad1379579c.js.gz
.
.
.
app.bundle.d0fb27baffad1379579c.js.gz
قبل از اینکه انواع hash هایی که میتونید بزنید رو بگم، بگم این hash ها چگونه کار میکنن؟ بعد از هر build یه dependency گرافی، بین فایل های asset شما ایجاد میشه. یعنی، index شما که لود میشه، درخواست دریافت dependency های خودش که اصطلاحا بهشون گفته میشه Entrypoints. این فایل ها خودشون به فایل های دیگه dependency دارن و الی آخر (در صورتی که split chunks و lazy loading فعال کرده باشید).
اینجای کار،اگر همه ی dependency ها درست ست شده باشن، اینجا شما به هیچ مشکلی از نظر کش نمی خورید و به محض دیپلوی شدن ورژن جدید، فایل های جدید در اختیار کاربر قرار میگیره، مگر در یک حالت اونم اینکه document اصلی (یا فایل index.html) کش شده باشه. پس لازمه ی اینکه همه ی آپدیت شدن شما درست صورت بگیره اینه که از کش شدن Document جلوگیری کنید ( در nginx و service worker). البته اگر بخواید Offline mode رو برای pwa فعال کنید، باید document رو کش کنید که اونجا برای آپدیت کردن نیاز به کارهای دیگه ای دارید که اگر نیاز بود، بپرسید همین پایین، میگم!
خب، حالا بیاین در مورد این صحبت کنیم که چند حالت hash داریم:
- Hash:
وابسته به بیلد هست، با هر بیلدی، یک hash یکتا تولید شده و به همه ی asset ها الصاق میشه. اگر فقط یک تغییر کوچک هم بدین، hash کل بیلدتون عوض میشه. این نوع hashing به درد زمانی میخوره که باندلتون کوچیکه و یا هر نوع مدیریتی ، سمت کلاینت، روی asset هاتون بخواین اعمال کنین.
output: {
filename: 'app.bundle.[hash].js',
chunkFilename: '[id].[hash].js'
},
- Chunkhash
این فرمول، وابسته به entry point ها در webpack هست. هر entry دارای hash اختصاصی خودش هست. بالاتر گفتم منظور از entry چی هست. هرچیزی در یک entry خاص، تغییر کنه، hash اون entry تغییر میکنه. بهترین حالت برای استفاده از حداکثر ظرفیت caching در browser، در این فرمول نهفته هست. با اولین بار لود شدن یک asset، اون فایل در کلاینت شما cache میشه ( چه بهتر اگر سرویس ورکر داشته باشید). فرض کنید شما یه هاتفیکس یه خطی زدید، اگر از استراتژی اول استفاده کنید، hash همه ی فایل هاتون تغییر کرده و کش فعلی بروزر رو باید بریزید دور و همه ی فایل هاتون رو از اول بگیرید. اما با این استراتژی فقط فایل های entry خاصی که تغییر کرده دوباره از سرور دریافت میشن.
output: {
filename: 'app.bundle.[chunkhash].js',
chunkFilename: '[id].[chunkhash].js'
},
البته این داستان بحث زیادی داره، من سعی کردم خیلی خلاصه در موردش بگم. اگر سوالی در مورد hashing، caching، service worker و ... داشتید، در خدمتتون هستم!
مطلبی دیگر از این انتشارات
داستان مهاجرت من
مطلبی دیگر از این انتشارات
بهترین زبان های برنامه نویسی در سال ۱۳۹۷
مطلبی دیگر از این انتشارات
رایانه کار درجه ۱ و ۲ ICDl (مهارت های هفتگانه رایانه) چیست؟