Commit 16c359b4 authored by 莫坚培's avatar 莫坚培

feat: 迁移自动化构建流程

parent b2bb6f72
# visual-html <!--
可视化html页面 * @Author: 莫靓仔
* @description: 文件描述
* @Date: 2021-08-23 17:36:37
* @LastEditors: 莫靓仔
* @LastEditTime: 2021-09-14 19:21:02
-->
## 本地 run 项目
```
yarn dev
```
## 切换环境
- 切换到开发环境
```
npm run set-d
```
- 切换到测试环境
```
npm run set-t
```
- 切换到预发布环境
```
npm run set-y
```
- 切换到正式环境(应该没啥用)
```
npm run set-p
```
## 发布
- 开发环境发布
```
npm run bd
```
- 测试环境发布
```
npm run bt
```
- 预发布环境发布
```
npm run by
```
## 打包
- 由于引入打包之前项目已经存在,用 webpack 配置比较坎坷,遂采用 gulp 简单打包一下,配置都在 gulpfile.js 中
- 默认生产 dist 目录,目录结构如下
```
dist
└─ bi
├─ index.html
├─ ...
```
## 压缩
- Mac 的压缩使用的是 compressing 插件,该插件支持 tar 和 gzip 格式,可以组合压缩成 Linux 系统的 tar.gz 格式。
- windows 的压缩使用 zip 格式(compressing 插件的压缩在 windows 解压之后会带一串路径在前边),公司的服务器安装了 zip 插件,可以使用 zip 格式的压缩包,压缩的过程在 config/zip.js,压缩的目录是 dist/bi。
## 关于 request 文件
- 现在项目使用的 axios 实例是由 browserify 编译 request.js 文件出来的,编译之后的文件名是 request_browserify.js
- 由于需要使用 require 引入环境配置(如果 api 地址),浏览器不支持 require 的写法,所以需要由 browserify 编译。
- 另外,问了兼容 browserify 的编译,需要在编译 request 之前加入如下代码。现已处理,无需再修改。
```
if(!window.request) {
window.request = request
}
```
## 关于本地直连服务器
请查看语雀文档
{"apiUrl":"https://apidev.sycdev.com","baseUrl":"https://slmdev.sycdev.com","domain":"sycdev.com","name":"开发环境"} {"apiUrl":"https://api.sycdev.com","baseUrl":"https://slm.sycdev.com","domain":"sycdev.com","name":"测试环境"}
\ No newline at end of file \ No newline at end of file
...@@ -126,7 +126,7 @@ ...@@ -126,7 +126,7 @@
<script src="./js/jquery-1.10.2.min.js"></script> <script src="./js/jquery-1.10.2.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="./utils/request.js"></script> <script src="./utils/request_browserify.js"></script>
<script src="https://unpkg.com/dayjs@1.8.21/dayjs.min.js"></script> <script src="https://unpkg.com/dayjs@1.8.21/dayjs.min.js"></script>
<script src="./js/moment.js"></script> <script src="./js/moment.js"></script>
<!-- --> <!-- -->
......
This diff is collapsed.
/*
* @Author: 莫靓仔
* @description: 文件描述
* @Date: 2021-09-14 17:49:54
* @LastEditors: 莫靓仔
* @LastEditTime: 2021-09-14 19:03:37
*/
// 防抖 // 防抖
function debounce (fn, delay) { function debounce(fn, delay) {
var time = delay || 1000 var time = delay || 1000
var timer var timer
return function () { return function () {
var th = this var th = this
var args = arguments var args = arguments
if (timer) { if (timer) {
clearTimeout(timer) clearTimeout(timer)
}
timer = setTimeout(function () {
timer = null
fn.apply(th, args)
}, time)
} }
timer = setTimeout(function () {
timer = null
fn.apply(th, args)
}, time)
}
} }
// 节流 // 节流
function throttle (fn, interval) { function throttle(fn, interval) {
var last var last
var timer var timer
var time = interval || 2000 var time = interval || 2000
return function () { return function () {
var th = this var th = this
var args = arguments var args = arguments
var now = +new Date() var now = +new Date()
if (last && now - last < time) { if (last && now - last < time) {
clearTimeout(timer) clearTimeout(timer)
timer = setTimeout(function () { timer = setTimeout(function () {
last = now last = now
fn.apply(th, args) fn.apply(th, args)
}, time) }, time)
} else { } else {
last = now last = now
fn.apply(th, args) fn.apply(th, args)
}
} }
} }
}
\ No newline at end of file // 弹窗
var appTips = {
successMsg: function (message, style) {
var css = {
skin: 'layui-msg-success-style',
offset: '20px'
}
css = $.extend(css, style)
layer.msg(message, css)
},
warningMsg: function (message, style) {
var css = {
skin: 'layui-msg-warning-style',
offset: '20px'
}
css = $.extend(css, style)
layer.msg(message, css)
},
tipsMsg: function (message, style) {
var css = {
skin: 'layui-msg-tips-style',
offset: '20px'
}
css = $.extend(css, style)
layer.msg(message, css)
},
errorMsg: function (message, style) {
var css = {
skin: 'layui-msg-error-style',
offset: '20px'
}
css = $.extend(css, style)
layer.msg(message, css)
},
alert: function () {
layer.alert()
}
}
...@@ -8,15 +8,7 @@ ...@@ -8,15 +8,7 @@
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests"> <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
<title>BI系统</title> <title>BI系统</title>
<script src="./js/watcher.js"></script> <script src="./js/watcher.js"></script>
<script> <script src="./js/domainSetting.js"></script>
// 离开页面保存功能代码(移动至此处)
if (window.location.host.indexOf('127.0.0') === -1) {
// 测试 && 开发:sycdev.com
// 正式: shengyc.com
document.domain = 'shengyc.com' || '';
}
</script>
<link rel="stylesheet" href="https://at.alicdn.com/t/font_2431045_hbwl3x53oep.css"> <link rel="stylesheet" href="https://at.alicdn.com/t/font_2431045_hbwl3x53oep.css">
<link rel="stylesheet" href="./styles/date.css"> <link rel="stylesheet" href="./styles/date.css">
<link rel="stylesheet" href="./layui/css/layui.css"> <link rel="stylesheet" href="./layui/css/layui.css">
...@@ -256,11 +248,11 @@ ...@@ -256,11 +248,11 @@
onchange="getFlag(this[selectedIndex].value)" placeholder="请选择"> onchange="getFlag(this[selectedIndex].value)" placeholder="请选择">
<option value=">">></option> <option value=">">></option>
<option value="=">=</option> <option value="=">=</option>
<option value="<"> <option value="&lt;">
<< /option> &lt;</option>
<option value=">=">>=</option> <option value=">=">>=</option>
<option value="<="> <option value="&lt;=">
<=< /option> &lt;=</option>
</select> </select>
</div> </div>
<div class="form-item"> <div class="form-item">
...@@ -519,7 +511,7 @@ ...@@ -519,7 +511,7 @@
<!-- 引入axiox --> <!-- 引入axiox -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="./utils/request.js"></script> <script src="./utils/request_browserify.js"></script>
<script src="./js/color.js"></script> <script src="./js/color.js"></script>
<script type="text/javascript" src="./js/data.js"></script> <script type="text/javascript" src="./js/data.js"></script>
<script type="text/javascript" src="./js/dropdown.js"></script> <script type="text/javascript" src="./js/dropdown.js"></script>
...@@ -2347,11 +2339,6 @@ ...@@ -2347,11 +2339,6 @@
canvasWrap.addEventListener('drop', async function (event) { canvasWrap.addEventListener('drop', async function (event) {
$("#saveBtnTips").show() $("#saveBtnTips").show()
// $(".details").show() // $(".details").show()
if (window.location.host.indexOf('127.0.0') === -1) {
// 测试 && 开发:sycdev.com
// 正式: shengyc.com
document.domain = 'shengyc.com' || '';
}
buttonid = '' buttonid = ''
// leg初始化之后没拖动一个元素下来就+1,此值会一直++, 防止元素名称重复 // leg初始化之后没拖动一个元素下来就+1,此值会一直++, 防止元素名称重复
......
...@@ -9,12 +9,6 @@ var fd = null ...@@ -9,12 +9,6 @@ var fd = null
var appId = '' //appId var appId = '' //appId
appId = getParams('appId', window.location.href) appId = getParams('appId', window.location.href)
// // 离开页面保存功能代码(移动至此处)
// if (window.location.host.indexOf('127.0.0') === -1) {
// // 测试 && 开发:sycdev.com
// // 正式: shengyc.com
// // document.domain = 'shengyc.com' || '';
// }
window.addEventListener('message', goToBi, false) window.addEventListener('message', goToBi, false)
function goToBi(event) { function goToBi(event) {
......
/*
* @Author: 莫靓仔
* @description: 设置domain
* @Date: 2021-09-02 15:36:23
* @LastEditors: 莫靓仔
* @LastEditTime: 2021-09-02 16:37:03
*/
if (window.location.host.indexOf('shengyc.com') > -1) {
document.domain = 'shengyc.com'
}
if (window.location.host.indexOf('sycdev.com') > -1) {
document.domain = 'sycdev.com'
}
...@@ -29,11 +29,6 @@ function choice(type, index, refresh) { ...@@ -29,11 +29,6 @@ function choice(type, index, refresh) {
$('#chart-list').css('display', 'block') $('#chart-list').css('display', 'block')
showIframe(Controls.ControlList[index].ControlType) showIframe(Controls.ControlList[index].ControlType)
} }
if (window.location.host.indexOf('127.0.0') === -1) {
// 测试 && 开发:sycdev.com
// 正式: shengyc.com
document.domain = 'shengyc.com' || '';
}
} }
} }
......
{ {
"name": "bi", "name": "bi",
"version": "1.0.0", "version": "1.0.0",
"description": "", "scripts": {
"main": "index.js", "test": "echo \"Error: no test specified\" && exit 1",
"scripts": { "dev": "webpack-dev-server",
"test": "echo \"Error: no test specified\" && exit 1" "build": "webpack -p --progress --mode production --config webpack.config.js",
}, "bd": "npm run set-d && gulp && node ./config/zip.js && npm run scp-d",
"author": "", "bt": "npm run set-t && gulp && node ./config/zip.js && npm run scp-t",
"license": "ISC" "by": "npm run set-y && gulp && node ./config/zip.js && npm run scp-y",
} "scp-d": "cross-env NODE_ENV=develop node ./config",
"scp-t": "cross-env NODE_ENV=test node ./config",
"scp-y": "cross-env NODE_ENV=pre-release node ./config",
"zip": "node ./config/zip.js",
"set-d": "node ./config/changeConfig.js dev && npm run br",
"set-t": "node ./config/changeConfig.js test && npm run br",
"set-y": "node ./config/changeConfig.js pre && npm run br",
"set-p": "node ./config/changeConfig.js prod && npm run br",
"browserify_request": "browserify ./utils/request.js > utils/request_browserify.js",
"br": "npm run browserify_request"
},
"devDependencies": {
"css-loader": "^5.2.7",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"file-loader": "^6.2.0",
"gulp-htmlmin": "^5.0.1",
"gulp-minify-css": "^1.2.4",
"gulp-uglify": "^3.0.2",
"html-webpack-plugin": "^4.5.2",
"jquery": "^3.6.0",
"less-loader": "^4.1.0",
"style-loader": "^2.0.0",
"url-loader": "^4.1.1",
"webpack": "^4.46.0",
"webpack-cli": "^3.3.12"
},
"dependencies": {
"@babel/core": "^7.15.0",
"@babel/plugin-transform-runtime": "^7.15.0",
"@babel/preset-env": "^7.15.0",
"@babel/runtime": "^7.15.3",
"browserify": "^17.0.0",
"clean-webpack-plugin": "^4.0.0-alpha.0",
"compressing": "^1.5.1",
"cross-env": "^7.0.3",
"del": "^6.0.0",
"gulp": "^4.0.2",
"gulp-babel": "^8.0.0",
"jszip": "^3.7.1",
"scp2": "0.5.0",
"ssh2-sftp-client": "6.0.1",
"webpack-dev-server": "^3.11.2"
}
}
// // 配置axios // // 配置axios
let configInfo = require('../config/config.json')
const request = axios.create({ const request = axios.create({
// 开发环境: https://apidev.sycdev.com // 开发环境: https://apidev.sycdev.com
// 测试环境: https://api.sycdev.com 登录界面 https://slm.sycdev.com/#/login // 测试环境: https://api.sycdev.com 登录界面 https://slm.sycdev.com/#/login
/* 1.1 */ /* 1.1 */
// 开发环境: https://apidev-alpha.sycdev.com // 开发环境: https://apidev-alpha.sycdev.com
// 测试环境: https://api-alpha.sycdev.com 登录界面 https://slm.sycdev.com/#/login // 测试环境: https://api-alpha.sycdev.com 登录界面 https://slm.sycdev.com/#/login
// 正式环境: https://slmapi.shengyc.com 登录界面 https://slm.shengyc.com/#/login // 正式环境: https://slmapi.shengyc.com 登录界面 https://slm.shengyc.com/#/login
// 预发布::https://apipre.sycdev.com // 预发布::https://apipre.sycdev.com
baseURL: 'https://slmapi.shengyc.com', // url = base url + request url baseURL: configInfo.apiUrl, // url = base url + request url
withCredentials: true, // send cookies when cross-domain requests withCredentials: true, // send cookies when cross-domain requests
timeout: 900000 // request timeout timeout: 900000 // request timeout
}) })
let url = 'https://slm.shengyc.com/#/login' let url = `${configInfo.baseUrl}/#/login`
// // request interceptor // // request interceptor
request.interceptors.request.use( request.interceptors.request.use(
config => { config => {
// do something before request is sent // do something before request is sent
// if (store.getters.token) { // if (store.getters.token) {
// // let each request carry token // // let each request carry token
// // ['X-Token'] is a custom headers key // // ['X-Token'] is a custom headers key
// // please modify it according to the actual situation // // please modify it according to the actual situation
// config.headers['X-Token'] = getToken() // config.headers['X-Token'] = getToken()
// config.headers.common['Authorization'] = 'Bearer ' + getToken() // config.headers.common['Authorization'] = 'Bearer ' + getToken()
// } // }
// startLoad() // startLoad()
if (localStorage.getItem('token')) { if (localStorage.getItem('token')) {
config.headers['X-Token'] = localStorage.getItem('token') config.headers['X-Token'] = localStorage.getItem('token')
// config.headers.common['Authorization'] = localStorage.getItem('token') // config.headers.common['Authorization'] = localStorage.getItem('token')
config.headers.common['Authorization'] = 'Bearer ' + localStorage.getItem('token') config.headers.common['Authorization'] = 'Bearer ' + localStorage.getItem('token')
config.headers.common['TENANT-ID'] = localStorage.getItem('tenantId') config.headers.common['TENANT-ID'] = localStorage.getItem('tenantId')
config.headers.common['VERSION'] = 'V1' config.headers.common['VERSION'] = 'V1'
return config return config
}
return config
},
error => {
// do something with request error
console.log(error) // for debug
return Promise.reject(error)
} }
return config
},
error => {
// do something with request error
console.log(error) // for debug
return Promise.reject(error)
}
) )
// response interceptor // response interceptor
request.interceptors.response.use( request.interceptors.response.use(
/** /**
* If you want to get http information such as headers or status * If you want to get http information such as headers or status
* Please return response => response * Please return response => response
*/ */
/** /**
* Determine the request status by custom code * Determine the request status by custom code
* Here is just an example * Here is just an example
* You can also judge the status by HTTP Status Code * You can also judge the status by HTTP Status Code
*/ */
response => { response => {
// response code=200 // response code=200
// const res = response.data // const res = response.data
return response return response
}, },
response => { response => {
// response code!=200 // response code!=200
if (response.response === undefined) { if (response.response === undefined) {
// Message({ // Message({
// message: '网络异常', // message: '网络异常',
// type: 'error', // type: 'error',
// duration: 3 * 1000 // duration: 3 * 1000
// }) // })
appTips.errorMsg('网络异常'); appTips.errorMsg('网络异常')
return Promise.reject('error') return Promise.reject('error')
} }
if (response.response.status === 401 || response.response.status === 403) { if (response.response.status === 401 || response.response.status === 403) {
if (response.response.status === 401) { if (response.response.status === 401) {
// Message({ // Message({
// message: '对不起,您未登陆 或 页面已过期,请重新登陆!', // message: '对不起,您未登陆 或 页面已过期,请重新登陆!',
// type: 'error', // type: 'error',
// duration: 3 * 1000 // duration: 3 * 1000
// }) // })
window.location.href(url) // window.location.href = url
appTips.errorMsg('对不起,您未登陆 或 页面已过期,请重新登陆!'); appTips.errorMsg('对不起,您未登陆 或 页面已过期,请重新登陆!')
return Promise.reject('error') return Promise.reject('error')
} }
if (response.response.status === 403) { if (response.response.status === 403) {
// Message({ // Message({
// message: '对不起,您没有该权限,请联系管理员!', // message: '对不起,您没有该权限,请联系管理员!',
// type: 'error', // type: 'error',
// duration: 3 * 1000 // duration: 3 * 1000
// }) // })
appTips.errorMsg('对不起,您没有该权限,请联系管理员!'); appTips.errorMsg('对不起,您没有该权限,请联系管理员!')
return Promise.reject('error') return Promise.reject('error')
} }
} else { } else {
if (response.response.status !== 200) { if (response.response.status !== 200) {
// Message({
// message: '对不起,程序错误,请联系管理员',
// type: 'error',
// duration: 3 * 1000
// })
appTips.errorMsg('对不起,程序错误,请联系管理员')
}
}
},
error => {
console.log('err' + error) // for debug
// Message({ // Message({
// message: '对不起,程序错误,请联系管理员', // message: error.message,
// type: 'error', // type: 'error',
// duration: 3 * 1000 // duration: 5 * 1000
// }) // })
appTips.errorMsg('对不起,程序错误,请联系管理员'); appTips.errorMsg(error.message)
} return Promise.reject(error)
} }
}, )
error => {
console.log('err' + error) // for debug // 兼容本文件通过browserify编译之后无法获取到request的问题
// Message({ if (!window.request) {
// message: error.message, window.request = request
// type: 'error', }
// duration: 5 * 1000
// })
appTips.errorMsg(error.message);
return Promise.reject(error)
}
)
\ No newline at end of file
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
module.exports={"apiUrl":"https://api.sycdev.com","baseUrl":"https://slm.sycdev.com","domain":"sycdev.com","name":"测试环境"}
},{}],2:[function(require,module,exports){
// // 配置axios
let configInfo = require('../config/config.json')
const request = axios.create({
// 开发环境: https://apidev.sycdev.com
// 测试环境: https://api.sycdev.com 登录界面 https://slm.sycdev.com/#/login
/* 1.1 */
// 开发环境: https://apidev-alpha.sycdev.com
// 测试环境: https://api-alpha.sycdev.com 登录界面 https://slm.sycdev.com/#/login
// 正式环境: https://slmapi.shengyc.com 登录界面 https://slm.shengyc.com/#/login
// 预发布::https://apipre.sycdev.com
baseURL: configInfo.apiUrl, // url = base url + request url
withCredentials: true, // send cookies when cross-domain requests
timeout: 900000 // request timeout
})
let url = `${configInfo.baseUrl}/#/login`
// // request interceptor
request.interceptors.request.use(
config => {
// do something before request is sent
// if (store.getters.token) {
// // let each request carry token
// // ['X-Token'] is a custom headers key
// // please modify it according to the actual situation
// config.headers['X-Token'] = getToken()
// config.headers.common['Authorization'] = 'Bearer ' + getToken()
// }
// startLoad()
if (localStorage.getItem('token')) {
config.headers['X-Token'] = localStorage.getItem('token')
// config.headers.common['Authorization'] = localStorage.getItem('token')
config.headers.common['Authorization'] = 'Bearer ' + localStorage.getItem('token')
config.headers.common['TENANT-ID'] = localStorage.getItem('tenantId')
config.headers.common['VERSION'] = 'V1'
return config
}
return config
},
error => {
// do something with request error
console.log(error) // for debug
return Promise.reject(error)
}
)
// response interceptor
request.interceptors.response.use(
/**
* If you want to get http information such as headers or status
* Please return response => response
*/
/**
* Determine the request status by custom code
* Here is just an example
* You can also judge the status by HTTP Status Code
*/
response => {
// response code=200
// const res = response.data
return response
},
response => {
// response code!=200
if (response.response === undefined) {
// Message({
// message: '网络异常',
// type: 'error',
// duration: 3 * 1000
// })
appTips.errorMsg('网络异常')
return Promise.reject('error')
}
if (response.response.status === 401 || response.response.status === 403) {
if (response.response.status === 401) {
// Message({
// message: '对不起,您未登陆 或 页面已过期,请重新登陆!',
// type: 'error',
// duration: 3 * 1000
// })
// window.location.href = url
appTips.errorMsg('对不起,您未登陆 或 页面已过期,请重新登陆!')
return Promise.reject('error')
}
if (response.response.status === 403) {
// Message({
// message: '对不起,您没有该权限,请联系管理员!',
// type: 'error',
// duration: 3 * 1000
// })
appTips.errorMsg('对不起,您没有该权限,请联系管理员!')
return Promise.reject('error')
}
} else {
if (response.response.status !== 200) {
// Message({
// message: '对不起,程序错误,请联系管理员',
// type: 'error',
// duration: 3 * 1000
// })
appTips.errorMsg('对不起,程序错误,请联系管理员')
}
}
},
error => {
console.log('err' + error) // for debug
// Message({
// message: error.message,
// type: 'error',
// duration: 5 * 1000
// })
appTips.errorMsg(error.message)
return Promise.reject(error)
}
)
// 兼容本文件通过browserify编译之后无法获取到request的问题
if (!window.request) {
window.request = request
}
},{"../config/config.json":1}]},{},[2]);
This diff is collapsed.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment