nodeJS前端腳手架——公用代碼塊怀挠,只寫(xiě)一邊就好


最近接手一個(gè)任務(wù)析蝴,給一個(gè)集團(tuán)寫(xiě)一個(gè)靜態(tài)站點(diǎn),看了設(shè)計(jì)稿發(fā)現(xiàn)除了首頁(yè)绿淋,其他頁(yè)面的頭部nav和底部footer都是一樣的闷畸。如果寫(xiě)好粘貼賦值粘貼復(fù)制,多累巴讨汀佑菩!————于是想到一個(gè)需求:




如何能讓頁(yè)面公用部分寫(xiě)一邊,然后所有頁(yè)面都能同步裁赠?



作為前端出身殿漠,技術(shù)棧又比較少~ 第一個(gè)想到的就是nodeJS了!畢竟JS是前端特有唯一一門(mén)編程語(yǔ)言了组贺!






首先凸舵,屢屢思路:



  1. 目的是:公用部分單獨(dú)寫(xiě)一份,然后頁(yè)面只需要寫(xiě)除了公用部分之外的即可失尖。
  2. 前提是:如果出現(xiàn)異常啊奄,不能影響自己寫(xiě)的代碼->所以要另外建立一個(gè)文件夾,用于存放node處理后的代碼




接下來(lái)掀潮,開(kāi)始node編寫(xiě):

<strong>section 1</strong>


一菇夸、 首先在新建文件夾下創(chuàng)建兩個(gè)文件夾:

app(寫(xiě)代碼的地方)
public(生成代碼的地方)
handile.js(nodeJS文件)

目錄結(jié)構(gòu)如下:




二、 做到將app里的文件復(fù)制到public中
  解析功能

//復(fù)制文件用到node的fs模塊仪吧,用到readFile,writeFile功能庄新,然而如果用這兩個(gè)語(yǔ)法,它的原理是將文件內(nèi)容讀取保存在內(nèi)存中薯鼠,然后再一次性寫(xiě)入一個(gè)文件
//想想择诈,這樣就會(huì)遇到一個(gè)問(wèn)題:如果文件比較大,一次性讀取和寫(xiě)入出皇,會(huì)不會(huì)很吃?xún)?nèi)存羞芍。
//就像是這里要從水龍頭取水,將旁邊一個(gè)無(wú)法移動(dòng)的大缸接滿(mǎn)郊艘,如果選擇一次性接一缸水荷科,再倒到水缸里唯咬,這顯然是不明智的
//考慮這一點(diǎn),這里要用Stream流信息處理方式畏浆,就是讀著寫(xiě)著胆胰,像有水管一樣,上面流著刻获,下面接著蜀涨,這樣可行性就更高了,代碼如下:
var fs = require('fs');
function copy(origin, aim) {
    fs.createReadStream(origin).pipe(fs.createWriteStream(aim));
}

//這里pipe方法就是這里舉例中的水管



  現(xiàn)在有了一個(gè)能連通數(shù)據(jù)流的水管了,這里要將水管入口接到水龍頭上将鸵,出口接到大缸里





  但現(xiàn)在這里還遇到一個(gè)問(wèn)題勉盅,app文件夾下是可能會(huì)有img css js等文件夾的,而這里的方法createReadStream只能讀取指定的一個(gè)文件顶掉,



<strong>所以這里要有一個(gè)遍歷app和hbuild目錄的方法草娜,把a(bǔ)pp目錄里所有文件的路徑遍歷出來(lái),給copy方法的origin參數(shù)痒筒,再將app目錄里文件的路徑名字中app替換為hbuild宰闰,傳給copy方法的aim參數(shù),這樣如果app文件夾下有多個(gè)文件簿透,就相當(dāng)于這里創(chuàng)造了多條水管移袍,每個(gè)水管只負(fù)責(zé)一個(gè)文件信息流的傳輸</strong>



這里要用到readdir方法,這里選擇同步讀取老充,保證開(kāi)水龍頭葡盗,水管傳輸,水進(jìn)入水缸的正確順序啡浊,這樣就不用promise來(lái)單獨(dú)處理異步了觅够。所以這里用readdirSync方法

