jjb-cmd 1.0.14 → 1.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/command.js CHANGED
@@ -5,11 +5,11 @@ const cliScripts = require('../src/cli.pull.js');
5
5
  const cliScripts2 = require('../src/cli.pull2.js');
6
6
  const cliScripts3 = require('../src/cli.install/index.js');
7
7
  const cliScripts4 = require('../src/cli.rm-rf.js');
8
+ const cliScripts6 = require('../src/cli.init');
8
9
  const MergeScripts = require('../src/cli.merge.js');
9
10
 
10
11
  commander.command('v').description('-- 查看版本').action(() => {
11
- const package = JSON.parse(fs.readFileSync(path.resolve('./package.json'), 'utf-8').toString());
12
- console.log(`当前版本 ${package.version}`)
12
+ console.log('当前版本 v1.0.12');
13
13
  });
14
14
 
15
15
  commander.command('help').description('-- 帮助').action(() => {
@@ -36,6 +36,11 @@ commander.command('pull2 -- <文件夹名称必填。>').description('-- 文件
36
36
  cliScripts2(res);
37
37
  });
38
38
 
39
+ // pull 命令
40
+ commander.command('init').description('-- 初始化项目').action(res => {
41
+ cliScripts6(res);
42
+ });
43
+
39
44
  // rm-rf 命令
40
45
  commander.command('rm-rf').description('-- 删除全部').action(res => {
41
46
  cliScripts4(res);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jjb-cmd",
3
- "version": "1.0.14",
3
+ "version": "1.0.16",
4
4
  "description": "jjb脚手架工具",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -14,6 +14,7 @@
14
14
  "dependencies": {
15
15
  "commander": "1.3.2",
16
16
  "compressing": "^1.5.1",
17
- "request": "2.88.2"
17
+ "request": "2.88.2",
18
+ "single-line-log": "1.1.2"
18
19
  }
19
20
  }
@@ -1,7 +1,13 @@
1
+ /**
2
+ * @author XiWell
3
+ * @version 2.0.1
4
+ * @description 基于QianKun框架的APP注册文件,请勿修改!
5
+ */
6
+
7
+ import 'moment/locale/zh-cn';
1
8
  import dva from 'dva';
2
- import ReactDOM from 'react-dom';
3
9
  import { createBrowserHistory } from 'history';
4
- import 'antd/dist/antd.less';
10
+ import { unmountComponentAtNode } from 'react-dom';
5
11
 
6
12
  /**
7
13
  * @description 注册app
@@ -9,31 +15,30 @@ import 'antd/dist/antd.less';
9
15
  * @returns {{unmount: Function, mount: Function, bootstrap: Function}}
10
16
  */
11
17
  export const registerApplication = (selector = '#root') => {
12
- const createHistory = createBrowserHistory();
18
+ try {
19
+ const app = dva({ history: createBrowserHistory() });
20
+ require('./models').automaticModels(app);
21
+ app.router(config => require('./router').AutomaticRouter(config));
13
22
 
14
- const app = dva({ history: createHistory });
15
- require('./models').automaticModels(app);
23
+ const render = () => app.start(selector);
24
+ if (!window.__POWERED_BY_QIANKUN__) render();
16
25
 
17
- app.router(config => require('./router').AutomaticRouter({
18
- ...config,
19
- basename: process.env.app.basename
20
- }));
21
-
22
- const render = () => app.start(selector);
23
-
24
- if (!window.__POWERED_BY_QIANKUN__) {
25
- render();
26
+ return {
27
+ mount: () => render(),
28
+ unmount: props => {
29
+ if (window.__POWERED_BY_QIANKUN__) {
30
+ const { container } = props;
31
+ const element = container
32
+ ? container.querySelector(selector)
33
+ : document.querySelector(selector);
34
+ unmountComponentAtNode(element);
35
+ } else {
36
+ console.error('卸载APP失败,原因:', '当前环境非QianKun');
37
+ }
38
+ },
39
+ bootstrap: props => props
40
+ };
41
+ } catch (e) {
42
+ console.error('注册APP失败,原因:', e.message);
26
43
  }
27
-
28
- return {
29
- mount: () => render(),
30
- unmount: props => {
31
- const { container } = props;
32
- const element = container
33
- ? container.querySelector('#root')
34
- : document.querySelector('#root');
35
- ReactDOM.unmountComponentAtNode(element);
36
- },
37
- bootstrap: props => props
38
- };
39
44
  };
@@ -1,3 +1,9 @@
1
+ /**
2
+ * @author XiWell
3
+ * @version 1.0.1
4
+ * @description 基于QianKun框架的APP注册文件,请勿修改!
5
+ */
6
+
1
7
  import dva from 'dva';
2
8
  import ReactDOM from 'react-dom';
3
9
  import { createBrowserHistory } from 'history';
@@ -1,100 +1,177 @@
1
+ /**
2
+ * @author XiWell
3
+ * @version 2.0.1
4
+ * @description 此文件为dva/router自动化文件,无需配置路由,请勿修改!
5
+ */
6
+
1
7
  import React from 'react';
2
- import { ConfigProvider, Result } from 'antd';
3
- import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
8
+ import { ConfigProvider } from 'antd';
9
+ import { Route, Router, Switch } from 'dva/router';
4
10
 
5
11
  /**
6
- * @description react路由扫描器
7
- * @param props {{app: object}}
12
+ * @description 是否匹配页面
13
+ * @param name {string}
14
+ * @return {{stat: boolean, param: null}}
8
15
  */
9
- function ReactRouterScanner (props) {
10
- const paths = require.context('~/pages', true, /\.(jsx|js)$/).keys();
11
- const symbolByEntry = 'Entry_index.js';
12
- const symbolByContainer = 'Container_index.js';
16
+ function isParamPage (name) {
17
+ const result = {
18
+ stat: false,
19
+ param: null
20
+ };
21
+ if (/^_/.test(name)) {
22
+ const match = name.replace(/\.js$/, '').split(/_/).filter(item => !!item && item !== 'index');
23
+ result.stat = match.length !== 0;
24
+ result.param = match.join('_');
25
+ }
26
+ return result;
27
+ }
28
+
29
+ /**
30
+ * @description 首字母转小写
31
+ * @param value {string}
32
+ * @return {string}
33
+ */
34
+ function toLowerCase (value) {
35
+ return `${value[ 0 ].toLowerCase()}${value.substring(1)}`;
36
+ }
13
37
 
14
- /**
15
- * @description 路由处理
16
- * @param path {string}
17
- * @return string
18
- */
19
- function routeHandle (path) {
20
- return `/${path.replace(/\/index.js$/, '').split(/\//).map(a => {
21
- a = a.replace(a[ 0 ], a[ 0 ].toLowerCase());
22
- return a;
23
- }).map(a => {
24
- if (/^[a-zA-Z]+_[a-zA-Z]+$/.test(a)) {
25
- return `:${a.split(/_/).join('')}`;
38
+ /**
39
+ * @description 获取初始路由集合
40
+ * @return {{path: string, file: string}[]}
41
+ */
42
+ function getRoutes () {
43
+ const routes = [];
44
+ const fileList = require.context('~/pages', true, /\.js$/).keys();
45
+ for (let i = 0; i < fileList.length; i++) {
46
+ const route = {};
47
+ const file = fileList[ i ];
48
+ const fileSplit = file.split(/\//);
49
+ const fileName = fileSplit[ fileSplit.length - 1 ];
50
+ const {
51
+ stat: fileState,
52
+ param: fileParam
53
+ } = isParamPage(fileName);
54
+ const filePathArray = fileSplit.slice(1, fileSplit.length - 1).map(item => {
55
+ const {
56
+ stat,
57
+ param
58
+ } = isParamPage(item);
59
+ return stat
60
+ ? `:${param}`
61
+ : item;
62
+ });
63
+ if (fileState || fileName === 'index.js') {
64
+ if (filePathArray.length) {
65
+ const path = filePathArray.map(item => toLowerCase(item)).join('/');
66
+ route.path = (`/${path}${fileState
67
+ ? `/:${fileParam}`
68
+ : ''}`);
69
+ } else {
70
+ route.path = `/${fileState
71
+ ? `:${fileParam}`
72
+ : ''}`;
26
73
  }
27
- return a;
28
- }).join('/')}`;
74
+ route.file = file;
75
+ routes.push(route);
76
+ }
29
77
  }
78
+ return routes.reverse();
79
+ }
30
80
 
31
- const routerMap = paths.map(path => {
32
- const pure = path.replace(/^\.\//, '');
33
- return {
34
- path: pure === 'index.js'
35
- ? '/'
36
- : pure === symbolByContainer
37
- ? '/container'
38
- : path === symbolByEntry
39
- ? '/entry'
40
- : routeHandle(pure),
41
- suffix: 'index.js',
42
- component: require(`~/pages/${pure}`).default,
43
- componentName: pure.replace(/\//g, '_')
44
- };
45
- });
81
+ /**
82
+ * @typedef {object} TreeRoutes
83
+ * @property {string} path
84
+ * @property {string} file
85
+ * @property {TreeRoutes[]} children
86
+ */
46
87
 
47
- const Main = routerMap.find(item => item.componentName === 'index.js');
48
- const Entry = routerMap.find(item => item.componentName === symbolByEntry);
49
- const Container = routerMap.find(item => item.componentName === symbolByContainer);
50
- const ChildrenRoute = routerMap.filter(item => item.componentName.match(new RegExp('Container_')) && item.path !== '/container');
51
- const ContainerComponent = Container
52
- ? Container.component
53
- : null;
88
+ /**
89
+ * @description 优化tree
90
+ * @param tree {TreeRoutes[]}
91
+ * @return {TreeRoutes[]}
92
+ */
93
+ function optimizationTree (tree = []) {
94
+ function deep (array = []) {
95
+ const inner = [];
96
+ for (let i = 0; i < array.length; i++) {
97
+ const item = array[ i ];
98
+ const newItem = {};
99
+ newItem.children = item.children.length
100
+ ? deep(item.children)
101
+ : [];
102
+ newItem.path = item.path;
103
+ newItem.Component = require(`~/pages${item.file.replace(/^\./, '')}`).default;
104
+ inner.push(newItem);
105
+ }
106
+ return inner;
107
+ }
108
+
109
+ return deep(tree);
110
+ }
111
+
112
+ /**
113
+ * @description 将初始routes转换为tree结构
114
+ * @param routes {{path: string, file: string}[]}
115
+ * @return {TreeRoutes[]}
116
+ */
117
+ function treeRoutes (routes = []) {
118
+ const dataSource = [];
119
+ const indexItem = routes.find(item => item.path === '/');
120
+ for (let i = 0; i < routes.length; i++) {
121
+ const route = routes[ i ];
122
+ if (route.path === '/') {
123
+ continue;
124
+ }
125
+ const pathArray = route.path.split('/').slice(1);
126
+ route.parentFile = pathArray.length === 1
127
+ ? null
128
+ : routes[ i - 1 ].file;
129
+ dataSource.push(route);
130
+ }
131
+ if (indexItem) {
132
+ Object.assign(indexItem, { parentFile: null });
133
+ dataSource.push(indexItem);
134
+ }
135
+ let len;
136
+ for (let i = 0; len = dataSource.length, i < len; i++) {
137
+ const arrTemp = [];
138
+ for (let j = 0; j < dataSource.length; j++) {
139
+ if (dataSource[ i ].file === dataSource[ j ].parentFile) {
140
+ dataSource[ i ].children = arrTemp;
141
+ arrTemp.push(dataSource[ j ]);
142
+ } else {
143
+ dataSource[ i ].children = arrTemp;
144
+ }
145
+ }
146
+ }
147
+ const result = [];
148
+ for (let i = 0; i < dataSource.length; i++) {
149
+ if (dataSource[ i ].parentFile === null) {
150
+ result.push(dataSource[ i ]);
151
+ }
152
+ }
153
+ return optimizationTree(result);
154
+ }
155
+
156
+ function RenderRouter (routes = [], inProps = {}) {
54
157
  return (
55
- <Router
56
- basename={window.__POWERED_BY_QIANKUN__
57
- ? props.basename
58
- : '/'}
59
- >
158
+ <Router history={inProps.history}>
60
159
  <Switch>
61
- {Main && (
62
- <Route
63
- exact
64
- path={Main.path}
65
- component={Main.component}
66
- />
67
- )}
68
- {Entry && (
69
- <Route
70
- exact
71
- path={Entry.path}
72
- component={Entry.component}
73
- />
74
- )}
75
- {Container && (
160
+ {routes.map(({
161
+ path,
162
+ children,
163
+ Component
164
+ }, index) => (
76
165
  <Route
77
- path={Container.path}
78
- render={$props => (
79
- <ContainerComponent {...$props}>
80
- <Switch>
81
- {ChildrenRoute.map((route, key) => (
82
- <Route
83
- exact
84
- key={key}
85
- path={route.path}
86
- component={route.component}
87
- />
88
- ))}
89
- </Switch>
90
- </ContainerComponent>
166
+ key={index}
167
+ path={`${(process.env.app || {}).basename || ''}${path}`}
168
+ render={props => (
169
+ <Component {...props}>
170
+ {RenderRouter(children, inProps)}
171
+ </Component>
91
172
  )}
92
173
  />
93
- )}
94
- <Route
95
- path="*"
96
- component={() => <Result title="非常抱歉您访问的地址暂时无法显示,请确认后再试!" />}
97
- />
174
+ ))}
98
175
  </Switch>
99
176
  </Router>
100
177
  );
@@ -103,22 +180,19 @@ function ReactRouterScanner (props) {
103
180
  /**
104
181
  * @description 自动化路由组件
105
182
  * @param app {object}
106
- * @param basename {string}
183
+ * @param history {history}
107
184
  * @return {JSX.Element}
108
185
  */
109
186
  export const AutomaticRouter = ({
110
187
  app,
111
- basename
188
+ history
112
189
  }) => {
113
190
  return (
114
- <ConfigProvider
115
- locale={require('antd/lib/locale/zh_CN').default}
116
- prefixCls={require('../../../../package.json').antPrefix || 'ant'}
117
- >
118
- <ReactRouterScanner
119
- app={app}
120
- basename={basename}
121
- />
191
+ <ConfigProvider locale={require('antd/lib/locale/zh_CN').default}>
192
+ {RenderRouter(treeRoutes(getRoutes()), {
193
+ app,
194
+ history
195
+ })}
122
196
  </ConfigProvider>
123
197
  );
124
198
  };
@@ -1,3 +1,9 @@
1
+ /**
2
+ * @author XiWell
3
+ * @version 1.0.1
4
+ * @description 此文件为dva/router自动化文件,无需配置路由,请勿修改!
5
+ */
6
+
1
7
  import React from 'react';
2
8
  import { ConfigProvider } from 'antd';
3
9
  import { Route, Router, Switch } from 'dva/router';
@@ -0,0 +1,37 @@
1
+ {
2
+ "projectType": "micro-spa",
3
+ "installTarget": "node_modules",
4
+ "installResources": [
5
+ "common",
6
+ "react-admin-component"
7
+ ],
8
+ "environment": {
9
+ "development": {
10
+ "API_HOSE": ""
11
+ },
12
+ "test": {
13
+ "API_HOSE": ""
14
+ },
15
+ "release": {
16
+ "API_HOSE": ""
17
+ },
18
+ "production": {
19
+ "API_HOSE": ""
20
+ }
21
+ },
22
+ "contextInject": {},
23
+ "windowInject": {
24
+ "title": "JJB Micro APP"
25
+ },
26
+ "server": {
27
+ "port": "8088",
28
+ "host": "127.0.0.1"
29
+ },
30
+ "framework": {
31
+ "antd": {
32
+ "link-color": "red",
33
+ "primary-color": "red",
34
+ "border-radius-base": "2px"
35
+ }
36
+ }
37
+ }
@@ -0,0 +1,11 @@
1
+ const { hasEnvironment } = require('./utils');
2
+
3
+ if (!hasEnvironment()) {
4
+ throw Error('jjb.script[build]: 启动build需要提供NODE_ENV变量,请确认你所运行的脚本是否正确?');
5
+ }
6
+
7
+ require('webpack')(require('./config')('production').webpack).run(err => {
8
+ if (!err) {
9
+ console.log('项目打包完成!');
10
+ }
11
+ });