প্রকাশিত: 31 জানুয়ারী, 2025
আপনার ব্রাউজারে একটি সম্পূর্ণ কার্যকরী ব্লগ চালানোর কল্পনা করুন—শুধু ফ্রন্টএন্ড নয়, ব্যাকএন্ডেও। কোনো সার্ভার বা ক্লাউড জড়িত নয়—শুধু আপনি, আপনার ব্রাউজার, এবং... ওয়েব অ্যাসেম্বলি ! সার্ভার-সাইড ফ্রেমওয়ার্ককে স্থানীয়ভাবে চালানোর অনুমতি দিয়ে, WebAssembly ক্লাসিক ওয়েব ডেভেলপমেন্টের সীমানা ঝাপসা করে দিচ্ছে এবং নতুন নতুন সম্ভাবনার উন্মোচন করছে। এই পোস্টে, ভ্লাদিমির ডেমেন্তিয়েভ (হেড অফ ব্যাকএন্ড অ্যাট ইভিল মার্টিয়ান্স ) রেল ওয়াসম- এবং ব্রাউজার-রেডিতে রুবি তৈরির অগ্রগতি শেয়ার করেছেন:
- কিভাবে 15 মিনিটের মধ্যে ব্রাউজারে Rails আনতে হয়।
- রেইলস ওয়াসমিফিকেশনের পর্দার আড়ালে।
- রেল এবং ওয়াসমের ভবিষ্যত।
রুবি অন রেলের বিখ্যাত "ব্লগ ইন 15 মিনিট" এখন আপনার ব্রাউজারে চলছে
Ruby on Rails হল একটি ওয়েব ফ্রেমওয়ার্ক যা ডেভেলপারের উৎপাদনশীলতা এবং দ্রুত জিনিস পাঠানোর উপর দৃষ্টি নিবদ্ধ করে। এটি হল GitHub এবং Shopify এর মতো শিল্প নেতাদের দ্বারা ব্যবহৃত প্রযুক্তি৷ ফ্রেমওয়ার্কের জনপ্রিয়তা অনেক বছর আগে ডেভিড হেইনমেয়ার হ্যানসন (বা ডিএইচএইচ) দ্বারা প্রকাশিত বিখ্যাত "কিভাবে 15 মিনিটে একটি ব্লগ তৈরি করবেন" ভিডিও প্রকাশের মাধ্যমে শুরু হয়েছিল। 2005 সালে, এত অল্প সময়ের মধ্যে একটি সম্পূর্ণরূপে কাজ করা ওয়েব অ্যাপ্লিকেশন তৈরি করা অকল্পনীয় ছিল। এটা জাদু মত অনুভূত!
আজ, আমি আপনার ব্রাউজারে সম্পূর্ণভাবে চলে এমন একটি Rails অ্যাপ্লিকেশন তৈরি করে এই জাদুকরী অনুভূতি ফিরিয়ে আনতে চাই। আপনার যাত্রা শুরু হয় সাধারণ উপায়ে একটি বেসিক রেল অ্যাপ্লিকেশন তৈরি করে এবং তারপর এটিকে Wasm-এর জন্য প্যাকেজ করার মাধ্যমে।
পটভূমি: কমান্ড লাইনে একটি "15 মিনিটের মধ্যে ব্লগ"
ধরে নিলাম আপনার মেশিনে Ruby এবং Ruby on Rails ইনস্টল করা আছে, আপনি একটি নতুন Ruby on Rails অ্যাপ্লিকেশন তৈরি করে এবং কিছু কার্যকারিতা স্ক্যাফোল্ডিং দিয়ে শুরু করেন (যেমন আসল "ব্লগ ইন 15 মিনিট" ভিডিওতে):
$ rails new --css=tailwind web_dev_blog
create .ruby-version
...
$ cd web_dev_blog
$ bin/rails generate scaffold Post title:string date:date body:text
create db/migrate/20241217183624_create_posts.rb
create app/models/post.rb
...
$ bin/rails db:migrate
== 20241217183624 CreatePosts: migrating ====================
-- create_table(:posts)
-> 0.0017s
== 20241217183624 CreatePosts: migrated (0.0018s) ===========
এমনকি কোডবেস স্পর্শ না করেও, আপনি এখন অ্যাপ্লিকেশনটি চালাতে পারেন এবং এটিকে কার্যকরভাবে দেখতে পারেন:
$ bin/dev
=> Booting Puma
=> Rails 8.0.1 application starting in development
...
* Listening on http://127.0.0.1:3000
এখন, আপনি http://localhost:3000/posts- এ আপনার ব্লগ খুলতে পারেন এবং পোস্ট লেখা শুরু করতে পারেন!
আপনি একটি খুব খালি-হাড় আছে, কিন্তু কার্যকরী ব্লগ অ্যাপ্লিকেশন মিনিটের মধ্যে নির্মিত. এটি একটি সম্পূর্ণ-স্ট্যাক, সার্ভার-নিয়ন্ত্রিত অ্যাপ্লিকেশন: আপনার ডেটা রাখার জন্য আপনার কাছে একটি ডাটাবেস ( SQLite ) আছে, HTTP অনুরোধগুলি পরিচালনা করার জন্য একটি ওয়েব সার্ভার ( Puma ), এবং একটি রুবি প্রোগ্রাম রয়েছে যা আপনার ব্যবসার যুক্তি বজায় রাখতে, UI প্রদান করতে এবং ব্যবহারকারীর মিথস্ক্রিয়া প্রক্রিয়া করতে পারে৷ অবশেষে, ব্রাউজিং অভিজ্ঞতাকে স্ট্রীমলাইন করার জন্য জাভাস্ক্রিপ্ট ( Turbo ) এর একটি পাতলা স্তর রয়েছে।
অফিসিয়াল রেল ডেমো এই অ্যাপ্লিকেশনটিকে একটি বেয়ার মেটাল সার্ভারে স্থাপন করার দিক দিয়ে চলতে থাকে এবং এইভাবে, এটিকে উৎপাদন-প্রস্তুত করে। আপনার যাত্রা বিপরীত দিকে চলতে থাকবে: আপনার আবেদনটি দূরে কোথাও রাখার পরিবর্তে, আপনি এটিকে স্থানীয়ভাবে "নিয়োজিত" করবেন।
পরবর্তী স্তর: ওয়াসম-এ একটি "15 মিনিটের মধ্যে ব্লগ"৷
WebAssembly সংযোজনের পর থেকে, ব্রাউজারগুলি শুধুমাত্র জাভাস্ক্রিপ্ট কোড নয়, Wasm-এ সংকলনযোগ্য যেকোন কোড চালাতে সক্ষম হয়েছে। আর রুবিও এর ব্যতিক্রম নয়। নিঃসন্দেহে, রেলগুলি রুবির চেয়ে বেশি, তবে পার্থক্যগুলি খনন করার আগে, আসুন আমরা ডেমো এবং ওয়াসমিফাই ( ওয়াসমিফাই-রেল লাইব্রেরি দ্বারা তৈরি একটি ক্রিয়া) রেল অ্যাপ্লিকেশনটি চালিয়ে যাই!
আপনার ব্লগ অ্যাপ্লিকেশনটিকে একটি Wasm মডিউলে কম্পাইল করতে এবং ব্রাউজারে চালানোর জন্য আপনাকে শুধুমাত্র কয়েকটি কমান্ড কার্যকর করতে হবে।
প্রথমে, আপনি বান্ডলার (রুবির npm
) ব্যবহার করে wasmify-rails লাইব্রেরি ইনস্টল করুন এবং Rails CLI ব্যবহার করে এর জেনারেটর চালান:
$ bundle add wasmify-rails
$ bin/rails wasmify:install
create config/wasmify.yml
create config/environments/wasm.rb
...
info ✅ The application is prepared for Wasm-ificaiton!
wasmify:rails
কমান্ড একটি ডেডিকেটেড "wasm" এক্সিকিউশন এনভায়রনমেন্ট কনফিগার করে (ডিফল্ট "ডেভেলপমেন্ট", "টেস্ট" এবং "প্রোডাকশন" এনভায়রনমেন্ট ছাড়াও) এবং প্রয়োজনীয় নির্ভরতা ইনস্টল করে। একটি গ্রীনফিল্ড রেল অ্যাপ্লিকেশনের জন্য, এটি ওয়াসম-প্রস্তুত করার জন্য যথেষ্ট।
এর পরে, রুবি রানটাইম, স্ট্যান্ডার্ড লাইব্রেরি এবং সমস্ত অ্যাপ্লিকেশন নির্ভরতা ধারণকারী মূল Wasm মডিউল তৈরি করুন:
$ bin/rails wasmify:build
==> RubyWasm::BuildSource(3.3) -- Building
...
==> RubyWasm::CrossRubyProduct(ruby-3.3-wasm32-unknown-wasip1-full-4aaed4fbda7afe0bdf4e22167afd101e) -- done in 47.37s
INFO: Packaging gem: rake-13.2.1
...
INFO: Packaging gem: wasmify-rails-0.2.0
INFO: Packaging setup.rb: bundle/setup.rb
INFO: Size: 73.77 MB
এই ধাপে কিছু সময় লাগতে পারে: তৃতীয় পক্ষের লাইব্রেরি থেকে নেটিভ এক্সটেনশনগুলি (সি তে লেখা) সঠিকভাবে লিঙ্ক করতে আপনাকে উৎস থেকে রুবি তৈরি করতে হবে। এই (অস্থায়ী) অপূর্ণতা পোস্টে পরে কভার করা হয়েছে.
সংকলিত Wasm মডিউল আপনার অ্যাপ্লিকেশনের জন্য একটি ভিত্তি মাত্র। আপনাকে অবশ্যই অ্যাপ্লিকেশন কোড এবং সমস্ত সম্পদ (উদাহরণস্বরূপ, ছবি, CSS, JavaScript) প্যাক করতে হবে। প্যাকিং করার আগে, একটি মৌলিক লঞ্চার অ্যাপ্লিকেশন তৈরি করুন যা ব্রাউজারে ওয়াসমিফাইড রেল চালানোর জন্য ব্যবহার করা যেতে পারে। এর জন্য, একটি জেনারেটর কমান্ডও রয়েছে:
$ bin/rails wasmify:pwa
create pwa
create pwa/boot.html
create pwa/boot.js
...
prepend config/wasmify.yml
পূর্ববর্তী কমান্ড Vite এর সাথে নির্মিত একটি ন্যূনতম PWA অ্যাপ্লিকেশন তৈরি করে যা স্থানীয়ভাবে কম্পাইল করা Rails Wasm মডিউল পরীক্ষা করতে বা অ্যাপটি বিতরণ করার জন্য স্থিরভাবে স্থাপন করা যেতে পারে।
এখন, লঞ্চারের সাথে, আপনার যা দরকার তা হল পুরো অ্যাপ্লিকেশনটিকে একটি একক Wasm বাইনারিতে প্যাক করা:
$ bin/rails wasmify:pack
...
Packed the application to pwa/app.wasm
Size: 76.2 MB
তাই তো! লঞ্চার অ্যাপটি চালান এবং দেখুন আপনার Rails ব্লগিং অ্যাপ্লিকেশনটি ব্রাউজারে সম্পূর্ণভাবে চলছে:
$ cd pwa/
$ yarn dev
VITE v4.5.5 ready in 290 ms
➜ Local: http://localhost:5173/
http://localhost:5173 এ যান, "লঞ্চ" বোতামটি সক্রিয় হওয়ার জন্য একটু অপেক্ষা করুন এবং এটিতে ক্লিক করুন—আপনার ব্রাউজারে স্থানীয়ভাবে চলমান Rails অ্যাপের সাথে কাজ করা উপভোগ করুন!
এটা কি শুধু আপনার মেশিনে নয় ব্রাউজার স্যান্ডবক্সের মধ্যে একটি মনোলিথিক সার্ভার-সাইড অ্যাপ্লিকেশন চালানোর মতো জাদু বলে মনে হয় না? আমার জন্য (যদিও আমি "জাদুকর"), এটি এখনও একটি ফ্যান্টাসি মত দেখায়. কিন্তু কোন জাদু জড়িত নেই, শুধুমাত্র প্রযুক্তির অগ্রগতি।
ডেমো
আপনি নিবন্ধে এমবেড করা ডেমো অনুভব করতে পারেন বা একটি স্বতন্ত্র উইন্ডোতে ডেমো চালু করতে পারেন৷ GitHub-এ সোর্স কোডটি দেখুন।
Wasm উপর Rails পর্দার আড়ালে
একটি Wasm মডিউলে একটি সার্ভার-সাইড অ্যাপ্লিকেশন প্যাক করার চ্যালেঞ্জগুলি (এবং সমাধানগুলি) আরও ভালভাবে বোঝার জন্য, এই পোস্টের বাকি অংশগুলি এই আর্কিটেকচারের অংশগুলি ব্যাখ্যা করে৷
একটি ওয়েব অ্যাপ্লিকেশন শুধুমাত্র অ্যাপ্লিকেশন কোড লিখতে ব্যবহৃত একটি প্রোগ্রামিং ভাষা ছাড়াও আরও অনেক কিছুর উপর নির্ভর করে। প্রতিটি উপাদানকে অবশ্যই আপনার_ স্থানীয় স্থাপনার পরিবেশ_ ব্রাউজারে আনতে হবে। "15 মিনিটের মধ্যে ব্লগ" ডেমো সম্পর্কে উত্তেজনাপূর্ণ বিষয় হল এটি অ্যাপ্লিকেশন কোডটি পুনরায় লেখা ছাড়াই অর্জন করা যেতে পারে৷ ক্লাসিক, সার্ভার-সাইড মোডে এবং ব্রাউজারে অ্যাপ্লিকেশন চালানোর জন্য একই কোড ব্যবহার করা হয়েছিল।
একটি ফ্রেমওয়ার্ক, যেমন রুবি অন রেল, আপনাকে একটি ইন্টারফেস দেয়, অবকাঠামোগত উপাদানগুলির সাথে যোগাযোগ করার জন্য একটি বিমূর্ততা। নীচের অংশে আলোচনা করা হয়েছে যে আপনি কীভাবে কিছুটা গোপনীয় স্থানীয় পরিবেশন চাহিদাগুলি পূরণ করতে ফ্রেমওয়ার্ক আর্কিটেকচার ব্যবহার করতে পারেন।
ভিত্তি: ruby.wasm
Ruby আনুষ্ঠানিকভাবে 2022 সালে Wasm-এর জন্য প্রস্তুত হয়ে ওঠে (সংস্করণ 3.2.0 থেকে) যার অর্থ হল C সোর্স কোড Wasm-এ কম্পাইল করা যেতে পারে এবং আপনি যেখানে চান সেখানে একটি Ruby VM আনতে পারেন। ruby.wasm প্রকল্পটি ব্রাউজারে (বা অন্য কোন জাভাস্ক্রিপ্ট রানটাইম) রুবি চালানোর জন্য প্রি-কম্পাইল করা মডিউল এবং জাভাস্ক্রিপ্ট বাইন্ডিং পাঠায়। ruby:wasm প্রকল্পটি বিল্ড টুলগুলির সাথেও আসে যা আপনাকে অতিরিক্ত নির্ভরশীলতার সাথে একটি কাস্টম রুবি সংস্করণ তৈরি করতে দেয়—এটি C এক্সটেনশন সহ লাইব্রেরির উপর নির্ভরশীল প্রকল্পগুলির জন্য খুবই গুরুত্বপূর্ণ। হ্যাঁ, আপনিও Wasm-এ নেটিভ এক্সটেনশন কম্পাইল করতে পারেন! (ওয়েল, এখনও কোন এক্সটেনশন নয়, কিন্তু তাদের অধিকাংশ)।
বর্তমানে, রুবি সম্পূর্ণরূপে WebAssembly সিস্টেম ইন্টারফেস, WASI 0.1 সমর্থন করে। WASI 0.2 যার মধ্যে কম্পোনেন্ট মডেলটি ইতিমধ্যেই আলফা অবস্থায় রয়েছে এবং সমাপ্তির কয়েক ধাপ। একবার WASI 0.2 সমর্থিত হলে এটি প্রতিবার নতুন নেটিভ নির্ভরতা যোগ করার সময় পুরো ভাষাটি পুনরায় কম্পাইল করার বর্তমান প্রয়োজনীয়তা দূর করবে: সেগুলিকে কম্পোনেন্টাইজ করা যেতে পারে।
একটি পার্শ্ব প্রতিক্রিয়া হিসাবে, উপাদান মডেল বান্ডিল আকার কমাতে সাহায্য করা উচিত. আপনি WebAssembly টক-এ Ruby এর সাথে আপনি কি করতে পারেন থেকে ruby.wasm এর বিকাশ এবং অগ্রগতি সম্পর্কে আরও জানতে পারেন।
সুতরাং, Wasm সমীকরণের রুবি অংশটি সমাধান করা হয়েছে। কিন্তু রেলের একটি ওয়েব ফ্রেমওয়ার্ক হিসাবে পূর্ববর্তী চিত্রে দেখানো সমস্ত উপাদান প্রয়োজন। কিভাবে ব্রাউজারে অন্যান্য উপাদান রাখতে হয় এবং Rails এ তাদের একসাথে লিঙ্ক করতে হয় তা শিখতে পড়ুন।
ব্রাউজারে চলমান একটি ডাটাবেসের সাথে সংযোগ করুন
SQLite3 একটি অফিসিয়াল Wasm ডিস্ট্রিবিউশন এবং একটি সংশ্লিষ্ট জাভাস্ক্রিপ্ট র্যাপার সহ আসে, তাই ব্রাউজারে এম্বেড করার জন্য প্রস্তুত। Wasm-এর জন্য PostgreSQL PGlite প্রকল্পের মাধ্যমে উপলব্ধ। অতএব, আপনাকে শুধুমাত্র Rails on Wasm অ্যাপ্লিকেশন থেকে কিভাবে ব্রাউজার ডাটাবেসের সাথে সংযোগ করতে হবে তা বের করতে হবে।
ডেটা মডেলিং এবং ডাটাবেস ইন্টারঅ্যাকশনের জন্য দায়ী রেলের একটি উপাদান, বা সাব-ফ্রেমওয়ার্ককে বলা হয় সক্রিয় রেকর্ড (হ্যাঁ, ORM ডিজাইন প্যাটার্নের নামানুসারে)। অ্যাক্টিভ রেকর্ড ডাটাবেস অ্যাডাপ্টারের মাধ্যমে অ্যাপ্লিকেশন কোড থেকে প্রকৃত SQL-ভাষী ডাটাবেস বাস্তবায়নকে বিমূর্ত করে। বাক্সের বাইরে, রেল আপনাকে SQLite3, PostgreSQL, এবং MySQL অ্যাডাপ্টার দেয়। যাইহোক, তারা সবাই নেটওয়ার্কে উপলব্ধ বাস্তব ডাটাবেসের সাথে সংযোগ করছে বলে ধরে নেয়। এটি কাটিয়ে উঠতে, আপনি স্থানীয় , ইন-ব্রাউজার ডাটাবেসের সাথে সংযোগ করতে আপনার নিজস্ব অ্যাডাপ্টার লিখতে পারেন!
Wasmify Rails প্রকল্পের একটি অংশ হিসাবে বাস্তবায়িত SQLite3 Wasm এবং PGlite অ্যাডাপ্টারগুলি এইভাবে তৈরি করা হয়:
- অ্যাডাপ্টার ক্লাস সংশ্লিষ্ট বিল্ট-ইন অ্যাডাপ্টার থেকে উত্তরাধিকারসূত্রে প্রাপ্ত হয় (উদাহরণস্বরূপ,
class PGliteAdapter < PostgreSQLAdapter
), তাই আপনি প্রকৃত ক্যোয়ারী প্রস্তুতি এবং ফলাফল পার্সিং লজিক পুনরায় ব্যবহার করতে পারেন। - নিম্ন-স্তরের ডাটাবেস সংযোগের পরিবর্তে, আপনি একটি বাহ্যিক ইন্টারফেস অবজেক্ট ব্যবহার করেন যা JavaScript রানটাইমে থাকে—একটি Rails Wasm মডিউল এবং একটি ডাটাবেসের মধ্যে একটি সেতু।
উদাহরণস্বরূপ, এখানে SQLite3 Wasm এর জন্য ব্রিজ বাস্তবায়ন রয়েছে:
export function registerSQLiteWasmInterface(worker, db, opts = {}) {
const name = opts.name || "sqliteForRails";
worker[name] = {
exec: function (sql) {
let cols = [];
let rows = db.exec(sql, { columnNames: cols, returnValue: "resultRows" });
return {
cols,
rows,
};
},
changes: function () {
return db.changes();
},
};
}
অ্যাপ্লিকেশনের দৃষ্টিকোণ থেকে, একটি বাস্তব ডাটাবেস থেকে একটি ইন-ব্রাউজারে স্থানান্তরটি কেবলমাত্র কনফিগারেশনের বিষয়:
# config/database.yml
development:
adapter: sqlite3
production:
adapter: sqlite3
wasm:
adapter: sqlite3_wasm
js_interface: "sqliteForRails"
একটি স্থানীয় ডাটাবেসের সাথে কাজ করার জন্য অনেক প্রচেষ্টার প্রয়োজন হয় না। যাইহোক, যদি সত্যের কিছু কেন্দ্রীয় উৎসের সাথে ডেটা সিঙ্ক্রোনাইজেশন প্রয়োজন হয়, তাহলে আপনি একটি উচ্চ স্তরের চ্যালেঞ্জের মুখোমুখি হতে পারেন। এই প্রশ্নটি এই পোস্টের সুযোগের বাইরে (ইঙ্গিত: PGlite এবং ElectricSQL ডেমোতে রেলগুলি দেখুন)।
একটি ওয়েব সার্ভার হিসাবে পরিষেবা কর্মী
যেকোনো ওয়েব অ্যাপ্লিকেশনের আরেকটি অপরিহার্য উপাদান হল একটি ওয়েব সার্ভার। ব্যবহারকারীরা HTTP অনুরোধ ব্যবহার করে ওয়েব অ্যাপ্লিকেশনের সাথে যোগাযোগ করে। সুতরাং, আপনার Wasm মডিউলে নেভিগেশন বা ফর্ম জমা দিয়ে ট্রিগার করা HTTP অনুরোধগুলিকে রুট করার একটি উপায় প্রয়োজন। সৌভাগ্যবশত, ব্রাউজার এর জন্য একটি উত্তর আছে - পরিষেবা কর্মীরা ।
একটি পরিষেবা কর্মী হল একটি বিশেষ ধরনের ওয়েব কর্মী যা জাভাস্ক্রিপ্ট অ্যাপ্লিকেশন এবং নেটওয়ার্কের মধ্যে একটি প্রক্সি হিসাবে কাজ করে। এটি অনুরোধগুলিকে আটকাতে পারে এবং সেগুলিকে ম্যানিপুলেট করতে পারে, উদাহরণস্বরূপ: ক্যাশে করা ডেটা পরিবেশন করা, অন্য URL গুলিতে পুনঃনির্দেশ করা বা... Wasm মডিউলগুলিতে! এখানে Wasm-এ চলমান একটি Rails অ্যাপ্লিকেশন ব্যবহার করে অনুরোধ পরিবেশনকারী পরিষেবার একটি স্কেচ রয়েছে:
// The vm variable holds a reference to the Wasm module with a
// Ruby VM initialized
let vm;
// The db variable holds a reference to the in-browser
// database interface
let db;
const initVM = async (progress, opts = {}) => {
if (vm) return vm;
if (!db) {
await initDB(progress);
}
vm = await initRailsVM("/app.wasm");
return vm;
};
const rackHandler = new RackHandler(initVM});
self.addEventListener("fetch", (event) => {
// ...
return event.respondWith(
rackHandler.handle(event.request)
);
});
ব্রাউজার দ্বারা প্রতিবার অনুরোধ করা হলে "আনয়ন" ট্রিগার হয়। আপনি অনুরোধের তথ্য (URL, HTTP শিরোনাম, বডি) পেতে পারেন এবং আপনার নিজস্ব অনুরোধ বস্তু তৈরি করতে পারেন।
রেলগুলি, বেশিরভাগ রুবি ওয়েব অ্যাপ্লিকেশনগুলির মতো, HTTP অনুরোধগুলির সাথে কাজ করার জন্য র্যাক ইন্টারফেসের উপর নির্ভর করে। র্যাক ইন্টারফেস অনুরোধের বিন্যাস এবং প্রতিক্রিয়া বস্তুর পাশাপাশি অন্তর্নিহিত HTTP হ্যান্ডলার (অ্যাপ্লিকেশন) এর ইন্টারফেস বর্ণনা করে। আপনি নিম্নরূপ এই বৈশিষ্ট্য প্রকাশ করতে পারেন:
request = {
"REQUEST_METHOD" => "GET",
"SCRIPT_NAME" => "",
"SERVER_NAME" => "localhost",
"SERVER_PORT" => "3000",
"PATH_INFO" => "/posts"
}
handler = proc do |env|
[
200,
{"Content-Type" => "text/html"},
["<!doctype html><html><body>Hello Web!</body></html>"]
]
end
handler.call(request) #=> [200, {...}, [...]]
আপনি যদি অনুরোধের ফর্ম্যাটটি পরিচিত খুঁজে পান, তাহলে আপনি সম্ভবত সেই দিনগুলিতে CGI এর সাথে কাজ করেছেন।
RackHandler
JavaScript অবজেক্ট জাভাস্ক্রিপ্ট এবং রুবি রাজ্যের মধ্যে অনুরোধ এবং প্রতিক্রিয়া রূপান্তর করার জন্য দায়ী। প্রদত্ত যে র্যাক বেশিরভাগ রুবি ওয়েব অ্যাপ্লিকেশন দ্বারা ব্যবহৃত হয়, বাস্তবায়নটি সর্বজনীন হয়ে ওঠে, রেল-নির্দিষ্ট নয়। প্রকৃত বাস্তবায়ন যদিও এখানে পোস্ট করা খুব দীর্ঘ.
একটি পরিষেবা কর্মী একটি ইন-ব্রাউজার ওয়েব অ্যাপ্লিকেশনের মূল অবিচ্ছেদ্য পয়েন্টগুলির মধ্যে একটি। এটি শুধুমাত্র একটি HTTP প্রক্সি নয়, এটি একটি ক্যাশিং স্তর এবং একটি নেটওয়ার্ক সুইচার (অর্থাৎ, আপনি একটি স্থানীয়-প্রথম বা অফলাইন-সক্ষম অ্যাপ্লিকেশন তৈরি করতে পারেন)। এটি এমন একটি উপাদান যা আপনাকে ব্যবহারকারীর আপলোড করা ফাইলগুলি পরিবেশন করতে সহায়তা করতে পারে।
ব্রাউজারে ফাইল আপলোড রাখুন
আপনার নতুন ব্লগ অ্যাপ্লিকেশনে প্রয়োগ করার জন্য প্রথম অতিরিক্ত বৈশিষ্ট্যগুলির মধ্যে একটি ফাইল আপলোডের জন্য সমর্থন হতে পারে, বা আরও নির্দিষ্টভাবে, পোস্টে ছবি সংযুক্ত করা। এটি অর্জন করার জন্য, আপনার ফাইল সংরক্ষণ এবং পরিবেশন করার একটি উপায় প্রয়োজন।
রেলে, ফাইল আপলোডের সাথে ডিল করার জন্য দায়ী ফ্রেমওয়ার্কের অংশটিকে অ্যাক্টিভ স্টোরেজ বলা হয়। অ্যাক্টিভ স্টোরেজ ডেভেলপারদের নিম্ন-স্তরের স্টোরেজ মেকানিজম সম্পর্কে চিন্তা না করে ফাইলের সাথে কাজ করার জন্য বিমূর্ততা এবং ইন্টারফেস দেয়। হার্ড ড্রাইভে বা ক্লাউডে আপনি আপনার ফাইলগুলি যেখানেই সঞ্চয় করেন না কেন, অ্যাপ্লিকেশন কোডটি এটি সম্পর্কে অজানা থাকে৷
একইভাবে অ্যাক্টিভ রেকর্ডের মতো, একটি কাস্টম স্টোরেজ মেকানিজম সমর্থন করার জন্য, আপনার যা প্রয়োজন তা হল একটি সংশ্লিষ্ট স্টোরেজ পরিষেবা অ্যাডাপ্টার প্রয়োগ করা। ব্রাউজারে ফাইল কোথায় সংরক্ষণ করবেন?
ঐতিহ্যগত বিকল্প একটি ডাটাবেস ব্যবহার করা হয়. হ্যাঁ, আপনি ফাইলগুলিকে ডাটাবেসে ব্লব হিসাবে সংরক্ষণ করতে পারেন, কোনও অতিরিক্ত অবকাঠামো উপাদানের প্রয়োজন নেই৷ এবং এর জন্য ইতিমধ্যেই একটি রেডিমেড প্লাগইন রয়েছে Rails, Active Storage Database- এ। যাইহোক, WebAssembly-এর মধ্যে চলমান Rails অ্যাপ্লিকেশনের মাধ্যমে ডাটাবেসে সংরক্ষিত ফাইলগুলি পরিবেশন করা আদর্শ নয় কারণ এতে (ডি-)সিরিয়ালাইজেশনের রাউন্ড জড়িত যা বিনামূল্যে নয়।
একটি ভাল এবং আরও ব্রাউজার-অপ্টিমাইজ করা সমাধান হল ফাইল সিস্টেম API ব্যবহার করা এবং ফাইল আপলোড এবং সার্ভার আপলোড করা ফাইলগুলি সরাসরি পরিষেবা কর্মী থেকে প্রক্রিয়া করা। এই ধরনের অবকাঠামোর জন্য একটি নিখুঁত প্রার্থী হল OPFS (অরিজিন প্রাইভেট ফাইল সিস্টেম), একটি অতি সাম্প্রতিক ব্রাউজার API যা ভবিষ্যতের ইন-ব্রাউজার অ্যাপ্লিকেশনগুলির জন্য অবশ্যই একটি গুরুত্বপূর্ণ ভূমিকা পালন করবে।
রেল এবং ওয়াসম একসাথে কী অর্জন করতে পারে
আমি নিশ্চিত যে আপনি নিবন্ধটি পড়া শুরু করার সাথে সাথে আপনি নিজেকে এই প্রশ্নটি জিজ্ঞাসা করছেন: কেন ব্রাউজারে একটি সার্ভার-সাইড ফ্রেমওয়ার্ক চালাবেন? একটি ফ্রেমওয়ার্ক বা একটি লাইব্রেরি সার্ভার-সাইড (বা ক্লায়েন্ট-সাইড) হওয়ার ধারণাটি কেবল একটি লেবেল। ভাল কোড এবং, বিশেষ করে, একটি ভাল বিমূর্ততা সর্বত্র কাজ করে। লেবেলগুলি আপনাকে নতুন সম্ভাবনাগুলি অন্বেষণ করা এবং ফ্রেমওয়ার্কের সীমানা (উদাহরণস্বরূপ, রুবি অন রেল) পাশাপাশি রানটাইমের (ওয়েবঅ্যাসেম্বলি) সীমানাগুলিকে ঠেলে দেওয়া উচিত নয়৷ উভয়ই এই ধরনের অপ্রচলিত ব্যবহারের ক্ষেত্রে উপকৃত হতে পারে।
প্রচুর প্রচলিত , বা ব্যবহারিক, ব্যবহারের ক্ষেত্রেও রয়েছে।
প্রথমত, ব্রাউজারে ফ্রেমওয়ার্ক আনার ফলে প্রচুর শেখার এবং প্রোটোটাইপিং সুযোগ উন্মুক্ত হয়। আপনার ব্রাউজারে এবং অন্যান্য লোকেদের সাথে একসাথে লাইব্রেরি, প্লাগইন এবং প্যাটার্নগুলির সাথে খেলতে সক্ষম হওয়ার কল্পনা করুন৷ Stackblitz জাভাস্ক্রিপ্ট ফ্রেমওয়ার্কের জন্য এটি সম্ভব করেছে। আরেকটি উদাহরণ হল একটি ওয়ার্ডপ্রেস খেলার মাঠ যা ওয়েব পৃষ্ঠা ছাড়াই ওয়ার্ডপ্রেস থিমগুলির সাথে খেলা সম্ভব করেছে। Wasm রুবি এবং এর ইকোসিস্টেমের জন্য অনুরূপ কিছু সক্ষম করতে পারে।
ইন-ব্রাউজার কোডিং এর একটি বিশেষ কেস আছে যা বিশেষত ওপেন সোর্স ডেভেলপারদের জন্য উপযোগী- ট্রাইজিং এবং ডিবাগিং সমস্যা । আবার, StackBlitz জাভাস্ক্রিপ্ট প্রকল্পগুলির জন্য এটি একটি জিনিস তৈরি করেছে: আপনি একটি ন্যূনতম পুনরুৎপাদন স্ক্রিপ্ট তৈরি করেন, একটি গিটহাব ইস্যুতে লিঙ্কটি নির্দেশ করেন এবং আপনার দৃশ্যকল্পের পুনরুত্পাদনের জন্য অতিরিক্ত রক্ষণাবেক্ষণকারীদের সময় দেন। এবং, প্রকৃতপক্ষে, Ruby-এ এটি ইতিমধ্যেই ঘটতে শুরু করেছে RunRuby.dev প্রকল্পের জন্য ধন্যবাদ (এখানে একটি উদাহরণ দেওয়া হল ইন-ব্রাউজার রিপ্রোডাকশনের মাধ্যমে সমাধান করা হয়েছে)।
আরেকটি ব্যবহারের ক্ষেত্রে অফলাইন-সক্ষম (বা অফলাইন-সচেতন) অ্যাপ্লিকেশন । অফলাইন-সক্ষম অ্যাপ্লিকেশনগুলি যেগুলি সাধারণত নেটওয়ার্ক ব্যবহার করে কাজ করে, কিন্তু যখন কোনও সংযোগ না থাকে, সেগুলি ব্যবহারযোগ্য থাকে৷ উদাহরণস্বরূপ, একটি ইমেল ক্লায়েন্ট যা আপনাকে অফলাইনে থাকাকালীন আপনার ইনবক্সের মাধ্যমে অনুসন্ধান করতে দেয়। অথবা, "ডিভাইসে স্টোর" ক্ষমতা সহ একটি মিউজিক লাইব্রেরি অ্যাপ্লিকেশন, তাই নেটওয়ার্ক সংযোগ না থাকলেও আপনার প্রিয় সঙ্গীত বাজতে থাকে। উভয় উদাহরণই স্থানীয়ভাবে সংরক্ষিত ডেটার উপর নির্ভর করে, শুধুমাত্র ক্লাসিক PWA এর মতো ক্যাশে ব্যবহার করে না।
অবশেষে, রেলের সাথে স্থানীয় (বা ডেস্কটপ) অ্যাপ্লিকেশনগুলি তৈরি করাও বোধগম্য, কারণ ফ্রেমওয়ার্ক আপনাকে যে উত্পাদনশীলতা দেয় তা রানটাইমের উপর নির্ভর করে না। সম্পূর্ণ বৈশিষ্ট্যযুক্ত ফ্রেমওয়ার্কগুলি ব্যক্তিগত ডেটা- এবং লজিক-ভারী অ্যাপ্লিকেশন তৈরির জন্য উপযুক্ত। এবং পোর্টেবল ডিস্ট্রিবিউশন ফরম্যাট হিসাবে Wasm ব্যবহার করাও একটি কার্যকর বিকল্প।
এটি Wasm যাত্রার এই রেলের শুরু মাত্র। আপনি Ruby on Rails on WebAssembly ইবুক-এ চ্যালেঞ্জ এবং সমাধান সম্পর্কে আরও জানতে পারবেন (যা যাইহোক, একটি অফলাইন-সক্ষম রেল অ্যাপ্লিকেশন)।
,প্রকাশিত: 31 জানুয়ারী, 2025
আপনার ব্রাউজারে একটি সম্পূর্ণ কার্যকরী ব্লগ চালানোর কল্পনা করুন—শুধু ফ্রন্টএন্ড নয়, ব্যাকএন্ডেও। কোনো সার্ভার বা ক্লাউড জড়িত নয়—শুধু আপনি, আপনার ব্রাউজার, এবং... ওয়েব অ্যাসেম্বলি ! সার্ভার-সাইড ফ্রেমওয়ার্ককে স্থানীয়ভাবে চালানোর অনুমতি দিয়ে, WebAssembly ক্লাসিক ওয়েব ডেভেলপমেন্টের সীমানা ঝাপসা করে দিচ্ছে এবং নতুন নতুন সম্ভাবনার উন্মোচন করছে। এই পোস্টে, ভ্লাদিমির ডেমেন্তিয়েভ (হেড অফ ব্যাকএন্ড অ্যাট ইভিল মার্টিয়ান্স ) রেল ওয়াসম- এবং ব্রাউজার-রেডিতে রুবি তৈরির অগ্রগতি শেয়ার করেছেন:
- কিভাবে 15 মিনিটের মধ্যে ব্রাউজারে Rails আনতে হয়।
- রেইলস ওয়াসমিফিকেশনের পর্দার আড়ালে।
- রেল এবং ওয়াসমের ভবিষ্যত।
রুবি অন রেলের বিখ্যাত "ব্লগ ইন 15 মিনিট" এখন আপনার ব্রাউজারে চলছে
Ruby on Rails হল একটি ওয়েব ফ্রেমওয়ার্ক যা ডেভেলপারের উৎপাদনশীলতা এবং দ্রুত জিনিস পাঠানোর উপর দৃষ্টি নিবদ্ধ করে। এটি হল GitHub এবং Shopify এর মতো শিল্প নেতাদের দ্বারা ব্যবহৃত প্রযুক্তি৷ ফ্রেমওয়ার্কের জনপ্রিয়তা অনেক বছর আগে ডেভিড হেইনমেয়ার হ্যানসন (বা ডিএইচএইচ) দ্বারা প্রকাশিত বিখ্যাত "কিভাবে 15 মিনিটে একটি ব্লগ তৈরি করবেন" ভিডিও প্রকাশের মাধ্যমে শুরু হয়েছিল। 2005 সালে, এত অল্প সময়ের মধ্যে একটি সম্পূর্ণরূপে কাজ করা ওয়েব অ্যাপ্লিকেশন তৈরি করা অকল্পনীয় ছিল। এটা জাদু মত অনুভূত!
আজ, আমি আপনার ব্রাউজারে সম্পূর্ণভাবে চলে এমন একটি Rails অ্যাপ্লিকেশন তৈরি করে এই জাদুকরী অনুভূতি ফিরিয়ে আনতে চাই। আপনার যাত্রা শুরু হয় সাধারণ উপায়ে একটি বেসিক রেল অ্যাপ্লিকেশন তৈরি করে এবং তারপর এটিকে Wasm-এর জন্য প্যাকেজ করার মাধ্যমে।
পটভূমি: কমান্ড লাইনে একটি "15 মিনিটের মধ্যে ব্লগ"
ধরে নিলাম আপনার মেশিনে Ruby এবং Ruby on Rails ইনস্টল করা আছে, আপনি একটি নতুন Ruby on Rails অ্যাপ্লিকেশন তৈরি করে এবং কিছু কার্যকারিতা স্ক্যাফোল্ডিং দিয়ে শুরু করেন (যেমন আসল "ব্লগ ইন 15 মিনিট" ভিডিওতে):
$ rails new --css=tailwind web_dev_blog
create .ruby-version
...
$ cd web_dev_blog
$ bin/rails generate scaffold Post title:string date:date body:text
create db/migrate/20241217183624_create_posts.rb
create app/models/post.rb
...
$ bin/rails db:migrate
== 20241217183624 CreatePosts: migrating ====================
-- create_table(:posts)
-> 0.0017s
== 20241217183624 CreatePosts: migrated (0.0018s) ===========
এমনকি কোডবেস স্পর্শ না করেও, আপনি এখন অ্যাপ্লিকেশনটি চালাতে পারেন এবং এটিকে কার্যকরভাবে দেখতে পারেন:
$ bin/dev
=> Booting Puma
=> Rails 8.0.1 application starting in development
...
* Listening on http://127.0.0.1:3000
এখন, আপনি http://localhost:3000/posts- এ আপনার ব্লগ খুলতে পারেন এবং পোস্ট লেখা শুরু করতে পারেন!
আপনি একটি খুব খালি-হাড় আছে, কিন্তু কার্যকরী ব্লগ অ্যাপ্লিকেশন মিনিটের মধ্যে নির্মিত. এটি একটি সম্পূর্ণ-স্ট্যাক, সার্ভার-নিয়ন্ত্রিত অ্যাপ্লিকেশন: আপনার ডেটা রাখার জন্য আপনার কাছে একটি ডাটাবেস ( SQLite ) আছে, HTTP অনুরোধগুলি পরিচালনা করার জন্য একটি ওয়েব সার্ভার ( Puma ), এবং একটি রুবি প্রোগ্রাম রয়েছে যা আপনার ব্যবসার যুক্তি বজায় রাখতে, UI প্রদান করতে এবং ব্যবহারকারীর মিথস্ক্রিয়া প্রক্রিয়া করতে পারে৷ অবশেষে, ব্রাউজিং অভিজ্ঞতাকে স্ট্রীমলাইন করার জন্য জাভাস্ক্রিপ্ট ( Turbo ) এর একটি পাতলা স্তর রয়েছে।
অফিসিয়াল রেল ডেমো এই অ্যাপ্লিকেশনটিকে একটি বেয়ার মেটাল সার্ভারে স্থাপন করার দিক দিয়ে চলতে থাকে এবং এইভাবে, এটিকে উৎপাদন-প্রস্তুত করে। আপনার যাত্রা বিপরীত দিকে চলতে থাকবে: আপনার আবেদনটি দূরে কোথাও রাখার পরিবর্তে, আপনি এটিকে স্থানীয়ভাবে "নিয়োজিত" করবেন।
পরবর্তী স্তর: ওয়াসম-এ একটি "15 মিনিটের মধ্যে ব্লগ"৷
WebAssembly সংযোজনের পর থেকে, ব্রাউজারগুলি শুধুমাত্র জাভাস্ক্রিপ্ট কোড নয়, Wasm-এ সংকলনযোগ্য যেকোন কোড চালাতে সক্ষম হয়েছে। আর রুবিও এর ব্যতিক্রম নয়। নিঃসন্দেহে, রেলগুলি রুবির চেয়ে বেশি, তবে পার্থক্যগুলি খনন করার আগে, আসুন আমরা ডেমো এবং ওয়াসমিফাই ( ওয়াসমিফাই-রেল লাইব্রেরি দ্বারা তৈরি একটি ক্রিয়া) রেল অ্যাপ্লিকেশনটি চালিয়ে যাই!
আপনার ব্লগ অ্যাপ্লিকেশনটিকে একটি Wasm মডিউলে কম্পাইল করতে এবং ব্রাউজারে চালানোর জন্য আপনাকে শুধুমাত্র কয়েকটি কমান্ড কার্যকর করতে হবে।
প্রথমে, আপনি বান্ডলার (রুবির npm
) ব্যবহার করে wasmify-rails লাইব্রেরি ইনস্টল করুন এবং Rails CLI ব্যবহার করে এর জেনারেটর চালান:
$ bundle add wasmify-rails
$ bin/rails wasmify:install
create config/wasmify.yml
create config/environments/wasm.rb
...
info ✅ The application is prepared for Wasm-ificaiton!
wasmify:rails
কমান্ড একটি ডেডিকেটেড "wasm" এক্সিকিউশন এনভায়রনমেন্ট কনফিগার করে (ডিফল্ট "ডেভেলপমেন্ট", "টেস্ট" এবং "প্রোডাকশন" এনভায়রনমেন্ট ছাড়াও) এবং প্রয়োজনীয় নির্ভরতা ইনস্টল করে। একটি গ্রীনফিল্ড রেল অ্যাপ্লিকেশনের জন্য, এটি ওয়াসম-প্রস্তুত করার জন্য যথেষ্ট।
এর পরে, রুবি রানটাইম, স্ট্যান্ডার্ড লাইব্রেরি এবং সমস্ত অ্যাপ্লিকেশন নির্ভরতা ধারণকারী মূল Wasm মডিউল তৈরি করুন:
$ bin/rails wasmify:build
==> RubyWasm::BuildSource(3.3) -- Building
...
==> RubyWasm::CrossRubyProduct(ruby-3.3-wasm32-unknown-wasip1-full-4aaed4fbda7afe0bdf4e22167afd101e) -- done in 47.37s
INFO: Packaging gem: rake-13.2.1
...
INFO: Packaging gem: wasmify-rails-0.2.0
INFO: Packaging setup.rb: bundle/setup.rb
INFO: Size: 73.77 MB
এই ধাপে কিছু সময় লাগতে পারে: তৃতীয় পক্ষের লাইব্রেরি থেকে নেটিভ এক্সটেনশনগুলি (সি তে লেখা) সঠিকভাবে লিঙ্ক করতে আপনাকে উৎস থেকে রুবি তৈরি করতে হবে। এই (অস্থায়ী) অপূর্ণতা পোস্টে পরে কভার করা হয়েছে.
সংকলিত Wasm মডিউল আপনার অ্যাপ্লিকেশনের জন্য একটি ভিত্তি মাত্র। আপনাকে অবশ্যই অ্যাপ্লিকেশন কোড এবং সমস্ত সম্পদ (উদাহরণস্বরূপ, ছবি, CSS, JavaScript) প্যাক করতে হবে। প্যাকিং করার আগে, একটি মৌলিক লঞ্চার অ্যাপ্লিকেশন তৈরি করুন যা ব্রাউজারে ওয়াসমিফাইড রেল চালানোর জন্য ব্যবহার করা যেতে পারে। এর জন্য, একটি জেনারেটর কমান্ডও রয়েছে:
$ bin/rails wasmify:pwa
create pwa
create pwa/boot.html
create pwa/boot.js
...
prepend config/wasmify.yml
পূর্ববর্তী কমান্ড Vite এর সাথে নির্মিত একটি ন্যূনতম PWA অ্যাপ্লিকেশন তৈরি করে যা স্থানীয়ভাবে কম্পাইল করা Rails Wasm মডিউল পরীক্ষা করতে বা অ্যাপটি বিতরণ করার জন্য স্থিরভাবে স্থাপন করা যেতে পারে।
এখন, লঞ্চারের সাথে, আপনার যা দরকার তা হল পুরো অ্যাপ্লিকেশনটিকে একটি একক Wasm বাইনারিতে প্যাক করা:
$ bin/rails wasmify:pack
...
Packed the application to pwa/app.wasm
Size: 76.2 MB
তাই তো! লঞ্চার অ্যাপটি চালান এবং দেখুন আপনার Rails ব্লগিং অ্যাপ্লিকেশনটি ব্রাউজারে সম্পূর্ণভাবে চলছে:
$ cd pwa/
$ yarn dev
VITE v4.5.5 ready in 290 ms
➜ Local: http://localhost:5173/
http://localhost:5173 এ যান, "লঞ্চ" বোতামটি সক্রিয় হওয়ার জন্য একটু অপেক্ষা করুন এবং এটিতে ক্লিক করুন—আপনার ব্রাউজারে স্থানীয়ভাবে চলমান Rails অ্যাপের সাথে কাজ করা উপভোগ করুন!
এটা কি শুধু আপনার মেশিনে নয় ব্রাউজার স্যান্ডবক্সের মধ্যে একটি মনোলিথিক সার্ভার-সাইড অ্যাপ্লিকেশন চালানোর মতো জাদু বলে মনে হয় না? আমার জন্য (যদিও আমি "জাদুকর"), এটি এখনও একটি ফ্যান্টাসি মত দেখায়. কিন্তু কোন জাদু জড়িত নেই, শুধুমাত্র প্রযুক্তির অগ্রগতি।
ডেমো
আপনি নিবন্ধে এমবেড করা ডেমো অনুভব করতে পারেন বা একটি স্বতন্ত্র উইন্ডোতে ডেমো চালু করতে পারেন৷ GitHub-এ সোর্স কোডটি দেখুন।
Wasm উপর Rails পর্দার আড়ালে
একটি Wasm মডিউলে একটি সার্ভার-সাইড অ্যাপ্লিকেশন প্যাক করার চ্যালেঞ্জগুলি (এবং সমাধানগুলি) আরও ভালভাবে বোঝার জন্য, এই পোস্টের বাকি অংশগুলি এই আর্কিটেকচারের অংশগুলি ব্যাখ্যা করে৷
একটি ওয়েব অ্যাপ্লিকেশন শুধুমাত্র অ্যাপ্লিকেশন কোড লিখতে ব্যবহৃত একটি প্রোগ্রামিং ভাষা ছাড়াও আরও অনেক কিছুর উপর নির্ভর করে। প্রতিটি উপাদানকে অবশ্যই আপনার_ স্থানীয় স্থাপনার পরিবেশ_ ব্রাউজারে আনতে হবে। "15 মিনিটের মধ্যে ব্লগ" ডেমো সম্পর্কে উত্তেজনাপূর্ণ বিষয় হল এটি অ্যাপ্লিকেশন কোডটি পুনরায় লেখা ছাড়াই অর্জন করা যেতে পারে৷ ক্লাসিক, সার্ভার-সাইড মোডে এবং ব্রাউজারে অ্যাপ্লিকেশন চালানোর জন্য একই কোড ব্যবহার করা হয়েছিল।
একটি ফ্রেমওয়ার্ক, যেমন রুবি অন রেল, আপনাকে একটি ইন্টারফেস দেয়, অবকাঠামোগত উপাদানগুলির সাথে যোগাযোগ করার জন্য একটি বিমূর্ততা। নীচের অংশে আলোচনা করা হয়েছে যে আপনি কীভাবে কিছুটা গোপনীয় স্থানীয় পরিবেশন চাহিদাগুলি পূরণ করতে ফ্রেমওয়ার্ক আর্কিটেকচার ব্যবহার করতে পারেন।
ভিত্তি: ruby.wasm
Ruby আনুষ্ঠানিকভাবে 2022 সালে Wasm-এর জন্য প্রস্তুত হয়ে ওঠে (সংস্করণ 3.2.0 থেকে) যার অর্থ হল C সোর্স কোড Wasm-এ কম্পাইল করা যেতে পারে এবং আপনি যেখানে চান সেখানে একটি Ruby VM আনতে পারেন। ruby.wasm প্রকল্পটি ব্রাউজারে (বা অন্য কোন জাভাস্ক্রিপ্ট রানটাইম) রুবি চালানোর জন্য প্রি-কম্পাইল করা মডিউল এবং জাভাস্ক্রিপ্ট বাইন্ডিং পাঠায়। ruby:wasm প্রকল্পটি বিল্ড টুলগুলির সাথেও আসে যা আপনাকে অতিরিক্ত নির্ভরশীলতার সাথে একটি কাস্টম রুবি সংস্করণ তৈরি করতে দেয়—এটি C এক্সটেনশন সহ লাইব্রেরির উপর নির্ভরশীল প্রকল্পগুলির জন্য খুবই গুরুত্বপূর্ণ। হ্যাঁ, আপনিও Wasm-এ নেটিভ এক্সটেনশন কম্পাইল করতে পারেন! (ওয়েল, এখনও কোন এক্সটেনশন নয়, কিন্তু তাদের অধিকাংশ)।
বর্তমানে, রুবি সম্পূর্ণরূপে WebAssembly সিস্টেম ইন্টারফেস, WASI 0.1 সমর্থন করে। WASI 0.2 যার মধ্যে কম্পোনেন্ট মডেলটি ইতিমধ্যেই আলফা অবস্থায় রয়েছে এবং সমাপ্তির কয়েক ধাপ। একবার WASI 0.2 সমর্থিত হলে এটি প্রতিবার নতুন নেটিভ নির্ভরতা যোগ করার সময় পুরো ভাষাটি পুনরায় কম্পাইল করার বর্তমান প্রয়োজনীয়তা দূর করবে: সেগুলিকে কম্পোনেন্টাইজ করা যেতে পারে।
একটি পার্শ্ব প্রতিক্রিয়া হিসাবে, উপাদান মডেল বান্ডিল আকার কমাতে সাহায্য করা উচিত. আপনি WebAssembly টক-এ Ruby এর সাথে আপনি কি করতে পারেন থেকে ruby.wasm এর বিকাশ এবং অগ্রগতি সম্পর্কে আরও জানতে পারেন।
সুতরাং, Wasm সমীকরণের রুবি অংশটি সমাধান করা হয়েছে। কিন্তু রেলের একটি ওয়েব ফ্রেমওয়ার্ক হিসাবে পূর্ববর্তী চিত্রে দেখানো সমস্ত উপাদান প্রয়োজন। কিভাবে ব্রাউজারে অন্যান্য উপাদান রাখতে হয় এবং Rails এ তাদের একসাথে লিঙ্ক করতে হয় তা শিখতে পড়ুন।
ব্রাউজারে চলমান একটি ডাটাবেসের সাথে সংযোগ করুন
SQLite3 একটি অফিসিয়াল Wasm ডিস্ট্রিবিউশন এবং একটি সংশ্লিষ্ট জাভাস্ক্রিপ্ট র্যাপার সহ আসে, তাই ব্রাউজারে এম্বেড করার জন্য প্রস্তুত। Wasm-এর জন্য PostgreSQL PGlite প্রকল্পের মাধ্যমে উপলব্ধ। অতএব, আপনাকে শুধুমাত্র Rails on Wasm অ্যাপ্লিকেশন থেকে কিভাবে ব্রাউজার ডাটাবেসের সাথে সংযোগ করতে হবে তা বের করতে হবে।
ডেটা মডেলিং এবং ডাটাবেস ইন্টারঅ্যাকশনের জন্য দায়ী রেলের একটি উপাদান, বা সাব-ফ্রেমওয়ার্ককে বলা হয় সক্রিয় রেকর্ড (হ্যাঁ, ORM ডিজাইন প্যাটার্নের নামানুসারে)। অ্যাক্টিভ রেকর্ড ডাটাবেস অ্যাডাপ্টারের মাধ্যমে অ্যাপ্লিকেশন কোড থেকে প্রকৃত SQL-ভাষী ডাটাবেস বাস্তবায়নকে বিমূর্ত করে। বাক্সের বাইরে, রেল আপনাকে SQLite3, PostgreSQL, এবং MySQL অ্যাডাপ্টার দেয়। যাইহোক, তারা সবাই নেটওয়ার্কে উপলব্ধ বাস্তব ডাটাবেসের সাথে সংযোগ করছে বলে ধরে নেয়। এটি কাটিয়ে উঠতে, আপনি স্থানীয় , ইন-ব্রাউজার ডাটাবেসের সাথে সংযোগ করতে আপনার নিজস্ব অ্যাডাপ্টার লিখতে পারেন!
Wasmify Rails প্রকল্পের একটি অংশ হিসাবে বাস্তবায়িত SQLite3 Wasm এবং PGlite অ্যাডাপ্টারগুলি এইভাবে তৈরি করা হয়:
- অ্যাডাপ্টার ক্লাস সংশ্লিষ্ট বিল্ট-ইন অ্যাডাপ্টার থেকে উত্তরাধিকারসূত্রে প্রাপ্ত হয় (উদাহরণস্বরূপ,
class PGliteAdapter < PostgreSQLAdapter
), তাই আপনি প্রকৃত ক্যোয়ারী প্রস্তুতি এবং ফলাফল পার্সিং লজিক পুনরায় ব্যবহার করতে পারেন। - নিম্ন-স্তরের ডাটাবেস সংযোগের পরিবর্তে, আপনি একটি বাহ্যিক ইন্টারফেস অবজেক্ট ব্যবহার করেন যা JavaScript রানটাইমে থাকে—একটি Rails Wasm মডিউল এবং একটি ডাটাবেসের মধ্যে একটি সেতু।
উদাহরণস্বরূপ, এখানে SQLite3 Wasm এর জন্য ব্রিজ বাস্তবায়ন রয়েছে:
export function registerSQLiteWasmInterface(worker, db, opts = {}) {
const name = opts.name || "sqliteForRails";
worker[name] = {
exec: function (sql) {
let cols = [];
let rows = db.exec(sql, { columnNames: cols, returnValue: "resultRows" });
return {
cols,
rows,
};
},
changes: function () {
return db.changes();
},
};
}
অ্যাপ্লিকেশনের দৃষ্টিকোণ থেকে, একটি বাস্তব ডাটাবেস থেকে একটি ইন-ব্রাউজারে স্থানান্তরটি কেবলমাত্র কনফিগারেশনের বিষয়:
# config/database.yml
development:
adapter: sqlite3
production:
adapter: sqlite3
wasm:
adapter: sqlite3_wasm
js_interface: "sqliteForRails"
একটি স্থানীয় ডাটাবেসের সাথে কাজ করার জন্য অনেক প্রচেষ্টার প্রয়োজন হয় না। যাইহোক, যদি সত্যের কিছু কেন্দ্রীয় উৎসের সাথে ডেটা সিঙ্ক্রোনাইজেশন প্রয়োজন হয়, তাহলে আপনি একটি উচ্চ স্তরের চ্যালেঞ্জের মুখোমুখি হতে পারেন। এই প্রশ্নটি এই পোস্টের সুযোগের বাইরে (ইঙ্গিত: PGlite এবং ElectricSQL ডেমোতে রেলগুলি দেখুন)।
একটি ওয়েব সার্ভার হিসাবে পরিষেবা কর্মী
যেকোনো ওয়েব অ্যাপ্লিকেশনের আরেকটি অপরিহার্য উপাদান হল একটি ওয়েব সার্ভার। ব্যবহারকারীরা HTTP অনুরোধ ব্যবহার করে ওয়েব অ্যাপ্লিকেশনের সাথে যোগাযোগ করে। সুতরাং, আপনার Wasm মডিউলে নেভিগেশন বা ফর্ম জমা দিয়ে ট্রিগার করা HTTP অনুরোধগুলিকে রুট করার একটি উপায় প্রয়োজন। সৌভাগ্যবশত, ব্রাউজার এর জন্য একটি উত্তর আছে - পরিষেবা কর্মীরা ।
একটি পরিষেবা কর্মী হল একটি বিশেষ ধরনের ওয়েব কর্মী যা জাভাস্ক্রিপ্ট অ্যাপ্লিকেশন এবং নেটওয়ার্কের মধ্যে একটি প্রক্সি হিসাবে কাজ করে। এটি অনুরোধগুলিকে আটকাতে পারে এবং সেগুলিকে ম্যানিপুলেট করতে পারে, উদাহরণস্বরূপ: ক্যাশে করা ডেটা পরিবেশন করা, অন্য URL গুলিতে পুনঃনির্দেশ করা বা... Wasm মডিউলগুলিতে! এখানে Wasm-এ চলমান একটি Rails অ্যাপ্লিকেশন ব্যবহার করে অনুরোধ পরিবেশনকারী পরিষেবার একটি স্কেচ রয়েছে:
// The vm variable holds a reference to the Wasm module with a
// Ruby VM initialized
let vm;
// The db variable holds a reference to the in-browser
// database interface
let db;
const initVM = async (progress, opts = {}) => {
if (vm) return vm;
if (!db) {
await initDB(progress);
}
vm = await initRailsVM("/app.wasm");
return vm;
};
const rackHandler = new RackHandler(initVM});
self.addEventListener("fetch", (event) => {
// ...
return event.respondWith(
rackHandler.handle(event.request)
);
});
ব্রাউজার দ্বারা প্রতিবার অনুরোধ করা হলে "আনয়ন" ট্রিগার হয়। আপনি অনুরোধের তথ্য (URL, HTTP শিরোনাম, বডি) পেতে পারেন এবং আপনার নিজস্ব অনুরোধ বস্তু তৈরি করতে পারেন।
রেলগুলি, বেশিরভাগ রুবি ওয়েব অ্যাপ্লিকেশনগুলির মতো, HTTP অনুরোধগুলির সাথে কাজ করার জন্য র্যাক ইন্টারফেসের উপর নির্ভর করে। র্যাক ইন্টারফেস অনুরোধের বিন্যাস এবং প্রতিক্রিয়া বস্তুর পাশাপাশি অন্তর্নিহিত HTTP হ্যান্ডলার (অ্যাপ্লিকেশন) এর ইন্টারফেস বর্ণনা করে। আপনি নিম্নরূপ এই বৈশিষ্ট্য প্রকাশ করতে পারেন:
request = {
"REQUEST_METHOD" => "GET",
"SCRIPT_NAME" => "",
"SERVER_NAME" => "localhost",
"SERVER_PORT" => "3000",
"PATH_INFO" => "/posts"
}
handler = proc do |env|
[
200,
{"Content-Type" => "text/html"},
["<!doctype html><html><body>Hello Web!</body></html>"]
]
end
handler.call(request) #=> [200, {...}, [...]]
আপনি যদি অনুরোধের ফর্ম্যাটটি পরিচিত খুঁজে পান, তাহলে আপনি সম্ভবত সেই দিনগুলিতে CGI এর সাথে কাজ করেছেন।
RackHandler
JavaScript অবজেক্ট জাভাস্ক্রিপ্ট এবং রুবি রাজ্যের মধ্যে অনুরোধ এবং প্রতিক্রিয়া রূপান্তর করার জন্য দায়ী। প্রদত্ত যে র্যাক বেশিরভাগ রুবি ওয়েব অ্যাপ্লিকেশন দ্বারা ব্যবহৃত হয়, বাস্তবায়নটি সর্বজনীন হয়ে ওঠে, রেল-নির্দিষ্ট নয়। প্রকৃত বাস্তবায়ন যদিও এখানে পোস্ট করা খুব দীর্ঘ.
একটি পরিষেবা কর্মী একটি ইন-ব্রাউজার ওয়েব অ্যাপ্লিকেশনের মূল অবিচ্ছেদ্য পয়েন্টগুলির মধ্যে একটি। এটি শুধুমাত্র একটি HTTP প্রক্সি নয়, এটি একটি ক্যাশিং স্তর এবং একটি নেটওয়ার্ক সুইচার (অর্থাৎ, আপনি একটি স্থানীয়-প্রথম বা অফলাইন-সক্ষম অ্যাপ্লিকেশন তৈরি করতে পারেন)। এটি এমন একটি উপাদান যা আপনাকে ব্যবহারকারীর আপলোড করা ফাইলগুলি পরিবেশন করতে সহায়তা করতে পারে।
ব্রাউজারে ফাইল আপলোড রাখুন
আপনার নতুন ব্লগ অ্যাপ্লিকেশনে প্রয়োগ করার জন্য প্রথম অতিরিক্ত বৈশিষ্ট্যগুলির মধ্যে একটি ফাইল আপলোডের জন্য সমর্থন হতে পারে, বা আরও নির্দিষ্টভাবে, পোস্টে ছবি সংযুক্ত করা। এটি অর্জন করার জন্য, আপনার ফাইল সংরক্ষণ এবং পরিবেশন করার একটি উপায় প্রয়োজন।
রেলে, ফাইল আপলোডের সাথে ডিল করার জন্য দায়ী ফ্রেমওয়ার্কের অংশটিকে অ্যাক্টিভ স্টোরেজ বলা হয়। অ্যাক্টিভ স্টোরেজ ডেভেলপারদের নিম্ন-স্তরের স্টোরেজ মেকানিজম সম্পর্কে চিন্তা না করে ফাইলের সাথে কাজ করার জন্য বিমূর্ততা এবং ইন্টারফেস দেয়। হার্ড ড্রাইভে বা ক্লাউডে আপনি আপনার ফাইলগুলি যেখানেই সঞ্চয় করেন না কেন, অ্যাপ্লিকেশন কোডটি এটি সম্পর্কে অজানা থাকে৷
একইভাবে অ্যাক্টিভ রেকর্ডের মতো, একটি কাস্টম স্টোরেজ মেকানিজম সমর্থন করার জন্য, আপনার যা প্রয়োজন তা হল একটি সংশ্লিষ্ট স্টোরেজ পরিষেবা অ্যাডাপ্টার প্রয়োগ করা। ব্রাউজারে ফাইল কোথায় সংরক্ষণ করবেন?
ঐতিহ্যগত বিকল্প একটি ডাটাবেস ব্যবহার করা হয়. হ্যাঁ, আপনি ফাইলগুলিকে ডাটাবেসে ব্লব হিসাবে সংরক্ষণ করতে পারেন, কোনও অতিরিক্ত অবকাঠামো উপাদানের প্রয়োজন নেই৷ এবং এর জন্য ইতিমধ্যেই একটি রেডিমেড প্লাগইন রয়েছে Rails, Active Storage Database- এ। যাইহোক, WebAssembly-এর মধ্যে চলমান Rails অ্যাপ্লিকেশনের মাধ্যমে ডাটাবেসে সংরক্ষিত ফাইলগুলি পরিবেশন করা আদর্শ নয় কারণ এতে (ডি-)সিরিয়ালাইজেশনের রাউন্ড জড়িত যা বিনামূল্যে নয়।
একটি ভাল এবং আরও ব্রাউজার-অপ্টিমাইজ করা সমাধান হল ফাইল সিস্টেম API ব্যবহার করা এবং ফাইল আপলোড এবং সার্ভার আপলোড করা ফাইলগুলি সরাসরি পরিষেবা কর্মী থেকে প্রক্রিয়া করা। এই ধরনের অবকাঠামোর জন্য একটি নিখুঁত প্রার্থী হল OPFS (অরিজিন প্রাইভেট ফাইল সিস্টেম), একটি অতি সাম্প্রতিক ব্রাউজার API যা ভবিষ্যতের ইন-ব্রাউজার অ্যাপ্লিকেশনগুলির জন্য অবশ্যই একটি গুরুত্বপূর্ণ ভূমিকা পালন করবে।
রেল এবং ওয়াসম একসাথে কী অর্জন করতে পারে
আমি নিশ্চিত যে আপনি নিবন্ধটি পড়া শুরু করার সাথে সাথে আপনি নিজেকে এই প্রশ্নটি জিজ্ঞাসা করছেন: কেন ব্রাউজারে একটি সার্ভার-সাইড ফ্রেমওয়ার্ক চালাবেন? একটি ফ্রেমওয়ার্ক বা একটি লাইব্রেরি সার্ভার-সাইড (বা ক্লায়েন্ট-সাইড) হওয়ার ধারণাটি কেবল একটি লেবেল। ভাল কোড এবং, বিশেষ করে, একটি ভাল বিমূর্ততা সর্বত্র কাজ করে। লেবেলগুলি আপনাকে নতুন সম্ভাবনাগুলি অন্বেষণ করা এবং ফ্রেমওয়ার্কের সীমানা (উদাহরণস্বরূপ, রুবি অন রেল) পাশাপাশি রানটাইমের (ওয়েবঅ্যাসেম্বলি) সীমানাগুলিকে ঠেলে দেওয়া উচিত নয়৷ উভয়ই এই ধরনের অপ্রচলিত ব্যবহারের ক্ষেত্রে উপকৃত হতে পারে।
প্রচুর প্রচলিত , বা ব্যবহারিক, ব্যবহারের ক্ষেত্রেও রয়েছে।
প্রথমত, ব্রাউজারে ফ্রেমওয়ার্ক আনার ফলে প্রচুর শেখার এবং প্রোটোটাইপিং সুযোগ উন্মুক্ত হয়। আপনার ব্রাউজারে এবং অন্যান্য লোকেদের সাথে একসাথে লাইব্রেরি, প্লাগইন এবং প্যাটার্নগুলির সাথে খেলতে সক্ষম হওয়ার কল্পনা করুন৷ Stackblitz জাভাস্ক্রিপ্ট ফ্রেমওয়ার্কের জন্য এটি সম্ভব করেছে। আরেকটি উদাহরণ হল একটি ওয়ার্ডপ্রেস খেলার মাঠ যা ওয়েব পৃষ্ঠা ছাড়াই ওয়ার্ডপ্রেস থিমগুলির সাথে খেলা সম্ভব করেছে। Wasm রুবি এবং এর ইকোসিস্টেমের জন্য অনুরূপ কিছু সক্ষম করতে পারে।
ইন-ব্রাউজার কোডিং এর একটি বিশেষ কেস আছে যা বিশেষত ওপেন সোর্স ডেভেলপারদের জন্য উপযোগী- ট্রাইজিং এবং ডিবাগিং সমস্যা । আবার, StackBlitz জাভাস্ক্রিপ্ট প্রকল্পগুলির জন্য এটি একটি জিনিস তৈরি করেছে: আপনি একটি ন্যূনতম পুনরুৎপাদন স্ক্রিপ্ট তৈরি করেন, একটি গিটহাব ইস্যুতে লিঙ্কটি নির্দেশ করেন এবং আপনার দৃশ্যকল্পের পুনরুত্পাদনের জন্য অতিরিক্ত রক্ষণাবেক্ষণকারীদের সময় দেন। এবং, প্রকৃতপক্ষে, Ruby-এ এটি ইতিমধ্যেই ঘটতে শুরু করেছে RunRuby.dev প্রকল্পের জন্য ধন্যবাদ (এখানে একটি উদাহরণ দেওয়া হল ইন-ব্রাউজার রিপ্রোডাকশনের মাধ্যমে সমাধান করা হয়েছে)।
আরেকটি ব্যবহারের ক্ষেত্রে অফলাইন-সক্ষম (বা অফলাইন-সচেতন) অ্যাপ্লিকেশন । অফলাইন-সক্ষম অ্যাপ্লিকেশনগুলি যেগুলি সাধারণত নেটওয়ার্ক ব্যবহার করে কাজ করে, কিন্তু যখন কোনও সংযোগ না থাকে, সেগুলি ব্যবহারযোগ্য থাকে৷ উদাহরণস্বরূপ, একটি ইমেল ক্লায়েন্ট যা আপনাকে অফলাইনে থাকাকালীন আপনার ইনবক্সের মাধ্যমে অনুসন্ধান করতে দেয়। অথবা, "ডিভাইসে স্টোর" ক্ষমতা সহ একটি মিউজিক লাইব্রেরি অ্যাপ্লিকেশন, তাই নেটওয়ার্ক সংযোগ না থাকলেও আপনার প্রিয় সঙ্গীত বাজতে থাকে। উভয় উদাহরণই স্থানীয়ভাবে সংরক্ষিত ডেটার উপর নির্ভর করে, শুধুমাত্র ক্লাসিক PWA এর মতো ক্যাশে ব্যবহার করে না।
অবশেষে, রেলের সাথে স্থানীয় (বা ডেস্কটপ) অ্যাপ্লিকেশনগুলি তৈরি করাও বোধগম্য, কারণ ফ্রেমওয়ার্ক আপনাকে যে উত্পাদনশীলতা দেয় তা রানটাইমের উপর নির্ভর করে না। সম্পূর্ণ বৈশিষ্ট্যযুক্ত ফ্রেমওয়ার্কগুলি ব্যক্তিগত ডেটা- এবং লজিক-ভারী অ্যাপ্লিকেশন তৈরির জন্য উপযুক্ত। এবং পোর্টেবল ডিস্ট্রিবিউশন ফরম্যাট হিসাবে Wasm ব্যবহার করাও একটি কার্যকর বিকল্প।
এটি ওয়াসম যাত্রায় এই রেলগুলির শুরু। আপনি ওয়েবসেম্বলি ইবুকের রুবি অন রুবিতে চ্যালেঞ্জ এবং সমাধানগুলি সম্পর্কে আরও জানতে পারেন (যা যাইহোক, একটি অফলাইন-সক্ষম রেল অ্যাপ্লিকেশন নিজেই)।