@oceans/oceans-cli
Version:
work for oceans
247 lines (210 loc) • 7.6 kB
JavaScript
const path = require('path');
const fs = require('fs');
const base32 = require('base32');
const { exec } = require('child_process');
const chalk = require('chalk');
const util = require('util');
const readFile = util.promisify(fs.readFile);
const writeFile = util.promisify(fs.writeFile);
const mkdir = util.promisify(fs.mkdir);
const { execCommand } = require('../common/utils');
const createAppId = () => {
let millisecond = new Date().getTime() + '';
const len = millisecond.length;
millisecond = millisecond.slice(0, len - 3);
return 'oc_' + base32.encode(millisecond);
};
const getPrefix = (applicationId) => {
return `/${applicationId}/`
}
const _initPackageJSON = async (projectPath) => {
//修改scripts内容
console.log('=== project modules package.json start update ===');
const packageJSONPath = path.join(projectPath, 'package.json');
const data = await readFile(packageJSONPath, { encoding: 'utf8', flag: 'r' });
const watchCss = [
'npm run',
'build-css && node-sass-chokidar',
'--include-path ./src --include-path ./node_modules src/ -o src/ --watch --recursive'
].join(' ');
const temp = `"scripts": {
"build-css": "node-sass-chokidar --include-path ./src --include-path ./node_modules src/ -o src/",
"watch-css": "${watchCss}",
"start-js": "react-scripts start",
"dev": "npm-run-all -p watch-css start-js",
"start": "npm-run-all -p watch-css start-js",
"build-js": "react-scripts build",
"build": "npm-run-all build-css build-js",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},`;
const homepage = getPrefix();
const replaceContent = `},\n "homepage": "${ homepage }"\n}\n`;
let content = data.replace(/"scripts":[^}]*},/, temp);
content = content.replace(/\}\n\}\n/, replaceContent);
await writeFile(packageJSONPath, content);
console.log('=== project modules package.json update finish ===');
}
const _initIndexJSFile = async (projectPath) => {
console.log('=== project index.js start update ===');
const targetPath = path.join(projectPath, 'src', 'index.js');
const temp = `import React from 'react';
import ReactDOM from 'react-dom';
import 'normalize.css/normalize.css'
import '@blueprintjs/icons/lib/css/blueprint-icons.css'
import '@blueprintjs/core/lib/css/blueprint.css'
import '@oceans/core/lib/css/index.css'
import '@oceans/core/lib/css/react-index.css'
import './index.css';
import Router from './router/router';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(<Router />, document.getElementById('root'));
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: http://bit.ly/CRA-PWA
serviceWorker.unregister();
`;
await writeFile(targetPath, temp, {encoding: 'utf8', flag: 'w'});
console.log('=== project index.js update finish ===');
return 'ok';
};
const _addRouterSupport = async (projectPath) => {
console.log('=== project add router support start update ===');
const routerFolder = path.join(projectPath, 'src', 'router');
const targetPath = path.join(routerFolder, 'router.js');
const routerFileContent = `import React from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import { HOME_PAGE } from "../config";
import App from '../App';
import Demo from '../App';
// import NoMatch from './nomatch';
export default class Routers extends React.Component {
render() {
return (
<Router>
<Switch>
<Route path={HOME_PAGE} exact component={App} />
<Route path={HOME_PAGE + '/demo'} component={Demo} />
{/*<Route path="*" component={NoMatch} />*/}
</Switch>
</Router>
);
}
}
`;
await mkdir(routerFolder);
await writeFile(targetPath, routerFileContent);
console.log('=== project add router support finish ===');
};
const _addProjectConfig = async (projectPath, applicationId) => {
console.log('=== project add config start update ===');
const targetPath = path.join(projectPath, 'src', 'config.js');
const prefix = getPrefix();
const routerFileContent = `export const HOME_PAGE = '${prefix}'
export const APP_ID = '${applicationId}'
`;
await writeFile(targetPath, routerFileContent);
console.log('=== project add config finish ===');
}
const _installModule = async (projectPath) => {
const modules = [
'@blueprintjs/core',
'@blueprintjs/datetime',
'@blueprintjs/select',
'@blueprintjs/table',
'@oceans/core',
'axios',
'node-sass',
'node-sass-chokidar',
'qs',
'react-router',
'react-router-dom',
'npm-run-all'
].join(' ');
const devModules = [
'npm-run-all'
].join(' ');
console.log('start init project modules : ', modules, projectPath);
await execCommand(`cd ${projectPath} && npm install --save ${modules} && npm install --save-dev ${devModules}`)
console.log('=== project modules finish ===');
};
const _initAppJSFile = async (projectPath) => {
console.log('=== project app.js start update ===');
const targetPath = path.join(projectPath, 'src', 'App.js');
const temp = `import React, { Component } from 'react';
import './App.css';
import { Classes } from '@blueprintjs/core'
import { Api } from '@oceans/core'
import { APP_ID } from './config'
class App extends Component {
constructor (props) {
super(props)
this.state = {}
}
componentDidMount() {
const connectInstance = new Api.Connect()
connectInstance.listen(APP_ID, () => {
console.log('Application connected!!@_@')
// Window resize event
// const windowInstance = new Api.Window();
// windowInstance.onWindowResize((rs) => {
// console.log('onWindowResize ===>', rs);
// })
// Get Account Permission
// const account = new Api.Account()
// account.auth((data) => {
// if (data.status === '0') {
// const nickname = data.result.nickName
// this.setState({ nickname })
// }
// console.log('account auth callback --->', data);
// })
})
}
render() {
return (
<div className={[Classes.DARK, 'App'].join(' ')}>
<div style={{
height: '100px',
padding: '100px',
textAlign: 'center'
}}>
Welcome to Oceans!
</div>
</div>
);
}
}
export default App;
`;
await writeFile(targetPath, temp, { encoding: 'utf8' });
console.log('=== project app.js update finish ===');
}
const _initEnvFile = async (projectPath) => {
const content = `INLINE_RUNTIME_CHUNK=false
GENERATE_SOURCEMAP=false
SKIP_PREFLIGHT_CHECK=true
`;
const targetPath = path.join(projectPath, '.env');
await writeFile(targetPath, content);
console.log('=== env file finish ===');
}
module.exports = async () => {
const appName = process.argv[2] || '';
if (!appName) {
console.log(chalk.yellow('[warning]: Application name is necessary, please enter it.'));
return false;
}
const projectPath = path.join(__dirname, appName);
const applicationId = createAppId();
await execCommand(`npx create-react-app ${appName}`);
await _initPackageJSON(projectPath);
await _initAppJSFile(projectPath);
await _initIndexJSFile(projectPath);
await _addRouterSupport(projectPath);
await _addProjectConfig(projectPath, applicationId);
await _installModule(projectPath);
await _initEnvFile(projectPath);
console.log('=== project has been created ===');
process.exit(0);
}