Το NPM σημαίνει Node package manager, το οποίο είναι ένα μητρώο λογισμικού για λογισμικό ανοιχτού κώδικα όπου οι χρήστες μπορούν να δημοσιεύουν πακέτα για δημόσια και ιδιωτική χρήση.
Διαχείριση πακέτων μέσα σε πακέτο npm
Ένα πακέτο npm είναι συνήθως μια βασική εφαρμογή που χρησιμοποιεί άλλα πακέτα για τη διαχείριση και τη χρήση βασικών λειτουργιών. Αλλά σε κανονικό σενάριο, χρησιμοποιούμε νήμα ή npm για να εγκαταστήσουμε αυτά τα πακέτα, αλλά κατά τη δημιουργία ενός πακέτου npm χρειαζόμαστε έναν καθολικό τρόπο αποθήκευσης και διαχείρισης πακέτων σε ολόκληρο το έργο. Για αυτό λοιπόν χρησιμοποίησα το LERNA, μπορείτε να βρείτε την επίσημη τεκμηρίωση για τη lerna εδώ.
Αυτή είναι η βασική δομή φακέλου για τη διαχείριση έργων lerna
Ο φάκελος έχει τις ακόλουθες εξαρτήσεις:
- cli (Διαχείριση της διεπαφής της γραμμής εντολών)
- local-API (Το back-end API που βασίζεται στο express)
- local-client (Η διεπαφή διεπαφής χρήστη χρησιμοποιεί React, redux και bulma για στυλ)
Ας δούμε πρώτα το CLI
Για το CLI, χρησιμοποίησα ένα πακέτο που ονομάζεται commander
στον οποίο γράφετε κώδικα για να περιγράψετε τη διεπαφή της γραμμής εντολών σας. Το Commander φροντίζει να αναλύσει τα επιχειρήματα σε επιλογές και επιχειρήματα εντολών, εμφανίζει σφάλματα χρήσης για προβλήματα και εφαρμόζει ένα σύστημα βοήθειας για μη αναγνωρισμένες επιλογές και εμφανίζει ένα σφάλμα.
Μπορείτε να βρείτε την επίσημη τεκμηρίωση προς τον διοικητή Εδώ.
Ο χειριστής δέχεται μια εντολή και μερικές επιλογές, σε αυτήν την περίπτωση η εντολή είναι η υπηρεσία και η επιλογή είναι ένας αριθμός θύρας όπου εκτελείται αυτό το πρόγραμμα που από προεπιλογή είναι 4005.
const serveCommand = new Command() .command('serve [filename]') .description('Open a file for editing') .option('-p --port <number>', 'port to run server on', '4005') .action(async (filename = 'notebook.js', options: { port: string }) => { try { const dir = path.join(process.cwd(), path.dirname(filename)); await serve( parseInt(options.port), path.basename(filename), dir, !isProduction ); console.log( `Opened ${filename}. Navigate to http://localhost:${options.port} to edit the file.` ); } catch (error: any) { if (error.code === 'EADDRINUSE') { console.error('Port is already in use please try another port'); } else { console.log(error.message); } process.exit(1); } });
Εκτός από αυτό, οι ακόλουθες εξαρτήσεις χρησιμοποιούνται επίσης στο πακέτο cli
Στον τοπικό κατάλογο api, ορίζονται όλες οι διαδρομές, έχει βασικά δύο διαδρομές:-
- Μια διαδρομή για να
/cells
(Αυτό το τελικό σημείο επιστρέφει τα υπάρχοντα δεδομένα κελιών από το αρχείο σημειωματάριου)
router.get('/cells', async (req, res) => { try { const result = await fs.readFile(fullPath, { encoding: 'utf-8' }); res.send(JSON.parse(result)); } catch (error: any) { if (error.code === 'ENOENT') { await fs.writeFile(fullPath, '[]', 'utf-8'); res.send([]); } else { throw error; } } });
Αρχικά προσπαθούμε να διαβάσουμε τα υπάρχοντα περιεχόμενα του αρχείου χρησιμοποιώντας την ενσωματωμένη μονάδα αρχείων συστήματος(fs) και επειδή τα δεδομένα είναι σε μορφή JSON, τα αναλύουμε και τα στέλνουμε πίσω.
Η αναδίπλωση ολόκληρου του κώδικα σε ένα μπλοκ try-catch διευκολύνει την αποστολή σφαλμάτων αντί για τη συντριβή της εφαρμογής.
- Μια ταχυδρομική διαδρομή προς
/cells
(Αυτό το τελικό σημείο στέλνει τα υπάρχοντα δεδομένα κυψέλης προς αποθήκευση σε αρχείο σημειωματάριου)
router.post('/cells', async (req, res) => { const { cells }: { cells: Cell[] } = req.body; await fs.writeFile(fullPath, JSON.stringify(cells), 'utf-8'); res.send({ status: 'ok' }); });
Ομοίως, στη διαδρομή ανάρτησης λαμβάνουμε τα δεδομένα από τον πελάτη, μετατρέποντάς τα σε συμβολοσειρά JSON και τα γράφουμε ξανά χρησιμοποιώντας την ίδια ενότητα συστήματος αρχείων (fs).
Μπορείτε να βρείτε περισσότερα για τις μονάδες FS εδώ.
Τέλος, έρχεται η μονάδα πελάτη που έχει δημιουργηθεί με τη χρήση React, redux, typescript, bulma και monaco editor.
Για αυτό οι κύριες προκλήσεις ήταν:
- Δημιουργία προγράμματος επεξεργασίας σήμανσης
- Δημιουργία λύσης για τη σύνταξη και τη μεταγλώττιση κώδικα online στο ίδιο το πρόγραμμα περιήγησης.
- Δημιουργία bundler για μεταγλώττιση.
Για το πρόγραμμα επεξεργασίας σήμανσης που κατέληξα να χρησιμοποιήσω @uiw/react-md-editor
.
import { useState, useEffect, useRef } from 'react';
import MDEditor from '@uiw/react-md-editor';
import './css/text-editor.css';
import { Cell } from '../state';
import { useActions } from '../hooks/use-actions'; interface TextEditorProps { cell: Cell;
} const TextEditor: React.FC<TextEditorProps> = ({ cell }) => { const [editing, setEditing] = useState(false); const ref = useRef<HTMLDivElement | null>(null); const { updateCell } = useActions(); useEffect(() => { const listener = (event: MouseEvent) => { if ( ref.current && event.target && ref.current.contains(event.target as Node) ) return; setEditing(false); }; document.addEventListener('click', listener, { capture: true }); return () => { document.removeEventListener('click', listener, { capture: true }); }; }, []); if (editing) { return ( <div className="text-editor" ref={ref}> <MDEditor value={cell.content} onChange={(v) => updateCell(cell.id, v || '')} /> </div> ); } return ( <div className="text-editor card" onClick={() => setEditing(true)}> <div className="card-content"> <MDEditor.Markdown source={cell.content || 'Click to edit'} /> </div> </div> );
}; export default TextEditor;
Για να διαβάσετε περισσότερα σχετικά με @uiw/react-md-editor
μπορείτε να πάτε εδώ.
Τώρα για τη σύνταξη και τη μεταγλώττιση κώδικα στο διαδίκτυο χρειαζόμουν ένα πρόγραμμα επεξεργασίας κώδικα που μοιάζει και έχει την αίσθηση του VS-Code και έτσι κατέληξα να χρησιμοποιώ το πρόγραμμα επεξεργασίας monaco που δημιουργείται από την ίδια τη Microsoft και παρέχει επίσης τον κώδικα VS.
Αυτή είναι η διαμόρφωση που χρησιμοποίησα για το στοιχείο του επεξεργαστή μου:-
<MonacoEditor editorDidMount={onEditorMount} value={initialValue} height="100%" language="javascript" theme="dark" options={{ wordWrap: 'on', matchBrackets: 'always', minimap: { enabled: false }, showUnused: false, folding: false, lineNumbersMinChars: 3, fontSize: 18, scrollBeyondLastLine: false, automaticLayout: true, }}
/>
Τώρα, μετά τη δημιουργία του προγράμματος επεξεργασίας, υπήρχαν άλλα 2 ζητήματα:-
- Ο κώδικας δεν είχε μορφοποιηθεί σωστά.
- Και υπήρξαν ορισμένα θέματα επισήμανσης.
Για να διορθώσω τη μορφοποίηση κώδικα, δημιούργησα ένα κουμπί που καλεί το πιο όμορφο πακέτο να μορφοποιήσει κώδικα.
const onFormatClick = () => { const unFormatted = editorRef.current.getModel().getValue(); const formatted = prettier .format(unFormatted, { parser: 'babel', plugins: [parser], useTabs: false, semi: true, singleQuote: true, }) .replace(/n$/, ''); editorRef.current.setValue(formatted); }; <button onClick={onFormatClick}> Format
</button>
Στη συνέχεια χρησιμοποίησα για την επισήμανση κώδικα jscodeshift
και monaco-jsx-highlighter
και δημιούργησε ένα στοιχείο προσάρτησης το οποίο έτρεχε κατά την προσάρτηση του επεξεργαστή:-
const onEditorMount: EditorDidMount = (getValue, monacoEditor) => { editorRef.current = monacoEditor; monacoEditor.onDidChangeModelContent(() => { onChange(getValue()); }); monacoEditor.getModel()?.updateOptions({ tabSize: 2 }); const highlighter = new Highlighter( // @ts-ignore window.monaco, codeshift, monacoEditor ); highlighter.highLightOnDidChangeModelContent( () => {}, () => {}, undefined, () => {} ); };
Μετά έρχεται το πιο σημαντικό κομμάτι Το bundler :-
Για τη ομαδοποίηση, η βασική περίπτωση χρήσης είναι ότι πρέπει να πάρουμε τον κώδικα, να τον μεταγλωττίσουμε και μετά να δείξουμε την έξοδο. Τώρα τι γίνεται αν ένας χρήστης εισάγει ορισμένα πακέτα από το μητρώο npm; Για αυτόν τον λόγο θα χρειαζόμασταν ένα bundler και στην περίπτωσή μου χρησιμοποίησα το unpkg και δημιούργησα μια υπηρεσία bundler.
import * as esbuild from 'esbuild-wasm';
import { fetchPlugin } from './plugins/fetch-plugin';
import { unpkgPathPlugin } from './plugins/unpkg-path-plugin'; let service: esbuild.Service;
const bundle = async (rawCode: string) => { if (!service) { service = await esbuild.startService({ worker: true, wasmURL: 'https://unpkg.com/esbuild-wasm@0.8.27/esbuild.wasm', }); } try { const result = await service.build({ entryPoints: ['index.js'], bundle: true, write: false, plugins: [unpkgPathPlugin(), fetchPlugin(rawCode)], define: { 'process.env.NODE_ENV': '"production"', global: 'window', }, jsxFactory: '_React.createElement', jsxFragment: '_React.Fragment', }); return { code: result.outputFiles[0].text, err: '' }; } catch (err) { return { code: '', err: (err as Error).message }; }
}; export default bundle;
Βάζοντας όλα μαζί
Μετά από αυτό, ήρθε η ώρα να το αναπτύξουμε στο μητρώο npm, τώρα για αυτό θα πρέπει να δημιουργήσουμε έναν λογαριασμό npm που είναι σχεδόν απλός και μπορεί να γίνει εύκολα μεταβαίνοντας στο npm και εγγραφή.
Τώρα πρέπει να κάνουμε κάποιες αλλαγές στο αρχείο μας package.json.
Πρέπει να προσθέσουμε την κύρια, τους τύπους (αν είναι αρχείο γραφομηχανής) και την άδεια (κυρίως MIT για OSS)
Τώρα προσθέστε το publicConfig να είναι δημόσιο ή ιδιωτικό και τον φάκελο καταχώρισης από τον οποίο εξυπηρετεί το npm.
Αυτό είναι που είσαι καλός να πας…
Εδώ είναι ολόκληρος ο πηγαίος κώδικας για το έργο.
Ελέγξτε το και αφήστε ένα αστέρι..
- SEO Powered Content & PR Distribution. Ενισχύστε σήμερα.
- Platoblockchain. Web3 Metaverse Intelligence. Ενισχύθηκε η γνώση. Πρόσβαση εδώ.
- πηγή: https://www.codementor.io/dpak1999/creating-your-own-npm-package-23fygg52hd
- :είναι
- $UP
- 1
- 8
- a
- Σχετικά με εμάς
- Λογαριασμός
- απέναντι
- Μετά το
- Όλα
- ήδη
- πάντοτε
- και
- Άλλος
- api
- app
- Εφαρμογή
- ΕΙΝΑΙ
- επιχειρήματα
- AS
- At
- αναμένω
- Βαβέλ
- πίσω
- Πίσω μέρος
- βασικός
- Βασικα
- BE
- Αποκλεισμός
- σώμα
- πρόγραμμα περιήγησης
- χτισμένο
- Δέσμη
- κουμπί
- by
- που ονομάζεται
- κλήσεις
- CAN
- πιάνω
- κάρτα
- περίπτωση
- πάλη
- Κύτταρα
- προκλήσεις
- Αλλαγές
- έλεγχος
- κλικ
- πελάτης
- κωδικός
- συστατικό
- διαμόρφωση
- πρόξενος
- περιεχόμενο
- περιεχόμενα
- κάλυμμα
- Συντριβή
- δημιουργία
- δημιουργήθηκε
- δημιουργία
- CSS
- Ρεύμα
- σκοτάδι
- ημερομηνία
- Προεπιλογή
- ορίζεται
- παρατάσσω
- περιγράφουν
- οθόνες
- έγγραφο
- τεκμηρίωση
- ευκολότερη
- εύκολα
- επεξεργασία
- συντάκτης
- ενεργοποιημένη
- Τελικό σημείο
- Ολόκληρος
- καταχώριση
- σφάλμα
- λάθη
- Αιθέρας (ΕΤΗ)
- Συμβάν
- υφιστάμενα
- εξαγωγή
- ρητή
- Αρχεία
- Εύρεση
- Όνομα
- Πρώτη ματιά
- σταθερός
- Εξής
- Για
- μορφή
- Προς τα εμπρός
- Βρέθηκαν
- από
- FS
- λειτουργίες
- παίρνω
- να πάρει
- Παγκόσμιο
- Go
- μετάβαση
- καλός
- βοήθεια
- επισήμανση
- http
- HTTPS
- i
- ID
- εικόνα
- υλοποιεί
- εισαγωγή
- σημαντικό
- εισαγωγές
- in
- ευρετήριο
- εγκαθιστώ
- περιβάλλον λειτουργίας
- θέματα
- IT
- ΤΟΥ
- εαυτό
- το JavaScript
- json
- Άδεια
- Άδεια
- Μου αρέσει
- γραμμή
- τοπικός
- ματιά
- ΦΑΊΝΕΤΑΙ
- Κυρίως
- κάνω
- ΚΑΝΕΙ
- διαχείριση
- διευθυντής
- διαχείριση
- μήνυμα
- Microsoft
- MIT
- ενότητα
- ενότητες
- Μονακό
- περισσότερο
- πλέον
- ΤΟΠΟΘΕΤΗΣΗ
- Πλοηγηθείτε
- Ανάγκη
- που απαιτούνται
- Νέα
- κόμβος
- κανονικός
- Κανονικά
- σημειωματάριο
- αριθμός
- of
- επίσημος ανώτερος υπάλληλος
- on
- διαδικτυακά (online)
- ανοίξτε
- ανοικτού κώδικα
- Επιλογή
- Επιλογές
- Μας
- ΑΛΛΑ
- παραγωγή
- δική
- πακέτο
- Packages
- μέρος
- μονοπάτι
- Πλάτων
- Πληροφορία δεδομένων Plato
- Πλάτωνα δεδομένα
- σας παρακαλούμε
- Plugins
- Θέση
- αρμοδιότητες
- αρκετά
- ιδιωτικός
- προβλήματα
- διαδικασια μας
- παραγωγή
- Πρόγραμμα
- σχέδιο
- έργα
- δεόντως
- δημόσιο
- δημοσιεύει
- Βάζοντας
- μάλλον
- Αντίδραση
- Διάβασε
- λόγος
- Redux
- μητρώου
- αποτέλεσμα
- απόδοση
- Επιστροφές
- Διαδρομή
- δρομολόγια
- τρέξιμο
- s
- ίδιο
- σενάριο
- Ημι
- αποστολή
- εξυπηρετούν
- εξυπηρετεί
- υπηρεσία
- δείχνουν
- υπογραφή
- αφού
- So
- λογισμικό
- λύση
- μερικοί
- Πηγή
- πρωτογενής κώδικας
- στέκεται
- Αστέρι
- Κατάσταση
- Βήμα
- κατάστημα
- ευθεία
- Σπάγγος
- δομή
- σύστημα
- παίρνει
- στόχος
- ότι
- Η
- Αυτοί
- ώρα
- προς την
- αληθής
- Typescript
- ui
- us
- Χρήση
- χρήση
- Χρήστες
- Χρήστες
- vs
- έναντι κώδικα
- Τρόπος..
- Τι
- Ποιό
- ενώ
- εργάτης
- θα
- γράφω
- γράψτε κώδικα
- γραφή
- Σας
- zephyrnet