利用docker搭建node開發(fā)環(huán)境

開發(fā)環(huán)境

操作系統(tǒng):macOS High Sierra 10.13.6
Docker:Community Edition Version 18.03.1-ce-mac65

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

采用node:10-alpine鏡像

docker pull node:10-alpine

創(chuàng)建docker容器卷node_modules10,作為node10相關(guān)應(yīng)用的包引用

docker volume create node_modules10

創(chuàng)建項(xiàng)目及運(yùn)行koa2

# 創(chuàng)建項(xiàng)目目錄
mkdir /path/to/koa2-beginning

# 初始化package.json并創(chuàng)建index文件
|____src
|   |____index.js
|   |____package.json

# package.json指定啟動腳本
{
    ...
    "scripts": {
        "start": "node index.js"
    },
    ...
}


# 運(yùn)行容器,指定宿主機(jī)的3001端口映射到容器的3000端口,這樣每個(gè)應(yīng)用在容器內(nèi)部都是3000,外部可根據(jù)不同項(xiàng)目指定不同端口
docker run -itd -p 3001:3000 -v ~/workspace/research/koa2_beginning/src:/koa2 -v node_modules10:/koa2/node_modules --name koa2-beginning node:10-alpine

# 安裝koa2
```text
docker exec -it -w /koa2 koa2-beginning npm install koa --save

# 修改index.js
const Koa = require('koa');
const app = new Koa();

// response
app.use(ctx => {
    ctx.body = 'Hello Koa';
});

app.listen(3000);

# 運(yùn)行
docker exec -it -w /koa2 koa2-beginning npm start

# 訪問
curl -L 127.0.0.1:3001

自動刷新

使用nodemon幫助我們進(jìn)行自動刷新

docker exec -it -w /koa2 koa2-beginning npm install nodemon --save-dev

修改npm啟動命令,在scripts下增加dev

"dev":"./node_modules/.bin/nodemon -L index.js"

這里需要使用-L參數(shù),否則在docker容器中不會自動重啟,參考nodemon官方自述:

In some networked environments (such as a container running nodemon reading across a mounted drive), you will need to use the legacyWatch: true which enables Chokidar's polling.

Via the CLI, use either --legacy-watch or -L for short:

重新運(yùn)行容器

docker exec -it -w /koa2 koa2-beginning npm run dev

>>>
> koa2-beginning@0.0.1 dev /koa2
> nodemon -L index.js

[nodemon] 1.18.3
[nodemon] to restart at any time, enter `rs`
[nodemon] watching: *.*
[nodemon] starting `node index.js`

現(xiàn)在嘗試修改代碼,發(fā)現(xiàn)已經(jīng)可以自動重啟了

[nodemon] restarting due to changes...
[nodemon] starting `node index.js`

單元測試

單元測試框架使用 mocha + supertest

docker exec -it -w /koa2 koa2-beginning npm install supertest mocha --save-dev

添加test文件夾,添加body_parsing.js

|____src
|   |____test
|   |    |____body_parsing.js

添加測試代碼

const app = require('../index');
const server = app.listen();
const request = require('supertest').agent(server);

describe('Body Parsing', function () {
    after(function () {
        server.close();
    });

    describe('POST /uppercase', function () {
        describe('with JSON', function () {
            it('should work', function (done) {
                request
                    .post('/uppercase')
                    .send({ name: 'tobi' })
                    .expect(200)
                    .expect({ name: 'TOBI' }, done);
            });
        });

        describe('with urlencoded', function () {
            it('should work', function (done) {
                request
                    .post('/uppercase')
                    .send('name=tj')
                    .expect(200)
                    .expect({ name: 'TJ' }, done);
            });
        });

        describe('when length > limit', function () {
            it('should 413', function (done) {
                request
                    .post('/json')
                    .send({ name: Array(5000).join('a') })
                    .expect(413, done);
            });
        });

        describe('when no name is sent', function () {
            it('should 400', function (done) {
                request
                    .post('/uppsercase')
                    .send('age=10')
                    .expect(400, done);
            });
        });
    });
});

修改index.js,以適應(yīng)單元測試

const Koa = require('koa');
const koaBody = require('koa-body')

// export Koa app
const app = module.exports = new Koa();

app.use(koaBody({
    jsonLimit: '1kb'
}))

app.use(async (ctx) => {
    const body = ctx.request.body;
    if (!body.name) ctx.throw(400, '.name required');
    ctx.body = { name: body.name.toUpperCase() };
})

// if test/*.js has require('index.js'),module.parent will not be null
if (!module.parent) app.listen(3000);

修改package.json,添加test

{
  ...
  "scripts": {
    "test": "mocha",
    ...
  },
  ...
}

執(zhí)行測試

docker exec -it -w /koa2 koa2-beginning npm test

>>>
> koa2-beginning@0.0.1 test /koa2
> mocha



  Body Parsing
    POST /uppercase
      with JSON
        ? should work (46ms)
      with urlencoded
        ? should work
      when length > limit
        ? should 413
      when no name is sent
        ? should 400


  4 passing (76ms)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末簸搞,一起剝皮案震驚了整個(gè)濱河市吧秕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌罩旋,老刑警劉巖,帶你破解...
    沈念sama閱讀 223,126評論 6 520
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件叁巨,死亡現(xiàn)場離奇詭異敞斋,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)廊遍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,421評論 3 400
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來贩挣,“玉大人喉前,你說我怎么就攤上這事⊥醪疲” “怎么了卵迂?”我有些...
    開封第一講書人閱讀 169,941評論 0 366
  • 文/不壞的土叔 我叫張陵,是天一觀的道長绒净。 經(jīng)常有香客問我见咒,道長,這世上最難降的妖魔是什么疯溺? 我笑而不...
    開封第一講書人閱讀 60,294評論 1 300
  • 正文 為了忘掉前任论颅,我火速辦了婚禮,結(jié)果婚禮上囱嫩,老公的妹妹穿的比我還像新娘。我一直安慰自己漏设,他們只是感情好墨闲,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,295評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著郑口,像睡著了一般鸳碧。 火紅的嫁衣襯著肌膚如雪盾鳞。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,874評論 1 314
  • 那天瞻离,我揣著相機(jī)與錄音腾仅,去河邊找鬼。 笑死套利,一個(gè)胖子當(dāng)著我的面吹牛推励,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播肉迫,決...
    沈念sama閱讀 41,285評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼验辞,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了喊衫?” 一聲冷哼從身側(cè)響起跌造,我...
    開封第一講書人閱讀 40,249評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎族购,沒想到半個(gè)月后壳贪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,760評論 1 321
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡寝杖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,840評論 3 343
  • 正文 我和宋清朗相戀三年撑碴,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片朝墩。...
    茶點(diǎn)故事閱讀 40,973評論 1 354
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡醉拓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出收苏,到底是詐尸還是另有隱情亿卤,我是刑警寧澤,帶...
    沈念sama閱讀 36,631評論 5 351
  • 正文 年R本政府宣布鹿霸,位于F島的核電站排吴,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏懦鼠。R本人自食惡果不足惜钻哩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,315評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望肛冶。 院中可真熱鬧街氢,春花似錦、人聲如沸睦袖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,797評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至伦乔,卻和暖如春厉亏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背烈和。 一陣腳步聲響...
    開封第一講書人閱讀 33,926評論 1 275
  • 我被黑心中介騙來泰國打工爱只, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,431評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像椎眯,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子忘渔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,982評論 2 361

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)缰儿,斷路器畦粮,智...
    卡卡羅2017閱讀 134,722評論 18 139
  • Docker — 云時(shí)代的程序分發(fā)方式 要說最近一年云計(jì)算業(yè)界有什么大事件?Google Compute Engi...
    ahohoho閱讀 15,548評論 15 147
  • 以下原文轉(zhuǎn)載于(https://docs.docker.com/docker-for-mac/)(想找中文版的最新...
    Veekend閱讀 7,582評論 0 17
  • Node.js第一天 1. 初識Node.js 1.1 Node.js是什么 Node.js? is a Java...
    再見天才閱讀 4,747評論 1 24
  • 不絕雨乖阵,亂佳期宣赔。人間幾度云低。秋重才凝芳露瞪浸,陰風(fēng)摧欲急儒将。 何堪月圓難復(fù),清涼道盡別離对蒲。殘霧斷晴無數(shù)钩蚊,濕錦繡,夢依稀蹈矮。
    文泳閱讀 225評論 13 18