Selama proses pengembangan, sering digunakan Node.js, yang menggunakan kemampuan yang diberikan oleh V8 untuk memperluas kemampuan JS. Di Node.js kita bisa menggunakan modul path yang tidak ada di JS. Agar kita lebih mengenal aplikasinya, mari kita lihat ~
Versi Node.js artikel ini adalah 16.14.0 , dan kode sumber artikel ini berasal dari sini Versi. Saya berharap setelah membaca artikel ini, dapat bermanfaat bagi semua orang untuk membaca kode sumbernya.
Path digunakan untuk memproses jalur file dan direktori. Modul ini menyediakan beberapa fungsi alat yang mudah dikembangkan oleh pengembang untuk membantu kami membuat penilaian jalur yang kompleks dan meningkatkan efisiensi pengembangan. Misalnya:
Konfigurasikan alias dalam proyek. Konfigurasi alias memudahkan kita untuk mereferensikan file dan menghindari pencarian ke atas langkah demi langkah.
cinta kembali: { alias: { // __dirname jalur direktori 'src' tempat file saat ini berada: path.resolve(__dirname, './src'), // process.cwd direktori kerja saat ini '@': path.join(process.cwd(), 'src'), }, }
Di webpack, jalur keluaran file juga dapat dihasilkan ke lokasi yang ditentukan melalui konfigurasi kita sendiri.
modul.ekspor = { entri: './path/to/my/entry/file.js', keluaran: { jalur: path.resolve(__dirname, 'dist'), nama file: 'webpack-pertama-saya.bundle.js', }, };
Atau untuk operasi folder
let fs = require("fs"); biarkan jalur = memerlukan("jalur"); // Hapus foldernya let deleDir = (src) => { // Baca foldernya biarkan anak-anak = fs.readdirSync(src); anak-anak.forEach(item => { biarkan jalur anak = jalur.join(src, item); // Periksa apakah file tersebut ada let file = fs.statSync(childpath).isFile(); jika (berkas) { // Hapus file jika ada fs.unlinkSync(childpath) } kalau tidak { //Lanjutkan mendeteksi folder deleDir(childpath) } }) // Hapus folder kosong fs.rmdirSync(src) } deleDir("../floor")
memahami secara singkat skenario penggunaan jalur. Selanjutnya, kita akan mempelajari mekanisme eksekusinya dan bagaimana penerapannya berdasarkan penggunaannya.
Ketika modul jalur diperkenalkan dan fungsi alat jalur dipanggil, logika pemrosesan modul asli akan dimasukkan.
Gunakan fungsi _load
untuk menggunakan nama modul yang Anda perkenalkan sebagai ID untuk menentukan bahwa modul yang akan dimuat adalah modul JS asli. Setelah itu, fungsi loadNativeModule
akan digunakan untuk menggunakan id untuk menemukan kode ASCII yang sesuai dari _source
( string kode sumber yang menyimpan modul JS asli). Data dimuat ke modul JS asli.
Jalankan file lib/path.js dan gunakan proses untuk menentukan sistem operasi. Tergantung pada sistem operasi, mungkin ada perbedaan pemrosesan karakter operasi dalam pemrosesan file, tetapi metodenya kira-kira sama Setelah diproses, itu dikembalikan ke penelepon.
penyelesaian, mengembalikan jalur absolut dari
penyelesaian jalur saat ini, menyambungkan beberapa parameter secara berurutan untuk menghasilkan jalur absolut baru.
tekad(...args) { biarkan terselesaikanPerangkat = ''; biarkan ResolveTail = ''; biarkan terselesaikanAbsolute = false; // Deteksi parameter dari kanan ke kiri untuk (misalkan i = args.length - 1; i >= -1; i--) { ... } //Jalur yang dinormalisasi ResolveTail = normalizeString(resolvedTail, !resolvedAbsolute, '\', isPathSeparator); kembali terselesaikanMutlak? `${resolvedDevice}\${resolvedTail}` : `${resolvedDevice}${resolvedTail}` ||.'; }
Dapatkan jalur sesuai dengan parameter, lintasi parameter yang diterima, mulai penyambungan ketika panjang parameter lebih besar dari atau sama dengan 0, lakukan verifikasi non-string pada jalur yang disambung, jika ada parameter yang tidak cocok , throw new ERR_INVALID_ARG_TYPE(name, 'string', value)
, jika persyaratan terpenuhi, panjang jalur akan dinilai. Jika ada nilai, += jalur akan digunakan untuk langkah selanjutnya.
biarkan jalan; jika (saya >= 0) { jalur = args[i]; // internal/validator validasiString(jalur, 'jalur'); // Jika panjang jalur adalah 0, maka jalur tersebut akan langsung keluar dari perulangan for pada blok kode di atas if (path.length === 0) { melanjutkan; } } else if (resolvedDevice.length === 0) { //Panjang ResolveDevice adalah 0, tetapkan nilai ke path sebagai direktori kerja saat ini path = process.cwd(); } kalau tidak { // Menetapkan nilai ke objek lingkungan atau jalur direktori kerja saat ini = process.env[`=${resolvedDevice}`] || process.cwd(); jika (jalur === tidak terdefinisi || (StringPrototypeToLowerCase(StringPrototypeSlice(jalur, 0, 2)) !== StringPrototypeToLowerCase(Perangkat terselesaikan) && StringPrototypeCharCodeAt(jalur, 2) === CHAR_BACKWARD_SLASH)) { //Menilai jalur ke jalur tidak kosong dan absolut untuk mendapatkan jalur path = `${resolvedDevice}\`; } }
Cobalah untuk mencocokkan jalur root, tentukan apakah hanya ada satu pemisah jalur ('') atau jalur tersebut merupakan jalur absolut, kemudian tandai jalur absolut dan setel tanda intersepsi rootEnd
ke 1 (subskrip). Jika item kedua masih berupa pemisah jalur (''), tentukan nilai intersepsi sebagai 2 (subskrip), dan gunakan last
untuk menyimpan nilai intersepsi untuk penilaian selanjutnya.
Lanjutkan untuk menentukan apakah item ketiga adalah pemisah jalur (''). Jika demikian, ini adalah jalur absolut, dan pengidentifikasi intersepsi rootEnd
adalah 1 (subskrip), tetapi mungkin juga merupakan jalur UNC (namaservernamaberbagi). , nama server nama server). Jika ada nilai lain maka nilai yang dicegat akan terus bertambah dan membaca nilai berikut, dan menggunakan firstPart
untuk menyimpan nilai bit ketiga sehingga nilai tersebut dapat diperoleh saat menyambung direktori, dan mempertahankan nilai terakhir dan nilai yang dicegat konsisten untuk mengakhiri penghakiman.
const len = jalur.panjang; biarkan rootEnd = 0; // Subskrip akhir intersepsi jalur biarkan perangkat = ''; let isAbsolute = false; // Apakah itu jalur root disk const code = StringPrototypeCharCodeAt(path, 0); // panjang jalur adalah 1 jika (len === 1) { // Hanya ada satu pemisah jalur untuk jalur absolut if (isPathSeparator(code)) { rootEnd = 1; isAbsolute = benar; } } else if (isPathSeparator(kode)) { // Mungkin merupakan akar UNC, dimulai dengan pembatas , setidaknya salah satunya merupakan jalur absolut (UNC atau lainnya) isAbsolute = benar; // Mulai mencocokkan pemisah jalur ganda if (isPathSeparator(StringPrototypeCharCodeAt(path, 1))) { misalkan j = 2; biarkan bertahan = j; // Cocokkan satu atau lebih pembatas non-jalur while (j < len && !isPathSeparator(StringPrototypeCharCodeAt(jalur, j))) { j++; } if (j < len && j !== terakhir) { const firstPart = StringPrototypeSlice(jalur, terakhir, j); terakhir = j; // Cocokkan satu atau lebih pemisah jalur while (j < len && isPathSeparator(StringPrototypeCharCodeAt(jalur, j))) { j++; } if (j < len && j !== terakhir) { terakhir = j; sementara (j < len && !isPathSeparator(StringPrototypeCharCodeAt(jalur, j))) { j++; } if (j === len || j !== terakhir) { perangkat= `\\${firstPart}\${StringPrototypeSlice(jalur, terakhir, j)}`; rootEnd = j; } } } } kalau tidak { rootEnd = 1; } // Mendeteksi contoh pencocokan direktori root disk: D:, C: } else if (isWindowsDeviceRoot(kode) && StringPrototypeCharCodeAt(jalur, 1) === CHAR_COLON) { perangkat = StringPrototypeSlice(jalur, 0, 2); rootEnd = 2; if (len > 2 && isPathSeparator(StringPrototypeCharCodeAt(jalur, 2))) { isAbsolute = benar; rootEnd = 3; } }
Deteksi jalur dan hasilkan, periksa apakah direktori akar disk ada atau tentukan apakah resolvedAbsolute
merupakan jalur absolut.
//Deteksi direktori root disk if (device.length > 0) { // ResolvedDevice mempunyai nilai if (resolvedDevice.length > 0) { if (StringPrototypeToLowerCase(perangkat) !== StringPrototypeToLowerCase(Perangkat terselesaikan)) melanjutkan; } kalau tidak { // ResolveDevice tidak memiliki nilai dan diberi nilai direktori root disk ResolveDevice = Device; } } // Jalur absolut jika (resolvedAbsolute) { // Ada loop akhir jika direktori root disk ada (resolvedDevice.length > 0) merusak; } kalau tidak { // Dapatkan awalan jalur untuk penyambungan ResolveTail = `${StringPrototypeSlice(jalur, rootEnd)}\${resolvedTail}`; terselesaikanAbsolute = isAbsolute; if (isAbsolute &&resolveDevice.length > 0) { // Perulangan berakhir ketika root disk rusak; } }
join melakukan penyambungan jalur berdasarkan fragmen jalur masuk
Terima beberapa parameter, gunakan pemisah spesifik sebagai pembatas untuk menghubungkan semua parameter jalur bersama-sama, dan buat jalur baru yang dinormalisasi.
Setelah menerima parameter, verifikasi. Jika tidak ada parameter, ia akan mengembalikan '.' secara langsung. Jika tidak, ia akan melintasi dan memverifikasi setiap parameter melalui metode validateString
throw new ERR_INVALID_ARG_TYPE(name, 'string', value);
. throw new ERR_INVALID_ARG_TYPE(name, 'string', value);
join
dari karakter escape adalah jika digunakan sendiri, dianggap sebagai escape dari string setelah garis miring, sehingga digunakan garis miring terbalik ganda untuk menghindari garis miring terbalik ('').
Terakhir, string gabungan diverifikasi dan dikembalikan dalam format.
if (argumen panjang === 0) kembali '.'; ayo bergabung; biarkan duluBagian; // Deteksi parameter dari kiri ke kanan untuk (misalkan i = 0; i < args.length; ++i) { const arg = args[i]; // internal/validator validasiString(arg, 'jalur'); if (panjang argumen > 0) { if (bergabung === tidak terdefinisi) // Tetapkan string pertama untuk digabungkan, dan gunakan variabel firstPart untuk menyimpan string pertama untuk digunakan nanti join = firstPart = arg; kalau tidak // yang digabungkan mempunyai nilai, lakukan += operasi penyambungan yang digabungkan += `\${arg}`; } } if (bergabung === tidak terdefinisi) return '.';
Di bawah sistem jendela, pemrosesan jalur jaringan diperlukan karena penggunaan garis miring terbalik ('') dan jalur UNC (terutama mengacu pada nama lengkap sumber daya Windows 2000 di LAN), ('') mewakili adalah format jalur jaringan, sehingga metode join
yang dipasang di win32 akan mencegat secara default.
Jika garis miring terbalik ('') cocok, slashCount
akan bertambah. Selama ada lebih dari dua garis miring terbalik ('') yang cocok, jalur yang disambung akan dicegat dan disambung secara manual serta di-escape. '').
biarkan kebutuhanReplace = true; biarkan garis miringHitung = 0; // Ekstrak kode kode string pertama secara berurutan sesuai dengan StringPrototypeCharCodeAt, dan cocokkan dengan kode kode yang ditentukan melalui metode isPathSeparator if (isPathSeparator(StringPrototypeCharCodeAt(firstPart, 0))) { ++hitungan garis miring; const firstLen = firstPart.panjang; jika (Len pertama > 1 && isPathSeparator(StringPrototypeCharCodeAt(firstPart, 1))) { ++hitungan garis miring; jika (Len pertama > 2) { jika (isPathSeparator(StringPrototypeCharCodeAt(firstPart, 2))) ++hitungan garis miring; kalau tidak { kebutuhanGanti = salah; } } } } jika (perluGanti) { while (slashCount <bergabung.panjang && isPathSeparator(StringPrototypeCharCodeAt(bergabung, garis miring))) { garis miringCount++; } jika (jumlah garis miring >= 2) bergabung = `\${StringPrototypeSlice(bergabung, jumlah garis miring)}`; }
Penyortiran hasil eksekusi
resolve | join | |
---|---|---|
tidak memiliki parameter | . | Jalur absolut dari file saat ini | .
absolut | ||
. | Jalur absolut dari file saat ini disambung | secara berurutan |
disambung ke jalur absolut dari | jalur non-absolut berikutnya. | |
Parameter pasca jalur adalah | parameter jalur absolut. Jalur tersebut menimpa jalur absolut dari file saat ini dan menimpa | jalur yang disambung oleh | pra-parameter.
Parameter pertama adalah (./) | dan memiliki parameter berikutnya. Parameter penyambungan jalur absolut dari file saat ini tidak memiliki parameter berikutnya. Jalur absolut dari file saat ini adalah Jalur | memiliki parameter berikutnya, dan jalur disambung oleh parameter selanjutnya tidak memiliki parameter berikutnya. (./) |
( | ||
./) | Parameter penyambungan jalur absolut yang diurai | memiliki parameter berikutnya |
parameter pertama adalah (../) | dan ada parameter selanjutnya. Parameter penyambungan setelah direktori tingkat terakhir yang mencakup jalur absolut dari file saat ini tidak | memiliki parameter berikutnya . Penyambungan Tidak ada parameter berikutnya untuk parameter berikutnya. (../) |
Parameter pasca memiliki (../ | ). Direktori tingkat atas tempat (../) muncul akan ditimpa Ditimpa. Direktori tingkat atas akan ditimpa. Setelah itu, kembali (/), parameter selanjutnya akan disambung dan | direktori atas yang muncul (../) akan ditimpa Setelah direktori atas ditimpa, |
dibaca setelah kode sumber, metode resolve
akan memproses parameter, mempertimbangkan bentuk jalur, dan membuang jalur absolut di akhir. Saat menggunakannya, jika Anda melakukan operasi seperti file, disarankan untuk menggunakan metode resolve
. Sebagai perbandingan, metode resolve
akan mengembalikan jalur meskipun tidak ada parameter untuk dioperasikan pengguna, dan jalur akan diproses selama proses eksekusi. Metode join
hanya melakukan penyambungan standar terhadap parameter masuk, yang lebih praktis untuk menghasilkan jalur baru dan dapat dibuat sesuai keinginan pengguna. Namun, setiap metode memiliki kelebihannya masing-masing. Anda harus memilih metode yang sesuai dengan skenario penggunaan dan kebutuhan proyek Anda.