تا %60 تخفیف خرید برای 6 نفر با صدور مدرک فقط تا
00 00 00

آموزش Webpack قسمت 9: مدیریت فایل ها و Cache

حسین احمدی
حسین احمدی
0 پسند
54 بازدید
0 نظر
3 ماه قبل

ضمیمه ها

WebpackSample.rar

در این بخش مورد نحوه مدیریت Cache در Webpack صحبت می کنیم. زمانی که درخواستی از سمت مرورگر به سمت سرور ارسال می شود، فایل های استاتیک مانند تصاویر، فایل های JavaScript و فایل های CSS یکبار دانلود شده و در Cache مرورگر ذخیره می شود تا برای دفعات بعد، درخواستی به سمت سرور ارسال نشود و سرعت بارگذاری صفحات افزایش پیدا کند. اما مشکلی که اینجا باهاش روبرو هستیم، Cache کردن بر اساس نام و مسیر فایل انجام می شود و اگر تغییری در فایل ها ایجاد شود، مرور به صورت خودکار فایل ها را به روز رسانی نمی کند. برای رفع این مشکل باید نام فایل ها بر اساس محتویات داخل آنها ایجاد شود تا مرورگر فایل های به روز شده را مجدد دانلود کند. بوسیله Webpack، اینکار با افزودن یک رشته اضافی به نام فایل مانند Hash امکان پذیر است که در این بخش با این موارد آشنا خواهیم شد.
موضوع دیگری که وجود دارد این است که شاید داخل پروژه ما، نیاز به چند فایل script داشته باشیم. برای مثال، یک فایل اسکریپت برای پنل مدیریت و یک فایل اسکریپت برای بخش اصلی وب سایت. در این بخش ما در مورد مدیریت فایل ها و همچنین مبحث Cache صحبت خواهیم کرد.
برای بخش اول، با نحوه ایجاد چند فایل خروجی در webpack صحبت می کنیم. برای مثال، فرض کنید که ما علاوه بر اسکریپت های مربوط به بخش اصلی سایت، یک سری اسکریپت ها برای پنل مدیریت داریم. داخل پوشه src یک فایل با نام admin.js ایجاد می کنیم با محتویات زیر:

function welcome(){
 alert("Welcome to admin panel!");
}

داخل فایل webpack.config.js بخشی به صورت زیر داریم:

entry: "./src/index.js",

برای اینکه فایل admin.js هم به عنوان یک اسکریپت مجزا در نظر گرفته شود، این بخش را به صورت زیر تغییر می دهیم:

entry: {
 application: "./src/index.js",
 admin: "./src/admin.js"
},

برای قدم بعدی باید به webpack بگیم که هنگام ایجاد خروجی، فایل نهایی بر اساس نام فایل اصلی ایجاد شود. برای اینکار بخش entry در فایل webpack.config.js رو به صورت زیر تغییر میدهیم:

output: {
 filename: "[name].js",
 path: path.resolve(__dirname, 'build')
},

اگر دستور npm run build رو اجرا کنیم و نگاهی به پوشه build بندازیم دو فایل با نام های application.js و admin.js خواهیم دید. اما برای فایل های CSS چطور؟ اگر به خاطر داشته باشید داخل فایل index.js ما دو خط زیر رو ابتدای فایل اضافه کرده بودیم:

import styles from './styles.css';
import application from './application.scss';

خط اول فایل بالا رو به فایل admin.js منتقل کرده و دستور npm run build رو اجرا می کنیم. اما اینبار خطای زیر رو دریافت می کنیم:

ERROR in chunk application [entry]
application.css
Conflict: Multiple chunks emit assets to the same filename application.css (chunks 0 and 1)

این خطا به ما میگه تداخل در ایچاد فایل application.css وجود داره. برای رفع این مشکل، داخل فایل webpack.config.js بخش plugins، تنظیمات MiniCssExtractPlugin رو به صورت زیر تغییر میدیم:

plugins: [
 new MiniCssExtractPlugin({
  filename: '[name].css'
 })
],

کاری که انجام دادیم، از [name] برای مشخص کردن نام فایل استفاده کردیم. مجدد دستور npm run build رو اجرا می کنیم. اگر پوشه build رو نگاه کنیم، دو فایل با نام های application.css و admin.css ایجاد شده. شاید این سوال براتون پیش بیاد که webpack نام فایل ها رو از کجا انتخاب میکنه، بخش زیر رو در فایل wepack.config.js تغییر داده بودیم:

