Git代码管理工具

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
简介: Git代码管理工具

Git代码管理工具


Git

分布式的版本控制系统

1.常用命令

$ git init # 初始化仓库
$ git status # 查看版本库状态
$ git add . # 添加到暂存区
$ git commit -m 'feat: message' # 提交到本地仓库
$ git log # 日志
$ git clone repo.git # 克隆远程中央仓库到本地
$ git push origin master # 将本地版本库推送到远程中央仓库中
$ git remote add origin repo.git # 将本地仓库与远程中央仓库关联
$ git pull origin master # 将远程分支中最新代码拉取到本地
# ..........

分支:

$ git branch <branch-name> # 创建分支
$ git checkout <branch-name> # 切换分支
$ git checkout -b <branch-name> # 创建并切换到新分支
# ...........

2.SSH Key

用于本地与远程中央仓库连接认证(不用每次输入用户名与密码)。

本地生成 ssk key 所需要使用到的 rsa 公私钥密钥对:

$ ssh-keygen

执行命令时,一路回车完成文件创建,默认在 系统用户目录下,会生成 .ssh 目录,在该目录下有两个文件:id_rsa 与 id_rsa.pub。打开 id_rsa.pub 公钥文件,复制所有内容。

在远程中央仓库用户账号中配置:

个人头像 --> 设置 --> 左侧 安全设置下 SSH公钥 --> 粘贴复制的 id_rsa.pub 文件内容 --> 确定 --> 确认密码 --> 添加成功

配置完成后,可测试是否配置成功:

$ ssh -T git@gitee.com

看到类似如下信息,则说明配置成功:

Hi 小明! You've successfully authenticated, but GITEE.COM does not provide shell access.

Nodejs

官网

中文文档 【读后端文档】

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时。

“Ryan Dahl 现在是 Google Brain 的一个软件工程师。他是 Node.js 之父,Node.js 是一个基于 Chrome V8 JavaScript 引擎的 JS 运行环境。”

Nodejs版本 => 偶数稳定 | 奇数开发版本

1.npm

node package manager - node 包资源管理器

cnpm npm install -g cnpm

yarn npm i -g yarn

安装包

$ npm install <package-name@version> --save-dev
# 或
$ yarn add <package-name@version> --dev
# 或
$ cnpm install <package-name>

--save 是将安装包资源信息保存到 package.json 中的 dependencies 字段中,而 --save-dev 是保存到 devDependencies 中。--save 可以简写为 -S,--save-dev 可简写为 -D

NPM是随同NodeJS一起安装的包管理工具,能解决NodeJS代码部署上的很多问题

$ npm -v # 检测安装是否成功
$ yarn -v # 检测安装是否成功
$ npm i <Module Name> # 安装软件包
$ npm uninstall <package-name> # 卸载npm软件包
软件包是全局安装的,则需要添加 -g 或 --global 标志:
$ npm uninstall -g <package-name>

2.package.json

项目描述文件 =>记录安装的依赖包

$ npm init -y # 初始化生成package.json文件

npm scripts

在 package.json 文件中,有一个 scripts 字段,可以在命令行中使用 npm run 来执行这个字段中的脚本:

{
  "scripts": {
    "start": "node ./bin/www",
    "dev": "node ./bin/www",
    "serve": "node ./bin/www"
  },
}

可执行

$ npm run start # 对于 start 任务,可省略 run 的书写:npm start
$ npm run dev
$ npm run serve

3.bs请求响应模式

Broswer浏览器

Server服务器

B/S 请求-响应模式

Client客户端

Node.js 创建第一个应用

端口号范围 0-65535,前1024端口为系统预留

http 80端口

https 443端口

浏览器chrome测试中,不要监听6666端口

js是单线程 JavaScript的单线程,与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如两个线程同时操作一个dom。

nodejs.js 文件内容如下:

