Back to "Δημοσιεύω ένα πακέτο NPM!! Publishing Mermaid Βελτιώσεις ως ένα πακέτο npm"

This is a viewer only at the moment see the article on how this works.

To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk

This is a preview from the server running through my markdig pipeline

JavaScript Mermaid npm TypeScript

Δημοσιεύω ένα πακέτο NPM!! Publishing Mermaid Βελτιώσεις ως ένα πακέτο npm

Friday, 07 November 2025

Εισαγωγή

Εγώ... ένας τύπος από το .net βρήκε επιτέλους το κουράγιο να βουτήξει τα δάχτυλα των ποδιών μου στον κόσμο των πακέτων! Γοργόνα.js είναι αρκετά σκοτεινό και αρκετά περίεργο ότι θα μπορούσα πραγματικά να παραδώσει κάτι χρήσιμο!

Μετά την κατασκευή κάποιων πραγματικά χρήσιμες βελτιώσεις για διαγράμματα Mermaid.js (διαδραστικό pan/zoom, fullscreen lightbox, εξαγωγή σε PNG/SVG, και αυτόματη αλλαγή θέματος), αποφάσισα ότι ήταν καιρός να τα συσκευάσει σωστά και να τα μοιραστούν με την κοινότητα. @mostlylucid/mermaid-enhancements ως πακέτο παραγωγής-έτοιμο npm.

ΣΗΜΕΙΩΣΗ: Εξακολουθεί να εργάζεται για την απελευθέρωση. Μείνετε συντονισμένοι (το πρώτο πακέτο μου npm έτσι παίρνει λίγο)

έκδοση npm npm downloads Άδεια: Unlicense TypeScript Μέγεθος bundleName

Γιατί το πακετάρετε;

Χρησιμοποιώ αυτές τις βελτιώσεις σε όλο το blog μου εδώ και λίγο καιρό, και έχουν γίνει απαραίτητες για να εργαστούν με σύνθετα διαγράμματα Γοργόνας. Τα χαρακτηριστικά περιλαμβάνουν:

  • Διαδραστικό Pan & ZoomName - Πλοήγηση μεγάλων διαγραμμάτων ομαλά
  • Fullscreen Lightbox - Immersive viewing experience
  • Εξαγωγή σε PNG/SVG - Υψηλής ποιότητας λήψεις διαγραμμάτων
  • Αυτόματη εναλλαγή θέματος - Αδιάβροχη υποστήριξη τρόπου φωτισμού/σκοτεινής κατάστασης
  • Αναπνευστικός σχεδιασμός - Εργασίες σε κινητά και επιφάνεια εργασίας

Δεδομένου ότι αντιγράφω τον ίδιο κώδικα μεταξύ των έργων, ήταν λογικό να δημιουργήσουμε ένα κατάλληλο πακέτο NPM που ο καθένας θα μπορούσε να χρησιμοποιήσει.

Δομή έργου

Έχω δημιουργήσει μια επαγγελματική δομή πακέτου με την υποστήριξη TypeScript:

mostlylucid-mermaid/
├── src/
│   ├── index.ts              # Main entry point
│   ├── enhancements.ts       # Pan/zoom/export functionality
│   ├── theme-switcher.ts     # Theme switching logic
│   ├── types.ts              # TypeScript type definitions
│   └── styles.css            # Complete styling
├── examples/
│   └── demo.html             # Full-featured demo
├── dist/                     # Built output (generated)
├── package.json
├── tsconfig.json
├── README.md
├── QUICKSTART.md
├── PUBLISHING.md
└── LICENSE

Το πακέτο χρησιμοποιεί το TypeScript για την ασφάλεια του τύπου και την καλύτερη εμπειρία του προγραμματιστή, αλλά καταρτίζει μέχρι JavaScript για μέγιστη συμβατότητα.

Η Αρχιτεκτονική

Εδώ είναι πώς τα συστατικά ταιριάζουν μεταξύ τους:

Έτσι φαίνεται!

Έτσι βλέπετε ότι είναι αρκετά συμπαγής και έχει κάποια χρήσιμη λειτουργικότητα πέρα από απλά στατικά διαγράμματα. Πάντα με ενοχλούσε το πώς MASSIVE ήταν στη σελίδα, έτσι ώστε αυτό φαινόταν μια λογική προσέγγιση στο μέγεθος refuckng διατηρώντας τη χρησιμότητα.