var path = require('path');
function travel(dir, callback) {
    fs.readdirSync(dir).forEach(function(file) {
        var pathname = path.join(dir, file); //將遍歷到文件的路徑給變量pathname
        
        if(fs.statSync(pathname).isDirectory()) {//判斷是當(dāng)前遍歷到的文件是否是一個(gè)文件夾,如果是則進(jìn)入文件夾再進(jìn)行遍歷:
            travelSync(pathname, callback);
        } else {
            callback(pathname);
        }
    })
}




這樣一個(gè)tranvel函數(shù)巷嚣,需要兩個(gè)參數(shù)喘先,遍歷的目錄路徑,和回調(diào)函數(shù)
這樣這里就可以組合兩個(gè)函數(shù)進(jìn)行遍歷和寫(xiě)入  

var fs = require('fs');
var path = require('path');

travelSync('./app', function(pathname) {
    if(pathname) {
        var publicPath = pathname.replace('app', 'public')
            copy(pathname, publicPath);
    }
})

function travelSync(dir, callback) {
    fs.readdirSync(dir).forEach(function(file) {
        var pathname = path.join(dir, file);
        console.log(pathname)
        if(fs.statSync(pathname).isDirectory()) {
            travelSync(pathname, callback);
        } else {
            callback(pathname);
        }
    console.log('文件復(fù)制成功廷粒!')
    });
}

function copy(src, dst) {
    fs.createReadStream(src).pipe(fs.createWriteStream(dst));
}


這里在app文件夾里新建幾個(gè)目錄和文件來(lái)做測(cè)試


header index footer 三個(gè)html文件里分別寫(xiě):

<!-- header.html -->
<header>
this is header!
</header>
<!-- index.html -->
<div class="content">
this is index.html
</div>
<!-- footer.html -->
<footer>
this is footer!
</footer>



然后在終端 cmd窘拯, 進(jìn)入當(dāng)前文件夾路徑,執(zhí)行 node handle.js  




然后再打開(kāi)public文件夾坝茎,看下涤姊,發(fā)現(xiàn):


哎!what嗤放? 為什么css img js文件夾和里面的文件沒(méi)有復(fù)制過(guò)來(lái)砂轻?


這是因?yàn)檫@里在遍歷目錄的時(shí)候,copy方法只實(shí)現(xiàn)了文件流信息的傳輸斤吐,但沒(méi)有實(shí)現(xiàn)文件夾創(chuàng)建功能搔涝,所以這樣運(yùn)行會(huì)出現(xiàn)報(bào)錯(cuò):



那么接下來(lái)就要寫(xiě)cipyDir方法:

function copyDir(path) {
    fs.mkdir(path, function(err) { //mkdir方法創(chuàng)建文件夾只需要通過(guò)第一個(gè)參數(shù)告訴node路徑和文件夾名即可創(chuàng)建,簡(jiǎn)單暴力
        if(!err) console.log(path+' 目錄創(chuàng)建成功!')
    });
}

這里這里要修改一下travel方法和措,當(dāng)travel遍歷到文件夾的時(shí)候庄呈,在build文件夾下執(zhí)行創(chuàng)建文件夾命令:

function travelSync(dir, callback) {
    fs.readdirSync(dir).forEach(function(file) {
        var pathname = path.join(dir, file);

        if(fs.statSync(pathname).isDirectory()) {
            callback(pathname,'dir'); //新增:遇到文件夾也執(zhí)行回調(diào),并傳入一個(gè)字符串用于告知回調(diào)函數(shù)知道這是一個(gè)文件夾的pathname
            travelSync(pathname, callback);
        } else {
            callback(pathname,'file');//這里也添加告知回調(diào)函數(shù)文件類(lèi)型的第二個(gè)參數(shù)'file'
        }
    });
}

接下來(lái)擼一遍現(xiàn)在的handle.js派阱,是這樣的:


var fs = require('fs');
var path = require('path');