//使用 require 指令来载入 http 模块
const http = require('http');
//使用 fs 模块,来读取文件
const fs = require('fs')
//nodemon 自动重启文件
//创建服务器
http.createServer(function (request, response) {
    //监听到客户端请求时,会自动调用该回调函数处理请求并返回响应
    const {
        url,
        method
    } = request
    console.log('url', url, 'method', method)
    //服务端路由的处理 繁琐
    let html = 'hello Nodejs'
    switch (url) {
        case '/index.html':
            html = fs.readFileSync('index.html')
            break;
        case '/login.html':
            html = 'html'
            break;
    }
    //发动http头部
    //http状态值:200:ok
    //内容类型:text/plain
    response.writeHead(200, {
        'Content-Type': 'text/plain'  //纯文本格式
    });
    //发送响应数据
    response.end(html)
    //监听端口,等待客户端链接
}).listen(8888);
//终端打印信息如下
console.log('Server running at http://127.0.0.1:8888/')

4.模块化

模块化规范:

前端模块化开发中:一个js文件就是一个模块,在js文件模块中定义的数据是私有的, 可以向外部暴露数据和方法,其它js文件模块可以引入暴露的方法数据进行使用

AMD - require.js

CMD - sea.js

commonJS - NodeJS (引入依赖模块require() ,moudle.exports定义导出模块 )

ES6 - import / export

5.nodemon

这是一个能够监视文件变化,在文件变化后自动重启node应用的工具

$ npm i nodemon -g

6.核心模块

nodejs官网

oop 面向对象编程

oo 面向对象

os-操作系统

globa-全局变量:

setTimeout/setInterval/require()/module/__dirname/__filename 

path-路径

http-http模块

fs-文件系统

querystring-查询字符串 - 作用 向后端传递参数数据,请求数据

events - 事件

Express

express中文网 -

基于 Node.js 平台,快速、开放、极简的 Web 开发框架

0.安装

$ npm i express  #安装
# 或
$ yarn add express

1.使用

1.利用express搭建服务器

req.body 使用中间件,用于解析处理post请求主体的数据 =>req.body

req.query 请求路由,get请求获取url中的请求参数

express.static(‘public’) 使用中间件,托管静态资源将 public 目录下的图片、CSS 文件、JavaScript 文件对外开放访问了

//引入express模块
const express = require('express')
//创建Express 应用实例
const app = express()
// 使用中间件,用于解析处理请求主体的数据 =>req.body
app.use(express.json()) // for parsing application/json
app.use(express.urlencoded({
    extended: true // 普通文本数据
})) // for parsing application/x-www-form-urlencoded
// 使用中间件,托管静态资源将 public 目录下的图片、CSS 文件、JavaScript 文件对外开放访问了
// 如果要使用多个静态资源目录,请多次调用 express.static 中间件函数:
//Express 在静态目录查找文件,因此,存放静态文件的目录名不会出现在 URL 中。
app.use(express.static('public')) //=>url直接访问对应页面
/* 处理路由 */
// 处理 GET 请求
// app.get('/', (req, res) => {
//     /*此应用程序启动一个服务器并在端口 3000 上侦听连接。该应用程序响应“Hello World!” 对根 URL ( /) 或路由的请求。对于其他所有路径,它将以404 Not Found响应。 */
//     // res.send('你好!Express!!!')
//     // console.log('__dirname:',__dirname)
//     // // res.sendFile('public/index.html') => 绝对路径
//     // //TypeError: path must be absolute or specify root to res.sendFile
//     // res.sendFile(__dirname + '/public/index.html')
//     // res.json({
//     //     code:200,
//     //     data:{
//     //         usesrInfo:{
//     //             name:'张三',
//     //             age:18
//     //         }
//     //     }
//     // })   
// })
//处理post请求
app.post('/api/login.do', (req, res) => {
    //获取请求主体的数据
    console.log('BODY', req.body); //BODY undefined => express官网 Api参考手册
    const {
        username,
        password
    } = req.body
    // TODO: 进行数据库验证
    // TODO:::::
    res.send('处理用户登录')
})
// 处理get请求
app.get('/api/login.do', (req, res) => {
    //获取请求主体的数据
    console.log('BODY', req.query); //BODY undefined => express官网 Api参考手册
    const {
        username,
        password
    } = req.query
    // TODO: 进行数据库验证
    // TODO:::::
    res.send('处理用户登录1')
})
app.listen(9527, () => {
    console.log('Example app Listening on port 9527')
})

