Node.js學(xué)習(xí)筆記(一)

簡介

?? Node.js 是一個(gè)基于 Chrome V8 引擎的 JavaScript 運(yùn)行環(huán)境。Node.js 使用了一個(gè)事件驅(qū)動、非阻塞式 I/O的模型,使其輕量又高效。Node.js 的包管理器 npm,是全球最大的開源庫生態(tài)系統(tǒng)。

安裝以及運(yùn)行環(huán)境

?? Node.js最新版可在官網(wǎng)下載,傻瓜式安裝后我們可打開命令行工具,輸入node -vnpm -v后顯示顯示對應(yīng)版本號后說明已經(jīng)安裝成功。在開發(fā)過程中我使用的是webstorm編輯器,該編輯器功能強(qiáng)大,是前端使用比較普遍的一類編輯器。為支持我們快捷開發(fā),webstorm為我們提供了一系列快捷的設(shè)置選項(xiàng),如點(diǎn)擊webstotm中file -- Setting -- Languages -- JavaScript可設(shè)置編輯器支持最新語言版本為ES6,點(diǎn)擊file -- Setting -- Node.js and NPM --Enable可設(shè)置node命令。設(shè)置完成后,我們在編輯器中輸入

let a = 10 ;
console.log(a);

然后點(diǎn)擊Run,結(jié)果就出來了。

運(yùn)行結(jié)果

Node.js基本知識

一、模塊的使用
? ? Node.js有一個(gè)簡單的模塊加載系統(tǒng),在 Node.js 中,文件和模塊是一一對應(yīng)的(每個(gè)文件被視為一個(gè)獨(dú)立的模塊)。我們分別通過exportrequire來導(dǎo)出模塊以及引用模塊。
circle.js

let { PI } = Math;
exports.area = (r) => PI * r * r;

foo.js

const circle = require('./circle.js');
console.log(circle.area(4));

? ?輸出結(jié)果為 50.26548245743669;
?? 值得注意的是,module.exportsexports都可以導(dǎo)出模塊,他們有什么區(qū)別呢?用一句話來概括就是,require能看到的只有module.exports這個(gè)對象,它是看不到exports對象的,而我們在編寫模塊時(shí)用到的exports對象實(shí)際上只是對module.exports的引用。實(shí)際上如下:

var module = {
  exports:{
    name:"我是module的exports"屬性
  }
};
var exports = module.exports;//exports是對module.exports的引用.
//他們是指向同一塊內(nèi)存下的數(shù)據(jù)

? ?通常情況下,我們不會直接對exports賦值,而是把一個(gè)變量掛載到exports上,因?yàn)橹苯淤x值exports會指向新的地址,和原來的地址沒有了關(guān)系,起不到引用的作用了。

二、常用API

global -全局變量

??全局變量是在所有變量均可以使用。下面介紹一些常用的變量。
__dirname 當(dāng)前模塊的文件夾名稱;
__filename當(dāng)前模塊的文件夾名稱解析后的絕對路徑;
exports對于module.exports的更簡短的引用形式;
module對當(dāng)前模塊的引用,module.exports用于指定一個(gè)模塊所導(dǎo)出的內(nèi)容;
require引入模塊;
我們可以通過打印來查詢?nèi)肿兞坷锩娴木唧w內(nèi)容,例如 module,打印出為

Module {
  id: '.',
  exports: {},
  parent: null,
  filename: 'C:\\Users\\Administrator\\Desktop\\temporary\\node\\foo.js',
  loaded: false,
  children: 
   [ Module {
       id: 'C:\\Users\\Administrator\\Desktop\\temporary\\node\\circle.js',
       exports: [Object],
       parent: [Circular],
       filename: 'C:\\Users\\Administrator\\Desktop\\temporary\\node\\circle.js',
       loaded: true,
       children: [],
       paths: [Object] } ],
  paths: 
   [ 'C:\\Users\\Administrator\\Desktop\\temporary\\node\\node_modules',
     'C:\\Users\\Administrator\\Desktop\\temporary\\node_modules',
     'C:\\Users\\Administrator\\Desktop\\node_modules',
     'C:\\Users\\Administrator\\node_modules',
     'C:\\Users\\node_modules',
     'C:\\node_modules' ] }

