الفرق بين المراجعتين ل"Rails/asset pipeline"

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث
(إنشاء الصفحة. هذه الصفحة من مساهمات "تسنيم ولهازي")
 
سطر 1: سطر 1:
 
<noinclude>{{DISPLAYTITLE:خط أنابيب الأصول في ريلز}}</noinclude>
 
<noinclude>{{DISPLAYTITLE:خط أنابيب الأصول في ريلز}}</noinclude>
يغطّي هذا الدليل أنبوب الأصول.
+
يغطّي هذا الدليل أنبوب الأصول. ستتعلم بعد قراءة هذا الدليل:
 
 
ستعرف بعد قراءة هذا الدليل:
 
 
* ماهيّة أنبوب الأصول وماذا يفعل.
 
* ماهيّة أنبوب الأصول وماذا يفعل.
 
* كيفيّة تنظيم أصول تطبيقك بشكل صحيح.
 
* كيفيّة تنظيم أصول تطبيقك بشكل صحيح.
سطر 10: سطر 8:
  
 
== ما هو أنبوب الأصول؟ ==
 
== ما هو أنبوب الأصول؟ ==
يوفّر أنبوب الأصول إطارًا لسَلسَلة وتصغير أو ضغط أصول JavaScript و CSS. كما أنه يضيف القدرة على كتابة هذه الأصول بلغات أخرى ومعالجات مسبقة مثل CoffeeScript و Sass و ERB. يسمح للأصول في تطبيقك أن تُدمج تلقائيًّا مع الأصول من جواهر أخرى.
+
يوفّر أنبوب الأصول إطارًا لسَلسَلة وتصغير أو ضغط أصول [[JavaScript]] و [[CSS]]. كما أنه يضيف القدرة على كتابة هذه الأصول بلغات أخرى ومعالجات مسبقة مثل CoffeeScript و [[Sass]] و ERB. يسمح للأصول في تطبيقك أن تُدمج تلقائيًّا مع الأصول من جواهر أخرى.
  