travelSync('./app', function(pathname, fileType) {
    if(pathname && fileType === 'file') {
        // app/header.html
        var publicPath = pathname.replace('app', 'public');
        copy(pathname, publicPath);
    } else if (pathname && fileType === 'dir') {
        // app/css
        var publicPath = pathname.replace('app', 'public');
        copyDir(publicPath)
    }
})

function travelSync(dir, callback) {
    fs.readdirSync(dir).forEach(function(file) {
        var pathname = path.join(dir, file);

        if(fs.statSync(pathname).isDirectory()) {
            callback(pathname,'dir');
            travelSync(pathname, callback);
        } else {
            callback(pathname,'file');
        }
    });
}

function copy(path, aimPath) {
    fs.createReadStream(path).pipe(fs.createWriteStream(aimPath));
}

function copyDir(path) {
    fs.mkdir(path, function(err) {
        if(!err) console.log(path+' 目錄創(chuàng)建成功!')
    });
}

ok,現(xiàn)在再測(cè)試下復(fù)制功能是否能解決剛才無(wú)法復(fù)制文件夾的問(wèn)題:命令行運(yùn)行:node handle.js诬留,打印出:

再看public文件夾目錄:

漂亮!現(xiàn)在復(fù)制功能已經(jīng)達(dá)到贫母。敲代碼的文兑,就是需要做好鋪墊,才能快速行動(dòng)~ 接下來(lái)進(jìn)入關(guān)鍵時(shí)刻腺劣,處理文件的公用部分


<strong>section 2</strong>


這里模擬測(cè)試將app里的header footer 整合到index.html的 頭 和 尾绿贞。 現(xiàn)在要用到readFile 和 writeFile語(yǔ)法,讀取header footer里指定的內(nèi)容橘原,再寫(xiě)入index指定位置籍铁。


這里先想一個(gè)問(wèn)題:如果文件比較大,內(nèi)容比較復(fù)雜趾断,如何才能準(zhǔn)確的找到header footer里面指定的代碼段拒名, 然后準(zhǔn)確的寫(xiě)入index指定的位置?先別看下面解決方案芋酌,兩分鐘增显,看自己能想出哪些方法











我暫想到相對(duì)好用的方法是:

  1. 在header footer文件需要截取的代碼段頭尾添加一個(gè)標(biāo)記行注釋標(biāo)簽,同樣脐帝,在index里面也放一個(gè)注釋標(biāo)簽同云,告訴handle.js準(zhǔn)確位置

也有一個(gè)不好用的:就是直接判斷代碼段開(kāi)始標(biāo)簽,和結(jié)束標(biāo)簽腮恩,這樣每次都要嚴(yán)格查詢(xún)代碼并做更改梢杭,其實(shí)挺麻煩的。



這里修改header index footer秸滴,添加標(biāo)記注釋?zhuān)謩e更改為:

<!-- header begin -->
<header>
    this is header!
</header>
<!-- header end -->
<!-- index begin -->
<div class="content">
    this is index.html
</div>
<!-- index end -->
<!-- footer begin -->
<footer>
    this is footer!
</footer>
<!-- footer end -->

接下來(lái)在heandle.js里寫(xiě)header footer代碼段截取功能武契,

function getHeader() {
    fs.readFile('./app/header.html', function(err, html){
        var headerData = html.toString();
        // sliceStart只需要找到字符串的索引位置即可
        var sliceStart = headerData.indexOf('<!-- header begin -->');
        // sliceEnd找到字符串的位置后,加上字符串本身的長(zhǎng)度再加2是一個(gè)換行符的
        var sliceEnd = headerData.indexOf('<!-- header end -->') + '<!-- header end -->'.length+2;
        var header = headerData.slice(sliceStart, sliceEnd);
        console.log(header)
    });
}
getHeader();

命令行運(yùn)行node handle.js后 看到:

這樣就準(zhǔn)確找到想要的代碼段了荡含。
由于還需要用同樣的方法找到index和footer代碼段咒唆,所以這里將getHeader方法封裝成一個(gè)getAimCode方法:

