本章我們介紹使用React的Create React App工具,在O2平臺中創建React應用。在本例中,我們將列示當前用戶的前20條待辦,點擊標題打開待辦;並通過點擊按鈕啓動流程和打開主頁。
版本要求
本文適用於如下版本:
O2OA版本要求:5.1及以上版本;
React版本:本文撰寫時,react版本是16.13.1。(更低的版本未經驗證)
前提
開發端安裝了Node.js,Node >= 8.10, npm >= 5.6
有一臺O2服務器
使用合適的開發工具:WebStorm、VSCode、Atom等(本例使用WebStorm)
創建React應用
您可以使用WebStorm創建一個新的React App,如下圖:
或者創建一個空項目,然後使用以下命令創建React應用:
npx create-react-app my-app
cd my-app
創建後目錄結構如下:
添加O2腳本引入
在public/index.html的head中添加O2腳本引入:
<script src="../o2_core/bundle.js"></script>
修改src/index.js文件如下:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
//定義O2平臺對象
let layout = window.layout;
let o2 = window.o2;
//在O2平臺腳本載入完成後執行
layout.addReady(function(){
layout.app = true;
//通過平臺服務,獲取當前用戶的前20條待辦(可通過http://your-server:20030/x_program_center/jest/list.html查詢平臺接口服務)
o2.Actions.load("x_processplatform_assemble_surface").TaskAction.V2ListPaging(1,20, {}, function(json){
//React渲染App組件
ReactDOM.render(
<React.StrictMode>
<App value={json.count} data={json.data}></App>
</React.StrictMode>,
document.getElementById('root')
);
});
});
其中:
let layout = window.layout;
let o2 = window.o2;
獲取兩個O2的全局對象。
layout.addReady 方法會在O2載入完成後執行回調方法。
o2.Actions.load 方法可以調用平臺的Restful服務。
修改App組件
先修改src/App.css樣式文件,拷貝以下代碼:
.App {
padding: 20px;
margin: 20px;
}
.App-header {
padding: 5px 10px;
background: #0f81cc;
font-size: 18px;
color: #ffffff;
}
.o2-tasklist {
padding: 10px;
background: #f3f3f3;
font-size: 18px;
}
.o2-task {
line-height: 30px;
height: 30px;
cursor: pointer;
}
.o2-button {
padding: 10px 20px;
text-align: center;
background: #0f81cc;
margin-top: 10px;
color: #ffffff;
font-size: 18px;
float: left;
margin-right: 20px;
cursor: pointer;
}
修改src/App.js文件如下:
import React from 'react';
import './App.css';
function App(props) {
function openHomepage(){
//通過O2全局對象layout的openApplication方法打開主頁"Homepage"
window.layout.openApplication(null,"Homepage")
}
function openTask(id){
//通過O2全局對象layout的openApplication方法打開待辦
window.layout.openApplication(null,"process.Work", {"workId": id});
}
function startProcess(){
//通過o2.env對象啓動流程
//o2.env對象即是在O2門戶頁面的腳本中的this指向,可以使用其方法。
//請將“application-name”和“process-name”修改爲您的流程應用名稱和流程名
window.o2.env.page.startProcess("application-name", "process-name");
}
function listTask(){
let list = [];
props.data.each(function(d){
list.push(<div className="o2-task" onClick={()=>{openTask(d.work)}}>{d.title || "無標題"}</div>);
});
return list;
}
return (
<div className="App">
<header className="App-header">
<p>
您有{props.value}個待辦
</p>
</header>
<div className="o2-tasklist">
{listTask()}
</div>
<div className="o2-button" onClick={startProcess}>點擊此處啓動流程</div>
<div className="o2-button" onClick={openHomepage}>點擊此處打開O2首頁</div>
</div>
);
}
export default App;
上述代碼創建了一個React組件,列示了待辦列表,並創建兩個div,點擊後分別啓動指定的流程,打開主頁。
其中用到兩個全局對象:o2和layout。我們在Node.Js環境中開發,o2的對象是通過<script>標籤引入的,由於全局環境不同,直接使用layout和o2訪問對象會引起編譯錯誤,所以我們使用window.layout和window.o2來訪問。
當然,我們可以通過import來解決這個問題,創建一個src/o2.js文件,添加以下代碼:
let o2 = window.o2;
let layout = window.layout;
export {o2, layout};
然後在需要使用o2對象的組件中,使用以下代碼引入:
import {o2, layout} from './o2.js';
然後就可以直接使用layout和o2對象了。
App.js中,我們使用了o2.env對象,這個對象和在門戶頁面腳本中的this指向一致,可以調用除了與門戶頁面組件相關方法以外的各種方法,如:o2.env.page.openWork、o2.env.inculde、o2.env.confirm、o2.env.page.startProcess等,詳細內容可以參考API文檔。
編譯並運行
我們完成了上述開發工作,就可以編譯並運行我們的應用了。
由於我們要將react應用放到O2的web服務器的目錄下,而非根路徑下,所以我們需要在package.json中增加homepage字段,設置值爲".":
{
...
"homepage": ".",
...
}
在當前項目路徑下執行以下命令:
npm run build
React會在將所有的代碼編譯到build目錄,如下圖:
接着將build目錄部署到O2服務器的webServer下,並重命名爲“react-app”。然後通過瀏覽器訪問:http://your-server/react-app。
如果您未登錄到服務器,會出現登錄頁面,登錄後就可以看到登錄人的待辦列表,並可以啓動流程了。
登錄後:
如果您將您的應用部署到服務器的其他目錄,如custom/react-app下,那麼您需要在src/index.js文件中增加一行代碼:o2.base = "../";
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
//定義O2平臺對象
let layout = window.layout;
let o2 = window.o2;
//設置o2目錄
o2.base = "../";
//在O2平臺腳本載入完成後執行
layout.addReady(function(){
layout.app = true;
//通過平臺服務,獲取當前用戶的前20條待辦(可通過http://your-server:20030/x_program_center/jest/list.html查詢平臺接口服務)
o2.Actions.load("x_processplatform_assemble_surface").TaskAction.V2ListPaging(1,20, {}, function(json){
//React渲染App組件
ReactDOM.render(
<React.StrictMode>
<App value={json.count} data={json.data}></App>
</React.StrictMode>,
document.getElementById('root')
);
});
});
至此,我們已經可以在O2平臺的框架下,使用React開發應用了。
開發模式優化
雖然我們可以使用React開發O2應用,但上述模式在我們每次修改代碼後,需要運行build命令,並手工上傳到服務器,在開發比較複雜的應用時,還是比較影響效率的。下面價紹兩種方式來應對這種情況。
本地運行O2服務器
您可以在本地運行服務器,然後直接在服務器的webServer目錄下創建項目。然後您必須修改React的build路徑到正確的路徑。其中一個方法爲:
在項目目錄下運行以下命令:
npm run eject
此命令會暴露React應用的隱藏配置項,我們找到config/paths.js,找到“appBuild”並修改之:appBuild: resolveApp('../react-app')
module.exports = {
dotenv: resolveApp('.env'),
appPath: resolveApp('.'),
appBuild: resolveApp('../react-app'),
appPublic: resolveApp('public'),
appHtml: resolveApp('public/index.html'),
...
};
然後每次運行npm run build後,React會將編譯後的應用生成在webServer/react-app/目錄下,我們直接通過http://locahost/react-app就可以查看運行結果。
通過部署工具自動化部署到遠程服務器
當然,爲了節省我們部署遠程服務器的時間,我們可以使用javascript打包工具,自動完成這個過程,這裏我們使用gulp,通過ftp或sftp來進行自動化部署到遠程服務器。
這種方式不需要您本地運行O2服務器,但您必須有一臺遠程服務器,並可以通過ftp或sftp連接到服務器的webServer。
按上述方式創建好應用,然後我們安裝gulp環境:
npm i -g gulp-cli
安裝gulp以及gulp相關插件:
npm i gulp gulp-ftp gulp-sftp-up4 gulp-run -save-dev
在項目根目錄新建gulpfile.js文件:
var gulp = require('gulp'),
ftp = require('gulp-ftp'),
sftp = require('gulp-sftp-up4'),
run = require('gulp-run');
//根據您的實際服務器修改
var options = {
'build': 'build',
'host': 'o2server服務器',
'user': 'sftp user',
'pass': 'sftp password',
"port": 22,
"remotePath": "/data/o2server/servers/webServer/react-app"
};
//sftp任務
function upload_sftp(){
var build = "build/**/*";
return gulp.src(build)
.pipe(sftp({
host: options.host,
user: options.user || 'anonymous',
pass: options.pass || null,
port: options.port || 22,
remotePath: (options.remotePath || '/')
}));
}
//ftp任務
function upload_ftp(){
var build = "build/**/*";
return gulp.src(build)
.pipe(ftp({
host: options.host,
user: options.user || 'anonymous',
pass: options.pass || null,
port: options.port || 21,
remotePath: (options.remotePath || '/')
}));
}
//運行React build
function build_react() {
return run('npm run build').exec();
}
輸出gulp任務,如果使用ftp,更換第二個任務爲upload_ftp
exports.build = gulp.series(build_react, upload_sftp);
然後,當開發或修改代碼完成後,執行以下命令:
gulp build
就可以自動編譯React應用,並上傳到O2服務器。通過瀏覽器訪問:http://your-server/react-app就可以看到結果。
當然,這只是一個很簡單的例子,提供一個思路,您也可以使用其他您熟悉的工具實現相同或類似的功能。對於熟悉前端構建工具的用戶,實現更便捷的功能也不是難事,比如可以監控文件改動,實時部署,並刷新瀏覽器等。
總結
本章給大家介紹了在O2平臺的框架內,使用React開發應用,並在O2服務器的webServer中運行了起來。它集成了O2平臺的所有功能,您也不需要處理類似登錄等一些繁瑣的事,而且可以方便的調用O2的後端服務。並提供了一些優化開發模式的思路。
在大多數情況下,這樣的方式已經足夠滿足需要了,但如果您想要搭建自己的web服務器,並通過React作爲前端構建框架,那O2OA怎麼能夠與之集成呢?
下回分解!