2.Express 应用程序生成器

1.建立文件夹,打开bash,输入命令

$npx express-generator 
$npm i  
$npm run start #运行文件

npx是个非常强大的命令

引入核心模块 | 第三方包,直接写名字;引入自己的文件模块,写路径

中间件(本质函数)功能是按顺序执行的,因此中间件包含的顺序很重要。

app.use(function(err, req, res, next)

next=>这个中间件执行完毕,能否进到下一步。有next,进行下一步,没有next,中断

2.文件准备

建立文件 public/register.html

<h1>用户</h1>
   <form action="/api/users/register.do" method="post">
        <input type="text" name="username"><br>
        <input type="text" name="password"><br>
        <button>注册</button>
   </form>
<!--app.js文件-->
app.use('/api/users', usersRouter);//访问api/users下的资源

=>访问 http://localhost:3000/register.html => 确定 =>Not Found 404

users.js文件

//处理用户注册,完整url:/api/users/register.do
router.post('/register.do', function(req, res) {
  const {username,password} = req.body //post请求包主体
  console.log(req.body);
  res.json({
    username,
    password
  })
  res.send('处理用户注册');
});

=>访问 http://localhost:3000/register.html => 确定 => 处理用户注册

3.连接数据库=>复制首页案例

mogoose

$ npm i mongoose

users.js文件

//处理用户注册,完整url:/api/users/register.do
router.post('/register.do', function (req, res) {
  const {
    username,
    password
  } = req.body
  //保存到数据库中 <mogodb需要先服务运行,看任务管理器>
  const mongoose = require('mongoose'); //引入mongoose连接数据库
  mongoose.connect('mongodb://localhost/save'); //连接数据库 save
  //创建model
  const Cat = mongoose.model('Cat', {
    username: String,
    password: String,
  });
  //创建实例 -- 文档
  const kitty = new Cat({
    username,
    password,
  });
  //保存到数据库
  kitty.save().then((data) => {
    console.log(data, 'meow保存成功')
    //响应,返回给浏览器JSON格式额数据
    res.json({
     code:200,
     data:{
      username,
      password
     }
    })
  });

=>访问 http://localhost:3000/register.html => 确定 => mongodb数据库存入用户信息

不能重复创建 Cannot overwrite Cat model once compiled. 500

创建文件moudles/user.js =>引入公共部分,为了重复创建

4.user.js文件 && 修改后的users.js文件

user.js文件

const mongoose = require('mongoose');
//创建model
  module.exports = mongoose.model('Cat', {
    username: String,
    password: String,
  });

修改后的users.js文件

const Cat = require('../moudel/user') //引入公共的创建对象
//处理用户注册,完整url:/api/users/register.do
router.post('/register.do', function (req, res) {
  const {
    username,
    password
  } = req.body
  //保存到数据库中 <mogodb需要先服务运行,看任务管理器>
  const mongoose = require('mongoose'); //引入mongoose连接数据库
  mongoose.connect('mongodb://localhost/save'); //连接数据库 save
  //创建model 删除
  // const Cat = mongoose.model('Cat', {
  //   username: String,
  //   password: String,
  // });
  //创建实例 -- 文档
  const kitty = new Cat({
    username,
    password,
  });
  //保存到数据库
  kitty.save().then((data) => {
    console.log(data, 'meow保存成功')
    //响应,返回给浏览器JSON格式额数据
    res.json({
     code:200,
     data:{
      username,
      password
     }
    })
  });
});
module.exports = router; //导出路由对象

mongoDB-数据库

MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-875P1gEx-1669703515627)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1651717980974.png)]

0. 安装 (菜鸟教程)

1.配置环境变量