function getAimCode(headerPath, flagBegin, flagEnd) {
  fs.readFile(headerPath, function(err, html){
    if(!err) {
      var headerData = html.toString();
      // sliceStart只需要找到字符串的索引位置即可
      var sliceStart = headerData.indexOf(flagBegin);
      // sliceEnd找到字符串的位置后,加上字符串本身的長(zhǎng)度再加2是一個(gè)換行符的
      var sliceEnd = headerData.indexOf(flagEnd) + flagEnd.length+2;
      var header = headerData.slice(sliceStart, sliceEnd);
      console.log(header)
    }
  });
}
//測(cè)試以下用getAimCode獲取footer代碼段
getAimCode('./app/footer.html', '<!-- footer begin -->', '<!-- footer end -->');

封裝函數(shù)最笨的辦法:把可能會(huì)變動(dòng)的內(nèi)容释液,替換成參數(shù)變量全释,再通過(guò)函數(shù)調(diào)用,以參數(shù)的形式傳進(jìn)去误债,可以運(yùn)行下上面代碼浸船,即可得到footer代碼段妄迁,測(cè)試上面代碼即可得到:

現(xiàn)在能找到需要截取的代碼段,接下來(lái)要進(jìn)行代碼段的準(zhǔn)確插入:

其實(shí)插入代碼段的基礎(chǔ)原理李命,就是將目標(biāo)文件信息讀取出來(lái)登淘,分為三段:

  1. 插入位置之前的代碼段 top
  2. 插入header和footer之間的代碼段 content
  3. 插入footer之后的代碼段 bottom

然后只需要將代碼段拼接成 top + header + content + footer + bottom 這么一個(gè)完整的代碼塊,再寫(xiě)入目標(biāo)文件就完成了封字。

接下來(lái)對(duì)目標(biāo)文件index進(jìn)行分割:

為了明顯看出index的分割效果黔州,這里將index.html更改內(nèi)容為:

<html>
   <head>
       <title>index</title>
   </head>

<!-- index begin -->
<div class="content">
   this is index.html
</div>
<!-- index end -->

</html>

回想下,從header.html中切出header代碼段的時(shí)候阔籽,是找到

<!-- header begin -->
和
<!-- header end -->

兩個(gè)標(biāo)記的索引位置流妻,用String.slice(start,end)方法來(lái)切割的。那么index的三段一樣要找到top content bottom三者的開(kāi)始位置和結(jié)束位置笆制。這里先默認(rèn)index文件的內(nèi)容被讀取為:indexData绅这,那么:

1. top:是從文檔的開(kāi)始,開(kāi)始位置就是索引值0项贺,
2. 結(jié)束索引值就是index begin標(biāo)記的開(kāi)始君躺,即indexData.indexOf('<!-- index begin -->');

3. content:開(kāi)始索引值是indexData.indexOf('<!-- index begin -->');
4. 結(jié)束索引值是:indexData.indexOf('<!-- index end -->')+'<!-- index end -->'.length+2;

5. bottom:開(kāi)始索引值是indexData.indexOf('<!-- index end -->')+'<!-- index end -->'.length+2,
6. bottom可以直接切到文檔結(jié)尾,slice方法如果不傳入第二個(gè)參數(shù)的話(huà)就默認(rèn)直接從指定索引位置切割到結(jié)尾

這樣就可以寫(xiě)出函數(shù):

function cutIndex() {
  fs.readFile('./app/index.html', function(err, html) {
    if(!err) {
      var indexData = html.toString();
      var topStart = 0,
        topEnd = indexData.indexOf('<!-- index begin -->');
      var contentStart = indexData.indexOf('<!-- index begin -->'),
        contentEnd = indexData.indexOf('<!-- index end -->')+'<!-- index end -->'.length+2;
      var bottomStart = indexData.indexOf('<!-- index end -->')+'<!-- index end -->'.length+2;

      var top = indexData.slice(topStart, topEnd),
        content = indexData.slice(contentStart, contentEnd),
        bottom = indexData.slice(bottomStart);
      console.log(top+'top打印結(jié)束');
      console.log(content+'content打印結(jié)束');
      console.log(bottom+'\n bottom打印結(jié)束');
    }
  })
}
cutIndex();

命令行里執(zhí)行:node handle.js
打印出:

現(xiàn)在得到了header footer top content bottom开缎,接下來(lái)要做拼接并的功能棕叫。

將我們的代碼組裝起來(lái)成為:

fs.readFile('./app/header.html', function(err, html){
    if(!err) {
        var headerData = html.toString();
        // sliceStart只需要找到字符串的索引位置即可
        var sliceStart = headerData.indexOf('<!-- header begin -->');
        // sliceEnd找到字符串的位置后,加上字符串本身的長(zhǎng)度再加2是一個(gè)換行符的
        var sliceEnd = headerData.indexOf('<!-- header end -->') + '<!-- header end -->'.length+2;
        var header = headerData.slice(sliceStart, sliceEnd);
    }

    fs.readFile('./app/footer.html', function(err, html){
        if(!err) {
            var footerData = html.toString();
            // sliceStart只需要找到字符串的索引位置即可
            var sliceStart = footerData.indexOf('<!-- footer begin -->');
            // sliceEnd找到字符串的位置后奕删,加上字符串本身的長(zhǎng)度再加2是一個(gè)換行符的
            var sliceEnd = footerData.indexOf('<!-- footer end -->') + '<!-- footer end -->'.length+2;
            var footer = footerData.slice(sliceStart, sliceEnd);
        }
        
        fs.readFile('./app/index.html', function(err, html) {
            if(!err) {
                var indexData = html.toString();
                var topStart = 0,
                    topEnd = indexData.indexOf('<!-- index begin -->');
                var contentStart = indexData.indexOf('<!-- index begin -->'),
                    contentEnd = indexData.indexOf('<!-- index end -->')+'<!-- index end -->'.length+2;
                var bottomStart = indexData.indexOf('<!-- index end -->')+'<!-- index end -->'.length+2;

                var top = indexData.slice(topStart, topEnd),
                    content = indexData.slice(contentStart, contentEnd),
                    bottom = indexData.slice(bottomStart);
            }
            console.log(top+header+content+footer+bottom);
        })
    })
})

執(zhí)行代碼就可以得到:

最終俺泣,結(jié)合section1,handle.js要完成:

  1. 先將app文件夾的目錄結(jié)構(gòu)復(fù)制到public文佳夾下
  2. 對(duì)文件切割完畢完残,重組合伏钠,再寫(xiě)入public文件夾下的index.html中

基礎(chǔ)版最終代碼如下:

travelSync('./app', function(pathname, fileType) {
    if(pathname && fileType === 'file') {
        // app/header.html
        var publicPath = pathname.replace('app', 'public');
        copy(pathname, publicPath);
    } else if (pathname && fileType === 'dir') {
        // app/css
        var publicPath = pathname.replace('app', 'public');
        copyDir(publicPath)
    }

    fs.readFile('./app/header.html', function(err, html){
        if(!err) {
            var headerData = html.toString();
            // sliceStart只需要找到字符串的索引位置即可
            var sliceStart = headerData.indexOf('<!-- header begin -->');
            // sliceEnd找到字符串的位置后,加上字符串本身的長(zhǎng)度再加2是一個(gè)換行符的
            var sliceEnd = headerData.indexOf('<!-- header end -->') + '<!-- header end -->'.length+2;
            var header = headerData.slice(sliceStart, sliceEnd);
        }

        fs.readFile('./app/footer.html', function(err, html){
            if(!err) {
                var footerData = html.toString();
                // sliceStart只需要找到字符串的索引位置即可
                var sliceStart = footerData.indexOf('<!-- footer begin -->');
                // sliceEnd找到字符串的位置后谨设,加上字符串本身的長(zhǎng)度再加2是一個(gè)換行符的
                var sliceEnd = footerData.indexOf('<!-- footer end -->') + '<!-- footer end -->'.length+2;
                var footer = footerData.slice(sliceStart, sliceEnd);
            }
            
            fs.readFile('./app/index.html', function(err, html) {
                if(!err) {
                    var indexData = html.toString();
                    var topStart = 0,
                        topEnd = indexData.indexOf('<!-- index begin -->');
                    var contentStart = indexData.indexOf('<!-- index begin -->'),
                        contentEnd = indexData.indexOf('<!-- index end -->')+'<!-- index end -->'.length+2;
                    var bottomStart = indexData.indexOf('<!-- index end -->')+'<!-- index end -->'.length+2;

                    var top = indexData.slice(topStart, topEnd),
                        content = indexData.slice(contentStart, contentEnd),
                        bottom = indexData.slice(bottomStart);
                }
                var indexChunk = top+header+content+footer+bottom;
                fs.writeFile('./public/index.html', indexChunk, function(err) {
                    if(!err) console.log('文件處理成功熟掂!')
                })
            })
        })
    })
})

