JSON5 ও JSONC: কমেন্টসহ JSON
সংক্ষেপে: দুইটি ডায়ালেক্টই আছে কারণ মানুষের লেখা কনফিগে কমেন্ট ও ট্রেইলিং কমা দরকার, কিন্তু তাদের সিনট্যাক্স ও ইকোসিস্টেমের বিস্তার আলাদা — ভুলটি বাছলে আপনার টুলচেইন আটকে যাবে।

মূল কথা: VS Code ও TypeScript কনফিগারেশনের ভেতরে কমেন্টের জন্য JSONC ব্যবহার করুন, আর সিঙ্গেল কোট বা আনকোয়োটেড কি-এর মতো বিস্তৃত ES5.1 লিটেরাল সিনট্যাক্স দরকার হলে JSON5 ব্যবহার করুন; আর পাবলিক API স্ট্যান্ডার্ড JSON-ই রাখুন।
স্ট্যান্ডার্ড JSON কমেন্ট অনুমোদন করে না, তাই প্রতিটি দল চুপচাপ লিখেই ফেলে — যতদিন না একদিন বিল্ড ভেঙে যায়। গোপনে না করে একটি সঠিক ডায়ালেক্ট বেছে নিন।
১. দুই ডায়ালেক্টের প্রেরণা আলাদা
- JSONC (JSON with Comments): স্ট্যান্ডার্ড JSON প্লাস কমেন্ট ও ট্রেইলিং কমা, আর প্রায় কোনো সিনট্যাক্স পরিবর্তন নেই। এটি VS Code ইকোসিস্টেমের বাস্তব মান —
settings.json,tsconfig.jsonও.eslintrc.jsonসবই এটি ব্যবহার করে। - JSON5: অনেক বেশি উচ্চাভিলাষী, সোজা ES5.1 অবজেক্ট লিটেরালের সঙ্গে মেলে — সিঙ্গেল কোট, আনকোয়োটেড কি, হেক্সাডেসিমেল,
Infinity/NaN, ব্যাকস্ল্যাশ লাইন কন্টিনিউয়েশন এবং শুরুতে+চিহ্ন।
এক বাক্যে পার্থক্য: JSONC কেবল লেখা আরামদায়ক করে; JSON5 দিয়ে আপনি কনফিগারেশন ফাইল লিখতে পারেন যেন সেটি JavaScript।
২. সিনট্যাক্স তুলনা টেবিল
| বৈশিষ্ট্য | স্ট্যান্ডার্ড JSON | JSONC | JSON5 |
|---|---|---|---|
কমেন্ট // /* */ |
✗ | ✓ | ✓ |
| ট্রেইলিং কমা | ✗ | ✓ | ✓ |
| সিঙ্গেল-কোটেড স্ট্রিং | ✗ | ✗ | ✓ |
| আনকোয়োটেড কি | ✗ | ✗ | ✓ |
| হেক্সাডেসিমেল সংখ্যা | ✗ | ✗ | ✓ |
শুরু/শেষে দশমিক বিন্দু .5 5. |
✗ | ✗ | ✓ |
+ দিয়ে শুরু হওয়া সংখ্যা |
✗ | ✗ | ✓ |
Infinity / NaN |
✗ | ✗ | ✓ |
লাইন-শেষে \ কন্টিনিউয়েশন |
✗ | ✗ | ✓ |
| মাল্টি-লাইন স্ট্রিং | ✗ | ✗ | ✓ (কন্টিনিউয়েশনের মাধ্যমে বাস্তবায়িত) |
| যেকোনো টপ-লেভেল ভ্যালু | ✓ | ✓ | ✓ |
পূর্ণ JSON5 স্পেসিফিকেশন এক পৃষ্ঠার সামান্য বেশি; json5 প্যাকেজ দীর্ঘদিন কমিউনিটি রক্ষণাবেক্ষণ করছে, আর ব্রাউজার ও Node একই আচরণ করে।
৩. পার্সিং: দুই API, দুই ধরনের পজিশনিং ক্ষমতা
৩.১ JSON5: সরল পুরো-ডকুমেন্ট পার্সিং
import JSON5 from 'json5';
const config = JSON5.parse(`
{
// service port
port: 8080,
host: '0.0.0.0',
features: ['json5', 'jsonc',],
retries: 0x10,
}
`);
console.log(config.port, config.retries); // 8080 16
JSON5.parse কোনো অফসেট তথ্য ছাড়া একটি সাধারণ অবজেক্ট ফেরত দেয় — কারণ এটি সম্পাদনার পরিস্থিতির জন্য নয়, কেবল "কনফিগারেশন পড়ার" জন্য।
৩.২ JSONC: অফসেটসহ সিনট্যাক্স ট্রি
jsonc-parser-এর মূল্য পার্সিংয়ে নয়, সম্পাদনায়। এটি তিন স্তরের API দেয়:
| API | উদ্দেশ্য | সাধারণ ব্যবহার |
|---|---|---|
parse |
offset/length বহনকারী ট্রিতে পার্স করে |
সিনট্যাক্স হাইলাইটিং, ফোল্ডিং, নেভিগেশন |
visit |
ডেপথ-ফার্স্ট ট্রাভার্সাল; কলব্যাক নোড-পাথ পায় | JSONPath-সদৃশ পরিদর্শন |
modify + applyEdits |
ন্যূনতম টেক্সট এডিট তৈরি করে, তারপর মূল টেক্সটে প্রয়োগ করে | কমেন্ট রেখেই মান বদলানো |
import { parseTree, findNodeAtLocation, modify, applyEdits } from 'jsonc-parser';
const text = `{
// port configuration
"server": {
"port": 8080 // 80 in production
}
}`;
const tree = parseTree(text);
const portNode = findNodeAtLocation(tree!, ['server', 'port']);
console.log(portNode?.offset, portNode?.length);
const edits = modify(text, ['server', 'port'], 3000, {
formattingOptions: { insertSpaces: true, tabSize: 2 },
});
console.log(applyEdits(text, edits));
আউটপুট মূল কমেন্ট ধরে রাখে এবং কেবল 8080-এর তিনটি অক্ষর বদলায়:
{
// port configuration
"server": {
"port": 3000 // 80 in production
}
}
"রেগুলার এক্সপ্রেশন দিয়ে কনফিগারেশন সম্পাদনা" ঠিক যা করতে পারে না: একটি রেগুলার এক্সপ্রেশন জানে না কোন 8080 বদলাতে হবে, আর জানে না স্ট্রিংয়ের ভেতরের 8080 ছুঁড়তে হবে না।
৩.৩ এরর মেসেজে অফসেট থাকা আবশ্যক
jsonc-parser-এর এরর কোডগুলো এনাম মান; সাধারণগুলো হলো:
| এরর কোড | অর্থ |
|---|---|
InvalidSymbol |
এমন একটি অক্ষর এসেছে যা সেখানে থাকা উচিত নয় |
PropertyNameExpected |
একটি কি-নাম প্রত্যাশিত |
ColonExpected |
একটি কোলন প্রত্যাশিত |
CommaExpected |
একটি কমা প্রত্যাশিত |
CloseBraceExpected |
অবজেক্ট বন্ধ হয়নি |
UnexpectedEndOfComment |
কমেন্ট বন্ধ হয়নি |
InvalidEscapeCharacter |
অবৈধ এস্কেপ |
offset-কে লাইন ও কলামে রূপান্তর করলে এডিটর আক্ষরিকভাবে দোষী অবস্থানে ভাঙা রেখা আঁকতে পারে।
৪. কখন কোনটি ব্যবহার করবেন
| পরিস্থিতি | সুপারিশ | কারণ |
|---|---|---|
| পাবলিক API রিকোয়েস্ট/রেসপন্স বডি | স্ট্যান্ডার্ড JSON | সাধারণ-উদ্দেশ্যের ক্লায়েন্ট ডায়ালেক্ট সমর্থন করে না |
package.json, composer.json |
স্ট্যান্ডার্ড JSON | প্যাকেজ ম্যানেজার কেবল স্ট্যান্ডার্ড JSON বোঝে |
tsconfig.json, .vscode/settings.json |
JSONC | ইকোসিস্টেমের ডিফল্ট, টুলচেইন নেটিভভাবে সমর্থন করে |
| অ্যাপ্লিকেশন কনফিগারেশন (কমেন্ট দরকার) | JSONC বা YAML | কমেন্ট ধরে রাখতে হবে, অথচ টুল এখনও পড়তে ও লিখতে পারবে |
Infinity, হেক্সাডেসিমেল, জটিল লিটেরাল দরকার |
JSON5 | সবচেয়ে শক্তিশালী প্রকাশক্ষমতা |
| ডেটা বিনিময়, লগ, ক্যাশে | লাইনভিত্তিক বা স্ট্যান্ডার্ড JSON | স্ট্রিমিং ও সার্বজনীনতা দরকার |
হাতের নিয়ম: ফাইলটি যদি "মানুষের নয় এমন টুল" পড়ে, স্ট্যান্ডার্ড JSON-কে অগ্রাধিকার দিন; কেবল যখন নিশ্চিত যে এটি শুধু আপনার নিজের কোড পড়বে, তখনই ডায়ালেক্ট ভাবুন।
৫. ডায়ালেক্ট যে তিন ধরনের ঝুঁকি আনে
৫.১ চাহিদার বিস্তার
কোনো অন্য টুল JSON5 কনফিগারেশন ফাইল পড়ে JSON.parse কল করলে সরাসরি ক্র্যাশ করে। সাধারণ লক্ষণ "লোকালি ঠিক চলে, Docker-এ ব্যর্থ" — কারণ কন্টেইনার আলাদা পড়ার পথ ব্যবহার করে।
প্রতিকার: রিপোজিটরিতে একটি CI চেক যোগ করুন যা স্পষ্টভাবে তালিকা করে কোন ফাইল ডায়ালেক্ট ব্যবহার করতে পারবে; বাকি সব স্ট্যান্ডার্ড JSON হিসেবে যাচাই হবে।
৫.২ টাইপ অনুমানে অপ্রত্যাশিত পরিণতি
JSON5 আনকোয়োটেড কি ও সিঙ্গেল কোট অনুমোদন করে, কিন্তু তারিখ বা রেগুলার এক্সপ্রেশনের মতো লিটেরাল গঠন আনে না — এটি এখনও একটি ডেটা ফরম্যাট, JavaScript মূল্যায়ন নয়।
অনেকে ধরে নিয়েছেন JSON5 new Date() প্রকাশ করতে পারবে, শেষে পার্স ব্যর্থ দেখেছেন। JSON5 কোনো eval নয়।
৫.৩ কমেন্ট নীরবে হারিয়ে যাওয়া
JSON5.stringify বা JSON.stringify — কোনোটিই কমেন্ট সংরক্ষণ করে না। তাই "পড়ুন, একটি মান বদলান, আবার লিখুন" করলে প্রতিটি কমেন্ট হারায়।
কমেন্ট টিকিয়ে রাখতে হলে একমাত্র বিকল্প jsonc-parser-এর এডিটিং API, বা কমেন্ট সংরক্ষণ সমর্থনকারী YAML লাইব্রেরি।
৬. ব্যবহারিক সুপারিশ
- [ ] দলের ডকুমেন্টেশনে একটি "ফাইল টাইপ → ফরম্যাট" টেবিল রাখুন, যাতে কেউ নিজের ইচ্ছায় কিছু না বেছে নেয়;
- [ ] কনফিগারেশন পড়া একটি
loadConfig()-এ মুড়ে দিন যা ভেতরে কোন পার্সার ব্যবহার করবে তা ঠিক করে, যাতে ব্যবসায়িক কোড কখনো সরাসরিJSON.parseকল না করে; - [ ] কমেন্টসহ কনফিগারেশন প্রোগ্রামগতভাবে বদলাতে
modify+applyEditsব্যবহার করুন; কখনো পুরো ফাইল আবার লিখবেন না; - [ ] ডায়ালেক্ট ফাইলও CI-তে যাচাই করুন (JSONC-র জন্য
jsonc-parser, JSON5-এর জন্যJSON5.parse), নাহলে সিনট্যাক্স এরর কেবল রানটাইমে দেখা যায়; - [ ] পাবলিক ইন্টারফেস, ক্যাশে কি ও মেসেজ-কিউ পেললোডে স্ট্যান্ডার্ড JSON ব্যবহার করুন।
সাধারণ প্রশ্ন
JSON5 ও JSONC-এর মধ্যে কীভাবে বাছাই করব?
সিনট্যাক্সের সংখ্যা নয়, রানটাইম দিয়ে বাছুন: VS Code, TypeScript ও ESLint ডিফল্টভাবে JSONC পড়ে, তাই JSONC সবচেয়ে ভালো সামঞ্জস্য দেয়; কেবল যখন সিঙ্গেল কোট, আনকোয়োটেড কি বা Infinity-এর মতো বিস্তৃত ES5.1 লিটেরাল সিনট্যাক্স দরকার, তখন JSON5-এর দিকে যান। কোনোটিই পাবলিক API রেসপন্সের জন্য উপযুক্ত নয়।
স্ট্যান্ডার্ড JSON পার্সার JSONC সরাসরি পড়তে পারে না কেন?
JSONC কমেন্ট ও ট্রেইলিং কমা অনুমোদন করে, অথচ JSON.parse কেবল RFC 8259 JSON গ্রহণ করে এবং দুটিতেই এরর দেয়। JSONC পড়তে jsonc-parser-এর মতো পার্সার দরকার, বা স্ট্যান্ডার্ড পার্সারে পাঠানোর আগে কমেন্ট সরাতে হবে।
JSONC-র কমেন্ট কি ফাইলের সম্পাদনার পর টিকে থাকা উচিত?
হ্যাঁ, তবে কেবল এডিটিং API-এর মাধ্যমে। jsonc-parser-এর modify ও applyEdits লক্ষ্য নোড বদলায় আর বাকি কমেন্ট সংরক্ষণ করে; অবজেক্টে পার্স করে আবার স্ট্রিংফাই করলে প্রতিটি কমেন্ট হারায়।