entry: {
 application: "./src/index.js",
 admin: "./src/admin.js"
},

نام فایل بر اساس نام خصوصیت شئ ای که برای entry مشخص شده انتخاب میشه. یعنی اگر ما application رو به myapp تغییر بدیم، نام فایل ها به myapp تغییر میکنه:

entry: {
 myapp: "./src/index.js",
 admin: "./src/admin.js"
},

قدم بعدی، اضافه کردن Hash به نام فایل ها برای مدیریت Cache مرورگر می باشد. در مورد Cache ابتدای مطلب توضیح دادیم. برای اضافه کردن Hash به نام فایل ها، بخش Output در فایل webpack.config.js رو به صورت زیر تغییر میدیم:

output: {
 filename: "[name]-[contenthash].js",
 path: path.resolve(__dirname, 'build')
},

همچنین برای فایل های css هم بخش plugins به صورت زیر تغییر میکنه:

plugins: [
 new MiniCssExtractPlugin({
  filename: '[name]-[contenthash].css'
 })
],

دستور npm run build رو مجدد اجرا کرده و محتویات پوشه build باید به صورت زیر باشه:

آموزش Webpack

علاوه contenthash موارد دیگه ای هم هست که میشه ازشون استفاده کرد که داخل مستندات Webpack در موردشون توضیح داده شده.

فایل admin.js رو باز کرده و کد زیر رو به این فایل اضافه می کنیم:

function calculate(a,b){
 console.log(a+b);
}

دستور npm run build رو اجرا کرده و داخل پوشه build باید به این صورت باشه:

آموزش Webpack

مشکلی که اینجا وجود داره، با هر بار تغییر فایل ها، یک فایل جدید با Hash جدید برای ما ایجاد میشه که باعث بالا رفتن تعداد فایل های داخل پوشه به مرور زمان میشه. راهکار این مشکل حذف فایل های داخل پوشه build در زمان اجرای دستور build هست. برای اینکار از پلاگینی با نام clean-webpack-plugin استفاده می کنیم. ابتدا بوسیله دستور زیر این پلاگین رو نصب می کنیم:

npm install clean-webpack-plugin --save-dev

خط زیر رو به ابتدای فایل webpack.config.js اضافه می کنیم:

const CleanWebpackPlugin = require('clean-webpack-plugin').CleanWebpackPlugin;

و در ادامه بخش plugins رو به صورت زیر تغییر میدیم:

plugins: [
 new CleanWebpackPlugin(),
 new MiniCssExtractPlugin({
  filename: '[name]-[contenthash].css'
 })
],

و در نهایت دستور npm run build رو اجرا میکنیم. اگر اینبار پوشه build رو نگاه کنیم، خواهیم دید که فایل های اضافی حذف شده و تنها فایل های جدید ایجاد شده اند:

آموزش Webpack

تا این لحظه همه چیز به خوبی پیش رفته غیر از یک موضوع! به روز رسانی فایل index.html که باعث مشکل شده. اگر با هر بار تغییر فایل های js و css قرار باشه فایل index.html به صورت دستی تغییر کنه، کار ما خیلی سخت میشه. برای رفع این مشکل دو کار میشه انجام داد:

  1. استفاده از فایل manifest
  2. استفاده از template

فایل manifest، یک فایل شامل اطلاعات فایل های نهایی ما هست. برای ایجاد این فایل از پلاگین webpack-manifest-plugin استفاده می کنیم. ابتدا این پلاگین رو نصب می کنیم:

npm install webpack-manifest-plugin --save-dev

در ابتدای فایل webpack.config.js خط زیر رو اضافه کرده:

const WebpackManifestPlugin = require('webpack-manifest-plugin');

و بخش plugins رو هم به صورت زیر تغییر میدیم:

plugins: [
 new WebpackManifestPlugin(),
 new CleanWebpackPlugin(),
 new MiniCssExtractPlugin({
  filename: '[name]-[contenthash].css'
 })
],

دستور npm run build رو اجرا کرده و خواهیم دید داخل پوشه build یک فایل با نام manifest.json با محتویات زیر برای ما ایجاده شده:

