JSON Toolkit

ویرایشگرها، خط فرمان و زنجیره‌های خودکارسازی

جمع‌بندی: ویرایشگر «روشن دیدن و درست ویرایش کردن» را حل می‌کند و خط فرمان «دسته‌ای و تکرارپذیر» را. هر سو چند ابزار دارد که یک دهه مفید می‌مانند.

مقدماتیحدود 10 دقیقه مطالعهانتشار 2026-10-30به‌روزرسانی 2026-10-30
تصویر جلد ویرایشگرها، خط فرمان و زنجیره‌های خودکارسازی

جمع‌بندی: ویرایشگر را بر اساس سناریو انتخاب کنید — CodeMirror 6 برای سایت‌های ابزاری و موبایل، Monaco فقط وقتی به تجربه کامل IDE نیاز دارید؛ کارهای دسته‌ای را به 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 before doing heavy work; do not format on every keystroke
        scheduleParse(update.state.doc.toString());
      }
    }),
  ],
});

چهار نکته:

۱. json() برجسته‌سازی نحو و تطبیق براکت می‌دهد — خودتان ننویسید؛ ۲. jsonParseLinter() نشانگر خطا در سطح خط/ستون تولید می‌کند؛ آن را با lintGutter() جفت کنید تا آیکون‌ها کنار شماره خطوط نمایش داده شوند؛ ۳. updateListener باید debounce شود؛ صدا زدن JSON.parse روی صد هزار خط در هر فشردن کلید به‌طور محسوس تأخیر ایجاد می‌کند؛ ۴. اسناد بزرگ به بهینه‌سازی‌هایی فراتر از EditorView.lineWrapping نیاز دارند تا از رندر یک‌جای همه جلوگیری شود (CodeMirror 6 به‌طور پیش‌فرض بر اساس viewport رندر می‌کند، که بهبودی نسبت به نسخه‌های قدیمی است).

۱.۲ Folding و outline

CodeMirror 6 folding داخلی دارد؛ در سناریوهای JSON معمولاً بر اساس «object/array» جمع می‌کنید:

import { foldGutter, foldKeymap } from '@codemirror/language';
import { keymap } from '@codemirror/view';

با foldGutter() و keymap.of(foldKeymap)، کاربران می‌توانند آرایه‌های بلند را با میانبر صفحه‌کلید جمع کنند.

۱.۳ انتخاب میان CodeMirror و Monaco

بُعد CodeMirror 6 Monaco
اندازه بسته کوچک، ماژولار بزرگ (چند مگابایت)
موبایل پشتیبانی خوب تجربه متوسط
سرویس‌های زبانی باید خودتان بسازید غنی، داخلی
هزینه سفارشی‌سازی کم متوسط

سایت‌های ابزاری و موبایل‌محور → CodeMirror؛ تجربه کامل IDE (چند فایل، go-to-definition، تکمیل) → Monaco.

۲. خط فرمان: شش دستور پرتکرار jq

jq برای JSON همان چیزی است که sed + awk برای متن است؛ یادگیری بخش کوچکی از نحو آن ۸۰٪ نیازهای روزمره را پوشش می‌دهد.

# 1. Pick fields (the most common)
jq '.data.items[].name' response.json

# 2. Filter + reshape
jq '.data.items[] | select(.price < 10) | {id, price}' response.json

# 3. Aggregates (length, sum, max)
jq '[.items[] | .price] | {count: length, total: add, max: max}' response.json

# 4. Group and aggregate
jq '[.items[]] | group_by(.category) | map({category: .[0].category, count: length})' response.json
# 5. Merge multiple files into an array
jq -s '.' part-*.json > merged.json

# 6. Process JSON Lines line by line
jq -c 'select(.level == "error")' app.jsonl

# Common output switches
jq -r '.data.name'      # Strip the quotes so it pipes cleanly into the shell
jq -c '.'               # Compact output, one line
jq --arg id "$ID" '.id == $id'   # Pass arguments safely, avoiding injection through concatenation

