mirror of
https://github.com/YMFE/yapi.git
synced 2025-02-05 13:29:43 +08:00
Merge branch 'dev' of gitlab.corp.qunar.com:mfe/yapi into dev
This commit is contained in:
commit
49e2e5c5b3
@ -40,4 +40,5 @@ module.exports = {
|
||||
"strict": 0,
|
||||
"comma-dangle": ["error", "never"]
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
"/fekit_modules/*",
|
||||
"/node_modules/*",
|
||||
"/bower_components/*",
|
||||
"/plugins/*",
|
||||
"/dev/*",
|
||||
"/prd/*"
|
||||
]
|
||||
|
@ -65,6 +65,7 @@ export default class App extends Component {
|
||||
<Footer />
|
||||
</div>
|
||||
</Router>
|
||||
|
||||
)
|
||||
}
|
||||
return r;
|
||||
|
@ -3,6 +3,7 @@ import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Row, Col } from 'antd';
|
||||
import { Icon } from 'antd'
|
||||
import packageJson from '../../../package.json';
|
||||
class Footer extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
@ -100,7 +101,7 @@ Footer.defaultProps = {
|
||||
iconType: 'layout',
|
||||
linkList: [
|
||||
{
|
||||
itemTitle: '版本: 1.0',
|
||||
itemTitle: '版本: '+packageJson.version,
|
||||
itemLink: 'javascript:'
|
||||
}
|
||||
]
|
||||
|
@ -1,64 +0,0 @@
|
||||
// file_id:2D7ABF69-3BC0-4175-98C9-5C3D5CB00158 -- nerver change this !!
|
||||
|
||||
/*
|
||||
* file: qsso-auth.js
|
||||
* URL: https://qsso.corp.qunar.com/lib/qsso-auth.js
|
||||
* written by zhibin.ning
|
||||
* version: 0.1
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
var AUTH_SERVER = 'https://qsso.corp.qunar.com',
|
||||
LOGIN_PAGE = '/login.php',
|
||||
SORRY_PAGE = '/sorry.html';
|
||||
|
||||
if (location.hostname.match(/qunar\.ctripgroup\.com$/i)) {
|
||||
AUTH_SERVER = 'https://qunar.ctripgroup.com/sec/qsso/api';
|
||||
}
|
||||
|
||||
var qualifyURL = function (url, encode) {
|
||||
url = url || '';
|
||||
var ret = location.protocol + '//' + location.host + (url.substr(0, 1) === '/' ? '' : location.pathname.match(/.*\//)) + url;
|
||||
if (encode) {
|
||||
ret = encodeURIComponent(ret);
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
var URLStringify = function (o) {
|
||||
var ret = [];
|
||||
for (var i in o) {
|
||||
// ret.push( encodeURIComponent(i) + '=' + encodeURIComponent(o[i]) );
|
||||
ret.push(i + '=' + o[i]);
|
||||
}
|
||||
return ret.join('&');
|
||||
};
|
||||
var qsso;
|
||||
module.exports = qsso = {
|
||||
'auth': function (loginURI, opt_ext) {
|
||||
if (!location.hostname.match(/\.qunar(man|ops)?\.com$|\.qunarman\.com$|qunar\.it$|\.928383\.com$|^928383\.com$|qunar\.ctripgroup\.c(om|n)$|\.ctrip(corp)?\.com$|^opsdata\.me$|\.mofun\.com$/i)) {
|
||||
location.href = AUTH_SERVER + SORRY_PAGE + '?host=' + qualifyURL('', true);
|
||||
return;
|
||||
}
|
||||
var ret = qualifyURL(loginURI, true);
|
||||
|
||||
var redirectURL = AUTH_SERVER + LOGIN_PAGE + '?ret=' + ret + (opt_ext ? '&ext=' + encodeURIComponent(URLStringify(opt_ext)) : '');
|
||||
// console.log(redirectURL);
|
||||
location.href = redirectURL;
|
||||
},
|
||||
|
||||
'attach': function (eid, loginURI, opt_ext) {
|
||||
var login = function () {
|
||||
qsso.auth(loginURI, opt_ext);
|
||||
|
||||
};
|
||||
document.getElementById(eid).onclick = login;
|
||||
if (location.hash.match('qsso-auto-login')) {
|
||||
login();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -19,7 +19,7 @@ class Subnav extends Component {
|
||||
<div className="m-subnav">
|
||||
<Menu
|
||||
onClick={this.handleClick}
|
||||
defaultSelectedKeys={[this.props.default]}
|
||||
selectedKeys={[this.props.default]}
|
||||
mode="horizontal"
|
||||
className="g-row m-subnav-menu"
|
||||
>
|
||||
@ -29,7 +29,7 @@ class Subnav extends Component {
|
||||
item.name = item.name[0] + ' ' + item.name[1];
|
||||
}
|
||||
return (
|
||||
<Menu.Item className="item" key={item.name}>
|
||||
<Menu.Item className="item" key={item.name.replace(' ', '')}>
|
||||
<Link to={item.path}>{this.props.data[index].name}</Link>
|
||||
</Menu.Item>
|
||||
)
|
||||
|
@ -7,8 +7,7 @@ import PropTypes from "prop-types";
|
||||
import { withRouter } from 'react-router';
|
||||
import { logoSVG, getImgPath } from '../../common.js';
|
||||
import { changeMenuItem } from '../../reducer/modules/menu'
|
||||
import Qsso from '../../components/Qsso/Qsso.js'
|
||||
|
||||
import Plugins from '../../plugin.js'
|
||||
const HomeGuest = () => (
|
||||
<div className="g-body">
|
||||
<div className="m-bg">
|
||||
@ -37,7 +36,11 @@ const HomeGuest = () => (
|
||||
<div className="detail">高效、易用、功能强大的API管理平台<br /><span className="desc">旨在为开发、产品、测试人员提供更优雅的接口管理服务</span></div>
|
||||
<div className="btn-group">
|
||||
<Link to="/login"><Button type="primary" className="btn-home btn-login">登录 / 注册</Button></Link>
|
||||
<Button className="btn-home btn-home-normal" id="qsso-login">QSSO 登录</Button>
|
||||
{Plugins.third_login.listener != null ?
|
||||
<Plugins.third_login.listener />
|
||||
: null
|
||||
}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
@ -181,7 +184,7 @@ class Home extends Component {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
Qsso.attach('qsso-login', '/api/user/login_by_token')
|
||||
|
||||
}
|
||||
static propTypes = {
|
||||
introList: PropTypes.array,
|
||||
|
@ -68,6 +68,8 @@ $color-bg-lightblue: #c6e2ff;
|
||||
&:hover, &:focus {
|
||||
background-color: #f6f9fc;
|
||||
}
|
||||
background-color: #fff;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ import { loginActions } from '../../reducer/modules/user';
|
||||
import { withRouter } from 'react-router'
|
||||
const FormItem = Form.Item;
|
||||
import './Login.scss'
|
||||
import Qsso from '../../components/Qsso/Qsso.js'
|
||||
// import Qsso from '../../components/Qsso/Qsso.js'
|
||||
|
||||
const formItemStyle = {
|
||||
marginBottom: '.16rem'
|
||||
@ -54,7 +54,7 @@ class Login extends Component {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
Qsso.attach('qsso-login','/api/user/login_by_token')
|
||||
//Qsso.attach('qsso-login','/api/user/login_by_token')
|
||||
}
|
||||
|
||||
|
||||
|
@ -79,6 +79,7 @@ class Interface extends Component {
|
||||
render() {
|
||||
const { action } = this.props.match.params;
|
||||
const activeKey = action === 'api' ? 'api' : 'colOrCase';
|
||||
// console.log(matchPath(this.props.location.pathname, contentRouter));
|
||||
return <div className="web-content g-row" style={{ marginBottom: "15px" }}>
|
||||
<Row gutter={16} >
|
||||
<Col span={6}>
|
||||
|
@ -5,6 +5,7 @@
|
||||
.menu-title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
overflow: hidden;
|
||||
.case-delete-icon{
|
||||
display: none;
|
||||
}
|
||||
|
@ -14,7 +14,9 @@ const TreeNode = Tree.TreeNode;
|
||||
|
||||
|
||||
@connect(
|
||||
|
||||
state => {
|
||||
|
||||
return {
|
||||
list: state.inter.list,
|
||||
inter: state.inter.curdata,
|
||||
@ -213,8 +215,38 @@ class InterfaceMenu extends Component {
|
||||
render() {
|
||||
const matchParams = this.props.match.params;
|
||||
let menuList = this.props.list;
|
||||
const searchBox = <div className="interface-filter">
|
||||
<Input onChange={this.onFilter} value={this.state.filter} placeholder="Filter by name" style={{ width: "70%" }} />
|
||||
<Tag color="#108ee9" onClick={() => this.changeModal('add_cat_modal_visible', true)} style={{ marginLeft: "15px" }} ><Icon type="plus" /></Tag>
|
||||
<Modal
|
||||
title="添加接口"
|
||||
visible={this.state.visible}
|
||||
onCancel={() => this.changeModal('visible', false)}
|
||||
footer={null}
|
||||
>
|
||||
<AddInterfaceForm catdata={this.props.curProject.cat} catid={this.state.curCatid} onCancel={() => this.changeModal('visible', false)} onSubmit={this.handleAddInterface} />
|
||||
</Modal>
|
||||
|
||||
<Modal
|
||||
title="添加分类"
|
||||
visible={this.state.add_cat_modal_visible}
|
||||
onCancel={() => this.changeModal('add_cat_modal_visible', false)}
|
||||
footer={null}
|
||||
>
|
||||
<AddInterfaceCatForm onCancel={() => this.changeModal('add_cat_modal_visible', false)} onSubmit={this.handleAddInterfaceCat} />
|
||||
</Modal>
|
||||
|
||||
<Modal
|
||||
title="修改分类"
|
||||
visible={this.state.change_cat_modal_visible}
|
||||
onCancel={() => this.changeModal('change_cat_modal_visible', false)}
|
||||
footer={null}
|
||||
>
|
||||
<AddInterfaceCatForm catdata={this.state.curCatdata} onCancel={() => this.changeModal('change_cat_modal_visible', false)} onSubmit={this.handleChangeInterfaceCat} />
|
||||
</Modal>
|
||||
</div>
|
||||
if(menuList.length === 0){
|
||||
return null;
|
||||
return searchBox;
|
||||
}
|
||||
const defaultExpandedKeys = () => {
|
||||
const { router, inter, list } = this.props, rNull = { expands: [], selects: [] };
|
||||
@ -307,36 +339,7 @@ class InterfaceMenu extends Component {
|
||||
}
|
||||
}
|
||||
return <div>
|
||||
<div className="interface-filter">
|
||||
<Input onChange={this.onFilter} value={this.state.filter} placeholder="Filter by name" style={{ width: "70%" }} />
|
||||
<Tag color="#108ee9" onClick={() => this.changeModal('add_cat_modal_visible', true)} style={{ marginLeft: "15px" }} ><Icon type="plus" /></Tag>
|
||||
<Modal
|
||||
title="添加接口"
|
||||
visible={this.state.visible}
|
||||
onCancel={() => this.changeModal('visible', false)}
|
||||
footer={null}
|
||||
>
|
||||
<AddInterfaceForm catdata={this.props.curProject.cat} catid={this.state.curCatid} onCancel={() => this.changeModal('visible', false)} onSubmit={this.handleAddInterface} />
|
||||
</Modal>
|
||||
|
||||
<Modal
|
||||
title="添加分类"
|
||||
visible={this.state.add_cat_modal_visible}
|
||||
onCancel={() => this.changeModal('add_cat_modal_visible', false)}
|
||||
footer={null}
|
||||
>
|
||||
<AddInterfaceCatForm onCancel={() => this.changeModal('add_cat_modal_visible', false)} onSubmit={this.handleAddInterfaceCat} />
|
||||
</Modal>
|
||||
|
||||
<Modal
|
||||
title="修改分类"
|
||||
visible={this.state.change_cat_modal_visible}
|
||||
onCancel={() => this.changeModal('change_cat_modal_visible', false)}
|
||||
footer={null}
|
||||
>
|
||||
<AddInterfaceCatForm catdata={this.state.curCatdata} onCancel={() => this.changeModal('change_cat_modal_visible', false)} onSubmit={this.handleChangeInterfaceCat} />
|
||||
</Modal>
|
||||
</div>
|
||||
{searchBox}
|
||||
{menuList.length > 0 ?
|
||||
<Tree
|
||||
className="interface-list"
|
||||
@ -356,7 +359,7 @@ class InterfaceMenu extends Component {
|
||||
</Dropdown>
|
||||
</div>}
|
||||
key={'cat_' + item._id}
|
||||
className="interface-item-nav"
|
||||
className={`interface-item-nav ${item.list.length?"":"cat_switch_hidden"}`}
|
||||
>
|
||||
{item.list.map(item_interface_create)}
|
||||
|
||||
|
@ -31,9 +31,10 @@ class View extends Component {
|
||||
|
||||
req_body_form(req_body_type,req_body_form){
|
||||
if(req_body_type === 'json'){
|
||||
let h = this.countEnter(this.props.curData.req_body_other);
|
||||
return <div style={{display:this.props.curData.req_body_other?"block":"none"}} className="colBody">
|
||||
<span className="colKey">请求Body:</span>
|
||||
<div id="vreq_body_json" style={{ minHeight: "200px" }}></div>
|
||||
<div id="vreq_body_json" style={{ minHeight: h*16+20 }}></div>
|
||||
</div>
|
||||
|
||||
}else if(req_body_type === 'form'){
|
||||
@ -92,9 +93,10 @@ class View extends Component {
|
||||
}
|
||||
res_body(res_body_type,res_body){
|
||||
if(res_body_type === 'json'){
|
||||
let h = this.countEnter(this.props.curData.req_body_other);
|
||||
return <div style={{display:this.props.curData.res_body?"":"none"}} className="colBody">
|
||||
<span className="colKey">返回Body:</span>
|
||||
<div id="vres_body_json" style={{ minHeight: "200px" }}></div>
|
||||
<div id="vres_body_json" style={{ minHeight: h*16+20 }}></div>
|
||||
</div>
|
||||
}else if(res_body_type === 'raw'){
|
||||
return <div style={{display:this.props.curData.res_body?"":"none"}} className="colBody">
|
||||
@ -135,9 +137,19 @@ class View extends Component {
|
||||
return <Table bordered size="small" pagination = {false} columns= {columns} dataSource = {dataSource} />;
|
||||
}
|
||||
|
||||
|
||||
countEnter(str){
|
||||
let i = 0;
|
||||
let c = 0;
|
||||
if(!str||!str.indexOf) return 0;
|
||||
while(str.indexOf('\n',i)>-1){
|
||||
i = str.indexOf('\n',i) + 2;
|
||||
c++;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
bindAceEditor(){
|
||||
if(this.props.curData.req_body_type === "json"&&this.props.curData.title){
|
||||
// console.log(this.props.curData.req_body_other.indexOf("\n"));
|
||||
mockEditor({
|
||||
container: 'vreq_body_json',
|
||||
data: this.props.curData.req_body_other,
|
||||
|
@ -93,4 +93,9 @@
|
||||
text-indent: 2em;
|
||||
}
|
||||
}
|
||||
// .ace_scroller{
|
||||
// position: relative;
|
||||
// margin-left: 50px;
|
||||
// overflow:visible;
|
||||
// }
|
||||
}
|
@ -51,6 +51,13 @@
|
||||
background-color: #efefef
|
||||
}
|
||||
.interface-list{
|
||||
.cat_switch_hidden{
|
||||
.ant-tree-switcher{
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
a{
|
||||
color: #333
|
||||
}
|
||||
@ -85,7 +92,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.right-content{
|
||||
margin:3px;
|
||||
min-height: 5rem;
|
||||
|
@ -1,3 +1,4 @@
|
||||
import './plugin'
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import App from './Application'
|
||||
|
45
client/plugin.js
Normal file
45
client/plugin.js
Normal file
@ -0,0 +1,45 @@
|
||||
const config = process.env.config;
|
||||
|
||||
/**
|
||||
* type single 只绑定一个监听函数,会返回处理结果
|
||||
* mulit 绑定多个监听函数
|
||||
*
|
||||
*/
|
||||
|
||||
var hooks = {
|
||||
'third_login': {
|
||||
type: 'single',
|
||||
listener: null
|
||||
},
|
||||
'add_interface': {
|
||||
type: 'mulit',
|
||||
listener: []
|
||||
}
|
||||
};
|
||||
|
||||
function bindHook(name, listener) {
|
||||
if (!name) throw new Error('缺少hookname');
|
||||
if (name in hooks === false) {
|
||||
throw new Error('不存在的hookname');
|
||||
}
|
||||
if (hooks[name].type === 'multi') {
|
||||
hooks[name].listener.push(listener);
|
||||
} else {
|
||||
hooks[name].listener = listener;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var yapi = {
|
||||
hooks: hooks,
|
||||
bindHook: bindHook
|
||||
}
|
||||
|
||||
if (config.plugins && Array.isArray(config.plugins)) {
|
||||
config.plugins.forEach(plugin => {
|
||||
let pluginModule = require(`plugins/yapi-plugin-${plugin}/client.js`);
|
||||
pluginModule.call(yapi) ;
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = hooks;
|
@ -1,3 +1,3 @@
|
||||
{
|
||||
"watch": ["server/"]
|
||||
"watch": ["server/", "common/", "plugins"]
|
||||
}
|
5
npm-shrinkwrap.json
generated
5
npm-shrinkwrap.json
generated
@ -15012,6 +15012,11 @@
|
||||
"resolved": "https://repo.corp.qunar.com/artifactory/api/npm/npm-qunar/yallist/-/yallist-2.1.2.tgz",
|
||||
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
|
||||
},
|
||||
"yapi-plugin-qsso": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/yapi-plugin-qsso/-/yapi-plugin-qsso-1.0.2.tgz",
|
||||
"integrity": "sha512-x1LS8R5Vdjep+a93M97v7LcdV+3tupqIOkxxS+uYh+rbYB568BZFEpvfR43L7PcBZcCaOcsCOJEsrw1rcq5rhQ=="
|
||||
},
|
||||
"yargs": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://repo.corp.qunar.com/artifactory/api/npm/npm-qunar/yargs/-/yargs-7.1.0.tgz",
|
||||
|
@ -98,6 +98,7 @@
|
||||
"universal-cookie": "^2.0.8",
|
||||
"url": "^0.11.0",
|
||||
"validate-commit-msg": "^2.12.2",
|
||||
"yapi-plugin-qsso": "^1.0.2",
|
||||
"ykit-config-antd": "^0.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -9,12 +9,14 @@ const bodyParser = require('koa-bodyparser');
|
||||
const router = require('./router.js');
|
||||
const websockify = require('koa-websocket');
|
||||
const websocket = require('./websocket.js');
|
||||
const plugins = require('./plugin.js');
|
||||
|
||||
yapi.connect = dbModule.connect();
|
||||
const app = websockify(new Koa());
|
||||
let indexFile = process.argv[2] === 'dev' ? 'dev.html' : 'index.html';
|
||||
|
||||
|
||||
yapi.connect = dbModule.connect();
|
||||
const app = websockify(new Koa());
|
||||
yapi.app = app;
|
||||
plugins();
|
||||
app.use(mockServer);
|
||||
app.use(bodyParser({multipart: true}));
|
||||
app.use(router.routes());
|
||||
|
@ -109,11 +109,9 @@ class userController extends baseController {
|
||||
}
|
||||
|
||||
async loginByToken(ctx) {
|
||||
let config = this.thirdQunarLogin();
|
||||
let token = ctx.request.body[config.tokenField] || ctx.request.query[config.tokenField];
|
||||
|
||||
//let config = this.thirdQunarLogin();
|
||||
try {
|
||||
let ret = await config.request(token);
|
||||
let ret = await yapi.emitHook('third_login', ctx);
|
||||
let login = await this.handleThirdLogin(ret.email, ret.username);
|
||||
|
||||
if (login === true) {
|
||||
|
59
server/plugin.js
Normal file
59
server/plugin.js
Normal file
@ -0,0 +1,59 @@
|
||||
const yapi = require('./yapi.js');
|
||||
const plugin_path = yapi.path.join(yapi.WEBROOT, 'node_modules')
|
||||
var hooks = {
|
||||
'third_login': {
|
||||
type: 'single',
|
||||
listener: null
|
||||
},
|
||||
'add_interface': {
|
||||
type: 'mulit',
|
||||
listener: []
|
||||
}
|
||||
};
|
||||
|
||||
function bindHook(name, listener){
|
||||
if(!name) throw new Error('缺少hookname');
|
||||
if(name in hooks === false){
|
||||
throw new Error('不存在的hookname');
|
||||
}
|
||||
if(hooks[name].type === 'multi'){
|
||||
hooks[name].listener.push(listener);
|
||||
}else{
|
||||
hooks[name].listener = listener;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function emitHook(name){
|
||||
if(!name) throw new Error('缺少hookname');
|
||||
if(name in hooks === false){
|
||||
throw new Error('不存在的hookname');
|
||||
}
|
||||
|
||||
if(hooks[name] && typeof hooks[name] === 'object'){
|
||||
if(hooks[name].type === 'single' && typeof hooks[name].listener === 'function'){
|
||||
return hooks[name].listener.apply(yapi, Array.prototype.slice.call(arguments, 1));
|
||||
}
|
||||
if(Array.isArray(hooks[name.listener])){
|
||||
hooks[name].listener.forEach(listener=>{
|
||||
listener.apply(yapi, Array.prototype.slice.call(arguments,1))
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
yapi.bindHook = bindHook;
|
||||
yapi.emitHook = emitHook;
|
||||
|
||||
|
||||
module.exports = function(){
|
||||
if(yapi.WEBCONFIG.plugins && Array.isArray(yapi.WEBCONFIG.plugins)){
|
||||
yapi.WEBCONFIG.plugins.forEach(plugin=>{
|
||||
if(!yapi.commons.fileExist(yapi.path.join(plugin_path, 'yapi-plugin-' + plugin + '/server.js'))){
|
||||
throw new Error(`请安装插件(${plugin}), npm install yapi-plugin-${plugin}`)
|
||||
}
|
||||
let pluginModule = require(yapi.path.join(plugin_path, 'yapi-plugin-' + plugin + '/server.js'));
|
||||
pluginModule.apply(yapi)
|
||||
})
|
||||
}
|
||||
}
|
@ -39,6 +39,7 @@ function delInst(m) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let r = {
|
||||
fs: fs,
|
||||
path: path,
|
||||
|
@ -5,15 +5,15 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<title>YAPI-高效、易用、功能强大的api管理平台</title>
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="/image/favicon.png">
|
||||
<link rel="stylesheet" href="http://127.0.0.1:4000/yapi/prd/index@dev.css">
|
||||
<link rel="stylesheet" href="/prd/index.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="yapi" style="height: 100%;"></div>
|
||||
|
||||
<script src="http://127.0.0.1:4000/prd/manifest@dev.js"></script>
|
||||
<script src="http://127.0.0.1:4000/prd/lib2@dev.js"></script>
|
||||
<script src="http://127.0.0.1:4000/prd/lib@dev.js"></script>
|
||||
<script src="http://127.0.0.1:4000/prd/index@dev.js"></script>
|
||||
<script src="/prd/manifest.js"></script>
|
||||
<script src="/prd/lib2.js"></script>
|
||||
<script src="/prd/lib.js"></script>
|
||||
<script src="/prd/index.js"></script>
|
||||
|
||||
|
||||
|
||||
|
96
ykit.js
96
ykit.js
@ -1,12 +1,32 @@
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var AssetsPlugin = require('assets-webpack-plugin')
|
||||
var CompressionPlugin = require('compression-webpack-plugin')
|
||||
var config = require('../config.json');
|
||||
var assetsPluginInstance = new AssetsPlugin({
|
||||
filename: 'static/prd/assets.js',
|
||||
processOutput: function (assets) {
|
||||
return 'window.WEBPACK_ASSETS = ' + JSON.stringify(assets);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
function fileExist (filePath){
|
||||
try {
|
||||
return fs.statSync(filePath).isFile();
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
function initPlugins(){
|
||||
if(config.plugins && Array.isArray(config.plugins)){
|
||||
config.plugins = config.plugins.filter(item=>{
|
||||
return fileExist(path.resolve(__dirname, 'node_modules/yapi-plugin-' + item + '/client.js'))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
initPlugins();
|
||||
|
||||
var compressPlugin = new CompressionPlugin({
|
||||
asset: "[path].gz[query]",
|
||||
@ -81,21 +101,22 @@ function handleCommonsChunk(webpackConfig) {
|
||||
|
||||
|
||||
module.exports = {
|
||||
plugins: [{
|
||||
name: 'antd',
|
||||
options: {
|
||||
modifyQuery: function (defaultQuery) { // 可查看和编辑 defaultQuery
|
||||
defaultQuery.plugins = [];
|
||||
defaultQuery.plugins.push(["transform-runtime", {
|
||||
"polyfill": false,
|
||||
"regenerator": true
|
||||
}]);
|
||||
defaultQuery.plugins.push('transform-decorators-legacy');
|
||||
defaultQuery.plugins.push(["import", { libraryName: "antd"}])
|
||||
return defaultQuery;
|
||||
}
|
||||
}
|
||||
}],
|
||||
// plugins: [{
|
||||
// name: 'antd',
|
||||
// options: {
|
||||
// modifyQuery: function (defaultQuery) { // 可查看和编辑 defaultQuery
|
||||
// defaultQuery.plugins = [];
|
||||
// defaultQuery.plugins.push(["transform-runtime", {
|
||||
// "polyfill": false,
|
||||
// "regenerator": true
|
||||
// }]);
|
||||
// defaultQuery.plugins.push('transform-decorators-legacy');
|
||||
// defaultQuery.plugins.push(["import", { libraryName: "antd"}])
|
||||
// return defaultQuery;
|
||||
// },
|
||||
// exclude: /node_modules(?!\/yapi\-plugin\-)/
|
||||
// }
|
||||
// }],
|
||||
// devtool: 'cheap-source-map',
|
||||
config: function (ykit) {
|
||||
return {
|
||||
@ -119,19 +140,25 @@ module.exports = {
|
||||
}
|
||||
|
||||
baseConfig.plugins.push(new this.webpack.DefinePlugin({
|
||||
'process.env.NODE_ENV': JSON.stringify(ENV_PARAMS)
|
||||
'process.env.NODE_ENV': JSON.stringify(ENV_PARAMS),
|
||||
'process.env.config': JSON.stringify(config)
|
||||
}))
|
||||
|
||||
//初始化配置
|
||||
baseConfig.devtool = 'cheap-module-eval-source-map'
|
||||
baseConfig.context = path.resolve(__dirname, './client');
|
||||
baseConfig.resolve.alias.common = '/common';
|
||||
baseConfig.resolve.alias.plugins = '/node_modules';
|
||||
baseConfig.output.local.path = 'static/prd';
|
||||
baseConfig.output.dev.path = 'static/prd';
|
||||
baseConfig.output.prd.path = 'static/prd';
|
||||
baseConfig.output.prd.publicPath = '';
|
||||
baseConfig.output.prd.filename = '[name]@[chunkhash][ext]'
|
||||
|
||||
//commonsChunk
|
||||
handleCommonsChunk.call(this, baseConfig)
|
||||
handleCommonsChunk.call(this, baseConfig);
|
||||
|
||||
|
||||
baseConfig.module.loaders.push({
|
||||
test: /\.less$/,
|
||||
loader: ykit.ExtractTextPlugin.extract(
|
||||
@ -151,10 +178,39 @@ module.exports = {
|
||||
})
|
||||
baseConfig.module.preLoaders.push({
|
||||
test: /\.(js|jsx)$/,
|
||||
exclude: /node_modules/,
|
||||
loader: "eslint-loader"
|
||||
exclude: /node_modules|plugins/,
|
||||
loader: require.resolve('eslint-loader')
|
||||
});
|
||||
|
||||
var testReg = /\.(js|jsx)$/,
|
||||
exclude = /node_modules(?!\/yapi\-plugin\-)/,
|
||||
query = {
|
||||
cacheDirectory: true,
|
||||
presets: [
|
||||
["es2015", {"loose": true}],
|
||||
'es2017',
|
||||
'stage-0',
|
||||
'stage-1',
|
||||
'stage-2',
|
||||
'react'
|
||||
],
|
||||
plugins: []
|
||||
};
|
||||
query.plugins.push(["transform-runtime", {
|
||||
"polyfill": false,
|
||||
"regenerator": true
|
||||
}]);
|
||||
query.plugins.push('transform-decorators-legacy');
|
||||
query.plugins.push(["import", { libraryName: "antd"}])
|
||||
|
||||
|
||||
baseConfig.module.loaders.push({
|
||||
loader: require.resolve('babel-loader'),
|
||||
test: testReg,
|
||||
exclude: exclude,
|
||||
query: query
|
||||
})
|
||||
|
||||
if (this.env == 'prd') {
|
||||
baseConfig.plugins.push(assetsPluginInstance)
|
||||
baseConfig.plugins.push(compressPlugin)
|
||||
|
Loading…
Reference in New Issue
Block a user