graph TD
    A[User Initializes] --> B[init Function]
    B --> C[initMermaid]
    B --> D[enhanceMermaidDiagrams]

    C --> E[Theme Detection]
    C --> F[Event Listeners]
    C --> G[Mermaid Rendering]

    E --> E1[Global State]
    E --> E2[LocalStorage]
    E --> E3[DOM Class]
    E --> E4[OS Preference]

    F --> F1[Custom Events]
    F --> F2[Media Query]

    G --> H[Apply Enhancements]
    D --> H

    H --> I[Wrap Diagrams]
    H --> J[Init Pan/Zoom]
    H --> K[Add Controls]

    I --> L[Interactive Diagram]
    J --> L
    K --> L

    L --> M[User Interactions]
    M --> M1[Zoom In/Out]
    M --> M2[Pan]
    M --> M3[Fullscreen]
    M --> M4[Export PNG/SVG]

    style A stroke:#059669,stroke-width:3px,color:#10b981
    style L stroke:#2563eb,stroke-width:3px,color:#3b82f6
    style M stroke:#7c3aed,stroke-width:3px,color:#8b5cf6

Βασική εφαρμογή

Ορισμοί τύπου

Πρώτον, ορίζω τους ολοκληρωμένους τύπους TypeScript:

// src/types.ts
export interface PanZoomInstance {
    zoom(scale: number): void;
    zoomIn(): void;
    zoomOut(): void;
    reset(): void;
    fit(): void;
    center(): void;
    resize(): void;
    destroy(): void;
    isPanEnabled(): boolean;
    enablePan(enabled: boolean): void;
}

export type ExportFormat = 'png' | 'svg';
export type Theme = 'dark' | 'default';
export type ControlAction = 'fullscreen' | 'zoomIn' | 'zoomOut' |
                           'reset' | 'pan' | 'exportPng' | 'exportSvg';

export interface EnhancementConfig {
    icons?: IconConfig;
    controls?: {
        fullscreen?: boolean;
        zoom?: boolean;
        pan?: boolean;
        export?: boolean;
    };
}

Κύριο σημείο εισόδου

Το κύριο σημείο εισόδου είναι απλό:

// src/index.ts
export {
    enhanceMermaidDiagrams,
    cleanupMermaidEnhancements
} from './enhancements.js';

export {
    initMermaid
} from './theme-switcher.js';

export async function init() {
    await initMermaid();
}

export default {
    init,
    initMermaid,
    enhanceMermaidDiagrams,
};

Εφαρμογή Pan/Zoom

Η λογική ενίσχυσης τυλίγει κάθε διάγραμμα με χειριστήρια και αρχικοποιεί svg-pan-zoom:

// src/enhancements.ts
import svgPanZoom from 'svg-pan-zoom';
import { toPng, toSvg } from 'html-to-image';

const panZoomInstances = new Map();

function initPanZoom(svgElement: SVGElement, diagramId: string) {
    // Clean up existing instance if present
    if (panZoomInstances.has(diagramId)) {
        try {
            panZoomInstances.get(diagramId).destroy();
        } catch (e) {
            console.warn('Failed to destroy existing pan-zoom instance:', e);
        }
        panZoomInstances.delete(diagramId);
    }

    try {
        const panZoomInstance = svgPanZoom(svgElement, {
            zoomEnabled: true,
            controlIconsEnabled: false,
            fit: true,
            center: true,
            minZoom: 0.1,
            maxZoom: 10,
            zoomScaleSensitivity: 0.3,
            dblClickZoomEnabled: true,
            mouseWheelZoomEnabled: true,
            preventMouseEventsDefault: true,
            contain: false
        });

        panZoomInstances.set(diagramId, panZoomInstance);
        return panZoomInstance;
    } catch (error) {
        console.error('Failed to initialize pan-zoom:', error);
        return null;
    }
}

Τα κουμπιά ελέγχου δημιουργούνται δυναμικά:

function createControlButtons(container: HTMLElement, diagramId: string) {
    if (container.querySelector('.mermaid-controls')) {
        return;
    }

    const controlsDiv = document.createElement('div');
    controlsDiv.className = 'mermaid-controls';

    const buttons = [
        { icon: 'bx-fullscreen', title: 'Fullscreen', action: 'fullscreen' },
        { icon: 'bx-zoom-in', title: 'Zoom In', action: 'zoomIn' },
        { icon: 'bx-zoom-out', title: 'Zoom Out', action: 'zoomOut' },
        { icon: 'bx-reset', title: 'Reset View', action: 'reset' },
        { icon: 'bx-move', title: 'Pan', action: 'pan' },
        { icon: 'bx-image', title: 'Export as PNG', action: 'exportPng' },
        { icon: 'bx-code-alt', title: 'Export as SVG', action: 'exportSvg' }
    ];

    buttons.forEach(btn => {
        const button = document.createElement('button');
        button.className = `mermaid-control-btn bx ${btn.icon}`;
        button.setAttribute('title', btn.title);
        button.setAttribute('aria-label', btn.title);
        button.setAttribute('data-action', btn.action);
        button.setAttribute('data-diagram-id', diagramId);
        controlsDiv.appendChild(button);
    });

    container.appendChild(controlsDiv);
}

Εξαγωγή Λειτουργικότητας

Η εφαρμογή των εξ

logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.