يُعرَّفُ استخدام خط الأصل بواسطة جوهرة sprockets-rails، ويُفعّل افتراضيًّا. يمكنك تعطيله أثناء إنشاء تطبيق جديد عبر تمرير الخيار skip-sprockets--.
+
يُعرَّفُ استخدام خط الأصل بواسطة الجوهرة [https://github.com/rails/sprockets-rails sprockets-rails]، ويُفعّل افتراضيًّا. يمكنك تعطيله أثناء إنشاء تطبيق جديد عبر تمرير الخيار <code>skip-sprockets--</code>.
  
<syntaxhighlight lang="rails">
+
<syntaxhighlight lang="shell">
 
rails new appname --skip-sprockets
 
rails new appname --skip-sprockets
 
</syntaxhighlight>
 
</syntaxhighlight>
  
يضيف Rails تلقائيًّا الجواهر coffee-rails و sass-rails و uglifier إلى Gemfile التي يستخدمها Sprockets لضغط الأصول:
+
يضيف ريلز تلقائيًّا الجواهر coffee-rails و sass-rails و uglifier إلى Gemfile التي يستخدمها Sprockets لضغط الأصول:
 
<syntaxhighlight lang="rails">
 
<syntaxhighlight lang="rails">
 
gem 'sass-rails'
 
gem 'sass-rails'
سطر 24: سطر 22:
 
gem 'coffee-rails'
 
gem 'coffee-rails'
 
</syntaxhighlight>
 
</syntaxhighlight>
استخدام الخيار skip-sprockets-- سيمنع Rails من إضافتها إلى Gemfile لذا إن أردت تفعيل أنبوب الأصول فيما بعد سيتعيّن عليك إضافة تلك الجواهر إلى ملفك Gemfile. سيؤدي إنشاء تطبيق مع الخيار skip-sprockets-- إلى إنشاء ملف config/application.rb مختلف اختلافًا طفيفًا، مع عبارة طلب إلى sprockets railtie موضوعة داخل تعليق. سيتعيّن عليك إزالة مُعامل (operator) التعليق على هذا السطر لتفعيل أنبوب الأصول لاحقًا:
+
استخدام الخيار <code>skip-sprockets--</code> سيمنع ريلز من إضافتها إلى Gemfile لذا إن أردت تفعيل أنبوب الأصول فيما بعد سيتعيّن عليك إضافة تلك الجواهر إلى ملفك Gemfile. سيؤدي إنشاء تطبيق مع الخيار <code>skip-sprockets--</code> إلى إنشاء ملف config/application.rb مختلف اختلافًا طفيفًا، مع عبارة طلب (require) إلى sprockets railtie موضوعة داخل تعليق. سيتعيّن عليك إزالة مُعامل (operator) التعليق على هذا السطر لتفعيل أنبوب الأصول لاحقًا:
 
<syntaxhighlight lang="rails">
 
<syntaxhighlight lang="rails">
 
# require "sprockets/railtie"
 
# require "sprockets/railtie"
 
</syntaxhighlight>
 
</syntaxhighlight>
لضبط توابع ضغط الأصول، اضبط خيارات الإعداد المناسبة في production.rb - config.assets.css_compressor لملفك بـ CSS و config.assets.js_compressor من أجل شفرتك JavaScript:
+
لضبط توابع ضغط الأصول، اضبط خيارات الإعداد المناسبة في production.rb - config.assets.css_compressor لملفك بـ CSS و config.assets.js_compressor من أجل شيفرتك JavaScript:
 
<syntaxhighlight lang="rails">
 
<syntaxhighlight lang="rails">
 
config.assets.css_compressor = :yui
 
config.assets.css_compressor = :yui
 
 
config.assets.js_compressor = :uglifier
 
config.assets.js_compressor = :uglifier
 
</syntaxhighlight>
 
</syntaxhighlight>
تُستخدم الجوهرة sass-rails تلقائيًا لضغط CSS إذا ضُمّنت في Gemfile ولم يُضبط أي خيار config.assets.css_compressor.
+
'''ملاحظة''': تُستخدم الجوهرة sass-rails تلقائيًا لضغط ملفات CSS إذا ضُمّنت في Gemfile ولم يُضبط أي خيار <code>[[Rails/configuring#.D8.B6.D8.A8.D8.B7 .D8.A7.D9.84.D8.A3.D8.B5.D9.88.D9.84 .28Assets.29|config.assets.css_compressor]]</code>.
  
 
=== الميزات الرئيسية ===
 
=== الميزات الرئيسية ===
 
تكمن ميزة الأنابيب الأولى في تجميع الأصول ممّا يقلّل من عدد الطلبات التي يقدمها المتصفّح لعرض صفحة الويب. عدد الطلبات التي تقدر متصفّحّات الويب على إجرائها بالتوازي محدود لذا يمكن أن يعني تخفيض عدد الطلبات سرعة تحميل أعلى لتطبيقك.
 
تكمن ميزة الأنابيب الأولى في تجميع الأصول ممّا يقلّل من عدد الطلبات التي يقدمها المتصفّح لعرض صفحة الويب. عدد الطلبات التي تقدر متصفّحّات الويب على إجرائها بالتوازي محدود لذا يمكن أن يعني تخفيض عدد الطلبات سرعة تحميل أعلى لتطبيقك.
  
يُجمّع Sprockets جميع ملفات JavaScript في ملف js. رئيسي واحد وجميع ملفّات CSS في ملف css. رئيسي واحد. يمكنك تخصيص هذه الاستراتيجية لتجميع الملفات بالطريقة التي تريدها كما سترى لاحقًا في هذا الدليل. درج Rails عند الإنتاج بصمة SHA256 في كل اسم ملف بحيث يُخزّن الملف مؤقّتًا بواسطة متصفّح الويب. يمكنك إبطال ذاكرة التخزين المؤقّت عن طريق تغيير هذه البصمة التي تحدث تلقائيًا كلما غيّرت محتويات الملف.
+
يُجمّع Sprockets جميع ملفات [[JavaScript]] في ملف <code>js.</code> رئيسي واحد وجميع ملفّات CSS في ملف <code>css.</code> رئيسي واحد. يمكنك تخصيص هذه الاستراتيجية لتجميع الملفات بالطريقة التي تريدها كما سترى لاحقًا في هذا الدليل. يدرج ريلز عند الإنتاج بصمة SHA256 في كل اسم ملف بحيث يُخزّن الملف مؤقّتًا بواسطة متصفّح الويب. يمكنك إبطال ذاكرة التخزين المؤقّت عن طريق تغيير هذه البصمة التي تحدث تلقائيًا كلما غيّرت محتويات الملف.
  
الميزة الثانية لأنبوب الأصول هي اقتضاب (minification) الأصول أو ضغطها. وذلك عن طريق إزالة المسافات البيضاء والتعليقات بالنسبة إلى ملفّات CSS. بالنسبة إلى JavaScript يمكن تطبيق عمليّات أكثر تعقيدًا. يمكنك الاختيار بين مجموعة من الخيارات المضمنّة أو تحديد خياراتك الخاصّة.
+
الميزة الثانية لأنبوب الأصول هي اقتضاب (minification) الأصول أو ضغطها. وذلك عن طريق إزالة المسافات البيضاء والتعليقات بالنسبة إلى ملفّات [[CSS]]. بالنسبة إلى [[JavaScript]] يمكن تطبيق عمليّات أكثر تعقيدًا. يمكنك الاختيار بين مجموعة من الخيارات المضمنّة أو تحديد خياراتك الخاصّة.
  
الميزة الثالثة لأنبوب الأصول هي أنه يسمح بتشفير الأصول عبر لغة ذات مستوى أعلى، مع وصول التحويل المسبق حتّى مستوى الأصول الفعليّة. تتضمّن اللغات المدعومة Sass لـ CSS و CoffeeScript لـ JavaScript  و ERB بشكل افتراضي.
+
الميزة الثالثة لأنبوب الأصول هي أنه يسمح بتشفير الأصول عبر لغة ذات مستوى أعلى، مع وصول التحويل المسبق حتّى مستوى الأصول الفعليّة. تتضمّن اللغات المدعومة [[Sass]] لـ [[CSS]] و [[CoffeeScript]] لـ [[JavaScript]]  و ERB بشكل افتراضي.
  
 
=== ما هي البصمات ولماذا يجب أن أهتم؟ ===
 
=== ما هي البصمات ولماذا يجب أن أهتم؟ ===
سطر 50: سطر 47:
 
يمكن عندما يكون اسم الملف فريدًا ومستندًا على محتواه تعيين ترويسات HTTP لتشجيع التخزين المؤقّت في كل مكان (سواء في شبكات توصيل المحتوى أو في مزودي خدمات الإنترنت أو في معدّات الشبكات أو في متصفحّات الويب) للاحتفاظ بنسخهم الخاصّة من المحتوى. عند تحديث المحتوى ستتغيّر البصمة. سيؤدي ذلك إلى مطالبة العملاء البعيدين بنسخة جديدة من المحتوى. يُعرف هذا عمومًا باسم خرق ذاكرة التخزين المؤقّت (cache busting).
 
يمكن عندما يكون اسم الملف فريدًا ومستندًا على محتواه تعيين ترويسات HTTP لتشجيع التخزين المؤقّت في كل مكان (سواء في شبكات توصيل المحتوى أو في مزودي خدمات الإنترنت أو في معدّات الشبكات أو في متصفحّات الويب) للاحتفاظ بنسخهم الخاصّة من المحتوى. عند تحديث المحتوى ستتغيّر البصمة. سيؤدي ذلك إلى مطالبة العملاء البعيدين بنسخة جديدة من المحتوى. يُعرف هذا عمومًا باسم خرق ذاكرة التخزين المؤقّت (cache busting).
  
التقنية التي يستخدمها Sprockets للبصمة هي إدخال تجزئة (hash) المحتوى في الاسم، عادةً في النهاية. خذ ملف CSS مسمّى global.css مثلًا:
+
التقنية التي يستخدمها Sprockets للبصمة هي إدخال قيمة hash للمحتوى في الاسم، عادةً في النهاية. خذ ملف [[CSS]] مسمّى global.css مثلًا:
<syntaxhighlight lang="rails">
+
<syntaxhighlight lang="text">
 
global-908e25f4bf641868d8683022a5b62f54.css
 
global-908e25f4bf641868d8683022a5b62f54.css
 
</syntaxhighlight>
 
</syntaxhighlight>
هذه هي الاستراتيجية التي يعتمدها أنبوب الأصول Rails.
+
هذه هي الاستراتيجية التي يعتمدها أنبوب الأصول ريلز.
  
كانت إستراتيجية Rails القديمة هي إلحاق سلسلة استعلام نصيّة (query string) تستند إلى التاريخ بكل أصل مرتبط بمساعد مضمّن. تبدو الشفرة المُنشئَة كما يلي في المصدر:
+
كانت استراتيجية ريلز القديمة هي إلحاق سلسلة استعلام نصيّة (query string) تستند إلى التاريخ بكل أصل مرتبط بمساعد مضمّن. تبدو الشفرة المُنشئَة كما يلي في المصدر:
<syntaxhighlight lang="rails">
+
<syntaxhighlight lang="text">
 
/stylesheets/global.css?1309495796
 
/stylesheets/global.css?1309495796
 
</syntaxhighlight>
 
</syntaxhighlight>
 
تملك استراتيجية سلسلة الاستعلام عدّة عيوب:
 
تملك استراتيجية سلسلة الاستعلام عدّة عيوب:
# لن تُخزّن كل ذاكرات التخزين المؤقّت المحتوى بشكل يعتمد عليه حين يختلف اسم الملف فقط بمعاملات الإستعلام
+
# '''لن تُخزّن كل ذاكرات التخزين المؤقّت المحتوى بشكل يعتمد عليه حين يختلف اسم الملف فقط بمعاملات الاستعلام.''' يوصي [http://www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/ Steve Souders] "... تجنّب سلاسل الاستعلام في الموارد القابلة للتخزين المؤقّت". وجد أنّه في هذه الحالة لن يُخزّنَ 5-20٪ من الطلبات مؤقّتًا. سلاسل الاستعلام النصيّة على وجه الخصوص لا تعمل على الإطلاق مع بعض شبكات توصيل المحتوى لإبطال ذاكرة التخزين المؤقّت.
## يوصي Steve Souders "... تجنّب سلاسل الاستعلام عن الموارد القابلة للتخزين المؤقّت". وجد أنّه في هذه الحالة لن يُخزّنَ 5-20٪ من الطلبات مؤقّتًا. سلاسل الاستعلام النصيّة على وجه الخصوص لا تعمل على الإطلاق مع بعض شبكات توصيل المحتوى لإبطال ذاكرة التخزين المؤقّت.
+
# '''يمكن أن يتغيّر اسم الملف بين العقد في البيئات متعددة الخوادم.''' تستند سلسلة الاستعلام الافتراضية في الإصدار ‎2.x من ريلز على وقت تعديل الملفّات. عندما تُنشَر (deployed) الأصول إلى مجموعة، لا يوجد ضمان بأن الطوابع الزمنيّة ستكون نفسها مما يؤدي إلى استخدام قيم مختلفة بناءً على الخادم الذي يعالج الطلب.
# يمكن أن يتغيّر اسم الملف بين العقد في البيئات متعددة الخوادم.
+
# '''إبطال ذاكرات التخزين المؤقّت أكثر من اللازم.''' عندما تُطلق الأصول الثابتة مع كل إصدار جديد من التعليمات البرمجية، يتغيّر mtime (وقت التعديل الأخير) لجميع هذه الملفّات، مما يجبر كل العملاء البعيدين على جلبهم مرة أخرى، حتى عندما لا يتغيّر محتوى تلك الأصول.
## تستند سلسلة الاستعلام الافتراضية في Rails 2.x على وقت تعديل الملفّات. عندما تُطلَق (deployed) الأصول إلى مجموعة، لا يوجد ضمان بأن الطوابع الزمنيّة ستكون نفسها مما يؤدي إلى استخدام قيم مختلفة بناءً على الخادم الذي يعالج الطلب.
 
# إبطال ذاكرات التخزين المؤقّت أكثر من اللازم
 
## عندما تُطلق الأصول الثابتة مع كل إصدار جديد من التعليمات البرمجية،  يتغيّر mtime (وقت التعديل الأخير) لجميع هذه الملفّات، مما يجبر كل العملاء البعيدين على جلبهم مرة أخرى، حتى عندما لا يتغيّر محتوى تلك الأصول.
 
 
تعمل البصمات على إصلاح هذه المشكلات عن طريق تجنب سلاسل الاستعلام وضمان توافق أسماء الملفّات استنادًا إلى محتواها.
 
تعمل البصمات على إصلاح هذه المشكلات عن طريق تجنب سلاسل الاستعلام وضمان توافق أسماء الملفّات استنادًا إلى محتواها.
  
تُفعّل البصمات بشكل افتراضي لكل من بيئات التطوير والإنتاج. يمكنك تفعيلها أو تعطيلها بإعداداتك من خلال الخيار config.assets.digest.
+
تُفعّل البصمات بشكل افتراضي لكل من بيئات التطوير والإنتاج. يمكنك تفعيلها أو تعطيلها بإعداداتك من خلال الخيار <code>[[Rails/configuring#.D8.B6.D8.A8.D8.B7 .D8.A7.D9.84.D8.A3.D8.B5.D9.88.D9.84 .28Assets.29|config.assets.digest]]</code>.
  
 
قراءة المزيد:
 
قراءة المزيد:
* تحسين التخزين المؤقّت
+
* [https://developers.google.com/speed/docs/insights/LeverageBrowserCaching تحسين التخزين المؤقّت]
* Reving Filenames: لا تستخدم سلاسل الإستعلام
+
* [http://www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/ Reving Filenames: لا تستخدم سلاسل الاستعلام]
  
 
== كيفيّة استخدام أنبوب الأصول ==
 
== كيفيّة استخدام أنبوب الأصول ==
في الإصدارات السابقة من Rails، كانت جميع الأصول موجودة في مجلّدات فرعية public مثل images و javascripts و  stylesheets. أصبح الآن الموقع المفضّل لهذه الأصول هو المجلّد app/assets مع أنبوب الأصول. تقدّم الملفّات في هذا المجلّد بواسطة برمجيّات Sprockets الوسيطة.
+
في الإصدارات السابقة من ريلز، كانت جميع الأصول موجودة في مجلّدات فرعية public مثل images و javascripts و  stylesheets. أصبح الآن الموقع المفضّل لهذه الأصول هو المجلّد app/assets مع أنبوب الأصول. تقدّم الملفّات في هذا المجلّد بواسطة برمجيّات Sprockets الوسيطة.
  
لا يزال من الممكن وضع الأصول في التسلسل الهرمي public. ستُقدّم أي أصول تحت public كملفّات ثابتة من طرف التطبيق أو خادم الويب عند ضبط config.public_file_server.enabled على true. عليك استخدام app/assets للملفّات التي يجب أن تخضع لبعض المعالجة المسبقة قبل تقديمها.
+
لا يزال من الممكن وضع الأصول في التسلسل الهرمي public. ستُقدّم أي أصول تحت public كملفّات ثابتة من طرف التطبيق أو خادم الويب عند ضبط <code>[[Rails/configuring#.D8.A5.D8.B9.D8.AF.D8.A7.D8.AF.D8.A7.D8.AA .D8.B1.D9.8A.D9.84.D8.B2 .D8.A7.D9.84.D8.B9.D8.A7.D9.85.D8.A9|config.public_file_server.enabled]]</code> إلى القيمة <code>true</code>. عليك استخدام app/assets للملفّات التي يجب أن تخضع لبعض المعالجة المسبقة قبل تقديمها.
  
يُحوّل Rails هذه الملفّات إلى public/assets بشكل افتراضي عند الإنتاج. تُقدّم بعد ذلك النسخ المُحوّلة مسبقًا كأصول ثابتة من طرف خادم الويب. لا تُقدّم الملفّات في app/assets أبدًا مباشرةً في الإنتاج.
+
يُحوّل ريلز هذه الملفّات إلى public/assets بشكل افتراضي عند الإنتاج. تُقدّم بعد ذلك النسخ المُحوّلة مسبقًا كأصول ثابتة من طرف خادم الويب. لا تُقدّم الملفّات في app/assets أبدًا مباشرةً في الإنتاج.
  
=== الأصول الخاصّة بوحدة تحكّم (Controller Specific Assets) ===
+
=== الأصول الخاصة بوحدة تحكم (Controller Specific Assets) ===
عند توليد سقالة أو وحدة تحكّم، يُولّد Rails أيضا ملف JavaScript (أو ملف CoffeeScript إذا وُجدت الجوهرة coffee-rails في Gemfile) وملف أوراق الأنماط الانسيابيّة (أو ملف SCSS إن وُجد sass-rails في Gemfile) لوحدة التحكّم تلك. علاوة على ذلك، ينشئ Rails  ملف scaffolds.css عند إنشاء سقالة (أو scaffolds.scss إن وُجد sass-rails في Gemfile).
+
عند توليد سقالة (scaffold) أو وحدة تحكّم، يُولّد ريلز أيضا ملف [[JavaScript]] (أو ملف CoffeeScript إذا وُجدت الجوهرة coffee-rails في Gemfile) وملف أوراق الأنماط الانسيابيّة (أو ملف SCSS إن وُجد sass-rails في Gemfile) لوحدة التحكّم تلك. علاوة على ذلك، ينشئ ريلز الملف scaffolds.css عند إنشاء سقالة (أو scaffolds.scss إن وُجد sass-rails في Gemfile).
  
إن أنشأت مثلًا ProjectsController، سيضيف Rails أيضًا ملفًّا جديدًا في app/assets/javascripts/projects.coffee وآخر في app/assets/stylesheets/projects.scss. ستكون هذه الملفّات جاهزة للاستخدام من طرف تطبيقك إفتراضيًّا على الفور باستخدام الأمر require_tree. انظر للتعليمات والملفّات النصّيّة التي تحتوي على قائمة الملفات التي ستجرى عليها عملية ما (maniftest) لمزيد من التفاصيل حول require_tree.
+
إن أنشأت مثلًا ProjectsController، سيضيف ريلز أيضًا ملفًّا جديدًا في app/assets/javascripts/projects.coffee وآخر في app/assets/stylesheets/projects.scss. ستكون هذه الملفّات جاهزة للاستخدام من طرف تطبيقك إفتراضيًّا على الفور باستخدام الأمر require_tree. انظر [https://guides.rubyonrails.org/asset_pipeline.html#manifest-files-and-directives للتعليمات والملفّات النصّيّة التي تحتوي على قائمة الملفات التي ستجرى عليها عملية ما] (maniftest) لمزيد من التفاصيل حول <code>require_tree</code>.
  
يمكنك أيضًا اختيار تضمين أوراق أنماط خاصّة بوحدة التحكّم (controller specific stylesheets) وملفّات JavaScript فقط في وحدات تحكّمهم باستخدام ما يلي:
+
يمكنك أيضًا اختيار تضمين أوراق أنماط خاصّة بوحدة التحكّم (controller specific stylesheets) وملفّات [[JavaScript]] فقط في وحدات تحكّمهم باستخدام ما يلي:
<syntaxhighlight lang="rails">
+
<syntaxhighlight lang="html">
 
<%= javascript_include_tag params[:controller] %> or <%= stylesheet_link_tag
 
<%= javascript_include_tag params[:controller] %> or <%= stylesheet_link_tag
 
 
params[:controller] %>
 
params[:controller] %>
 
</syntaxhighlight>
 
</syntaxhighlight>
تأكد لو فعلت هذا من أنك لا تستخدم التوجيه require_tree لأن ذلك سيؤدي لتضمين أصولك أكثر من مرة.
+
تأكد لو فعلت هذا من أنك لا تستخدم التوجيه <code>require_tree</code> لأن ذلك سيؤدي لتضمين أصولك أكثر من مرة.
  
عند استخدام تصريف الأصول المسبق (asset precompilation) ستحتاج للتأكّد من أن أصول وحدة تحكمّك ستُحوّل مسبقًا عند تحميلها بكل صفحة على حدة. لن تُحوّل الملفّات coffee. و scss. مسبقًا من تلقاء نفسها افتراضيًّا. راجع تحميل الأصول المسبق للحصول على مزيد من المعلومات حول كيفيّة عمل التحويل البرمجي المسبق.
+
'''تحذير''': عند استخدام تصريف الأصول المسبق (asset precompilation) ستحتاج للتأكّد من أن أصول وحدة تحكمّك ستُحوّل مسبقًا عند تحميلها بكل صفحة على حدة. لن تُحوّل الملفّات <code>coffee.</code> و <code>scss.</code> مسبقًا من تلقاء نفسها افتراضيًّا. راجع تحميل الأصول المسبق للحصول على مزيد من المعلومات حول كيفيّة عمل التحويل البرمجي المسبق.
  
يجب أن يكون لديك تنفيذ (runtime) مدعوم من ExecJS من أجل استخدام CoffeeScript. إن كنت تستخدم macOS أو  Windows، سيُثبّت تنفيذ JavaScript في نظام تشغيلك. راجع توثيق ExecJS لمعرفة كل تنفيذات JavaScript المدعومة.
+
'''ملاحظة''': يجب أن يكون لديك تنفيذ (runtime) مدعوم من ExecJS من أجل استخدام CoffeeScript. إن كنت تستخدم macOS أو Windows، سيُثبّت تنفيذ JavaScript في نظام تشغيلك. راجع توثيق [https://github.com/rails/execjs#readme ExecJS] لمعرفة كل تنفيذات [[JavaScript]] المدعومة.
  
 
يمكنك أيضًا تعطيل إنشاء ملفّات أصول خاصة بوحدة تحكّم عن طريق إضافة التالي إلى config/application.rb:
 
يمكنك أيضًا تعطيل إنشاء ملفّات أصول خاصة بوحدة تحكّم عن طريق إضافة التالي إلى config/application.rb:
 
<syntaxhighlight lang="rails">
 
<syntaxhighlight lang="rails">
 
config.generators do |g|
 
config.generators do |g|
 
+
  g.assets false
g.assets false
+
end
 
 
 end
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 
=== تنظيم الأصول ===
 
=== تنظيم الأصول ===
 
يمكن وضع أصول أنبوب داخل تطبيق في أحد المواقع الثلاثة: app/assets أو lib/assets أو vendor/assets.
 
يمكن وضع أصول أنبوب داخل تطبيق في أحد المواقع الثلاثة: app/assets أو lib/assets أو vendor/assets.
* app/assets مخصّصة للأصول التي يملكها التطبيق مثل الصور المخصّصة أو ملفّات JavaScript أو أوراق الأنماط.
+
* app/assets مخصّص للأصول التي يملكها التطبيق مثل الصور المخصّصة أو ملفّات [[JavaScript]] أو أوراق الأنماط.
 
* lib/assets مخصّص لشفرات مكتباتك التي لا تتناسب حقًا مع نطاق التطبيق أو تلك المكتبات المشتركة عبر التطبيقات.
 
* lib/assets مخصّص لشفرات مكتباتك التي لا تتناسب حقًا مع نطاق التطبيق أو تلك المكتبات المشتركة عبر التطبيقات.
* vendor/assets مخصّص للأصول التي تملكها كيانات خارجية مثل شفرة لإضافات JavaScript وأطر عمل CSS. ضع بالحسبان وجوب إعادة كتابة شفرات الطرف الثالث ذات المراجع إلى ملفّات أخرى (الصور، أوراق الأنماط، إلخ) المعالجة من طرف أنبوب الأصول كي تستخدم المساعدين مثل asset_path.
+
* vendor/assets مخصّص للأصول التي تملكها كيانات خارجية مثل شفرة لإضافات [[JavaScript]] وأطر عمل [[CSS]]. ضع بالحسبان وجوب إعادة كتابة شفرات الطرف الثالث ذات المراجع إلى ملفّات أخرى (الصور، أوراق الأنماط، إلخ) المعالجة من طرف أنبوب الأصول كي تستخدم المساعدين مثل <code>asset_path</code>.
إن كنت تُحدّث من Rails 3، رجاءً راع أن الأصول تحت lib/assets أو vendor/assets متوفرة للتضمين عبر بيانات التطبيق لكنها لم تعد جزءًا من مصفوفة التصريف المسبق precompile()‎. انظر مقال تحويل الأصول المسبق لمزيد من الإرشادات.
+
'''تحذير''': إن كنت تُحدّث من ريلز 3، رجاءً راع أن الأصول تحت lib/assets أو vendor/assets متوفرة للتضمين عبر بيانات التطبيق لكنها لم تعد جزءًا من مصفوفة التصريف المسبق <code>precompile()</code>‎. انظر قسم [[Rails/asset pipeline#.D8.AA.D8.B5.D8.B1.D9.8A.D9.81 .D8.A7.D9.84.D8.A3.D8.B5.D9.88.D9.84 .D8.A7.D9.84.D9.85.D9.8F.D8.B3.D8.A8.D9.82 .28Precompiling Assets.29|تصريف الأصول المسبق]] لمزيد من الإرشادات.
  
=== مسارات البحث ===
+
==== مسارات البحث ====
 
عند الرجوع إلى ملف من بيان أو مُساعد، يبحث Sprockets عنه في مواقع الأصول الافتراضية الثلاثة.
 
عند الرجوع إلى ملف من بيان أو مُساعد، يبحث Sprockets عنه في مواقع الأصول الافتراضية الثلاثة.
  
المواقع الافتراضية هي: مجلّدات images و javascripts و stylesheets تحت مجلّد app/assets، ولكن هذه المجلّدات الفرعية ليست حالة فريدة - سيُبحث في أي مسار تحت */assets.
+
المواقع الافتراضية هي: المجلّدات images و javascripts و stylesheets تحت المجلّد app/assets، ولكن هذه المجلّدات الفرعية ليست حالة فريدة - سيُبحث في أي مسار تحت */assets.
  
 
هذه الملفّات مثلًا:
 
هذه الملفّات مثلًا:
<syntaxhighlight lang="rails">
+
<syntaxhighlight lang="text">
|app/assets/javascripts/home.js
+
app/assets/javascripts/home.js
 
 
 
lib/assets/javascripts/moovinator.js
 
lib/assets/javascripts/moovinator.js
 
 
vendor/assets/javascripts/slider.js
 
vendor/assets/javascripts/slider.js
 
 
vendor/assets/somepackage/phonebox.js
 
vendor/assets/somepackage/phonebox.js
 
</syntaxhighlight>
 
</syntaxhighlight>
 
سيُرجع إليها في بيان بهذا الشكل:
 
سيُرجع إليها في بيان بهذا الشكل:
<syntaxhighlight lang="rails">
+
<syntaxhighlight lang="text">
|//= require home
+
//= require home
 
 
 
//= require moovinator
 
//= require moovinator
 
 
//= require slider
 
//= require slider
 
 
//= require phonebox
 
//= require phonebox
 
</syntaxhighlight>
 
</syntaxhighlight>
 
يمكن الوصول إلى الأصول الموجودة داخل المجلّدات الفرعيّة أيضًا.
 
يمكن الوصول إلى الأصول الموجودة داخل المجلّدات الفرعيّة أيضًا.
<syntaxhighlight lang="rails">
+
<syntaxhighlight lang="text">
|app/assets/javascripts/sub/something.js
+
app/assets/javascripts/sub/something.js
 
</syntaxhighlight>
 
</syntaxhighlight>
 
يشار إليها على النحو التالي:
 
يشار إليها على النحو التالي:
<syntaxhighlight lang="rails">
+
<syntaxhighlight lang="text">
 
//= require sub/something
 
//= require sub/something
 
</syntaxhighlight>
 
</syntaxhighlight>
يمكنك رؤية مسار البحث عبر فحص Rails.application.config.assets.paths في وحدة تحكّم Rails.
+
يمكنك رؤية مسار البحث عبر فحص <code>Rails.application.config.assets.paths</code> في وحدة تحكّم ريلز.
  
عدا مسارات */assets القياسية يمكن إضافة مسارات إضافيّة (مؤهلّة بالكامل - fully qualified) إلى خط الأنابيب في config/initializers/assets.rb. مثلًا:
+
عدا مسارات */assets القياسية يمكن إضافة مسارات إضافيّة (مؤهلّة بالكامل [fully qualified]) إلى خط الأنابيب في config/initializers/assets.rb. مثلًا:
 
<syntaxhighlight lang="rails">
 
<syntaxhighlight lang="rails">
 
Rails.application.config.assets.paths << Rails.root.join("lib", "videoplayer", "flash")
 
Rails.application.config.assets.paths << Rails.root.join("lib", "videoplayer", "flash")
سطر 156: سطر 141:
 
تُجتاز المسارات بالترتيب الذي تظهر به في مسار البحث. هذا يعني افتراضيا أنّ الأسبقيّة للملفّات في app/assets وأنّها ستحجب المسارات المقابلة في lib و vendor.
 
تُجتاز المسارات بالترتيب الذي تظهر به في مسار البحث. هذا يعني افتراضيا أنّ الأسبقيّة للملفّات في app/assets وأنّها ستحجب المسارات المقابلة في lib و vendor.
  
من المهم ملاحظة وجوب إضافة الملفّات التي تريد الإشارة إليها خارج الملفّ النصّي الذي يحتوي على قائمة الملفات التي ستجرى عليها عملية ما (manifest) إلى المصفوفة precompile وإلّا لن تكون متوفّرة في بيئة الإنتاج.
+
من المهم ملاحظة وجوب إضافة الملفّات التي تريد الإشارة إليها خارج الملفّ النصّي الذي يحتوي على قائمة الملفات التي ستجرى عليها عملية ما (manifest) إلى المصفوفة <code>precompile</code> وإلّا لن تكون متوفّرة في بيئة الإنتاج.
  
==== استخدام ملفّات الفهرس (Using Index Files) ====
+
==== استخدام ملفات الفهرس ====
يستخدم Sprockets ملفّات مسمّات index (مع الملحقات ذات الصلة) لغرض خاص.
+
يستخدم Sprockets ملفّات تدعى <code>index</code> (مع الملحقات ذات الصلة) لغرض خاص.
  
إن كان لديك مكتبة jQuery تحتوي على العديد من الوحدات النمطية والتي تُخزّن في lib/assets/javascripts/library_name، يقوم الملف lib/assets/javascripts/library_name/index.js مقام الملفّ النصّي الذي يحتوي على قائمة الملفات التي ستجرى عليها عملية ما (maniftest) لجميع الملفّات الموجودة في هذه المكتبة. يمكن أن يتضمن هذا الملف قائمة بجميع الملفّات المطلوبة بالترتيب أو توجيهًا بسيطًا require_tree.
+
إن كان لديك مكتبة [[jQuery]] تحتوي على العديد من الوحدات النمطية والتي تُخزّن في lib/assets/javascripts/library_name، يقوم الملف lib/assets/javascripts/library_name/index.js مقام الملفّ النصّي الذي يحتوي على قائمة الملفات التي ستجرى عليها عملية ما (maniftest) لجميع الملفّات الموجودة في هذه المكتبة. يمكن أن يتضمن هذا الملف قائمة بجميع الملفّات المطلوبة بالترتيب أو توجيهًا بسيطًا <code>require_tree</code>.
  
 
يمكن الوصول للمكتبة ككل في بيان التطبيق بهذا الشكل:
 
يمكن الوصول للمكتبة ككل في بيان التطبيق بهذا الشكل:
<syntaxhighlight lang="rails">
+
<syntaxhighlight lang="text">
 
//= require library_name
 
//= require library_name
 
</syntaxhighlight>
 
</syntaxhighlight>
سطر 170: سطر 155:
  
 
=== روابط الترميز إلى الأصول ===
 
=== روابط الترميز إلى الأصول ===
لا يضيف Sprockets أي توابع جديدة للوصول إلى أصولك - ما زلت تستخدم javascript_include_tag و stylesheet_link_tag المألوفتين:
+
لا يضيف Sprockets أي توابع جديدة للوصول إلى أصولك - ما زلت تستخدم <code>javascript_include_tag</code> و <code>stylesheet_link_tag</code> المألوفتين:
 
<syntaxhighlight lang="rails">
 
<syntaxhighlight lang="rails">
 
<%= stylesheet_link_tag "application", media: "all" %>
 
<%= stylesheet_link_tag "application", media: "all" %>
 
 
<%= javascript_include_tag "application" %>
 
<%= javascript_include_tag "application" %>
 
</syntaxhighlight>
 
</syntaxhighlight>
في حالة استخدام الجوهرة turbolinks المُضمّنة افتراضيًا في Rails، ضمّن الخيار 'data-turbolinks-track' الذي يتسبب في تحقّق turbolinks من تحديث الأصل، وفي تلك الحالة يحمّله بالصفحة:
+
في حالة استخدام الجوهرة turbolinks المُضمّنة افتراضيًا في ريلز، ضمّن الخيار 'data-turbolinks-track' الذي يتسبب في تحقّق turbolinks من تحديث الأصل، وفي تلك الحالة يحمّله بالصفحة:
<syntaxhighlight lang="rails">
+
<syntaxhighlight lang="html">
 
<%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => "reload" %>
 
<%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => "reload" %>
 
 
<%= javascript_include_tag "application", "data-turbolinks-track" => "reload" %>
 
<%= javascript_include_tag "application", "data-turbolinks-track" => "reload" %>
 
</syntaxhighlight>
 
</syntaxhighlight>
 
في الواجهات (views) العاديّة، يمكنك الوصول للصور في مجلّد app/assets/images بهذا الشكل:
 
في الواجهات (views) العاديّة، يمكنك الوصول للصور في مجلّد app/assets/images بهذا الشكل:
<syntaxhighlight lang="rails">
+
<syntaxhighlight lang="html">
 
<%= image_tag "rails.png" %>
 
<%= image_tag "rails.png" %>
 
</syntaxhighlight>
 
</syntaxhighlight>
 
يُقدّم هذا الملف من طرف Sprockets بشرط أن يُفعّل الأنبوب داخل تطبيقك (و ولا يكون معطّلًا في سياق البيئة الحالي). إن وُجد الملف في public/assets/rails.png، سيقدّمه خادم الويب.
 
يُقدّم هذا الملف من طرف Sprockets بشرط أن يُفعّل الأنبوب داخل تطبيقك (و ولا يكون معطّلًا في سياق البيئة الحالي). إن وُجد الملف في public/assets/rails.png، سيقدّمه خادم الويب.
  
يُتعامل مع طلب ملف مع تجزئة SHA256 مثل public/assets/rails-f90d8a84c707a8dc923fca1ca1895ae8ed0a09237f6992015fef1e11be77c023.png بنفس الطريقة. كيفيّة توليد هذه التجزئات مُغطّى في قسم الإنتاج لاحقًا في هذا الدليل.
+
يُتعامل مع طلب ملف مع تجزئة SHA256 مثل public/assets/rails-f90d8a84c707a8dc923fca1ca1895ae8ed0a09237f6992015fef1e11be77c023.png بنفس الطريقة. كيفيّة توليد هذه التجزئات مُغطّى في [[Rails/asset pipeline#.D9.81.D9.8A .D8.A7.D9.84.D8.A5.D9.86.D8.AA.D8.A7.D8.AC|قسم الإنتاج]] لاحقًا في هذا الدليل.
  
سينظر Sprockets أيضًا عبر المسارات المحدّدة في config.assets.paths والتي تتضمّن مسارات التطبيق القياسية وأي مسارات تضيفها محرّكات Rails.
+
سينظر Sprockets أيضًا عبر المسارات المحدّدة في config.assets.paths والتي تتضمّن مسارات التطبيق القياسية وأي مسارات تضيفها محرّكات ريلز.
  
 
يمكن أيضًا تنظيم الصور في مجلّدات فرعية إن لزم الأمر ومن ثم الوصول إليها عبر تحديد اسم المجلّد في الوسم (tag):
 
يمكن أيضًا تنظيم الصور في مجلّدات فرعية إن لزم الأمر ومن ثم الوصول إليها عبر تحديد اسم المجلّد في الوسم (tag):
سطر 196: سطر 179:
 
<%= image_tag "icons/rails.png" %>
 
<%= image_tag "icons/rails.png" %>
 
</syntaxhighlight>
 
</syntaxhighlight>
إذا كنت تُصرّف أصولك مسبقًا أي precompiling (انظر في قسم الإنتاج أدناه) سيرفع الربط بأصل غير موجود استثناءً في صفحة الاستدعاء. بما في ذلك الربط بسلسلة نصيّة فارغة. لهذا السبب كن حذراً عند استخدام image_tag والمساعدين الآخرين مع البيانات التي يوفّرها المستخدم.
+
'''تحذير''': إذا كنت [[Rails/asset pipeline#.D8.AA.D8.B5.D8.B1.D9.8A.D9.81 .D8.A7.D9.84.D8.A3.D8.B5.D9.88.D9.84 .D8.A7.D9.84.D9.85.D9.8F.D8.B3.D8.A8.D9.82 .28Precompiling Assets.29|تُصرّف أصولك مسبقًا]] (أي precompiling، انظر في قسم [[Rails/asset pipeline#.D9.81.D9.8A .D8.A7.D9.84.D8.A5.D9.86.D8.AA.D8.A7.D8.AC|الإنتاج]] أدناه)، فسيرمي الربط بأصل غير موجود استثناءً في صفحة الاستدعاء. بما في ذلك الربط بسلسلة نصيّة فارغة. لهذا السبب كن حذرًا عند استخدام <code>image_tag</code> والمساعدين الآخرين مع البيانات التي يوفّرها المستخدم.
  
 
==== CSS و ERB ====
 
==== CSS و ERB ====
يُقيّم أنبوب الأصول تلقائيًا ERB. ويعني هذا أنك إن أضفت ملحق erb (أي erb extension) إلى أصل CSS (على سبيل المثال application.css.erb)، ستكون المساعِدات مثل asset_path متاحة في قواعد CSS:
+
يُقيّم أنبوب الأصول تلقائيًا ERB. ويعني هذا أنك إن أضفت ملحق erb (أي erb extension) إلى أصل [[CSS]] (على سبيل المثال application.css.erb)، ستكون المساعِدات مثل <code>asset_path</code> متاحة في قواعد [[CSS]]:
<syntaxhighlight lang="rails">
+
<syntaxhighlight lang="css">
 
.class { background-image: url(<%= asset_path 'image.png' %>) }
 
.class { background-image: url(<%= asset_path 'image.png' %>) }
 
</syntaxhighlight>
 
</syntaxhighlight>
سطر 206: سطر 189:
  
 
إذا كنت تريد استخدام رابط بيانات URI - وهي طريقة لتضمين (embedding) بيانات الصورة مباشرةً في ملف CSS - يمكنك استخدام المساعد asset_data_uri.
 
إذا كنت تريد استخدام رابط بيانات URI - وهي طريقة لتضمين (embedding) بيانات الصورة مباشرةً في ملف CSS - يمكنك استخدام المساعد asset_data_uri.
<syntaxhighlight lang="rails">
+
<syntaxhighlight lang="css">
 
#logo { background: url(<%= asset_data_uri 'logo.png' %>) }
 
#logo { background: url(<%= asset_data_uri 'logo.png' %>) }
 
</syntaxhighlight>
 
</syntaxhighlight>
يُدرج هذا URI بيانات منسقة بشكل صحيح في مصدر CSS.
+
يُدرج هذا URI بيانات منسقة بشكل صحيح في مصدر [[CSS]].
  
لاحظ أن علامة الإغلاق لا يمكن أن تكون بالشكل -%>.
+
لاحظ أن علامة الإغلاق لا يمكن أن تكون بالشكل ‎<code>-%>‎</code>.
  
 
==== CSS و Sass ====
 
==== CSS و Sass ====
عند استخدام أنبوب الأصول، يجب إعادة كتابة المسارات إلى الأصول ويوفّر sass-rails المُساعدين url- و path- ( يكتبان بالشَرطة في Sass والشَرطة السفليّة في Ruby) لأصناف الأصول التالية: الصورة والخط والفيديو والصوت وجافا سكربت وأوراق الأنماط الإنسيابيّة.
+
عند استخدام أنبوب الأصول، يجب إعادة كتابة المسارات إلى الأصول ويوفّر sass-rails المُساعدين url- و path- ( يكتبان بالشَرطة في Sass والشَرطة السفليّة في [[Ruby|روبي]]) لأصناف الأصول التالية: الصورة والخط والفيديو والصوت وجافاسكربت وأوراق الأنماط الإنسيابيّة.
* image-url("rails.png")‎ يرد url(/assets/rails.png)‎
+
* <code>image-url("rails.png")</code>يعيد <code>url(/assets/rails.png)‎</code>
* image-path("rails.png")‎ يرد "/assets/rails.png"
+
* <code>image-path("rails.png")‎</code> يعيد <code>"/assets/rails.png"</code>
 
يمكن أيضًا استخدام الشكل الأكثر شيوعًا:
 
يمكن أيضًا استخدام الشكل الأكثر شيوعًا:
* asset-url("rails.png")‎ يرد url(/assets/rails.png)‎
+
* <code>asset-url("rails.png")‎</code> يعيد <code>url(/assets/rails.png)‎</code>
* asset-path("rails.png")‎  يرد "/assets/rails.png"
+
* <code>asset-path("rails.png")‎</code>  يعيد <code>"/assets/rails.png"</code>
  
 
==== JavaScript / CoffeeScript و ERB ====
 
==== JavaScript / CoffeeScript و ERB ====
يمكنك استخدام المساعد asset_path في شفرتك JavaScript إن أضفت امتداد erb إلى أصل JavaScript جاعلًا منه application.js.erb مثلًا:
+
يمكنك استخدام المساعد <code>asset_path</code> في شفرتك [[JavaScript]] إن أضفت امتداد erb إلى أصل [[JavaScript]] جاعلًا منه application.js.erb مثلًا:
<syntaxhighlight lang="rails">
+
<syntaxhighlight lang="javascript">
 
$('#logo').attr({ src: "<%= asset_path('logo.png') %>" });
 
$('#logo').attr({ src: "<%= asset_path('logo.png') %>" });
 
</syntaxhighlight>
 
</syntaxhighlight>
 
يكتب هذا  المسار إلى الأصل المعيّن المشار إليه.
 
يكتب هذا  المسار إلى الأصل المعيّن المشار إليه.
  
تستطيع بالمثل استخدام المساعد asset_path في ملفّات CoffeeScript ذات امتداد erb (مثلًا application.coffee.erb):
+
تستطيع بالمثل استخدام المساعد <code>asset_path</code> في ملفّات [[CoffeeScript]] ذات امتداد erb (مثلًا application.coffee.erb):
<syntaxhighlight lang="rails">
+
<syntaxhighlight lang="coffeescript">
 
$('#logo').attr src: "<%= asset_path('logo.png') %>"
 
$('#logo').attr src: "<%= asset_path('logo.png') %>"
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 
=== ملفّات manifest والتوجيهات (Manifest Files and Directives) ===
 
=== ملفّات manifest والتوجيهات (Manifest Files and Directives) ===
يستخدم Sprockets ملفّات manifest لتحديد الأصول المراد تضمينها وعرضها. تحتوي ملفّات manifest على توجيهات - وهي تعليمات تخبر Sprockets بالملفّات التي يجب أن يتطلّبها لإنشاء ملف CSS أو JavaScript واحد. باستخدام هذه التوجيهات يُحمّل Sprockets الملفّات المحدّدة، ويعالجها إن لزم، ويجمعها في ملف واحد واحد ثم يضغطها (بناءً على قيمة Rails.application.config.assets.js_compressor). يمكن تقليل وقت تحميل الصفحات بشكل كبير بتقديم ملف واحد بدلاً من العديد لأن المتصفّح يرسل عددًا أقل من الطلبات. يُصغّر الضغط أيضًا من حجم الملف، ممّا يتيح للمتصفّح تنزيلها بشكل أسرع.
+
يستخدم Sprockets ملفّات manifest لتحديد الأصول المراد تضمينها وعرضها. تحتوي ملفّات manifest على توجيهات - وهي تعليمات تخبر Sprockets بالملفّات التي يجب أن يتطلّبها لإنشاء ملف [[CSS]] أو [[JavaScript]] واحد. باستخدام هذه التوجيهات يُحمّل Sprockets الملفّات المحدّدة، ويعالجها إن لزم، ويجمعها في ملف واحد واحد ثم يضغطها (بناءً على قيمة <code>Rails.application.config.assets.js_compressor</code>). يمكن تقليل وقت تحميل الصفحات بشكل كبير بتقديم ملف واحد بدلاً من العديد لأن المتصفّح يرسل عددًا أقل من الطلبات. يُصغّر الضغط أيضًا من حجم الملف، ممّا يتيح للمتصفّح تنزيلها بشكل أسرع.
  
على سبيل المثال، يتضمن تطبيق Rails جديد ملفًا افتراضيًا app/assets/javascripts/application.js يحتوي على السطور التالية:
+
على سبيل المثال، يتضمن تطبيق ريلز جديد ملفًا افتراضيًا app/assets/javascripts/application.js يحتوي على السطور التالية:
<syntaxhighlight lang="rails">
+
<syntaxhighlight lang="text">
 
// ...
 
// ...
 
 
//= require rails-ujs
 
//= require rails-ujs
 
 
//= require turbolinks
 
//= require turbolinks
 
 
//= require_tree .
 
//= require_tree .
 
</syntaxhighlight>
 
</syntaxhighlight>
تبدأ أوامر Sprockets بـ //= في ملفّات JavaScript. في الحالة المذكورة أعلاه، يستخدم الملف التوجيهات require و require_tree. يُستخدم التوجيه require لإخبار Sprockets بالملفّات التي ترغب في طلبها. أنت تطلب هنا الملفّات rails-ujs.js و turbolinks.js المتاحة في مكان ما في مسار البحث لـ Sprockets. لا تحتاج إلى توفير الامتدادات بشكل صريح. يفترض Sprockets أنك تطلب ملف js. عندما تفعل ذلك داخل ملف js.
+
تبدأ أوامر Sprockets بـ //=في ملفّات [[JavaScript]]. في الحالة المذكورة أعلاه، يستخدم الملف التوجيهات <code>require</code> و <code>require_tree</code>. يُستخدم التوجيه <code>require</code> لإخبار Sprockets بالملفّات التي ترغب في طلبها. أنت تطلب هنا الملفّات rails-ujs.js و turbolinks.js المتاحة في مكان ما في مسار البحث لـ Sprockets. لا تحتاج إلى توفير الامتدادات بشكل صريح. يفترض Sprockets أنك تطلب ملف <code>js.</code> عندما تفعل ذلك داخل ملف js.
  
يأمر التوجيه Sprockets require_tree تعاوديًّا (recursively) بأن يُضمّن كافة ملفّات JavaScript في المجلّد المحدّد في الإخراج. يجب تحديد هذه المسارات نسبة إلى ملف manifest. يمكنك أيضًا استخدام التوجيه require_directory الذي يتضمّن جميع ملفّات JavaScript في المجلّد المحدد فقط، بدون أي تعاوديّة (recursion).
+
التوجيه <code>require_tree</code> يأمر Sprockets تعاوديًّا (recursively) بأن يُضمّن كافة ملفّات [[JavaScript]] في المجلّد المحدّد في الإخراج. يجب تحديد هذه المسارات نسبة إلى ملف manifest. يمكنك أيضًا استخدام التوجيه <code>require_directory</code> الذي يتضمّن جميع ملفّات [[JavaScript]] في المجلّد المحدد فقط، بدون أي تعاوديّة (recursion).
  
تُعالج التوجيهات من الأعلى إلى الأسفل ولكن الترتيب الذي تُضمّن الملفّات به في require_tree غير محدّد. يجب ألا تعتمد على أي ترتيب معيّن بين هؤلاء. إن إحتجت إلى التأكد من أن يوضع JavaScript معين قبل غيره في الملف المُجمَّع (concatenated file)، تطلّب الملف اللازم أوّلًا في manifest. لاحظ أن عائلة توجيهات require تمنع الملفّات من تضمينها مرتين في الإخراج.
+
تُعالج التوجيهات من الأعلى إلى الأسفل ولكن الترتيب الذي تُضمّن الملفّات به في <code>require_tree</code> غير محدّد. يجب ألا تعتمد على أي ترتيب معيّن بين هؤلاء. إن إحتجت إلى التأكد من أن يوضع [[JavaScript]] معين قبل غيره في الملف المُجمَّع (concatenated file)، تطلّب الملف اللازم أوّلًا في manifest. لاحظ أن عائلة توجيهات <code>require</code> تمنع الملفّات من تضمينها مرتين في الإخراج.
  
ينشئ Rails أيضًا ملفًا افتراضيًا app/assets/stylesheets/application.css يحتوي على هذه السطور:
+
ينشئ ريلز أيضًا ملفًا افتراضيًا app/assets/stylesheets/application.css يحتوي على هذه السطور:
<syntaxhighlight lang="rails">
+
<syntaxhighlight lang="css">
 
/* ...
 
/* ...
 
+
*= require_self
<nowiki>*</nowiki>= require_self
+
*= require_tree .
 
+
*/
<nowiki>*</nowiki>= require_tree .
 
 
 
<nowiki>*</nowiki>/
 
 
</syntaxhighlight>
 
</syntaxhighlight>
ينشئ Rails كلا app/assets/javascripts/application.js و app/assets/stylesheets/application.css بغض النظر عن استخدام الخيار skip-sprockets-- عند إنشاء تطبيق Rails جديد. هذا يمكنك من إضافة pipelining الأصول بسهولة لاحقًا إن أردت.
+
ينشئ ريلز كلا app/assets/javascripts/application.js و app/assets/stylesheets/application.css بغض النظر عن استخدام الخيار <code>skip-sprockets--</code> عند إنشاء تطبيق ريلز جديد. هذا يمكنك من إضافة أنابيب الأصول (asset pipelining) بسهولة لاحقًا إن أردت.
  
تعمل التوجيهات التي تعمل في ملفّات JavaScript أيضًا في صفحات الأنماط (على الرغم من أنها تتضمن أوراق أنماط بدلاً من ملفّات JavaScript). يعمل التوجيه require_tree في بيان CSS بنفس طريقة بيان JavaScript، ويتطلب كل أوراق الأنماط من المجلّد الحالي.
+
تعمل التوجيهات التي تعمل في ملفّات [[JavaScript]] أيضًا في صفحات الأنماط (على الرغم من أنها تتضمن أوراق أنماط بدلاً من ملفّات [[JavaScript]]). يعمل التوجيه <code>require_tree</code> في بيان [[CSS]] بنفس طريقة بيان [[JavaScript]]، ويتطلب كل أوراق الأنماط من المجلّد الحالي.
  
يُستخدم require_self في هذا المثال. يضع شفرة CSS المضمنة داخل الملف (إن وجدت) في الموقع الدقيق للنداءrequire_self.
+
يُستخدم <code>require_self</code> في هذا المثال. يضع شفرة [[CSS]] المضمنة داخل الملف (إن وجدت) في الموقع الدقيق للنداء <code>require_self</code>.
  
إن أردت استخدام عدة ملفّات Sass، عليك استخدام قاعدة Sass @import بدلاً من توجيهات Sprockets. تتواجد ملفّات Sass داخل نطاقها الخاص عند استخدام توجيهات Sprockets ممّا يجعل المتغيّرات أو الاختلاطات (mixins) متوفّرة فقط داخل المستند الذي عُرّفت فيه.
+
'''ملاحظة''': إن أردت استخدام عدة ملفّات [[Sass]]، عليك استخدام القاعدة <code>[[Sass/@ rules|‎@import]]</code> بدلًا من توجيهات Sprockets. تتواجد ملفّات [[Sass]] داخل نطاقها الخاص عند استخدام توجيهات Sprockets ممّا يجعل المتغيّرات أو [[Sass/mixins|المخاليط]] (mixins) متوفّرة فقط داخل المستند الذي عُرّفت فيه.
  
يمكنك تعميم الملف (file globbing) أيضًا باستخدام "*" import@ و "*/**" import@ لإضافة الشجرة بأكملها وهو ما يعادل كيفيّة عمل require_tree. تحقق من توثيق sass-rails لمزيد من المعلومات والمحاذير المهمة.
+
يمكنك تعميم الملف (file globbing) أيضًا باستخدام <code>"*" import@</code> و <code>"*/**" import@</code> لإضافة الشجرة بأكملها وهو ما يعادل كيفيّة عمل <code>require_tree</code>. تحقق من [https://github.com/rails/sass-rails#features توثيق sass-rails] لمزيد من المعلومات والمحاذير المهمة.
  
 
يمكنك الحصول على أي عدد من الملفّات تريده. على سبيل المثال، يمكن أن يحتوي بيان admin.css و admin.js على ملفّات JS و CSS التي تُستخدم لقسم إدارة التطبيق.
 
يمكنك الحصول على أي عدد من الملفّات تريده. على سبيل المثال، يمكن أن يحتوي بيان admin.css و admin.js على ملفّات JS و CSS التي تُستخدم لقسم إدارة التطبيق.
  
 
تنطبق نفس الملاحظات حول الترتيب أعلاه. تحديدًا، يمكنك تحديد ملفّات منفردة وستُصرّف (compiled) بالترتيب المحدّد. قد تجمع مثلًا ثلاث ملفّات CSS معًا بهذه الطريقة:
 
تنطبق نفس الملاحظات حول الترتيب أعلاه. تحديدًا، يمكنك تحديد ملفّات منفردة وستُصرّف (compiled) بالترتيب المحدّد. قد تجمع مثلًا ثلاث ملفّات CSS معًا بهذه الطريقة:
<syntaxhighlight lang="rails">
+
<syntaxhighlight lang="css">
 
/* ...
 
/* ...
 
+
*= require reset
<nowiki>*</nowiki>= require reset
+
*= require layout
 
+
*= require chrome
<nowiki>*</nowiki>= require layout
+
*/
 
 
<nowiki>*</nowiki>= require chrome
 
 
 
<nowiki>*</nowiki>/
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 
=== المعالجة المسبقة (preprocessing) ===
 
=== المعالجة المسبقة (preprocessing) ===
تحدّد امتدادات الملفّات المستخدمة في أصل ما المعالجة السابقة التي وقعت عليه. يُنشأ ملف CoffeeScript وملف SCSS بدلاً من ملف JavaScript و CSS عاديين عند إنشاء وحدة تحكّم أو سقالة باستخدام gemset Rails الافتراضية. المثال المستخدم سابقًا كان وحدة تحكّم مُسمّاة "projects" ولّدت ملف app/assets/javascripts/projects.coffee and an app/assets/stylesheets/projects.scss.
+
تحدّد امتدادات الملفّات المستخدمة في أصل ما المعالجة السابقة التي وقعت عليه. يُنشأ ملف CoffeeScript وملف SCSS بدلًا من ملف [[JavaScript]] و [[CSS]] عاديين عند إنشاء وحدة تحكّم أو سقالة (scaffold) باستخدام مجموعة جواهر ريلز (gemset Rails) الافتراضية. المثال المستخدم سابقًا كان وحدة تحكّم مُسمّاة "projects" ولّدت الملف app/assets/javascripts/projects.coffee والملف app/assets/stylesheets/projects.scss.
  
في وضع التطوير أو في حالة تعطيل أنبوب الأصل، تُعالج هذه الملفّات عندما تُطلب بواسطة المُعالجات التي يوفرّها coffee-script وجواهر sass ثم تُعاد إلى المتصفّح على هيئة JavaScript و CSS على التوالي. عندما يُفعّل أنبوب أصول،
+
في وضع التطوير أو في حالة تعطيل أنبوب الأصل، تُعالج هذه الملفّات عندما تُطلب بواسطة المُعالجات التي يوفرّها coffee-script وجواهر sass ثم تُعاد إلى المتصفّح على هيئة [[JavaScript]] و [[CSS]] على التوالي. عندما يُفعّل أنبوب أصول، تُعالَج هذه الملفّات مسبقًا وتوضع في المجلّد public/assets لتقديمها إما من خلال تطبيق ريلز أو خادم الويب.
 
 
تُعالَج هذه الملفّات مسبقًا وتوضع في المجلّد public/assets لتقديمها إما من خلال تطبيق Rails أو خادم الويب.
 
  
 
يمكن طلب طبقات إضافيّة من المعالجة المسبقة عن طريق إضافة ملحقات أخرى، حيث يُعالَج كل ملحق بطريقة من اليمين إلى اليسار. يجب استخدامهن بالترتيب الذي يجب تطبيق المعالجة حسبه. على سبيل المثال، تُعالَج ورقة أنماط باسم app/assets/stylesheets/projects.scss.erb أولاً كـ ERB ثم SCSS وأخيرًا تُقدّم كـ CSS. - وينطبق الشيء نفسه على ملف JavaScript - يُعالَج app/assets/javascripts/projects.coffee.erb كـ ERB، ثم CoffeeScript وتُقدّم بمثابة JavaScript.
 
يمكن طلب طبقات إضافيّة من المعالجة المسبقة عن طريق إضافة ملحقات أخرى، حيث يُعالَج كل ملحق بطريقة من اليمين إلى اليسار. يجب استخدامهن بالترتيب الذي يجب تطبيق المعالجة حسبه. على سبيل المثال، تُعالَج ورقة أنماط باسم app/assets/stylesheets/projects.scss.erb أولاً كـ ERB ثم SCSS وأخيرًا تُقدّم كـ CSS. - وينطبق الشيء نفسه على ملف JavaScript - يُعالَج app/assets/javascripts/projects.coffee.erb كـ ERB، ثم CoffeeScript وتُقدّم بمثابة JavaScript.
  
وضع ترتيب هذه المعالجات المسبقة بالحسبان مهم. على سبيل المثال، إن ناديت ملفك JavaScript المسمّى app/assets/javascripts/projects.erb.coffee، سيُعالَج مع مترجم CoffeeScript أولاً والذي لن يفهم ERB وبالتالي ستواجه مشكلات.
+
وضع ترتيب هذه المعالجات المسبقة بالحسبان مهم. على سبيل المثال، إن استدعيت ملفك JavaScript المسمّى app/assets/javascripts/projects.erb.coffee، فسيُعالَج مع مترجم CoffeeScript أولاً والذي لن يفهم ERB وبالتالي ستواجه مشكلات.
  
 
== في التطوير ==
 
== في التطوير ==
 
تُقدّم الأصول في وضع التطوير كملفّات منفصلة بالترتيب المحدّد في ملف manifest.
 
تُقدّم الأصول في وضع التطوير كملفّات منفصلة بالترتيب المحدّد في ملف manifest.
  
هذا ويضهر الواضح app/assets/javascripts/application.js:
+
الملف app/assets/javascripts/application.js الذي يحوي:
<syntaxhighlight lang="rails">
+
<syntaxhighlight lang="javascript">
 
//= require core
 
//= require core
 
 
//= require projects
 
//= require projects
 
 
//= require tickets
 
//= require tickets
 
</syntaxhighlight>
 
</syntaxhighlight>
سيولد هذا HTML:
+
سيولد شيفرة [[HTML]] التالية:
<syntaxhighlight lang="rails">
+
<syntaxhighlight lang="html">
 
<script src="/assets/core.js?body=1"></script>
 
<script src="/assets/core.js?body=1"></script>
 
 
<script src="/assets/projects.js?body=1"></script>
 
<script src="/assets/projects.js?body=1"></script>
 
 
<script src="/assets/tickets.js?body=1"></script>
 
<script src="/assets/tickets.js?body=1"></script>
 
</syntaxhighlight>
 
</syntaxhighlight>
يتطلّب Sprockets المعاملة body.
+
يتطلّب Sprockets المعامل <code>body</code>.
  
=== رفع خطأ عندما لا يُعثر على الأصل ===
+
=== رفع خطأ عندما لا يعثر على الأصل ===
 
إذا كنت تستخدم sprockets-rails > = 3.2.0، تستطيع إعداد ما يحدث عند إجراء بحث عن أصول ولم يُعثر على أي شيء. سيظهر خطأ عند عدم العثور على أصل إذا أوقفت الأصول التراجعيّة (asset fallback).
 
إذا كنت تستخدم sprockets-rails > = 3.2.0، تستطيع إعداد ما يحدث عند إجراء بحث عن أصول ولم يُعثر على أي شيء. سيظهر خطأ عند عدم العثور على أصل إذا أوقفت الأصول التراجعيّة (asset fallback).
 
<syntaxhighlight lang="rails">
 
<syntaxhighlight lang="rails">
 
config.assets.unknown_asset_fallback = false
 
config.assets.unknown_asset_fallback = false
 
</syntaxhighlight>
 
</syntaxhighlight>
إن فُعّلت الأصول التراجعيّة، سيُخرج المسار بدلاً من ذلك ولن يظهر خطأ عندما لا يمكن العثور على أصل. سلوك الأصول ، مُفّعل افتراضيًا.
+
إن فُعّلت الأصول التراجعيّة، سيُخرج المسار بدلًا من ذلك ولن يظهر خطأ عندما لا يمكن العثور على أصل. سلوك الأصول، مُفّعل افتراضيًا.
  
=== إطفاء Digests ===
+
=== إطفاء القيم المشفرة المختصرة (Turning Digests Off) ===
يمكنك إيقاف تشغيل digests من خلال تحديث config/environments/development.rb لتشمل:
+
يمكنك إيقاف تشغيل القيم المشفرة المختصرة (digests) من خلال تحديث config/environments/development.rb ليشمل الضبط:
 
<syntaxhighlight lang="rails">
 
<syntaxhighlight lang="rails">
 
config.assets.digest = false
 
config.assets.digest = false
 
</syntaxhighlight>
 
</syntaxhighlight>
ستُنشأ digests لعناوين URL للأصول عندما تكون قيمة هذا الخيار true ملخصات.
+
ستُنشأ قيم مشفرة مختصرة لعناوين URL للأصول عندما تكون قيمة هذا الخيار <code>true</code>.
  
 
=== إيقاف تشغيل التنقيح (Turning Debugging Off) ===
 
=== إيقاف تشغيل التنقيح (Turning Debugging Off) ===
سطر 338: سطر 305:
 
config.assets.debug = false
 
config.assets.debug = false
 
</syntaxhighlight>
 
</syntaxhighlight>
يُجمّع Sprockets ويُشغّل المُعالجات التمهيديّة (preprocessors) الضروريّة على كافة الملفّات عند إيقاف وضع التنقيح. سيُنشئ manifest بدلاً منه:
+
يُجمّع Sprockets ويُشغّل المُعالجات التمهيديّة (preprocessors) الضروريّة على كافة الملفّات عند إيقاف وضع التنقيح. سيُنشئ manifest بدلًا منه:
<syntaxhighlight lang="rails">
+
<syntaxhighlight lang="html">
 
<script src="/assets/application.js"></script>
 
<script src="/assets/application.js"></script>
 
</syntaxhighlight>
 
</syntaxhighlight>
تُجمّع الأصول وتُخزّن مؤقّتًا في الطلب الأول بعد بدء تشغيل الخادم. يُعيّن Sprockets ترويسة Cache-Control HTTP  must-revalidate لتقليل حمل الطلبات على الطلبات اللاحقة - والتي يحصل عليها المتصفّح على استجابة 304 (غير مُعدّل).
+
تُجمّع الأصول وتُخزّن مؤقّتًا في الطلب الأول بعد بدء تشغيل الخادم. يُعيّن Sprockets ترويسة HTTP وهي <code>must-revalidate Cache-Control</code> لتقليل حمل الطلبات على الطلبات اللاحقة والتي يحصل عليها المتصفّح على استجابة 304 (غير مُعدّل).
  
 
يستجيب الخادم بملف مُصرَّف (compiled) جديد إن تغيّرت أي من الملفّات في manifest بين الطلبات.
 
يستجيب الخادم بملف مُصرَّف (compiled) جديد إن تغيّرت أي من الملفّات في manifest بين الطلبات.
سطر 826: سطر 793:
  
 
gem 'uglifier'
 
gem 'uglifier'
</syntaxhighlight>
+
<nowiki></syntaxhighlight></nowiki>
  
 
== مصادر ==
 
== مصادر ==
سطر 832: سطر 799:
 
[[تصنيف:Rails]]
 
[[تصنيف:Rails]]
 
[[تصنيف:Rails Digging Deeper]]
 
[[تصنيف:Rails Digging Deeper]]
 +
|}

مراجعة 11:33، 11 مارس 2019

يغطّي هذا الدليل أنبوب الأصول. ستتعلم بعد قراءة هذا الدليل:

  • ماهيّة أنبوب الأصول وماذا يفعل.
  • كيفيّة تنظيم أصول تطبيقك بشكل صحيح.
  • فوائد أنبوب الأصول.
  • كيفيّة إضافة معالج مسبق (pre-processor) إلى الأنبوب.
  • كيفيّة وضع الأصول مع جوهرة في حزمة.

ما هو أنبوب الأصول؟

يوفّر أنبوب الأصول إطارًا لسَلسَلة وتصغير أو ضغط أصول JavaScript و CSS. كما أنه يضيف القدرة على كتابة هذه الأصول بلغات أخرى ومعالجات مسبقة مثل CoffeeScript و Sass و ERB. يسمح للأصول في تطبيقك أن تُدمج تلقائيًّا مع الأصول من جواهر أخرى.

يُعرَّفُ استخدام خط الأصل بواسطة الجوهرة sprockets-rails، ويُفعّل افتراضيًّا. يمكنك تعطيله أثناء إنشاء تطبيق جديد عبر تمرير الخيار skip-sprockets--.

rails new appname --skip-sprockets

يضيف ريلز تلقائيًّا الجواهر coffee-rails و sass-rails و uglifier إلى Gemfile التي يستخدمها Sprockets لضغط الأصول:

gem 'sass-rails'
gem 'uglifier'
gem 'coffee-rails'

استخدام الخيار skip-sprockets-- سيمنع ريلز من إضافتها إلى Gemfile لذا إن أردت تفعيل أنبوب الأصول فيما بعد سيتعيّن عليك إضافة تلك الجواهر إلى ملفك Gemfile. سيؤدي إنشاء تطبيق مع الخيار skip-sprockets-- إلى إنشاء ملف config/application.rb مختلف اختلافًا طفيفًا، مع عبارة طلب (require) إلى sprockets railtie موضوعة داخل تعليق. سيتعيّن عليك إزالة مُعامل (operator) التعليق على هذا السطر لتفعيل أنبوب الأصول لاحقًا:

# require "sprockets/railtie"

لضبط توابع ضغط الأصول، اضبط خيارات الإعداد المناسبة في production.rb - config.assets.css_compressor لملفك بـ CSS و config.assets.js_compressor من أجل شيفرتك JavaScript:

config.assets.css_compressor = :yui
config.assets.js_compressor = :uglifier

ملاحظة: تُستخدم الجوهرة sass-rails تلقائيًا لضغط ملفات CSS إذا ضُمّنت في Gemfile ولم يُضبط أي خيار config.assets.css_compressor.

الميزات الرئيسية

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

يُجمّع Sprockets جميع ملفات JavaScript في ملف js. رئيسي واحد وجميع ملفّات CSS في ملف css. رئيسي واحد. يمكنك تخصيص هذه الاستراتيجية لتجميع الملفات بالطريقة التي تريدها كما سترى لاحقًا في هذا الدليل. يدرج ريلز عند الإنتاج بصمة SHA256 في كل اسم ملف بحيث يُخزّن الملف مؤقّتًا بواسطة متصفّح الويب. يمكنك إبطال ذاكرة التخزين المؤقّت عن طريق تغيير هذه البصمة التي تحدث تلقائيًا كلما غيّرت محتويات الملف.

الميزة الثانية لأنبوب الأصول هي اقتضاب (minification) الأصول أو ضغطها. وذلك عن طريق إزالة المسافات البيضاء والتعليقات بالنسبة إلى ملفّات CSS. بالنسبة إلى JavaScript يمكن تطبيق عمليّات أكثر تعقيدًا. يمكنك الاختيار بين مجموعة من الخيارات المضمنّة أو تحديد خياراتك الخاصّة.

الميزة الثالثة لأنبوب الأصول هي أنه يسمح بتشفير الأصول عبر لغة ذات مستوى أعلى، مع وصول التحويل المسبق حتّى مستوى الأصول الفعليّة. تتضمّن اللغات المدعومة Sass لـ CSS و CoffeeScript لـ JavaScript  و ERB بشكل افتراضي.

ما هي البصمات ولماذا يجب أن أهتم؟

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

يمكن عندما يكون اسم الملف فريدًا ومستندًا على محتواه تعيين ترويسات HTTP لتشجيع التخزين المؤقّت في كل مكان (سواء في شبكات توصيل المحتوى أو في مزودي خدمات الإنترنت أو في معدّات الشبكات أو في متصفحّات الويب) للاحتفاظ بنسخهم الخاصّة من المحتوى. عند تحديث المحتوى ستتغيّر البصمة. سيؤدي ذلك إلى مطالبة العملاء البعيدين بنسخة جديدة من المحتوى. يُعرف هذا عمومًا باسم خرق ذاكرة التخزين المؤقّت (cache busting).

التقنية التي يستخدمها Sprockets للبصمة هي إدخال قيمة hash للمحتوى في الاسم، عادةً في النهاية. خذ ملف CSS مسمّى global.css مثلًا:

global-908e25f4bf641868d8683022a5b62f54.css

هذه هي الاستراتيجية التي يعتمدها أنبوب الأصول ريلز.

كانت استراتيجية ريلز القديمة هي إلحاق سلسلة استعلام نصيّة (query string) تستند إلى التاريخ بكل أصل مرتبط بمساعد مضمّن. تبدو الشفرة المُنشئَة كما يلي في المصدر:

/stylesheets/global.css?1309495796

تملك استراتيجية سلسلة الاستعلام عدّة عيوب:

  1. لن تُخزّن كل ذاكرات التخزين المؤقّت المحتوى بشكل يعتمد عليه حين يختلف اسم الملف فقط بمعاملات الاستعلام. يوصي Steve Souders "... تجنّب سلاسل الاستعلام في الموارد القابلة للتخزين المؤقّت". وجد أنّه في هذه الحالة لن يُخزّنَ 5-20٪ من الطلبات مؤقّتًا. سلاسل الاستعلام النصيّة على وجه الخصوص لا تعمل على الإطلاق مع بعض شبكات توصيل المحتوى لإبطال ذاكرة التخزين المؤقّت.
  2. يمكن أن يتغيّر اسم الملف بين العقد في البيئات متعددة الخوادم. تستند سلسلة الاستعلام الافتراضية في الإصدار ‎2.x من ريلز على وقت تعديل الملفّات. عندما تُنشَر (deployed) الأصول إلى مجموعة، لا يوجد ضمان بأن الطوابع الزمنيّة ستكون نفسها مما يؤدي إلى استخدام قيم مختلفة بناءً على الخادم الذي يعالج الطلب.
  3. إبطال ذاكرات التخزين المؤقّت أكثر من اللازم. عندما تُطلق الأصول الثابتة مع كل إصدار جديد من التعليمات البرمجية، يتغيّر mtime (وقت التعديل الأخير) لجميع هذه الملفّات، مما يجبر كل العملاء البعيدين على جلبهم مرة أخرى، حتى عندما لا يتغيّر محتوى تلك الأصول.

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

تُفعّل البصمات بشكل افتراضي لكل من بيئات التطوير والإنتاج. يمكنك تفعيلها أو تعطيلها بإعداداتك من خلال الخيار config.assets.digest.

قراءة المزيد:

كيفيّة استخدام أنبوب الأصول

في الإصدارات السابقة من ريلز، كانت جميع الأصول موجودة في مجلّدات فرعية public مثل images و javascripts و  stylesheets. أصبح الآن الموقع المفضّل لهذه الأصول هو المجلّد app/assets مع أنبوب الأصول. تقدّم الملفّات في هذا المجلّد بواسطة برمجيّات Sprockets الوسيطة.

لا يزال من الممكن وضع الأصول في التسلسل الهرمي public. ستُقدّم أي أصول تحت public كملفّات ثابتة من طرف التطبيق أو خادم الويب عند ضبط config.public_file_server.enabled إلى القيمة true. عليك استخدام app/assets للملفّات التي يجب أن تخضع لبعض المعالجة المسبقة قبل تقديمها.

يُحوّل ريلز هذه الملفّات إلى public/assets بشكل افتراضي عند الإنتاج. تُقدّم بعد ذلك النسخ المُحوّلة مسبقًا كأصول ثابتة من طرف خادم الويب. لا تُقدّم الملفّات في app/assets أبدًا مباشرةً في الإنتاج.

الأصول الخاصة بوحدة تحكم (Controller Specific Assets)

عند توليد سقالة (scaffold) أو وحدة تحكّم، يُولّد ريلز أيضا ملف JavaScript (أو ملف CoffeeScript إذا وُجدت الجوهرة coffee-rails في Gemfile) وملف أوراق الأنماط الانسيابيّة (أو ملف SCSS إن وُجد sass-rails في Gemfile) لوحدة التحكّم تلك. علاوة على ذلك، ينشئ ريلز الملف scaffolds.css عند إنشاء سقالة (أو scaffolds.scss إن وُجد sass-rails في Gemfile).

إن أنشأت مثلًا ProjectsController، سيضيف ريلز أيضًا ملفًّا جديدًا في app/assets/javascripts/projects.coffee وآخر في app/assets/stylesheets/projects.scss. ستكون هذه الملفّات جاهزة للاستخدام من طرف تطبيقك إفتراضيًّا على الفور باستخدام الأمر require_tree. انظر للتعليمات والملفّات النصّيّة التي تحتوي على قائمة الملفات التي ستجرى عليها عملية ما (maniftest) لمزيد من التفاصيل حول require_tree.

يمكنك أيضًا اختيار تضمين أوراق أنماط خاصّة بوحدة التحكّم (controller specific stylesheets) وملفّات JavaScript فقط في وحدات تحكّمهم باستخدام ما يلي:

<%= javascript_include_tag params[:controller] %> or <%= stylesheet_link_tag
params[:controller] %>

تأكد لو فعلت هذا من أنك لا تستخدم التوجيه require_tree لأن ذلك سيؤدي لتضمين أصولك أكثر من مرة.

تحذير: عند استخدام تصريف الأصول المسبق (asset precompilation) ستحتاج للتأكّد من أن أصول وحدة تحكمّك ستُحوّل مسبقًا عند تحميلها بكل صفحة على حدة. لن تُحوّل الملفّات coffee. و scss. مسبقًا من تلقاء نفسها افتراضيًّا. راجع تحميل الأصول المسبق للحصول على مزيد من المعلومات حول كيفيّة عمل التحويل البرمجي المسبق.

ملاحظة: يجب أن يكون لديك تنفيذ (runtime) مدعوم من ExecJS من أجل استخدام CoffeeScript. إن كنت تستخدم macOS أو Windows، سيُثبّت تنفيذ JavaScript في نظام تشغيلك. راجع توثيق ExecJS لمعرفة كل تنفيذات JavaScript المدعومة.

يمكنك أيضًا تعطيل إنشاء ملفّات أصول خاصة بوحدة تحكّم عن طريق إضافة التالي إلى config/application.rb:

config.generators do |g|
  g.assets false
end

تنظيم الأصول

يمكن وضع أصول أنبوب داخل تطبيق في أحد المواقع الثلاثة: app/assets أو lib/assets أو vendor/assets.

  • app/assets مخصّص للأصول التي يملكها التطبيق مثل الصور المخصّصة أو ملفّات JavaScript أو أوراق الأنماط.
  • lib/assets مخصّص لشفرات مكتباتك التي لا تتناسب حقًا مع نطاق التطبيق أو تلك المكتبات المشتركة عبر التطبيقات.
  • vendor/assets مخصّص للأصول التي تملكها كيانات خارجية مثل شفرة لإضافات JavaScript وأطر عمل CSS. ضع بالحسبان وجوب إعادة كتابة شفرات الطرف الثالث ذات المراجع إلى ملفّات أخرى (الصور، أوراق الأنماط، إلخ) المعالجة من طرف أنبوب الأصول كي تستخدم المساعدين مثل asset_path.

تحذير: إن كنت تُحدّث من ريلز 3، رجاءً راع أن الأصول تحت lib/assets أو vendor/assets متوفرة للتضمين عبر بيانات التطبيق لكنها لم تعد جزءًا من مصفوفة التصريف المسبق precompile()‎. انظر قسم تصريف الأصول المسبق لمزيد من الإرشادات.

مسارات البحث

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

المواقع الافتراضية هي: المجلّدات images و javascripts و stylesheets تحت المجلّد app/assets، ولكن هذه المجلّدات الفرعية ليست حالة فريدة - سيُبحث في أي مسار تحت */assets.

هذه الملفّات مثلًا:

app/assets/javascripts/home.js
lib/assets/javascripts/moovinator.js
vendor/assets/javascripts/slider.js
vendor/assets/somepackage/phonebox.js

سيُرجع إليها في بيان بهذا الشكل:

//= require home
//= require moovinator
//= require slider
//= require phonebox

يمكن الوصول إلى الأصول الموجودة داخل المجلّدات الفرعيّة أيضًا.

app/assets/javascripts/sub/something.js

يشار إليها على النحو التالي:

//= require sub/something

يمكنك رؤية مسار البحث عبر فحص Rails.application.config.assets.paths في وحدة تحكّم ريلز.

عدا مسارات */assets القياسية يمكن إضافة مسارات إضافيّة (مؤهلّة بالكامل [fully qualified]) إلى خط الأنابيب في config/initializers/assets.rb. مثلًا:

Rails.application.config.assets.paths << Rails.root.join("lib", "videoplayer", "flash")

تُجتاز المسارات بالترتيب الذي تظهر به في مسار البحث. هذا يعني افتراضيا أنّ الأسبقيّة للملفّات في app/assets وأنّها ستحجب المسارات المقابلة في lib و vendor.

من المهم ملاحظة وجوب إضافة الملفّات التي تريد الإشارة إليها خارج الملفّ النصّي الذي يحتوي على قائمة الملفات التي ستجرى عليها عملية ما (manifest) إلى المصفوفة precompile وإلّا لن تكون متوفّرة في بيئة الإنتاج.

استخدام ملفات الفهرس

يستخدم Sprockets ملفّات تدعى index (مع الملحقات ذات الصلة) لغرض خاص.

إن كان لديك مكتبة jQuery تحتوي على العديد من الوحدات النمطية والتي تُخزّن في lib/assets/javascripts/library_name، يقوم الملف lib/assets/javascripts/library_name/index.js مقام الملفّ النصّي الذي يحتوي على قائمة الملفات التي ستجرى عليها عملية ما (maniftest) لجميع الملفّات الموجودة في هذه المكتبة. يمكن أن يتضمن هذا الملف قائمة بجميع الملفّات المطلوبة بالترتيب أو توجيهًا بسيطًا require_tree.

يمكن الوصول للمكتبة ككل في بيان التطبيق بهذا الشكل:

//= require library_name

يبسّط هذا الأسلوب الصيانة ويحافظ على ترتيب الأمور من خلال السماح بتجميع التعليمات البرمجية ذات الصلة قبل التضمين (inclusion) في مكان آخر.

روابط الترميز إلى الأصول

لا يضيف Sprockets أي توابع جديدة للوصول إلى أصولك - ما زلت تستخدم javascript_include_tag و stylesheet_link_tag المألوفتين:

<%= stylesheet_link_tag "application", media: "all" %>
<%= javascript_include_tag "application" %>

في حالة استخدام الجوهرة turbolinks المُضمّنة افتراضيًا في ريلز، ضمّن الخيار 'data-turbolinks-track' الذي يتسبب في تحقّق turbolinks من تحديث الأصل، وفي تلك الحالة يحمّله بالصفحة:

<%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => "reload" %>
<%= javascript_include_tag "application", "data-turbolinks-track" => "reload" %>

في الواجهات (views) العاديّة، يمكنك الوصول للصور في مجلّد app/assets/images بهذا الشكل:

<%= image_tag "rails.png" %>

يُقدّم هذا الملف من طرف Sprockets بشرط أن يُفعّل الأنبوب داخل تطبيقك (و ولا يكون معطّلًا في سياق البيئة الحالي). إن وُجد الملف في public/assets/rails.png، سيقدّمه خادم الويب.

يُتعامل مع طلب ملف مع تجزئة SHA256 مثل public/assets/rails-f90d8a84c707a8dc923fca1ca1895ae8ed0a09237f6992015fef1e11be77c023.png بنفس الطريقة. كيفيّة توليد هذه التجزئات مُغطّى في قسم الإنتاج لاحقًا في هذا الدليل.

سينظر Sprockets أيضًا عبر المسارات المحدّدة في config.assets.paths والتي تتضمّن مسارات التطبيق القياسية وأي مسارات تضيفها محرّكات ريلز.

يمكن أيضًا تنظيم الصور في مجلّدات فرعية إن لزم الأمر ومن ثم الوصول إليها عبر تحديد اسم المجلّد في الوسم (tag):

<%= image_tag "icons/rails.png" %>

تحذير: إذا كنت تُصرّف أصولك مسبقًا (أي precompiling، انظر في قسم الإنتاج أدناه)، فسيرمي الربط بأصل غير موجود استثناءً في صفحة الاستدعاء. بما في ذلك الربط بسلسلة نصيّة فارغة. لهذا السبب كن حذرًا عند استخدام image_tag والمساعدين الآخرين مع البيانات التي يوفّرها المستخدم.

CSS و ERB

يُقيّم أنبوب الأصول تلقائيًا ERB. ويعني هذا أنك إن أضفت ملحق erb (أي erb extension) إلى أصل CSS (على سبيل المثال application.css.erb)، ستكون المساعِدات مثل asset_path متاحة في قواعد CSS:

.class { background-image: url(<%= asset_path 'image.png' %>) }

يكتب هذا المسار إلى الأصل المعيّن المشار إليه. في هذا المثال ،من المنطقي امتلاك صورة في أحد مسارات تحميل الأصول مثل app/assets/images/image.png، والتي سيُشار إليها هنا. سيرجع إلى هذا المسار إذا كانت هذه الصورة متاحة بالفعل في public/assets كملف مبصوم (fingerprinted file).

إذا كنت تريد استخدام رابط بيانات URI - وهي طريقة لتضمين (embedding) بيانات الصورة مباشرةً في ملف CSS - يمكنك استخدام المساعد asset_data_uri.

#logo { background: url(<%= asset_data_uri 'logo.png' %>) }

يُدرج هذا URI بيانات منسقة بشكل صحيح في مصدر CSS.

لاحظ أن علامة الإغلاق لا يمكن أن تكون بالشكل ‎-%>‎.

CSS و Sass

عند استخدام أنبوب الأصول، يجب إعادة كتابة المسارات إلى الأصول ويوفّر sass-rails المُساعدين url- و path- ( يكتبان بالشَرطة في Sass والشَرطة السفليّة في روبي) لأصناف الأصول التالية: الصورة والخط والفيديو والصوت وجافاسكربت وأوراق الأنماط الإنسيابيّة.

  • image-url("rails.png")‎ يعيد url(/assets/rails.png)‎
  • image-path("rails.png")‎ يعيد "‎/assets/rails.png"

يمكن أيضًا استخدام الشكل الأكثر شيوعًا:

  • asset-url("rails.png")‎ يعيد url(/assets/rails.png)‎
  • asset-path("rails.png")‎  يعيد "‎/assets/rails.png"

JavaScript / CoffeeScript و ERB

يمكنك استخدام المساعد asset_path في شفرتك JavaScript إن أضفت امتداد erb إلى أصل JavaScript جاعلًا منه application.js.erb مثلًا:

$('#logo').attr({ src: "<%= asset_path('logo.png') %>" });

يكتب هذا  المسار إلى الأصل المعيّن المشار إليه.

تستطيع بالمثل استخدام المساعد asset_path في ملفّات CoffeeScript ذات امتداد erb (مثلًا application.coffee.erb):

$('#logo').attr src: "<%= asset_path('logo.png') %>"

ملفّات manifest والتوجيهات (Manifest Files and Directives)

يستخدم Sprockets ملفّات manifest لتحديد الأصول المراد تضمينها وعرضها. تحتوي ملفّات manifest على توجيهات - وهي تعليمات تخبر Sprockets بالملفّات التي يجب أن يتطلّبها لإنشاء ملف CSS أو JavaScript واحد. باستخدام هذه التوجيهات يُحمّل Sprockets الملفّات المحدّدة، ويعالجها إن لزم، ويجمعها في ملف واحد واحد ثم يضغطها (بناءً على قيمة Rails.application.config.assets.js_compressor). يمكن تقليل وقت تحميل الصفحات بشكل كبير بتقديم ملف واحد بدلاً من العديد لأن المتصفّح يرسل عددًا أقل من الطلبات. يُصغّر الضغط أيضًا من حجم الملف، ممّا يتيح للمتصفّح تنزيلها بشكل أسرع.

على سبيل المثال، يتضمن تطبيق ريلز جديد ملفًا افتراضيًا app/assets/javascripts/application.js يحتوي على السطور التالية:

// ...
//= require rails-ujs
//= require turbolinks
//= require_tree .

تبدأ أوامر Sprockets بـ ‎//=‎ في ملفّات JavaScript. في الحالة المذكورة أعلاه، يستخدم الملف التوجيهات require و require_tree. يُستخدم التوجيه require لإخبار Sprockets بالملفّات التي ترغب في طلبها. أنت تطلب هنا الملفّات rails-ujs.js و turbolinks.js المتاحة في مكان ما في مسار البحث لـ Sprockets. لا تحتاج إلى توفير الامتدادات بشكل صريح. يفترض Sprockets أنك تطلب ملف js. عندما تفعل ذلك داخل ملف js.

التوجيه require_tree يأمر Sprockets تعاوديًّا (recursively) بأن يُضمّن كافة ملفّات JavaScript في المجلّد المحدّد في الإخراج. يجب تحديد هذه المسارات نسبة إلى ملف manifest. يمكنك أيضًا استخدام التوجيه require_directory الذي يتضمّن جميع ملفّات JavaScript في المجلّد المحدد فقط، بدون أي تعاوديّة (recursion).

تُعالج التوجيهات من الأعلى إلى الأسفل ولكن الترتيب الذي تُضمّن الملفّات به في require_tree غير محدّد. يجب ألا تعتمد على أي ترتيب معيّن بين هؤلاء. إن إحتجت إلى التأكد من أن يوضع JavaScript معين قبل غيره في الملف المُجمَّع (concatenated file)، تطلّب الملف اللازم أوّلًا في manifest. لاحظ أن عائلة توجيهات require تمنع الملفّات من تضمينها مرتين في الإخراج.

ينشئ ريلز أيضًا ملفًا افتراضيًا app/assets/stylesheets/application.css يحتوي على هذه السطور:

/* ...
*= require_self
*= require_tree .
*/

ينشئ ريلز كلا app/assets/javascripts/application.js و app/assets/stylesheets/application.css بغض النظر عن استخدام الخيار skip-sprockets-- عند إنشاء تطبيق ريلز جديد. هذا يمكنك من إضافة أنابيب الأصول (asset pipelining) بسهولة لاحقًا إن أردت.

تعمل التوجيهات التي تعمل في ملفّات JavaScript أيضًا في صفحات الأنماط (على الرغم من أنها تتضمن أوراق أنماط بدلاً من ملفّات JavaScript). يعمل التوجيه require_tree في بيان CSS بنفس طريقة بيان JavaScript، ويتطلب كل أوراق الأنماط من المجلّد الحالي.

يُستخدم require_self في هذا المثال. يضع شفرة CSS المضمنة داخل الملف (إن وجدت) في الموقع الدقيق للنداء require_self.

ملاحظة: إن أردت استخدام عدة ملفّات Sass، عليك استخدام القاعدة ‎@import بدلًا من توجيهات Sprockets. تتواجد ملفّات Sass داخل نطاقها الخاص عند استخدام توجيهات Sprockets ممّا يجعل المتغيّرات أو المخاليط (mixins) متوفّرة فقط داخل المستند الذي عُرّفت فيه.

يمكنك تعميم الملف (file globbing) أيضًا باستخدام "*" import@ و "*/**" import@ لإضافة الشجرة بأكملها وهو ما يعادل كيفيّة عمل require_tree. تحقق من توثيق sass-rails لمزيد من المعلومات والمحاذير المهمة.

يمكنك الحصول على أي عدد من الملفّات تريده. على سبيل المثال، يمكن أن يحتوي بيان admin.css و admin.js على ملفّات JS و CSS التي تُستخدم لقسم إدارة التطبيق.

تنطبق نفس الملاحظات حول الترتيب أعلاه. تحديدًا، يمكنك تحديد ملفّات منفردة وستُصرّف (compiled) بالترتيب المحدّد. قد تجمع مثلًا ثلاث ملفّات CSS معًا بهذه الطريقة:

/* ...
*= require reset
*= require layout
*= require chrome
*/

المعالجة المسبقة (preprocessing)

تحدّد امتدادات الملفّات المستخدمة في أصل ما المعالجة السابقة التي وقعت عليه. يُنشأ ملف CoffeeScript وملف SCSS بدلًا من ملف JavaScript و CSS عاديين عند إنشاء وحدة تحكّم أو سقالة (scaffold) باستخدام مجموعة جواهر ريلز (gemset Rails) الافتراضية. المثال المستخدم سابقًا كان وحدة تحكّم مُسمّاة "projects" ولّدت الملف app/assets/javascripts/projects.coffee والملف app/assets/stylesheets/projects.scss.

في وضع التطوير أو في حالة تعطيل أنبوب الأصل، تُعالج هذه الملفّات عندما تُطلب بواسطة المُعالجات التي يوفرّها coffee-script وجواهر sass ثم تُعاد إلى المتصفّح على هيئة JavaScript و CSS على التوالي. عندما يُفعّل أنبوب أصول، تُعالَج هذه الملفّات مسبقًا وتوضع في المجلّد public/assets لتقديمها إما من خلال تطبيق ريلز أو خادم الويب.

يمكن طلب طبقات إضافيّة من المعالجة المسبقة عن طريق إضافة ملحقات أخرى، حيث يُعالَج كل ملحق بطريقة من اليمين إلى اليسار. يجب استخدامهن بالترتيب الذي يجب تطبيق المعالجة حسبه. على سبيل المثال، تُعالَج ورقة أنماط باسم app/assets/stylesheets/projects.scss.erb أولاً كـ ERB ثم SCSS وأخيرًا تُقدّم كـ CSS. - وينطبق الشيء نفسه على ملف JavaScript - يُعالَج app/assets/javascripts/projects.coffee.erb كـ ERB، ثم CoffeeScript وتُقدّم بمثابة JavaScript.

وضع ترتيب هذه المعالجات المسبقة بالحسبان مهم. على سبيل المثال، إن استدعيت ملفك JavaScript المسمّى app/assets/javascripts/projects.erb.coffee، فسيُعالَج مع مترجم CoffeeScript أولاً والذي لن يفهم ERB وبالتالي ستواجه مشكلات.

في التطوير

تُقدّم الأصول في وضع التطوير كملفّات منفصلة بالترتيب المحدّد في ملف manifest.

الملف app/assets/javascripts/application.js الذي يحوي:

//= require core
//= require projects
//= require tickets

سيولد شيفرة HTML التالية:

<script src="/assets/core.js?body=1"></script>
<script src="/assets/projects.js?body=1"></script>
<script src="/assets/tickets.js?body=1"></script>

يتطلّب Sprockets المعامل body.

رفع خطأ عندما لا يعثر على الأصل

إذا كنت تستخدم sprockets-rails > = 3.2.0، تستطيع إعداد ما يحدث عند إجراء بحث عن أصول ولم يُعثر على أي شيء. سيظهر خطأ عند عدم العثور على أصل إذا أوقفت الأصول التراجعيّة (asset fallback).

config.assets.unknown_asset_fallback = false

إن فُعّلت الأصول التراجعيّة، سيُخرج المسار بدلًا من ذلك ولن يظهر خطأ عندما لا يمكن العثور على أصل. سلوك الأصول، مُفّعل افتراضيًا.

إطفاء القيم المشفرة المختصرة (Turning Digests Off)

يمكنك إيقاف تشغيل القيم المشفرة المختصرة (digests) من خلال تحديث config/environments/development.rb ليشمل الضبط:

config.assets.digest = false

ستُنشأ قيم مشفرة مختصرة لعناوين URL للأصول عندما تكون قيمة هذا الخيار true.

إيقاف تشغيل التنقيح (Turning Debugging Off)

يمكنك إيقاف وضع التنقيح عبر تحديث config/environments/development.rb لتضمين:

config.assets.debug = false

يُجمّع Sprockets ويُشغّل المُعالجات التمهيديّة (preprocessors) الضروريّة على كافة الملفّات عند إيقاف وضع التنقيح. سيُنشئ manifest بدلًا منه:

<script src="/assets/application.js"></script>

تُجمّع الأصول وتُخزّن مؤقّتًا في الطلب الأول بعد بدء تشغيل الخادم. يُعيّن Sprockets ترويسة HTTP وهي must-revalidate Cache-Control لتقليل حمل الطلبات على الطلبات اللاحقة والتي يحصل عليها المتصفّح على استجابة 304 (غير مُعدّل).

يستجيب الخادم بملف مُصرَّف (compiled) جديد إن تغيّرت أي من الملفّات في manifest بين الطلبات.

يمكن أيضًا تفعيل وضع التنقيح في توابع Rails المساعدة:

<%= stylesheet_link_tag "application", debug: true %>

<%= javascript_include_tag "application", debug: true %>

الخيار debug: مجرّد تكرار إن كان وضع التنقيح مُشغّلًا بالفعل.

يمكنك أيضًا تفعيل الضغط في وضع التطوير كتحقّق من السلامة (sanity check) وتعطيله حسب الطلب وحسب الحاجة لتنقيح الأخطاء.

في الإنتاج

يستخدم Sprockets مخطط البصمات الموضّح أعلاه في بيئة الإنتاج. يفترض Rails أن الأصول صُرّفت مسبقًا (precompiled) وستُقدّم كأصول ثابتة بواسطة خادم ويبك.

يُنشأ SHA256 أثناء مرحلة التحويل المسبق من محتويات الملفّات المُصرّفة (compiled) ويُدخل في أسماء الملفّات عند كتابتها على القرص. تُستخدم هذه الأسماء الحاملة لبصمات بواسطة مساعدي Rails بدلاً من اسم ملف manifest.

على سبيل المثال  يولّد التالي:

<%= javascript_include_tag "application" %>

<%= stylesheet_link_tag "application" %>

شيئًا كهذا:

<script src="/assets/application-908e25f4bf641868d8683022a5b62f54.js"></script>

<link href="/assets/application-4dd5b109ee3439da54f5bdfd78a80473.css" media="screen"

rel="stylesheet" />

لا يُستخدم الخياران :cache: و concat: مع أنبوب الأصول بعد الآن، احذفهما من javascript_include_tag و stylesheet_link_tag.

يتحكّم الخيار config.assets.digest (الذي يضبط على true إفتراضيًّا) في سلوك البصمة (fingerprinting behavior).

في ظل الظروف العادية، لا يجب تغيير الخيار config.assets.digest الافتراضي. إن لم توجد أية digests في أسماء الملفّات، وعُيّنت ترويسات للمستقبل البعيد، لن يعلم العملاء البعيدون أبدًا أن عليهم إعادة جلب الملفّات عند تغيير محتواها.

تصريف الأصول المُسبق (Precompiling Assets)

يأتي Rails مجهّزًا بمهمة لتصريف بيانات الأصول والملفّات الأخرى في الأنابيب.

تُكتب الأصول المُصرّفة بالموقع المحدّد في config.assets.prefix. هذا هو المجلّد assets/ إفتراضيًّا.

يمكنك مناداة هذه المهمة على الخادم أثناء النشر على الخادم الإنتاجي (deployment) لإنشاء إصدارات مُصرّفة من أصولك مباشرة على الخادم. انظر القسم التالي للحصول على معلومات حول التصريف محليًّا.

المهمة هي:

$ RAILS_ENV=production bin/rails assets:precompile

يتضمّن Capistrano (النسخة v2.15.1 وما فوق) وصفة للتعامل مع هذا الأسلوب في النشر على الخادم الإنتاجي. أضف السطر التالي إلى Capfile:

load 'deploy/assets'

يربط أعلاه المجلد المحدّد في config.assets.prefix  بالمجلّد shared/assets. إن كنت تستخدم هذا المجلد المشترك بالفعل ستحتاج إلى كتابة مهمّة نشرك الخاصّة.

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

تتضمّن أداة المطابقة الافتراضية لترجمة الملفّات application.js و application.css وجميع ملفّات JS/CSS (وهذا يشمل جميع الأصول الصوريّة تلقائيًا) من مجلدات app/assets بما في ذلك جواهرك:

<nowiki>[ Proc.new { |filename, path| path =~ /app\/assets/ && !%w(.js .css).include?(File.extname(filename)) },</nowiki>

/application.(css|js)$/ ]

يُطبّق المُطابق (والأعضاء الآخرين في مصفوفة precompile؛ انظر أدناه) على أسماء الملفّات المصرّفة النهائية. وهذا يعني أن أي شيء يُصّرف إلى JS/CSS مستبعد، وكذلك ملفّات JS/CSS الأوليّة (raw)؛ على سبيل المثال، ‎.coffee وscss. لسن مُضمّنات تلقائيًّا لأنهن تصريف من JS/CSS.

يمكنك إن امتلكت بيانات أخرى أو أوراق أنماط منفردة وملفّات JavaScript تريد تضمينها إضافتها إلى المصفوفة precompile في config/initializers/assets.rb:

Rails.application.config.assets.precompile += %w( admin.js admin.css )

حدّد دائمًا اسم الملف المُصرّف المتوقّع الذي ينتهي بـ js. أو css. حتى إن أردت إضافة ملفّات Sass أو CoffeeScript إلى مصفوفة precompile.

تُنشئ المهمّة أيضًا sprockets-manifest-md5hash.json. (حيث md5hash هي تجزئة MD5) الذي يحتوي على قائمة بجميع أصولك وبصماتها. تستخدمها توابع Rails المساعدة لتجنّب تسليم طلبات التخطيط (mapping requests) مرة أخرى إلى Sprockets. يبدو ملف بيان اعتيادي كما يلي:

{"files":{"application-aee4be71f1288037ae78b997df388332edfd246471b533dcedaa8f9fe156442b.js":{"logical_path":"application.js","mtime":"2016-12-23T20:12:03-05:00","size":412383,

"digest":"aee4be71f1288037ae78b997df388332edfd246471b533dcedaa8f9fe156442b","integrity":"sha256-ruS+cfEogDeueLmX3ziDMu39JGRxtTPc7aqPn+FWRCs="},

"application-86a292b5070793c37e2c0e5f39f73bb387644eaeada7f96e6fc040a028b16c18.css":{"logical_path":"application.css","mtime":"2016-12-23T19:12:20-05:00","size":2994,

"digest":"86a292b5070793c37e2c0e5f39f73bb387644eaeada7f96e6fc040a028b16c18","integrity":"sha256-hqKStQcHk8N+LA5fOfc7s4dkTq6tp/lub8BAoCixbBg="},

"favicon-8d2387b8d4d32cecd93fa3900df0e9ff89d01aacd84f50e780c17c9f6b3d0eda.ico":{"logical_path":"favicon.ico","mtime":"2016-12-23T20:11:00-05:00","size":8629,

"digest":"8d2387b8d4d32cecd93fa3900df0e9ff89d01aacd84f50e780c17c9f6b3d0eda","integrity":"sha256-jSOHuNTTLOzZP6OQDfDp/4nQGqzYT1DngMF8n2s9Dto="},

"my_image-f4028156fd7eca03584d5f2fc0470df1e0dbc7369eaae638b2ff033f988ec493.png":{"logical_path":"my_image.png","mtime":"2016-12-23T20:10:54-05:00","size":23414,

<nowiki>"digest":"f4028156fd7eca03584d5f2fc0470df1e0dbc7369eaae638b2ff033f988ec493","integrity":"sha256-9AKBVv1+ygNYTV8vwEcN8eDbxzaequY4sv8DP5iOxJM="}},</nowiki>

"assets":{"application.js":"application-aee4be71f1288037ae78b997df388332edfd246471b533dcedaa8f9fe156442b.js",

"application.css":"application-86a292b5070793c37e2c0e5f39f73bb387644eaeada7f96e6fc040a028b16c18.css",

"favicon.ico":"favicon-8d2387b8d4d32cecd93fa3900df0e9ff89d01aacd84f50e780c17c9f6b3d0eda.ico",

<nowiki>"my_image.png":"my_image-f4028156fd7eca03584d5f2fc0470df1e0dbc7369eaae638b2ff033f988ec493.png"}}</nowiki>

الموقع الافتراضي لملف manifest هو جذر الموقع المحدّد في config.assets.prefix (أو '/assets' بشكل افتراضي).

إن افتُقدت ملفّات precompiled في الإنتاج ستحصل على استثناء Sprockets::Helpers::RailsHelper::AssetPaths::AssetNotPrecompiledError يشير إلى اسم الملف (الملفّات) المفقودة.

الترويسة ذات تاريخ صلاحيّة في المستقبل البعيد (Far-future Expires Header)

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

بالنسبة إلى Apache:

# Apache الوحدة  Expires* يتطلّب التوجيه

<nowiki>#</nowiki> `mod_expires` ستُفعّل

<Location /assets/>

 # Last-Modified غير منصوح به لما يوجد ETag إستعمال

 Header unset ETag

 FileETag None

 # ذاكرة تخزين مؤقتة لسنة واحدة  RFC يقول

 ExpiresActive On

 ExpiresDefault "access plus 1 year"

</Location>

بالنسبة إلى NGINX:

location ~ ^/assets/ {

 expires 1y;

 add_header Cache-Control public;

 add_header ETag "";

}

التصريف المسبق المحلّي

هناك عدّة أسباب قد تُرغّبك في تصريف أصولك محليًّا. من بين هؤلاء:

  • قد لا تمتلك حق الوصول للكتابة بنظام ملفّات إنتاجك.
  • قد تنشر بأكثر من خادم واحد وتريد تجنب تكرار العمل.
  • ربما تنشر بكثرة نشرات لا تتضمّن تغييرات في الأصول.

يسمح لك التصريف المحلّي بحفظ (commit) الملفّات المُصرّفة في عنصر التحكم بالمصدر ونشرها كالمعتاد.

هناك ثلاثة تحذيرات:

  • يجب عدم تشغيل مهمّة نشر Capistrano التي تصرّف الأصول إستباقيًّا.
  • يجب التأكّد من توفّر أي ضواغط (compressors) أو مقلّصات (minifiers) ضروريّة في نظام تطويرك.
  • يجب تغيير إعداد التطبيق التالي:

في config/environments/development.rb ضع السطر التالي:

config.assets.prefix = "/dev-assets"

يؤدي تغيير prefix لاستخدام Sprockets عنوان URL آخر لعرض الأصول في وضع التطوير وتمرير كل الطلبات إلى Sprockets. لا تزال البادئة (prefix) مضبوطة على assets/ في بيئة الإنتاج. بدون هذا التغيير، سيُقدّم التطبيق الأصول المُصرّفة مسبقًا من assets/ في التطوير ولن ترى أي تغييرات محليّة حتى تعيد تصريف الأصول مرة أخرى.

في الممارسة العملية، يسمح لك هذا بالتصريف الاستباقي محليًّا ووضع تلك الملفّات في شجرة عملك وحفظ (commit) هذه الملفّات بالتحكم في المصدر (source control) عند الحاجة. يعمل وضع التطوير مثل المتوقّع.

التصريف المباشر (Live Compilation)

قد ترغب ببعض الحالات في استخدام التصريف المباشر (Live Compilation). يتعامل Sprockets مع جميع طلبات الأصول الموجودة في خط الأنابيب مباشرة في هذا الوضع.

لتفعيل مجموعة الخيارات هذه:

config.assets.compile = true

في الطلب الأول تُصرّف الأصول وتخزّن مؤقّتًا كما هو موضّح في التطوير أعلاه، وتتغيّر أسماء manifest المستخدمة في المساعدات لتشمل التجزئة SHA256.

تحدّد Sprockets ترويسة HTTP Cache-Control إلى max-age=31536000 . يُنبّه هذا جميع ذاكرات التخزين المؤقّت بين الخادم ومتصفّح العميل أن من الممكن تخزين هذا المحتوى (الملف المقدّم) مؤقّتًا لمدة عام واحد. النتيجة هي تقليل عدد طلبات هذا الأصل من خادمك؛ هناك فرصة جيّدة أن يكون الأصل بذاكرة التخزين المؤقّت للمتصفّح المحلّي أو ذاكرة تخزين مؤقّت وسيطة.

يستخدم هذا الوضع ذاكرة أكثر مع أداء أقل من الوضع الافتراضي ولا يُنصح به.

إن كنت بصدد نشر تطبيق إنتاج على نظام دون أي تنفيذ JavaScript سابق (pre-existing JavaScript runtimes)، قد ترغب في إضافة أحدهم إلى ملفك Gemfile:

group :production do

 gem 'mini_racer'

end

شبكات تسليم المحتوى CDNs

CDN تعني شبكة تسليم محتوى (Content Delivery Network)، وهي مصمّمة بشكل أساسي لتخزين الأصول حول العالم بحيث توجد نسخة مخبّأة قريبة جغرافيًا من المتصفّح عندما يطلب أصولًا. أفضل ممارسة هي استخدام CDN أمام تطبيقك إن كنت تقدّم الأصول مباشرة من خادمك Rails في الإنتاج.

إن النمط الشائع لاستخدام CDN هو تعيين تطبيق إنتاجك كالخادم "الأصلي". يعني هذا أن المتصفّح سيأخذ الملف مباشرة من خادمك لو طلب أصلًا ما من CDN ولم يوجد بذاكرة التخزين المؤقّت ثم يخزّنه مؤقّتًا. إن شغّلت تطبيق Rails على example.com مثلًا ولديك CDN مُعدّ على mycdnsubdomain.fictional-cdn.com، سيستعلم CDN خادمك مرة واحدة عند تقديم طلب إلى mycdnsubdomain.fictional- cdn.com/assets/smile.png فيexample.com/assets/smile.png ثمّ يخزّن الطلب. سيأخذ الطلب التالي إلى شبكة CDN لنفس العنوان URL الأصل من النسخة المخزّنة. لا يقرب الطلب خادم Rails بتاتًا عندما يمكن لـ CDN أن تقدم الأصل مباشرةً. يكون الطلب أسرع نظرًا لأن الأصول من شبكة CDN أقرب جغرافيًا للمتصفّح، وبما أن الخادم لا يحتاج إلى قضاء وقت في تقديم الأصول، يستطيع التركيز على تقديم شفرات التطبيق بأسرع وقت ممكن.

إعداد CDN لتقديم أصول ثابتة

لإعداد CDN خاص بك، يجب تشغيل تطبيقك على الإنترنت على عنوان URL متاح للعموم، example.com مثلًا. بعد ذلك، ستحتاج للتسجيل بخدمة CDN من موفّر استضافة سحابيّة (cloud hosting provider). ثم تحتاج إلى إعداد "أصل" CDN للإشارة إلى موقعك example.com، تحقّق من موفّرك للحصول على توثيقات حول إعداد خادم الأصل.

يجب أن تعطيك CDN التي خصّصتها عنوانًا فرعيًا مخصصًا لتطبيقك مثل mycdnsubdomain.fictional-cdn.com (ملاحظة: fictional-cdn.com ليس موفّر CDN صالح في وقت كتابة هذه السطور). الآن بعد أن أعددت خادمك CDN،  ستحتاج لإخبار المتصفحّات أن يستخدموه لأخذ الأصول بدلاً من خادمك Rails مباشرةً. يمكنك ذلك عن طريق إعداد Rails ليعيّن CDN كمضيف الأصول بدلاً من استخدام مسار نسبي. لتعيين مضيف الأصول في ،Rails يجب تعيين config.action_controller.asset_host في config/environments/production.rb:

config.action_controller.asset_host = 'mycdnsubdomain.fictional-cdn.com'

تحتاج فقط إلى توفير "المضيف"، هذا هو النطاق الفرعي ومجال الجذر، لا تحتاج إلى تحديد بروتوكول أو "مخطط" مثل //:http أو //:https. عند طلب صفحة ويب، سيطابق البروتوكول الموجود برابط الأصول المُولّد كيفيّة الوصول إلى صفحة الويب افتراضيًّا.

يمكنك أيضًا تعيين هذه القيمة عبر متغيّر بيئة لجعل تشغيل نسخة تدريج (staging copy) موقعك أسهل:

config.action_controller.asset_host = ENV['CDN_HOST']

ملاحظة: ستحتاج إلى ضبط CDN_HOST بخادمك على mycdnsubdomain .fictional-cdn.com.

بمجرد إعدادك لخادمك وشبكتك CDN عند تقديم صفحة ويب بها أصل:

<%= asset_path('smile.png') %>

بدلاً من رد مسار مثل assets/smile.png/ (تجاهلنا digests من أجل سهولة القراءة)، سيتضمن العنوان URL المُولّد المسار الكامل لشبكتك CDN:

<nowiki>http://mycdnsubdomain.fictional-cdn.com/assets/smile.png</nowiki>

إن امتلكت CDN نسخة من ،smile.png ستقدّمها في المتصفّح ولن يعرف خادمك حتى أنها طُلبت. إن لم تمتلك CDN نسخة، ستحاول العثور عليها في "الأصل" example.com/assets/smile.png، ثم تُخزّنها للاستخدام في المستقبل.

إن رغبت في عرض بعض الأصول فقط من شبكتك CDN، يمكنك استخدام الخيار host: بمساعد أصولك، والذي يعيد تعريف القيمة المحدّدة في config.action_controller.asset_host.

<%= asset_path 'image.png', host: 'mycdnsubdomain.fictional-cdn.com' %>

تخصيص سلوك التخزين المؤقّت CDN

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

طلب التخزين المؤقّت لطلب CDN

في حين توصف CDN بأنها جيّدة لتخزين الأصول المؤقّتلًا هي تخزّن في الواقع الطلب بأكمله. يتضمن ذلك جسد (body)الأصل وأي ترويسات. وأهمها هو Cache-Control الذي يخبر CDN (ومتصفحّات الويب) بكيفيّة تخزين المحتويات. أي لو طلب شخص ما أصلًا غير موجود assets/i-dont-exist.png/ وكان رد تطبيق Rails خطأ 404، من المرجح أن يخزّن CDN الصفحة 404 إن وجدت ترويسة Cache-Control صالحة.

تصحيح ترويسات CDN

استخدام curl طريقة من طرق التحقق من تخزين الترويسات بشكل صحيح في  شبكتك CDN. يمكنك طلب الترويسات من كل من خادمك وشبكتك CDN للتحقق من أنها تطابقهما:

$ curl -I <nowiki>http://www.example/assets/application-</nowiki>

d0e099e021c95eb0de3615fd1d8c4d83.css

HTTP/1.1 200 OK

Server: Cowboy

Date: Sun, 24 Aug 2014 20:27:50 GMT

Connection: keep-alive

Last-Modified: Thu, 08 May 2014 01:24:14 GMT

Content-Type: text/css

Cache-Control: public, max-age=2592000

Content-Length: 126560

Via: 1.1 vegur

مقابل نسخة CDN.

$ curl -I <nowiki>http://mycdnsubdomain.fictional-cdn.com/application-</nowiki>

d0e099e021c95eb0de3615fd1d8c4d83.css

HTTP/1.1 200 OK Server: Cowboy Last-

Modified: Thu, 08 May 2014 01:24:14 GMT Content-Type: text/css

Cache-Control:

public, max-age=2592000

Via: 1.1 vegur

Content-Length: 126560

Accept-Ranges:

bytes

Date: Sun, 24 Aug 2014 20:28:45 GMT

Via: 1.1 varnish

Age: 885814

Connection: keep-alive

X-Served-By: cache-dfw1828-DFW

X-Cache: HIT

X-Cache-Hits:

68

X-Timer: S1408912125.211638212,VS0,VE0

تحقق من توثيقات شبكتك CDN لأي معلومات إضافية قد تقدّمها مثل X-Cache أو لأي ترويسات إضافيّة قد يضيفونها.

شبكات CDN وترويسة Cache-Control

لتعتبر ترويسة التحكم في ذاكرة التخزين المؤقّت (cache control header) أحد مواصفات W3C التي توضّح كيفيّة تخزين الطلب مؤقّتًا. سيستخدم المتصفّح هذه المعلومات لتخزين المحتويات مؤقّتًا عند عدم استخدام أي CDN. هذا مفيد جدًا للأصول التي لم تُعدّل بحيث لا يحتاج المتصفّح لإعادة تنزيل CSS أو JavaScript لموقع الويب مع كل طلب. بشكل عام نريد أن يخبر خادمنا Rails الشبكة CDN (والمتصفّح) بأن الأصل "عام" أي أن أي ذاكرة تخزين مؤقّت تستطيع تخزين الطلب. كما نرغب عمومًا أيضًا في ضبط المدّة max-age وهي مدّة تخزين الذاكرة التخزين المؤقّت للكائن قبل إبطالها. تُحسب قيمة max-age بالثواني مع حد أقصى يبلغ 31536000 وهو عام واحد. يمكنك فعل ذلك في تطبيقك Rails عن طريق الإعداد التالي:

config.public_file_server.headers = {

 'Cache-Control' => 'public, max-age=31536000'

}

الآن عندما يقدّم تطبيقك أصلًا في الإنتاج، سيخزّن نظام CDN الأصل لمدة تصل إلى عام. نظرًا لأن معظم شبكات CDNs تُخزّن ترويسات الطلبات مؤقّتًا، سيُمرّر Cache-Control إلى جميع المتصفحّات المستقبلية التي تبحث عن هذا الأصل ويعرف المتصفّح بعد ذلك أن بإمكانه تخزين هذا الأصل لفترة طويلة جدًا قبل الحاجة لإعادة طلبها.

CDNs و إبطال ذاكرة التخزين المؤقّت المستند إلى URL

تخزّن معظم شبكات CDN محتويات الأصل مؤقّتًا استنادًا إلى عنوان URL الكامل. أي أن طلبًا إلى :

<nowiki>http://mycdnsubdomain.fictional-cdn.com/assets/smile-123.png</nowiki>

سيكون سيختلف تماما عن:

<nowiki>http://mycdnsubdomain.fictional-cdn.com/assets/smile.png</nowiki>

إن أردت تعيين max-age للمستقبل البعيد (far future) في Cache-Control (وأنت فعلًا ترغب بذلك)، تأكّد عند تغيير أصولك من أن ذاكرة تخزينك باطلة. عند تغيير الوجه المبتسم مثلًا في صورة من الأصفر إلى الأزرق، ستريد أن يحصل جميع زوار موقعك على الوجه الأزرق الجديد. عند استخدام CDN مع أنبوب الأصول Rails، تُضبط قيمة config.assets.digest على true افتراضيًا بحيث يكون لكل أصل اسم ملف مختلف عند تغييره. بهذه الطريقة، لن تضطّر لإبطال أي عناصر في ذاكرة التخزين المؤقّت. باستخدام اسم أصل فريد مختلف بدلاً من ذلك، يحصل المستخدمون على آخر الأصول.

تخصيص الأنابيب

ضغط CSS

أحد الخيارات لضغط CSS هو YUI. يوفّر الضاغط YUI CSS خدمة تقليص.

يفعّل السطر التالي ضغط YUI ويتطلّب جوهرة yui-compressor:

config.assets.css_compressor = :yui

الخيار الآخر لضغط CSS إن امتلكت جوهرة sass-rails مثبّتة هو :

config.assets.css_compressor = :sass

ضغط JavaScript

الخيارات الممكنة لضغط JavaScript هي: closure: و uglifier: و yui:. وتتطلبن استخدام الجواهر closure-compiler أو uglifier أو yui-compressor على التوالي.

يتضّمن Gemfile الافتراضي uglifier. تلف هذه الجوهرة UglifyJS (مكتوبة من أجل NodeJS) في روبي. تصغّر شفرتك عبر إزالة المساحة البيضاء والتعليقات، وتقصير أسماء المتغيّرات المحلية، وأداء غيرها من التحسينات الصغيرة مثل تغيير تصريحات if و else لعاملات ثلاثية (ternary operators) حيثما أمكن.

يستدعى السطر التالي uglifier لضغط JavaScript:

config.assets.js_compressor = :uglifier

ستحتاج إلى تنفيذ مدعوم من ExecJS كي تستخدم uglifier. لديك تنفيذ JavaScript مثبت في نظام تشغيلك إن كنت تستخدم macOS أو Windows.

تقديم نسخة GZipped من الأصول

ستُولّد نسخة gzipped من الأصول المُصرّفة افتراضيًّا إلى جانب نسخة غير gzipped من الأصول. تساعد الأصول Gzipped في تقليل إرسال البيانات عبر السلك. يمكنك إعداده عبر ضبط علامة gzip:

config.assets.gzip = false # disable gzipped assets generation

استخدام ضاغطك الخاص

تأخذ إعدادات تهيئة الضاغط لـ CSS و JavaScript أيضًا أي كائن. يجب أن يحتوي هذا الكائن على تابع compress يأخذ سلسلة كوسيطة وحيدة ويجب أن يرد سلسلة نصيّة:

class Transformer

 def compress(string)

do_something_returning_a_string(string)

 end

end

مرّر كائنًا جديدًا إلى خيار الإعداد في application.rb:

config.assets.css_compressor = Transformer.new

تغيير مسار الأصول

المسار العام الذي يستخدمه Sprockets افتراضيًّا هو assets/.

يمكن تغييره إلى مسار آخر:

config.assets.prefix = "/some_other_path"

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

ترويسات X-Sendfile

الترويسة X-Sendfile توجيه لخادم الويب لتجاهل الاستجابة من التطبيق، وبدلًا من ذلك تقديم ملف محدّد من القرص. هذا الخيار معطّل افتراضيًا، ولكن يمكن تفعيله إن دعمه الخادم. تُمرّر عند التفعيل مسؤوليّة خدمة الملف إلى خادم الويب وهو أسرع. ألق نظرة على send_file حول كيفيّة استخدام هذه الميزة.

يدعم Apache و NGINX هذا الخيار الذي يمكن تفعيله في config/environments/production.rb:

# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache

<nowiki>#</nowiki> config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX

إن كنت بصدد تحديث تطبيق موجود بالفعل وتنوي استخدام هذا الخيار، احرص على لصق خيار الإعداد هذا في production.rb فقط وأي بيئات أخرى تُعرّفها بسلوك الإنتاج (وليس application.rb).

ألق نظرة على مستندات خادم ويب إنتاجك:

- Apache

- NGINX

لمزيد من التفاصيل.

مخزن ذاكرة التخزين المؤقت للأصول

يخزّن Sprockets الأصول افتراضيًّا في tmp/cache/assets في بيئات التطوير والإنتاج. يمكن تغيير هذا الأسلوب كما يلي:

<nowiki>config.assets.configure do |env|</nowiki>

 env.cache = ActiveSupport::Cache.lookup_store(:memory_store,

                                           	{ size: 32.megabytes })

end

لتعطيل مخزن ذاكرة التخزين المؤقّت للأصول:

<nowiki>config.assets.configure do |env|</nowiki>

 env.cache = ActiveSupport::Cache.lookup_store(:null_store)

end

إضافة الأصول إلى جواهرك

يمكن أيضا أن تأتي الأصول أيضًا من مصادر خارجية في شكل جواهر.

وخير مثال على ذلك جوهرة jquery-rails. تحتوي هذه الجواهر على صنف محرّك يرث من Rails::Engine. وبهذا يُبلّغ Rails أن دليل هذه الجواهر قد يحتوي على أصول ويُضاف app/assets و lib/assets vendor/assets ومجلّداتvendor/assets خاصّة بهذا المحرك إلى مسار البحث في Sprockets.

جعل مكتبتك أو جوهرتك معالجين إستباقيين (Pre-Processor)

تستخدم Sprockets المعالجات والمحوّلات والضاغطات والمصدّرات لتوسيع وظائف Sprockets. ألق نظرة على تمديد Sprockets لمعرفة المزيد. سجّلنا هنا معالجًا مسبقًا لإضافة تعليق إلى نهاية ملفّات text/css (ذات الامتداد css. ).

module AddComment

 def self.call(input)

{ data: input[:data] + "/* Hello From my sprockets extension */" }

 end

end

والآن بعد أن صار لديك وحدة تعمل على تعديل بيانات الإدخال، حان الوقت لتسجيلها كمعالِج مسبق لنوع mime.

Sprockets.register_preprocessor 'text/css', AddComment

الترقية من نسخ Rails القديمة

هناك بعض المشكلات عند الترقية من Rails 3.0 أو Rails 2.x. أوّلها نقل الملفّات من /public إلى المواقع الجديدة. راجع تنظيم الأصول المذكور أعلاه لإرشادات حول المواقع الصحيحة لأنواع الملفّات المختلفة.

الخطوة التالية هي تحديث ملفّات البيئة المختلفة مع الخيارات الافتراضيّة الصحيحة.

في application.rb:

# Version of your assets, change this if you want to expire all your assets

config.assets.version = '1.0'

<nowiki>#</nowiki> Change the path that assets are served from config.assets.prefix = "/assets"

في development.rb:

# Expands the lines which load the assets

config.assets.debug = true

وفي production.rb:

# Choose the compressors to use (if any)

config.assets.js_compressor = :uglifier

<nowiki>#</nowiki> config.assets.css_compressor = :yui

<nowiki>#</nowiki> Don't fallback to assets pipeline if a precompiled asset is missed

config.assets.compile = false

<nowiki>#</nowiki> Generate digests for assets URLs.

config.assets.digest = true

<nowiki>#</nowiki> Precompile additional assets (application.js, application.css, and all

<nowiki>#</nowiki> non-JS/CSS are already added)

<nowiki>#</nowiki> config.assets.precompile += %w( admin.js admin.css )

لم يعد Rails 4 وما أعلى يعيّنون قيم الإعداد الافتراضية لـ Sprockets في test.rb، لذلك يتطلّب test.rb الآن إعداد Sprockets. الإعدادات الافتراضية القديمة في بيئة الاختبار هي:

config.assets.compile = true, config.assets.compress = false,

config.assets.debug = false and config.assets.digest = false.

يجب أيضًا إضافة ما يلي إلى Gemfile:

gem 'sass-rails',   "~> 3.2.3"

gem 'coffee-rails', "~> 3.2.1"

gem 'uglifier' </syntaxhighlight>

مصادر