node.js提供了path模塊用于處理文件與目錄路徑;

const path = require('path');

具體使用見官網(wǎng)。

Buffer

??JavaScript 語言自身只有字符串?dāng)?shù)據(jù)類型,沒有二進(jìn)制數(shù)據(jù)類型。Buffer 類,該類用來創(chuàng)建一個(gè)專門存放二進(jìn)制數(shù)據(jù)的緩存區(qū)。一個(gè) Buffer 類似于一個(gè)整數(shù)數(shù)組,但它對應(yīng)于 V8 堆內(nèi)存之外的一塊原始內(nèi)存。Buffer對象占用的內(nèi)存空間是不計(jì)算在Node.js進(jìn)程內(nèi)存空間限制上的,因此,我們也常常會使用Buffer來存儲需要占用大量內(nèi)存的數(shù)據(jù):

const buf = Buffer.from('hello world', 'ascii');
// 輸出 68656c6c6f20776f726c64

console.log(buf.toString('hex'));
// 輸出 aGVsbG8gd29ybGQ=
console.log(buf.toString('base64'));

我們可以用Buffer.alloc(size[,fill[,encoding])來初始化一個(gè)buffer類:

const buf = Buffer.alloc(5,'abcde');
console.log(buf);
//輸出 <Buffer 61 62 63 64 65>

當(dāng)輸入字符串長度大于Buffer指定長度,字符串會被按長度折斷;當(dāng)輸入字符串長度不足Buffer指定長度,輸出內(nèi)容會按字符重復(fù)拼接。

const buf = Buffer.alloc(5,'abcdef');
console.log(buf);
console.log(buf.toString())
//輸出<Buffer 61 62 63 64 65>
//輸出 abcde
const buf = Buffer.alloc(5,'ab');
console.log(buf);
console.log(buf.toString())
//輸出<Buffer 61 62 61 62 61>
//輸出 ababa

注意一個(gè)漢字占有3個(gè)Buffer長度。
Buffer.concat(list[, totalLength])返回一個(gè)合并了list中所有Buffer實(shí)例的新建的Buffer。

fs

??fs是node.js對文件以及文件夾進(jìn)行操作的方法。
??監(jiān)聽fs.watch

const fs = require('fs');

fs.watch('./circle.js',function (eventType , filename) {
  if(eventType ==='rename'){
   ///
  }else if(eventType ==='change'){
  ///
  }
})

相對穩(wěn)定一些的是watchFile()這個(gè)方法,文檔中介紹原理是輪詢(每隔一個(gè)固定的時(shí)間去檢查文件是否改動)。而且這個(gè)時(shí)間間隔是可以通過參數(shù)設(shè)置的。watch()這個(gè)方法是通過監(jiān)聽操作系統(tǒng)提供的各種“事件”(內(nèi)核發(fā)布的消息)實(shí)現(xiàn)的。這個(gè)不同的平臺實(shí)現(xiàn)的細(xì)節(jié)不一致,導(dǎo)致這個(gè)方法不能保證在所有平臺上可用(而且經(jīng)過實(shí)驗(yàn)發(fā)現(xiàn)在Mac上行為不正常,內(nèi)容的改動只能觸發(fā)一次回調(diào),再改動watch()就沒動靜了)。
??讀取fs.readFile(path[, options], callback)

const fs = require('fs');

fs.readFile('./circle.js',(err,data) =>{
  if(err) throw err;
  console.log(data.toString());
})

??寫入fs.writeFile(file, data[, options], callback)

const fs = require('fs');

fs.writeFile('./input.txt',"希望的田野上",function (err) {
  if(err) throw err ;
  console.log("寫入成功!");
})

??參數(shù)里面flag如果為w,則把原來內(nèi)容抹去重寫,如果為a,則是在內(nèi)容后面追加。fs還包括同步寫入讀取文件,創(chuàng)建刪除文件以及文件夾等操作。
??自動化構(gòu)建在前端非常普遍,我們可以用fs實(shí)現(xiàn)簡單的自動化構(gòu)建前端項(xiàng)目。代碼如下:

const fs = require('fs');
const indexContent = '<!doctype html>\r'+
  '<html lang="en">\r'+
  '<head>\r'+
  '\t<meta charset="UTF-8">\r'+
  '\t<meta name="viewport"'+
'content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">\r'+
  '\t<meta http-equiv="X-UA-Compatible" content="ie=edge">\r'+
  '\t<title>Document</title>\r'+
  '</head>\r'+
  '<body>\r'+
  '\t<h1>這是首頁</h1>\r'+
  '</body>\r'+
  '</html>\r';
const projectData = {
  name:"gallon",
  fileData:[
    {
      name:"css",
      type:"dir"
    },
    {
      name:"image",
      type:"dir"
    },
    {
      name:"js",
      type:"dir"
    },
    {
      name:"index.html",
      type:"file",
      content:indexContent
    },
  ]
};
if(projectData.name){
  fs.mkdirSync(projectData.name)//生成項(xiàng)目文件夾
  const fileData = projectData.fileData;
  if(fileData && fileData.forEach){
    fileData.forEach(function (f) {
      f.path = projectData.name + '/' + f.name;
      f.content = f.content || '';
        if(f.type == "dir"){
          fs.mkdirSync(f.path);
        }else if(f.type == 'file'){
          fs.writeFileSync(f.path, f.content);
        }
    })
  }
}

生成結(jié)構(gòu)如下:

項(xiàng)目文件夾

??我們也可以通過fs進(jìn)行代碼合并:
foo.js

const fs = require('fs');
const fileDir = './source';

fs.watch(fileDir,function (eventType,filename) {
  fs.readdir('./source',function (err,fileList) {
    if(err) throw err;
    let content = '';
    fileList.forEach(function (f) {
      content += fs.readFileSync(fileDir + '/' + f) + '\r';
    });
    fs.writeFile('./app.js',content ,function (err) {
      if(err) throw err ;
      console.log("合并完成");
    })
  })
});

??當(dāng)項(xiàng)目下文件發(fā)生變化的時(shí)候,即會生成app.js

項(xiàng)目結(jié)構(gòu)

test1.js

window.onload = function () {
    alert(13);
};

test2.js

window.onload = function () {
    alert(2);
};

test3.js

window.onload = function () {
    alert(10);
};

生成app.js

window.onload = function () {
    alert(13);
};
window.onload = function () {
    alert(2);
};
window.onload = function () {
    alert(10);
};
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • https://nodejs.org/api/documentation.html 工具模塊 Assert 測試 ...
    KeKeMars閱讀 6,620評論 0 6
  • Node.js是目前非?;馃岬募夹g(shù),但是它的誕生經(jīng)歷卻很奇特。 眾所周知,在Netscape設(shè)計(jì)出JavaScri...
    w_zhuan閱讀 3,737評論 2 41
  • 個(gè)人入門學(xué)習(xí)用筆記、不過多作為參考依據(jù)。如有錯(cuò)誤歡迎斧正 目錄 簡書好像不支持錨點(diǎn)、復(fù)制搜索(反正也是寫給我自己看...
    kirito_song閱讀 2,654評論 1 37
  • Node.js是目前非?;馃岬募夹g(shù),但是它的誕生經(jīng)歷卻很奇特。 眾所周知,在Netscape設(shè)計(jì)出JavaScri...
    Myselfyan閱讀 4,205評論 2 58
  • 小莉談過一個(gè)男朋友,在一起5年,同居了3年,到了談婚論嫁的年紀(jì),男生出軌,小莉選擇了分手。 說實(shí)話,小莉年紀(jì)不小了...
    深夜pao堂閱讀 825評論 0 0

友情鏈接更多精彩內(nèi)容