@oceans/cli
Version:
work for oceans
251 lines (213 loc) • 7.63 kB
JavaScript
const path = require('path')
const fs = require('fs')
const base32 = require('base32')
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, appId) => {
// 修改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(appId)
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(applicationId)
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 (appName) => {
if (!appName) {
console.log(chalk.yellow('[warning]: Application name is necessary, please enter it.'))
return false
}
const projectPath = path.join(process.cwd(), appName)
const applicationId = createAppId()
console.log('projcet path ===>', projectPath)
try {
await execCommand(`npx create-react-app ${appName}`)
await _initPackageJSON(projectPath, applicationId)
await _initAppJSFile(projectPath)
await _initIndexJSFile(projectPath)
await _addRouterSupport(projectPath)
await _addProjectConfig(projectPath, applicationId)
await _initEnvFile(projectPath)
await _installModule(projectPath)
console.log('=== project has been created ===')
} catch (e) {
console.log('error capture: ', e)
}
process.exit(0)
}