安装目录下-bin ( 复制路径地址 )

我的电脑-鼠标右键-属性-高级系统设置-环境变量-path-编辑-新建-确定 (目录放进去)

配置完毕后,重新打开新的cmd提示

$ mongod --version

2.启动mongoDb服务

注意,windows 10,如果在服务中,mongoDb服务状态是正在运行,则不需要此操作

命令行执行:

$ mongod --dbpath <path-name>

是数据文件的保存路径,该路径需要事先创建好

启动服务后,命令窗口中的任务并没结束,请不要关闭( 关闭窗口,则服务停止 )

启动成功状态如上:

$ mongo

3.数据库概念

database:数据库,容器,用于保存管理数据

collection:集合(类似于 MySQL 中 table)

document:文档(类似于 MySQL table 中的 row)

primary key: 主键,唯一标识,默认 _id 为主键字段

robo3t可视化软件 常用

4.常用命令

show dbs:显示所有数据库

db:查看当前所在数据库,默认为test

use db-name:切换数据库

db.createCollection(coll-name集合名):创建集合 = 表

CRUD - CreateReadUpdateDelete

db.coll-name.insert() : 向集合中插入文档

db.coll-name.find() :查找集合中的文档

db.coll-name.updata() :修改集合中的文档

db,coll-name.remove() :删除集合中的文档

5.mongoose

用于在 NodeJS 应用中连接 MongoDB 数据库

官网

安装

$ npm i mongoose
# 或
$ yarn add mongoose

数据库

mysql数据库 - 连接数据库 -> Sequelize 【关系型】

mongodb数据库 - 连接 - mongoose 【非关系型】

RESTful

Node.js RESTful API

RESTful 架构详解

REST即表述性状态传递,是一套软件架构风格。是一组约束条件与原则,满足这些约束条件和原则的应用程序或设计就是RESTful。 REST 通常使用 JSON 数据格式。

虽然REST本身受Web技术的影响很深, 但是理论上REST架构风格并不是绑定在HTTP上,只不过目前HTTP是唯一与REST相关的实例。 所以我们这里描述的REST也是通过HTTP实现的REST。

资源与URI

任何事物,只要有被引用到的必要,它就是一个资源。资源可以是实体(例如手机号码),也可以只是一个抽象概念(例如价值) 。

要让一个资源可以被识别,需要有个唯一标识,在Web中这个唯一标识就是URI (Uniform Resource Identifier)。

统一资源接口

接口应该使用标准的HTTP方法如GET,PUT和POST,并遵循这些方法的语义。

GET - 查询

POST - 添加

PUT - 修改

DELETE - 删除

使用案例

当后端未开发完成接口文档的时候,前端需要接口进行数据测试,就用到以下两种方式进行接口测试

Express 应用程序生成器

1.postman软件|插件使用

day03 - user-management1 routes - users.js - 使用postman请求

1.app.js =>
  app.use('/api/users', usersRouter);
2.routes/user.js =>
  /* GET */
    router.get('/', function(req, res, next) {
      res.send('get1111');
    });
    router.post('/', function(req, res, next) {
      res.send('post2222');
    });
3.postman插件 输入完整地址
  http://127.0.0.1:3000/api/users

2.REST client => vscode插件

day03 - user-management1 - users.http

http消息结构=>菜鸟教程

占用资源小

1.moudle/user.http =>
  ### get
    GET http://127.0.0.1:3000/api/users  HTTP/1.1
    ### post
    POST http://127.0.0.1:3000/api/users   HTTP/1.1
2.点击send

用户管理系统创建

1.快速搭建服务器 => Express应用程序生成器

$npx express-generator
$npm i  => node_modules文件夹

2.moogoose官网- 阅读文档 -schemas

新建文件model/user.js

$ npm install mongoose

const mongoose = require('mongoose');
//1.定义一个schemas 表结构的项
const Schema = mongoose.Schema;
var userSchema = new Schema({
  username: String,
  password: String,
  sex: String,
  address: String,
  headerImg: String,
});
//2.创建一个实例model
var userModel = mongoose.model('user', userSchema);
//3.导出模块
module.exports = userModel;

3.app.js => 连接mongodb数据库

//02.连接mongo数据库
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/test');
app.use('/api/users', usersRouter); 

test是默认数据库

4.routes/users.js => 数据库添加删除修改查找用户数据

post从请求主体中获取待添加用户的数据 req.body

modle方法检索

const User = require('../moudles/user') //引入模块实例
const CryptoJS = require('crypto-js') //引入加密包
/**
 * 获取用户信息 get 完整地址:http://127.0.0.1:3000/api/users
 * 如果传入参数id,则查找确认id的用户
 * 如果没有传入参数id,则根据页数,每页数据查找用户
 * :_id? => 是否有参数都可以 正则表达式
 */
router.get('/:_id?', function (req, res, next) {
  //获取用户id
  const {
    _id
  } = req.params
  //查找用户id
  if (_id) {
    // 有 _id,则查询单个用户数据
    User.findById(_id) 
      .then(data => {
        res.json({
          code: 200,
          data
        })
      })
  }else{
    // 没有 _id,则分页查询数据
    // 从查询字符串中获取分页页码与每页记录数
    const {page,pageSize} = req.query
    User.find()
    .limit(pageSize)
    .skip((page-1)*pageSize)
    .then(data=>{
      res.json({
        code:200,
        data
      })
    })
  }
  // res.send('get');
});
/**
 * 添加保存用户信息 post 完整地址:api/users
 */
router.post('/', function (req, res, next) {
  //post从请求主体中获取待添加用户的数据
  const {
    username,
    password,
    sex,
    address,
    phone
  } = req.body
  //1.判断用户名|密码是否填写
  if (!username || !password) {
    res.json({
      code: 400,
      data: null,
      message: '用户名与密码为必填项'
    })
    return;
  }
  // res.send('post');
  //2.判断数据库中用户名是否已经注册,是则提示错误;否,则保存用户信息到数据库中
  User
    .findOne({
      username
    })
    .then(data => {
      // console.log("查寻数据库结果:", data); //查结果: []
      if (!data) {
        //不存在用户,则可以保存到数据库中
        //3.密码加密 MD5 => npm i crypto-js 
        const hash = CryptoJS.MD5(password).toString()
        new User({
            username,
            password: hash,
            sex,
            address,
            phone
          })
          .save() //保存到数据库中
          .then(data => {
            res.json({
              code: 200,
              data: {
                id: data.__id,
                username
              }
            })
          })
      } else {
        //用户存在,提示用户错误
        res.json({
          code: 400,
          data: null,
          message: "用户已注册,请修改您的用户名"
        })
      }
    })
});
/**
 * 修改用户信息 get 
 * 完整URL: /api/users/123497124
 * :_id 定义的是动态路径参数
 */
router.put('/:_id', function (req, res, next) {
  // 从请求的路径参数中获取待修改用户的主键值
  const {
    _id
  } = req.params
  // 从请求主体中获取修改后的数据
  const {
    sex,
    phone,
    address
  } = req.body
  // 修改数据库中的数据
  User.updateOne({
      _id
    }, {
      sex,
      address,
      phone
    }) //条件,修改的信息
    .then(() => {
      res.json({
        code: 200,
        data: {
          status: 200,
          message: '修改成功'
        }
      })
    })
  // res.send('put');
});
/**
 * 删除用户信息 get 
 * 完整URL: /api/users/123497124
 * :_id 定义的是动态路径参数
 */
