本次博文依然是對 multi-spa-webpack-cli
的擴充和完善。html
multi-spa-webpack-cli
已經發布到 npm,只要在 node 環境下安裝便可。前端
npm install multi-spa-webpack-cli -g
複製代碼
使用步驟以下:node
# 1. 初始化項目
multi-spa-webpack-cli init spa-project
# 2. 進入文件目錄
cd spa-project
# 未使用 Docker
# 3. 打包不變的部分
npm run build:dll
# 4. 啓動項目(手動打開瀏覽器:localhost:8090)
npm start
# 5. 啓動 MongoDB
mongod
# 6. 啓動服務
cd server
npm install
npm start
# 使用 Docker(需安裝docker)
# 3. 啓動項目(手動打開瀏覽器:0.0.0.0:8090)
npm run docker:dev
複製代碼
從上面的步驟能夠看出,Docker 只須要 3 步就能夠啓動項目了。mysql
mongoose 是在 node.js 環境下對 MongoDB 進行便捷操做的對象模型工具。webpack
在沒開始以前,要先安裝 MongoDB。安裝 MongoDB 的過程當中,可能有些小麻煩,尤爲是公司的電腦(誰也不知道電腦裏配置了什麼東西)。安裝過程可參照 【官網:安裝MongoDB】web
還要知道 MongoDB 的一些概念。sql
SQL術語/概念 | MongoDB術語/概念 | 解釋/說明 |
---|---|---|
database | database | 數據庫 |
table | collection | 數據庫表/集合 |
row | document | 數據記錄行/文檔 |
column | field | 數據字段/域 |
index | index | 索引 |
table | joins | 錶鏈接,MongoDB不支持 |
primary key | primary key | 主鍵,MongoDB自動將_id字段設置爲主鍵 |
數據庫服務和客戶端:mongodb
SQL | MongoDB |
---|---|
Mysqld/Oracle | mongod |
mysql/sqlplus | mongo |
mongoose 相關概念看看官網就行了【mongoose 中文文檔】docker
用法很簡單,定義 Schema,轉換成 Model,操做 Model,生成實例。數據庫
/* model.js */
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// 定義 Schema
const UserSchema = new Schema({
username: {
type: String,
unique: true,
require: true
},
password: {
type: String,
require: true
}
});
// 轉換成 Model
const UserModel = mongoose.model('User', UserSchema);
module.exports = UserModel;
/* user.js */
// 操做 Model
let user = await UserModel.findOne({ username });
if (!user) {
try {
// 生成實例
await new UserModel({
username,
password
}).save();
ctx.body = {
"success": true,
"message": "註冊成功"
}
} catch (error) {
ctx.body = {
"success": false,
"message": "註冊失敗"
}
}
} else {
ctx.body = {
"success": false,
"message": "用戶名已存在"
}
}
複製代碼
由上面的步驟,咱們能夠看出來,項目啓動步驟麻煩,並且在安裝 MongoDB 環境時,容易受干擾。
下面經過 Docker 來構建開發環境,提升開發體驗。
在使用 Docker 以前,先了解下幾個概念。
鏡像構建時,會一層層構建,前一層是後一層的基礎。每一層構建完就不會再發生改變,後一層上的任何改變只發生在本身這一層。好比,刪除前一層文件的操做,實際不是真的刪除前一層的文件,而是僅在當前層標記爲該文件已刪除。在最終容器運行的時候,雖然不會看到這個文件,可是實際上該文件會一直跟隨鏡像。所以,在構建鏡像的時候,須要額外當心,每一層儘可能只包含該層須要添加的東西,任何額外的東西應該在該層構建結束前清理掉。
因此,在生產部署時,確保每一層的純淨,剔除沒必要要文件。好比開發編譯時的文件等( node_module )。這樣也避免了鏡像沒必要要的臃腫。
容器內的進程是運行在一個隔離的環境裏,使用起來,就好像是在一個獨立於宿主的系統下操做同樣。這種特性使得容器封裝的應用比直接在宿主運行更加安全。
每個容器運行時,是以鏡像爲基礎層,在其上建立一個當前容器的存儲層,咱們能夠稱這個爲容器運行時讀寫而準備的存儲層爲容器存儲層。
容器存儲層的生存週期和容器同樣,容器消亡時,容器存儲層也隨之消亡。所以,任何保存於容器存儲層的信息都會隨容器刪除而丟失。
按照 Docker 最佳實踐的要求,容器不該該向其存儲層內寫入任何數據,容器存儲層要保持無狀態化。全部的文件寫入操做,都應該使用 數據卷(Volume)、或者綁定宿主目錄,在這些位置的讀寫會跳過容器存儲層,直接對宿主(或網絡存儲)發生讀寫,其性能和穩定性更高。
開發環境常常對文件修改,就能夠利用這裏的數據卷綁定宿主目錄。
Docker 在運行時分爲 Docker 引擎(也就是服務端守護進程)和客戶端工具。在構建鏡像時,會將上下文複製到 Docker 引擎。而後經過 Docker 客戶端發出指令,而指令的執行是在 Docker 引擎中。因此,上下文的範圍要合理,範圍過大,就會致使文件複製到 Docker 引擎的時間長;範圍太小,則會致使沒法操做範圍外的文件。
部署開發環境其實很簡單,只須要配置 Dockerfile 和 docker-compose 便可。相關文檔可見:【Dockerfile 指令詳解】和【Compose 模板文件】
docker-compose 使用的是 YAML 語言,【YAML 語言教程】
version: '3.6'
services:
client:
container_name: "client"
build:
context: ../
dockerfile: Dockerfile.client.dev
volumes:
- ../src:/app/client/src
ports:
- "8090:8090"
depends_on:
- server
server:
container_name: "server"
build:
context: ../server
dockerfile: Dockerfile.server.dev
volumes:
- ../server:/app/server
ports:
- "8080:8080"
depends_on:
- database
database:
container_name: mongo
image: mongo
volumes:
- ../data:/data/db
ports:
- "27017:27017"
複製代碼
開發環境須要的就是實時展示效果,前端頁面是這樣,後端服務亦是如此。 如上文提到,上下文已經提交到鏡像,前端項目如何纔可以在容器中實現熱替換?其實很簡單,就是 volumes 這個配置。同理,後端也是,不過還須要 modemon 工具協助。
在部署時,也要到了一些問題,就是在鏡像中,localhost 沒法使用,須要用 IP 代替。
// 前端項目
/* webpack.dev.js */
devServer: {
publicPath: '/',
contentBase: path.resolve(__dirname, '..', 'dist'),
port: APP_CONFIG.port,
host: '0.0.0.0', // 需指明
hot: true,
historyApiFallback: {
index: '/'
}
}
// 後端項目
/* config.js */
module.exports = {
'database': 'mongodb://database:27017/yexiaochen' // 與 docker-compose 中 database 服務名匹配
}
複製代碼