--arg شایسته ذکر ویژه است: چسباندن مستقیم متغیر در عبارت به‌محض اینکه مقدار گیومه داشته باشد می‌شکند، در حالی که --arg می‌گذارد jq خودش escape را مدیریت کند.

۲.۱ ابزارهای دیگر در یک نگاه

ابزار کاربرد در یک جمله
yq تبدیل YAML/JSON/XML نحوی شبیه jq، اسب کار فایل‌های پیکربندی
dasel پرس‌وجوی یکسان میان قالب‌ها JSON/YAML/TOML/XML/CSV را پشتیبانی می‌کند
fx مرور تعاملی JSON در ترمینال کلیک کنید، خوب برای کاوش
jless مرور صفحه‌بندی‌شده در ترمینال مانند less، با folding و جست‌وجو
gron تخت کردن JSON به خطوط قابل grep ابزار عالی برای فهمیدن «این فیلد در کدام سطح است»
ajv-cli اعتبارسنجی Schema اعتبارسنجی فایل‌های JSON در CI

ایده پشت 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 + schema فیلدهای غایب، نوع‌های نادرست
سبک Prettier قالب‌بندی ناهمگون، diffهای پرنویز
# Syntax: batch-validate every json file in the repository
find . -name '*.json' -not -path './node_modules/*' -print0 \
  | xargs -0 -n1 jq empty

# Structure: validate against a schema
npx ajv-cli validate -s schemas/order.json -d 'fixtures/orders/*.json' --strict=false

# Style: check only, do not modify
npx prettier --check "**/*.json"

به هر سه لایه نیاز دارید، چون پیام‌های خطایشان کاملاً متفاوت است: jq empty فقط می‌گوید «کدام خط شکسته است»، ajv می‌گوید «کدام فیلد کدام کلمه کلیدی را نقض می‌کند» و Prettier فقط می‌گوید «قالب‌بندی ناهمگون است».

۴. قلاب‌های pre-commit

# .husky/pre-commit example (excerpt)
npx lint-staged
{
  "lint-staged": {
    "*.json": ["prettier --write", "jq empty"]
  }
}

با فایل‌های پیکربندی ابزار مانند package.json و tsconfig.json مراقب باشید؛ نگذارید Prettier بی‌دلیل تورفتگی‌شان را عوض کند — برخی ابزارها به قالب‌بندی حساس‌اند (JSON معتبر نباید باشد، اما در عمل این مشکل ایجاد کرده است). می‌توانید آن‌ها را جداگانه حذف کنید.

۵. نکات اشکال‌زدایی

۱. از jq -e به‌عنوان assertion استفاده کنید: وقتی نتیجه عبارت false یا null است، کد خروج ۱ می‌شود، پس می‌تواند مستقیم به‌عنوان بررسی در اسکریپت‌ها برود؛ ۲. 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 را می‌توان بر اساس نیاز ترکیب کرد. فقط وقتی به تجربه کامل IDE با چند فایل، go-to-definition و تکمیل نیاز دارید به Monaco بروید — به قیمت بسته چندمگابایتی و تلاش بیشتر برای سفارشی‌سازی.

چرا CI به بررسی نحو، ساختار و سبک با هم نیاز دارد؟

سه لایه خطاهای کاملاً متفاوتی گزارش می‌کنند: jq empty می‌گوید کدام خط شکسته است، ajv می‌گوید کدام فیلد کدام کلمه کلیدی را نقض می‌کند و Prettier فقط می‌گوید قالب‌بندی ناهمگون است. حذف یک لایه باعث می‌شود خطاهای بقیه به‌آسانی بد خوانده شوند، پس هر سه را نگه دارید و به‌محض شکست یک لایه متوقف شوید.

آیا به‌جای اعتبارسنجی در CI به pre-commit تکیه کنم؟

نه. قلاب‌ها فقط فایل‌های staged را پردازش می‌کنند، که بازخوردی در یک دقیقه می‌دهد اما نمی‌تواند کل مخزن یا تغییرات دورزننده از commit را پوشش دهد. CI مسئول کامل بودن است: pre-commit را روی فایل‌های staged نگه دارید و اسکن کامل را به CI بسپارید.