前端项目
开发环境
- nodejs 推荐使用
10.16.0(最新的lts版本)
- yarn
npm install -g yarn
- lerna
npm install -g lerna
- hzero-front-cli
npm install -g hzero-front-cli --registry=http://nexus.saas.hand-china.com/content/groups/hzero-npm-group/
ide
创建新项目
1 创建新项目
-
使用前端在线创建创建项目
-
使用
hzero-front-cli
工具
# srm-front 为新项目名称,--puppeteer-skip 为省略非必需的 puppeteer 依赖的下载
hzero-front-cli srm-front --puppeteer-skip
2 创建主模块
# 主模块 spfm-front, 项目 srm-front
cd srm-front
hzero-front-cli . --create-packages 'spfm-front'
3 创建其他模块
# 其他模块 spfm-front-sslm
hzero-front-cli . --create-packages 'spfm-front-sslm'
升级平台依赖
-
升级 runtime
- 备份自己的修改的
srm-front
的内容(重新clone一个仓库来做升级) - 在升级runtime时忽略 config/webpack.config.js 文件
cd srm-front
;hzero-front . -i config/webpack.config.js
cd srm-front
;hzero-front-cli .
- 将自己做的修改 patch 到 刚更新的文件中
- 备份自己的修改的
-
升级
hzero-front@0.10.5
平台依赖cd srm-front
;yarn add -W hzero-front@0.10.1 --registry=http://nexus.saas.hand-china.com/content/groups/hzero-npm-group/
-
升级多个依赖
cd srm-front
;yarn add -W hzero-front@0.10.1 hzero-front-hiam@0.10.1 --registry=http://nexus.saas.hand-china.com/content/groups/hzero-npm-group/
- 根据package.json,更新依赖:更改需要升级的模块版本号,之后执行
yarn -W --registry=http://nexus.saas.hand-china.com/content/groups/hzero-npm-group/
-
安装一个新的模块
hzero-front-hnlp@0.10.0
cd srm-front
;yarn add -W hzero-front-hnlp@0.10.0 --registry=http://nexus.saas.hand-china.com/content/groups/hzero-npm-group/
- 将新安装的模块加入到主工程中:
- 在
srm-front/src/utils/getModuleRouters.js
引入import * as hzeroFrontHNlpRouters from 'hzero-front-hnlp/lib/utils/router';
- 在
srm-front/src/utils/getModuleRouters.js
的 默认导出中 加入hzeroFrontHNlpRouters
启动项目
- 按需修改
srm-front/config/compileStartEnv.js
中的环境变量 - 安装依赖 yarn bootstrap
- 编译子模块 lerna run transpile
- 打包dll yarn build:dll
- 启动本地环境 yarn start
部署项目
- 编译项目:
- 安装依赖 yarn bootstrap
- 编译子模块 lerna run transpile
- 打包dll yarn build:dll
- 编译项目 yarn build
- 将build完成的
dist
所有文件 复制到/usr/share/nginx/html(服务器部署目录)
- 替换环境变量
run.sh
/usr/share/nginx/html
: 服务器部署目录
#!/bin/bash
set -e
find /usr/share/nginx/html -name '*.js' | xargs sed -i "s BUILD_BASE_PATH $BUILD_BASE_PATH g"
find /usr/share/nginx/html -name '*.js' | xargs sed -i "s BUILD_API_HOST $BUILD_API_HOST g"
find /usr/share/nginx/html -name '*.js' | xargs sed -i "s BUILD_CLIENT_ID $BUILD_CLIENT_ID g"
find /usr/share/nginx/html -name '*.js' | xargs sed -i "s BUILD_BPM_HOST $BUILD_BPM_HOST g"
find /usr/share/nginx/html -name '*.js' | xargs sed -i "s BUILD_WFP_EDITOR $BUILD_WFP_EDITOR g"
find /usr/share/nginx/html -name '*.js' | xargs sed -i "s BUILD_WEBSOCKET_HOST $BUILD_WEBSOCKET_HOST g"
find /usr/share/nginx/html -name '*.js' | xargs sed -i "s BUILD_PLATFORM_VERSION $BUILD_PLATFORM_VERSION g"
exec "$@"
环境变量说明
- BUILD_BASE_PATH:
如果`/app/`二级目录部署 需要修改 `srm-front/config/compileBuildEnv.js` 中的
BASE_PATH 为 `/app/(二级目录)`
PUBLIC_URL 为 `/app(二级目录不要后面的/)`
- BUILD_API_HOST: 网关地址
- BUILD_CLIENT_ID: oauth 认证客户端id
- BUILD_BPM_HOST: 工作流地址
- BUILD_WEBSOCKET_HOST: websocket 地址
- BUILD_PLATFORM_VERSION: OP/SAAS
gitlab-ci & docker
docker/enterpoint.sh
#!/bin/bash
set -e
find /usr/share/nginx/html -name '*.js' | xargs sed -i "s BUILD_BASE_PATH $BUILD_BASE_PATH g"
find /usr/share/nginx/html -name '*.js' | xargs sed -i "s BUILD_API_HOST $BUILD_API_HOST g"
find /usr/share/nginx/html -name '*.js' | xargs sed -i "s BUILD_CLIENT_ID $BUILD_CLIENT_ID g"
find /usr/share/nginx/html -name '*.js' | xargs sed -i "s BUILD_BPM_HOST $BUILD_BPM_HOST g"
find /usr/share/nginx/html -name '*.js' | xargs sed -i "s BUILD_WFP_EDITOR $BUILD_WFP_EDITOR g"
find /usr/share/nginx/html -name '*.js' | xargs sed -i "s BUILD_WEBSOCKET_HOST $BUILD_WEBSOCKET_HOST g"
find /usr/share/nginx/html -name '*.js' | xargs sed -i "s BUILD_PLATFORM_VERSION $BUILD_PLATFORM_VERSION g"
exec "$@"
docker/default.conf
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/log/host.access.log main;
root /usr/share/nginx/html;
location / {
# react-router BrowserHistory 需要配合这个
try_files $uri /index.html;
}
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# Media: images, icons, video, audio, HTC
location ~* \.(jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
expires 1M;
access_log off;
add_header Cache-Control "public";
}
# CSS and Javascript
location ~* \.(css|js)$ {
expires 1y;
access_log off;
add_header Cache-Control "public";
}
}
Dockerfile
FROM registry.cn-hangzhou.aliyuncs.com/choerodon-tools/frontbase:0.5.0
RUN echo "Asia/shanghai" > /etc/timezone;
RUN sed -i 's/\#gzip/gzip/g' /etc/nginx/nginx.conf;
ADD ./dist /usr/share/nginx/html
ADD ./docker/default.conf /etc/nginx/conf.d/
COPY ./docker/enterpoint.sh /usr/share/nginx/html
RUN chmod 777 /usr/share/nginx/html/enterpoint.sh
ENTRYPOINT ["/usr/share/nginx/html/enterpoint.sh"]
CMD ["nginx", "-g", "daemon off;"]
EXPOSE 80
.gitlab-ci.yml
# 使用 choerodon 镜像
image: registry.cn-hangzhou.aliyuncs.com/choerodon-tools/cifront:0.7.0
stages:
# 编译代码
- node_build
# 编译Docker镜像
- docker_build
node_build:
stage: node_build
script:
# 安装依赖
- node_module
# 编译代码
- node_build
# 复制编译好的文件到 磁盘 volumn, 一遍二次构建 获取编译好的文件
- cp -r dist /cache/${CI_PROJECT_NAME}-${CI_PROJECT_ID}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}/dist
only:
# 只在 master 分支merge 的时候触发
- master
# 打包部署镜像
docker_build:
image: registry.cn-hangzhou.aliyuncs.com/choerodon-tools/cibase:0.7.0
stage: docker_build
script:
# 打包镜像
- docker_build
# 删除缓存
- rm -rf /cache/${CI_PROJECT_NAME}-${CI_PROJECT_ID}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
# 没有找到 估计是 k8s chart 替换环境变量?
- chart_build
only:
- master
.auto_devops: &auto_devops |
http_status_code=`curl -o .auto_devops.sh -s -m 10 --connect-timeout 10 -w %{http_code} "${CHOERODON_URL}/devops/ci?token=${Token}&type=front"`
if [ "$http_status_code" != "200" ]; then
cat .auto_devops.sh
exit 1
fi
source .auto_devops.sh
function node_module(){
# 在 volumn 创建缓存目录
mkdir -p /cache/${CI_PROJECT_NAME}-${CI_PROJECT_ID}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
# 安装 lerna
yarn global add lerna
# 安装依赖
lerna bootstrap --registry http://nexus.saas.hand-china.com/content/groups/hzero-npm-group
# 安装依赖
yarn --registry http://nexus.saas.hand-china.com/content/groups/hzero-npm-group
}
function node_build(){
# 可能是有些 脚本需要执行权限
chmod -R 777 node_modules
lerna run transpile
yarn dll
yarn build
}
function docker_build(){
cp -r /cache/${CI_PROJECT_NAME}-${CI_PROJECT_ID}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}/* ${1:-"."}
docker login -u ${DOCKER_USER} -p ${DOCKER_PWD} ${DOCKER_REGISTRY}
docker build --pull -t ${DOCKER_REGISTRY}/${GROUP_NAME}/${PROJECT_NAME}:${CI_COMMIT_TAG} ${1:-"."}
docker push ${DOCKER_REGISTRY}/${GROUP_NAME}/${PROJECT_NAME}:${CI_COMMIT_TAG}
echo "${DOCKER_REGISTRY}/${GROUP_NAME}/${PROJECT_NAME}:${CI_COMMIT_TAG}"
}
before_script:
- *auto_devops
jenkins & 开发服务器
jenkins 点击构建后 触发对应 服务器上的 run.sh
脚本
jenkins-run-sh
- 服务器需要安装运行环境(以及编译环境)
- nginx, node
- yarn, lerna
- 脚本目录在
**/srm-fornt/**.sh
- nginx root 指向
**/srm-fornt/html
# 获取最新代码
git pull
# 阻止下载 测试依赖
export PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
# 安装依赖
yarn install
# 编译子模块
lerna run transpile
# 打包第三方包等
yarn build:dll
# 编译
yarn build
# 编译失败后的处理
buildErrorCode=$?
if [ 0 -ne $buildErrorCode ]; then
echo $buildErrorCode
echo 'build error';
exit $buildErrorCode;
fi
# 替换变量
find dist -name '*.js' | xargs sed -i "s BUILD_API_HOST http://hzeronb.saas.hand-china.com g"
find dist -name '*.js' | xargs sed -i "s BUILD_CLIENT_ID hzero-front-dev g"
find dist -name '*.js' | xargs sed -i "s BUILD_WEBSOCKET_HOST ws://hzeronb.saas.hand-china.com/hpfm/websocket g"
find dist -name '*.js' | xargs sed -i "s BUILD_PLATFORM_VERSION SAAS g"
find dist -name '*.js' | xargs sed -i "s BUILD_IM_ENABLE true g"
find dist -name '*.js' | xargs sed -i "s BUILD_IM_WEBSOCKET_HOST ws://192.168.16.150:9876 g"
find dist -name '*.js' | xargs sed -i "s BUILD_CUSTOMIZE_ICON_NAME customize-icon g"
# 删除 之前的dist目录
rm -rf html
mv dist html
echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
新服务开发流程
新服务开发分为平台(HZERO)开发和项目开发两种。
1. 平台开发
1.1 服务命名
新服务命名格式为hzero-front-xxx
新服务需要放在 packags
文件夹下
1.2 配置文件
配置文件请参照其他hzero-front-xxx模块文件内的配置文件进行配置即可。
1.3 添加API服务前缀
先在packages/hzero-front/config/apiConfig.js
中,在config中添加新模块的API
比如新模块名为 hzero-front-new
const config = {
//...
// new 模块
HZERO_NEW: {
init: () => {
return "'/new'";
},
route: true,
},
},
添加过后,使用node命令在根目录
下运行packages/hzero-front/scripts/genConfig.js
文件。必须运行该文件。
node ./packages/hzero-front/scripts/genConfig.js
如果有安装run code插件,可以直接右键genConfig.js这个文件后,点击run code即可。
添加完成后,需要重新编译 hzero-front
模块的文件。在根目录下执行下面的命令,单独编译该模块文件:
lerna run transpile --scope hzero-front
或者在根目录下执行下面的命令,编译所有文件:
lerna run transpile
1.4 添加模块路由
在src/utils/getModuleRouters.js
文件中添加模块路由,代码格式如下图所示,
1.5 代码开发
详情查看:前端开发指引
1.6 单模块启动测试
代码编写完成后,需要单个模块启动测试
启动方法:在该服务模块文件目录下执行:
yarn build:dll // 此行命令只需要在需要第一次启动时执行
yarn start
1.7 全局启动测试
hzero-front主体工程依赖于packages下的各模块,所以需要编译packages下的各模块,执行如下命令:
yarn transpile:prod
或者
lerna run transpile
接下来,确保dll操作已经执行成功后,执行如下命令,即可启动hzero-front主体工程
yarn start
1.8 UI使用
新的功能模块的开发必须要用 Choerodon UI,优先使用Pro版本的组件,Pro版没有的才使用普通版本的组件。
2. 项目开发
2.1 服务模块存放位置
新服务需要放在 packags
文件夹下
2.2 配置文件
模块内的配置文件参照其他服务模块文件内的配置文件即可。
2.3 添加API服务前缀
先在packages/xxx-front/config/apiConfig.js
中,(xxx为项目名)。在config中添加新模块的API
比如新模块名为 demo-new
const config = {
//...
// new 模块
DEMO_NEW: {
init: () => {
return "'/new'";
},
route: true,
},
},
添加过后,使用node命令在根目录
下运行packages/xxx-front/scripts/genConfig.js
文件。必须运行该文件。(xxx为项目名)
node ./packages/xxx-front/scripts/genConfig.js
如果有安装run code插件,可以直接右键genConfig.js这个文件后,点击run code即可。
运行完这个文件后,packages/xxx-front/src/utils/config.js文件会自动发生变化,无需手动更改。
添加完成后,需要重新编译 xxx-front
模块的文件,在根路径下执行下面的命令,单独编译该模块文件。
lerna run transpile --scope xxx-front
或者在根目录下执行下面的命令,编译所有文件:
lerna run transpile
2.4 添加模块路由
在src/utils/getModuleRouters.js
文件中添加模块路由,代码格式如下图所示,(new
的位置替换为设置的新服务名,xxx
-为项目名)
// ...
import * as xxxFrontNewRouters from 'xxx-front-new/lib/utils/router';
export default app =>
getModuleRouters(app, [
// ...
xxxFrontNewRouters,
]);
2.5 代码开发
详情查看:前端开发指引
2.6 单模块启动测试
代码编写完成后,需要单个模块启动测试
启动方法:
yarn build:dll // 此行命令只需要在需要第一次启动时执行
yarn start
2.7 全局启动测试
hzero-front主体工程依赖于packages下的各模块,所以需要编译packages下的各模块,执行如下命令:
yarn transpile:prod
或者
lerna run transpile
接下来,确保dll操作已经执行成功后,执行如下命令,即可启动hzero-front主体工程
yarn start
2.8 覆盖原有服务
如果想要覆盖平台原有的服务进行二次开发:
1.覆盖原有路径(比如想要覆盖汇率类型定义的服务)
在对应的服务模块下,覆盖原有页面的路由配置
从url上可以发现该页面服务是hpfm服务下的,所以,在packages/xxx-front-hpfm/config/routers.js
进行路由覆盖配置
module.exports = [
{
path: "/hpfm/mdm/rate-type",
component: "RateType",
models: [
"rateType",
],
},
];
注意:如果只想覆盖某个页面的子页面,那么不仅要覆盖这个子页面的路由,父级页面的路由也必须要进行覆盖。
2.进行代码开发即可。(如果想要进行二次开发,建议向平台索要该服务的源码进行二次开发)