本次博文依然是对 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 服务名匹配
}
复制代码