{
 "admin.css": "admin-06cb27c45a021926b1c4.css",
 "admin.js": "admin-fc4cad311bcd9ee7e5d8.js",
 "application.css": "application-a6f39414f54ee74e901e.css",
 "application.js": "application-46a73b324507f99360e1.js",
"application.scss": "flowers.7b441a0.jpg"
}

کاری که ما باید با این فایل انجام بدیم، بوسیله یک تکنولوژی Server-Side مثل PHP یا ASP.NET، محتویات این فایل رو بخونیم و استایل ها رو در مکان مناسب قرار بدیم.
روش دوم استفاده از قابلیت template هست، بوسیله این قابلیت ما یک template برای صفحه html مشخص میکنیم و خود webpack بخش های مربوط به js و css رو برای ما ایجاد میکنه. برای استفاده از این قابلیت پلاگین زیر رو نصب می کنیم:

npm install html-webpack-plugin --save-dev

و در قدم بعدی خط زیر رو به فایل webpack.config.js اضافه می کنیم:

const HtmlWebpackPlugin = require('html-webpack-plugin');

بخش plugins رو به صورت زیر تغییر میدیم:

plugins: [
 new HtmlWebpackPlugin(),
 new WebpackManifestPlugin(),
 new CleanWebpackPlugin(),
 new MiniCssExtractPlugin({
  filename: '[name]-[contenthash].css'
 })
],

دستور npm run build رو اجرا می کنیم و اگر داخل پوشه build رو نگاه کنیم فایل جدیدی با نام index.html با محتویات زیر ایجاد شده:

<!doctype html>
<html>
 <head>
  <meta charset="utf-8">
  <title>Webpack App</title>
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <link href="application-a6f39414f54ee74e901e.css" rel="stylesheet">
  <link href="admin-06cb27c45a021926b1c4.css" rel="stylesheet">
 </head>
 <body>
  <script src="application-46a73b324507f99360e1.js"></script>
  <script src="admin-fc4cad311bcd9ee7e5d8.js"></script>
 </body>
</html>

مورد آخری که باید بهش اشاره کنیم این هست که این فایل توسط خود webpack ایجاد شده و هیچ کدی داخلش وجود نداره. برای رفع این مشکل یک فایل با نام template.html داخل پوشه src و با محتویات زیر ایجاد می کنیم:

<!DOCTYPE html>
<html lang="en" dir="ltr">
 <head>
  <meta charset="utf-8">
  <title>Hello Webpack</title>
 </head>
 <body>
  <h1>Welcome to TOSINSO Webpack Tutorial!</h1>
 </body>
</html>

حالا باید به پلاگین html-webpack-plugin بگیم که از این template برای ایجاد خروجی استفاده کنه. بخش plugins داخل فایل webpack.config.js رو به صورت زیر تغییر میدیم:

plugins: [
 new HtmlWebpackPlugin({
  template: './src/template.html'
 }),
 new WebpackManifestPlugin(),

دستور npm run build رو اجرا کرده و میبینیم که محتویات فایل index.html ایجاد شده به صورت زیر هست:

<!doctype html>
<html lang="en" dir="ltr">
 <head>
  <meta charset="utf-8">
  <title>Hello Webpack</title>
  <link href="application-a6f39414f54ee74e901e.css" rel="stylesheet">
  <link href="admin-06cb27c45a021926b1c4.css" rel="stylesheet">
 </head>
 <body>
  <h1>Welcome to TOSINSO Webpack Tutorial!</h1>
  <script src="application-46a73b324507f99360e1.js"></script>
  <script src="admin-fc4cad311bcd9ee7e5d8.js"></script>
 </body>
</html>

کدهای این قسمت به صورت ضمیمه از ابتدای این مطلب قابل دریافت هست. قبل از استفاده از کدها دستور npm install رو برای resolve کردن dependency ها اجرا کنید.

نویسنده: حسین احمدی
منبع: جزیره طراحی و توسعه وب توسینسو
هر گونه نشر و کپی برداری با ذکر نام منبع و نویسنده بلامانع است

نظر شما
برای ارسال نظر باید وارد شوید.
0 نظر

هیچ نظری ارسال نشده است! اولین نظر برای این مطلب را شما ارسال کنید...