再次在命令行里執(zhí)行:node handle.js
終端輸出:

再打開(kāi)public/index.html,就變成了:

這里node命令是異步處理扎拣,所以出現(xiàn)代碼嵌套非常多赴肚,稍微改動(dòng)就成了傳說(shuō)中的回調(diào)地獄~

后續(xù)更新promise優(yōu)化版。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末二蓝,一起剝皮案震驚了整個(gè)濱河市誉券,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌刊愚,老刑警劉巖踊跟,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異鸥诽,居然都是意外死亡商玫,警方通過(guò)查閱死者的電腦和手機(jī)箕憾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)拳昌,“玉大人厕九,你說(shuō)我怎么就攤上這事〉鼗兀” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵俊鱼,是天一觀的道長(zhǎng)刻像。 經(jīng)常有香客問(wèn)我,道長(zhǎng)并闲,這世上最難降的妖魔是什么细睡? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮帝火,結(jié)果婚禮上溜徙,老公的妹妹穿的比我還像新娘。我一直安慰自己犀填,他們只是感情好蠢壹,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著九巡,像睡著了一般图贸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上冕广,一...
    開(kāi)封第一講書(shū)人閱讀 49,144評(píng)論 1 285
  • 那天疏日,我揣著相機(jī)與錄音,去河邊找鬼撒汉。 笑死沟优,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的睬辐。 我是一名探鬼主播挠阁,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼溉委!你這毒婦竟也來(lái)了鹃唯?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤瓣喊,失蹤者是張志新(化名)和其女友劉穎坡慌,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體藻三,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡洪橘,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年跪者,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片熄求。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡渣玲,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出弟晚,到底是詐尸還是另有隱情忘衍,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布卿城,位于F島的核電站枚钓,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏搀捷。R本人自食惡果不足惜多望,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望怀偷。 院中可真熱鬧家厌,春花似錦、人聲如沸像街。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至木西,卻和暖如春畴栖,著一層夾襖步出監(jiān)牢的瞬間八千,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工照皆, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留沸停,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓瘟滨,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親倒淫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子败玉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理运翼,服務(wù)發(fā)現(xiàn),斷路器南蹂,智...
    卡卡羅2017閱讀 134,601評(píng)論 18 139
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,520評(píng)論 25 707
  • 原文鏈接:http://www.reibang.com/p/2a9367afe9e7 1510997059(1)....
    懸筆e絕閱讀 5,439評(píng)論 0 0
  • 今天是正月初六,昨晚下定決心準(zhǔn)備去唐三彩上班峰伙,約好了初八面試,兩班倒制瞳氓,剛好有時(shí)間可以去練車(chē)匣摘,順便學(xué)習(xí)化妝,這個(gè)經(jīng)...
    趙小仙Rose閱讀 372評(píng)論 0 0
  • 我是耳朵郭。愛(ài)好寫(xiě)東西的文盲嘴办。 中午坐在工作的地方,我托著腮幫子贯被,盯著放在桌子上黑屏的手機(jī)發(fā)呆。一整夜不睡帶來(lái)了強(qiáng)...
    耳朵郭閱讀 482評(píng)論 0 1