router.delete('/:_id', function (req, res, next) {
  // 从请求的路径参数中获取待修改用户的主键值
  const {
    _id
  } = req.params
  User.deleteOne({
      _id
    })
    .then(() => {
      res.json({
        code: 200,
        data: {
          status: 200,
          message: "删除成功"
        }
      })
    })
  // res.send('delete');
});
module.exports = router;
5.test / users.http
const {
_id
} = req.params
// 从请求主体中获取修改后的数据
const {
sex,
phone,
address
} = req.body
// 修改数据库中的数据
User.updateOne({
_id
}, {
sex,
address,
phone
}) //条件,修改的信息
.then(() => {
res.json({
code: 200,
data: {
status: 200,
message: ‘修改成功’
}
})
})
// res.send(‘put’);
});
/**
删除用户信息 get
完整URL: /api/users/123497124
:_id 定义的是动态路径参数
*/
router.delete(‘/:_id’, function (req, res, next) {
// 从请求的路径参数中获取待修改用户的主键值
const {
_id
} = req.params
User.deleteOne({
_id
})
.then(() => {
res.json({
code: 200,
data: {
status: 200,
message: “删除成功”
}
})
})
// res.send(‘delete’);
});
module.exports = router;
5.test / users.http


相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。 &nbsp; 相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
相关文章
|
7月前
|
数据可视化 开发工具 C#
.NET开源、免费、跨平台的Git可视化管理工具
俗话说得好“工欲善其事,必先利其器”,合理的选择和使用可视化的管理工具可以降低技术入门和使用的门槛。今天大姚给大家分享一款.NET Avalonia开源、免费、跨平台、快速的Git可视化管理工具:SourceGit。
|
4月前
|
开发工具 数据安全/隐私保护 git
记录一次使用git工具拉取coding上代码密码账号错误的经历
这篇文章记录了作者在使用Git工具从Coding平台克隆项目时遇到的账号密码错误问题,并分享了通过清除电脑凭证中错误记录的账号密码来解决这个问题的方法。
记录一次使用git工具拉取coding上代码密码账号错误的经历
|
1月前
|
存储 开发工具 git
git工具使用教程全讲解
本文介绍了版本控制的概念及其重要性,详细对比了多种版本控制工具,如VSS、CVS、SVN和Git,重点讲解了Git的基本使用方法、工作原理及与SVN的区别。此外,文章还介绍了GitHub、GitLab和Gitee等流行的代码托管平台,以及如何在这些平台上注册账号、创建和管理仓库。最后,文章还提供了如何在IntelliJ IDEA中配置和使用Git的具体步骤。
48 1
|
1月前
|
Ubuntu 开发工具 git
Git高手必备:掌握这些版本控制最佳实践,让你的代码管理效率翻倍!
【10月更文挑战第25天】使用 Git 进行版本控制是现代软件开发的重要部分。本文详细介绍了 Git 的安装、配置、基本操作、分支管理、冲突解决及常用命令,帮助开发者提高工作效率,确保代码质量和团队协作的顺利进行。通过合理使用 Git,可以有效管理代码变更,支持多人协作,并追踪历史记录。
70 4
|
2月前
|
开发工具 git
git显示开发日志+WinSW——将.exe文件注册为服务的一个工具+图床PicGo+kubeconfig 多个集群配置 如何切换
git显示开发日志+WinSW——将.exe文件注册为服务的一个工具+图床PicGo+kubeconfig 多个集群配置 如何切换
39 1
|
2月前
|
开发工具 git
【Git快速入门】Git代码管理手册与协同开发之分支管理与协作(五)
【Git快速入门】Git代码管理手册与协同开发之分支管理与协作(五)
|
2月前
|
网络协议 网络安全 开发工具
【Git快速入门】Git代码管理手册与协同开发之远程仓库(四)
【Git快速入门】Git代码管理手册与协同开发之远程仓库(四)
|
2月前
|
开发工具 git
【Git快速入门】Git代码管理手册与协同开发之基本操作(三)
【Git快速入门】Git代码管理手册与协同开发之基本操作(三)
|
2月前
|
Shell 开发工具 git
【Git快速入门】Git代码管理手册与协同开发之基本操作(二)
【Git快速入门】Git代码管理手册与协同开发之基本操作(二)
|
2月前
|
开发工具 git 索引
【Git快速入门】Git代码管理手册与协同开发之环境搭建(一)
【Git快速入门】Git代码管理手册与协同开发之环境搭建(一)