এডিটর, কমান্ড লাইন ও অটোমেশন টুলচেইন
সংক্ষেপে: এডিটর "পরিষ্কার দেখা, সঠিক সম্পাদনা" সমাধান করে, আর কমান্ড লাইন "ব্যাচ, পুনরাবৃত্তিযোগ্য"। দুই দিকেই এমন কয়েকটি টুল আছে যা এক দশক কাজে লাগে।

মূল কথা: পরিস্থিতি অনুযায়ী এডিটর বাছুন — ইউটিলিটি সাইট ও মোবাইলে CodeMirror 6, পূর্ণ IDE অভিজ্ঞতা দরকার হলে কেবল Monaco; ব্যাচের কাজ jq-এর হাতে ছাড়ুন, সঙ্গে সিনট্যাক্স, কাঠামো ও স্টাইলের তিনটি CI চেক, আর আর্গুমেন্ট সবসময় jq --arg দিয়ে দিন।
হাতে JSON মিলিয়ে দেখার যুগ শেষ হওয়া উচিত: মেশিন যা পুনরাবৃত্তি করতে পারে, তা মানুষের চোখে ছাড়বেন না।
১. ব্রাউজারে এডিটর
১.১ ন্যূনতম CodeMirror 6 সংযোগ
import { EditorView, basicSetup } from 'codemirror';
import { json, jsonParseLinter } from '@codemirror/lang-json';
import { linter, lintGutter } from '@codemirror/lint';
const view = new EditorView({
parent: document.getElementById('editor')!,
doc: '{"hello": "json"}',
extensions: [
basicSetup,
json(),
linter(jsonParseLinter()),
lintGutter(),
EditorView.updateListener.of((update) => {
if (update.docChanged) {
// ভারী কাজের আগে debounce করুন; প্রতিটি কিস্ট্রোকে ফরম্যাট করবেন না
scheduleParse(update.state.doc.toString());
}
}),
],
});
চারটি বিষয় খেয়াল করুন:
json()সিনট্যাক্স হাইলাইটিং ও ব্র্যাকেট মিলিয়ে দেয় — নিজে লিখবেন না;jsonParseLinter()লাইন/কলাম পর্যায়ের এরর মার্কার তৈরি করে;lintGutter()-এর সঙ্গে জুড়লে লাইন নম্বরের পাশে আইকন দেখায়;updateListenerঅবশ্যই debounce করতে হবে; এক লক্ষ লাইনে প্রতিটি কীস্ট্রোকেJSON.parseকল করলে দৃশ্যমান ল্যাগ হবে;- বড় ডকুমেন্টে একবারে পুরোটা রেন্ডার এড়াতে
EditorView.lineWrapping-এর বাইরে অতিরিক্ত অপ্টিমাইজেশন দরকার (CodeMirror 6 ডিফল্টভাবে ভিউপোর্ট অনুযায়ী রেন্ডার করে, যা পুরোনো সংস্করণের চেয়ে উন্নতি)।
১.২ Folding ও আউটলাইন
CodeMirror 6-এ folding অন্তর্নির্মিত; JSON পরিস্থিতিতে সাধারণত "অবজেক্ট/অ্যারে" অনুযায়ী ফোল্ড করা হয়:
import { foldGutter, foldKeymap } from '@codemirror/language';
import { keymap } from '@codemirror/view';
foldGutter() ও keymap.of(foldKeymap) থাকলে ব্যবহারকারী কীবোর্ড শর্টকাটে লম্বা অ্যারে জুড়ে দিতে পারেন।
১.৩ CodeMirror আর Monaco-র মধ্যে বাছাই
| মাত্রা | CodeMirror 6 | Monaco |
|---|---|---|
| বান্ডেল আকার | ছোট, মডুলার | বড় (কয়েক MB) |
| মোবাইল | ভালো সমর্থিত | মাঝারি অভিজ্ঞতা |
| ভাষা সেবা | নিজে বানাতে হয় | সমৃদ্ধ, অন্তর্নির্মিত |
| কাস্টমাইজের খরচ | কম | মাঝারি |
ইউটিলিটি সাইট ও মোবাইল-প্রথম → CodeMirror; পূর্ণ IDE অভিজ্ঞতা (একাধিক ফাইল, go-to-definition, completion) → Monaco।
২. কমান্ড লাইন: ছয়টি উচ্চ-ফ্রিকোয়েন্সি jq রেসিপি
টেক্সটের কাছে sed + awk যেমন, JSON-এর কাছে jq তেমন; এর সিনট্যাক্সের অল্প অংশ শিখলেই দৈনন্দিন প্রয়োজনের আশি শতাংশ কভার হয়।
# ১. ফিল্ড বাছাই (সবচেয়ে সাধারণ)
jq '.data.items[].name' response.json
# ২. ফিল্টার + পুনরাকৃতি
jq '.data.items[] | select(.price < 10) | {id, price}' response.json
# ৩. অ্যাগ্রিগেট (length, sum, max)
jq '[.items[] | .price] | {count: length, total: add, max: max}' response.json
# ৪. গ্রুপ ও অ্যাগ্রিগেট
jq '[.items[]] | group_by(.category) | map({category: .[0].category, count: length})' response.json
# ৫. একাধিক ফাইলকে একটি অ্যারেতে মেলানো
jq -s '.' part-*.json > merged.json
# ৬. JSON Lines লাইন ধরে প্রসেস করা
jq -c 'select(.level == "error")' app.jsonl
# সাধারণ আউটপুট সুইচ
jq -r '.data.name' # কোট সরিয়ে দেয় যাতে শেলেতে পরিষ্কারভাবে পাইপ হয়
jq -c '.' # কম্প্যাক্ট আউটপুট, এক লাইন
jq --arg id "$ID" '.id == $id' # নিরাপদে আর্গুমেন্ট দিন, জোড়া লাগিয়ে ইনজেকশন এড়ান
--arg বিশেষভাবে উল্লেখযোগ্য: ভেরিয়েবল সরাসরি এক্সপ্রেশনে জোড়া লাগালে মানে কোট থাকলেই ভাঙে, অথচ --arg দিলে jq এস্কেপিং হ্যান্ডল করে।
২.১ অন্য টুল এক নজরে
| টুল | উদ্দেশ্য | এক বাক্যে |
|---|---|---|
yq |
YAML/JSON/XML রূপান্তর | jq-এর মতো সিনট্যাক্স, কনফিগারেশন ফাইলের মূল হাতিয়ার |
dasel |
ফরম্যাটজুড়ে একক কুয়েরি | JSON/YAML/TOML/XML/CSV সমর্থন করে |
fx |
ইন্টারঅ্যাকটিভ JSON ব্রাউজিং | টার্মিনালে ক্লিক করে ঘুরে দেখুন, অন্বেষণের জন্য ভালো |
jless |
টার্মিনালে পেজকৃত ব্রাউজিং | less-এর মতো, folding ও সার্চসহ |
gron |
JSON-কে greppable লাইনে ফ্ল্যাট করা | "এই ফিল্ড কোন স্তরে" বের করার দারুণ টুল |
ajv-cli |
স্কিমা ভ্যালিডেশন | CI-তে JSON ফাইল যাচাই |
gron-এর ধারণা বিশেষভাবে জানার মতো:
$ echo '{"a":{"b":[1,2]}}' | gron
json = {};
json.a = {};
json.a.b = [];
json.a.b[0] = 1;
json.a.b[1] = 2;
ফ্ল্যাট হওয়ার পর grep দিয়ে পাথ খুঁজে পাওয়া যায়, যা এডিটরে স্তরে স্তরে খোলার চেয়ে অনেক দ্রুত।
৩. CI-তে ভ্যালিডেশনের তিন স্তর
| স্তর | টুল | ব্যর্থতার অর্থ |
|---|---|---|
| সিনট্যাক্স | JSON.parse / jq empty |
ফাইলটাই বিকৃত |
| কাঠামো | ajv-cli + স্কিমা |
ফিল্ড অনুপস্থিত, টাইপ ভুল |
| স্টাইল | Prettier | অসামঞ্জস্যপূর্ণ ফরম্যাটিং, কোলাহলপূর্ণ diff |
# সিনট্যাক্স: রিপোজিটরির প্রতিটি json ফাইল ব্যাচে যাচাই
find . -name '*.json' -not -path './node_modules/*' -print0 \
| xargs -0 -n1 jq empty
# কাঠামো: স্কিমার বিরুদ্ধে যাচাই
npx ajv-cli validate -s schemas/order.json -d 'fixtures/orders/*.json' --strict=false
# স্টাইল: কেবল চেক, পরিবর্তন নয়
npx prettier --check "**/*.json"
তিনটি স্তরই দরকার, কারণ তাদের এরর মেসেজ সম্পূর্ণ আলাদা:
jq empty কেবল বলে "কোন লাইন ভাঙা", ajv বলে "কোন ফিল্ড কোন কীওয়ার্ড ভাঙছে", আর Prettier কেবল বলে "ফরম্যাটিং অসামঞ্জস্যপূর্ণ"।
৪. pre-commit হুক
# .husky/pre-commit উদাহরণ (অংশ)
npx lint-staged
{
"lint-staged": {
"*.json": ["prettier --write", "jq empty"]
}
}
package.json ও tsconfig.json-এর মতো টুল-কনফিগারেশন ফাইলে সাবধান; Prettier-কে তাদের অবাধে আবার ইনডেন্ট করতে দেবেন না —
কিছু টুল ফরম্যাটিংয়ে সংবেদনশীল (বৈধ JSON সংবেদনশীল হওয়া উচিত নয়, তবে বাস্তবে এতে সমস্যা হয়েছে)। আলাদাভাবে বাদ দিতে পারেন।
৫. ডিবাগিং টিপস
jq -e-কে অ্যাসার্শন হিসেবে ব্যবহার করুন: এক্সপ্রেশনের ফলfalseবাnullহলে exit code ১ হয়, তাই সরাসরি স্ক্রিপ্টে চেক হিসেবে বসানো যায়;jq 'paths'সব পাথ তালিকা করে, অচেনা ডকুমেন্টের কাঠামো দ্রুত দেখা যায়;- **
jq '.. | objects | keys'**এখনো পর্যন্ত দেখা যাওয়া প্রতিটি কি-নাম খুঁজে বের করে, অসামঞ্জস্যপূর্ণ বানান ধরার জন্য উপযোগী; - এডিটরে তুলনার আগে ফরম্যাট করুন: আনফরম্যাটেড diff শুধু কোলাহল;
/diff-এর মতো কাঠামোগত তুলনা বেশি নির্ভুল।
৬. চেকলিস্ট
- [ ] এডিটরের এরর মার্কার লাইন ও কলামে নিখুঁত, আর পার্সিং debounce করা;
- [ ] টিমের স্ক্রিপ্ট
jq --argদিয়ে আর্গুমেন্ট দেয়, স্ট্রিং জোড়া লাগায় না; - [ ] CI-তে তিনটি ভ্যালিডেশন স্তরই আছে (সিনট্যাক্স/কাঠামো/স্টাইল);
- [ ] pre-commit কেবল staged ফাইল প্রসেস করে, যাতে পুরো স্ক্যান commit ধীর না করে;
- [ ] টুলের সংস্করণ
package.jsonবা.tool-versions-এ পিন করা।
সাধারণ প্রশ্ন
CodeMirror 6 আর Monaco-র মধ্যে কীভাবে বেছে নেব?
ইউটিলিটি সাইট ও মোবাইলে CodeMirror 6 প্রাধান্য দিন: এটি ছোট, মডুলার, মোবাইলে ভালো সমর্থিত, আর সিনট্যাক্স হাইলাইটিং, ব্র্যাকেট মিল ও folding প্রয়োজনে জোড়া দেওয়া যায়। একাধিক ফাইল, go-to-definition ও completionসহ পূর্ণ IDE অভিজ্ঞতা দরকার হলে কেবল Monaco-তে যান — কয়েক মেগাবাইট বান্ডেল ও বেশি কাস্টমাইজ খরচের বিনিময়ে।
CI-তে সিনট্যাক্স, কাঠামো ও স্টাইল চেক একসঙ্গে দরকার কেন?
তিনটি স্তর সম্পূর্ণ আলাদা এরর রিপোর্ট করে: jq empty বলে কোন লাইন ভাঙা, ajv বলে কোন ফিল্ড কোন কীওয়ার্ড ভাঙছে, আর Prettier কেবল বলে ফরম্যাটিং অসামঞ্জস্যপূর্ণ। একটি স্তর বাদ দিলে বাকিগুলোর এরর ভুল পড়া সহজ, তাই তিনটিই রাখুন আর কোনো স্তর ব্যর্থ হলে সেখানেই থামুন।
CI-তে ভ্যালিডেশনের বদলে pre-commit-এর উপর নির্ভর করা উচিত?
না। হুক কেবল staged ফাইল প্রসেস করে, ফলে এক মিনিটের মধ্যে ফিডব্যাক দেয় কিন্তু পুরো রিপোজিটরি বা commit এড়িয়ে যাওয়া পরিবর্তন কভার করে না। সম্পূর্ণতার দায় CI-র: pre-commit staged ফাইলে রাখুন আর পূর্ণ স্ক্যান CI-কে দিন।