Skip to content

Commit 8dab386

Browse files
committed
refactor: make webpack version app
1 parent d4b09bd commit 8dab386

23 files changed

+4387
-279
lines changed

.gitignore

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
.DS_Store
2-
**/node_modules/**
3-
/dist/
2+
node_modules/
3+
/app/dist/
44
npm-debug.log*
55
yarn-debug.log*
66
yarn-error.log*
@@ -14,7 +14,4 @@ selenium-debug.log
1414
*.suo
1515
*.ntvs*
1616
*.njsproj
17-
*.sln
18-
19-
static/config.json
20-
prod/static/config.json
17+
*.sln

app/assets/logo.png

6.97 KB
Loading

app/config/webpack.config.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
require('../src/Global')
2+
module.exports = () => {
3+
return {
4+
target: 'node',
5+
entry: ['babel-polyfill', pathResolve(appRoot, 'src/App.js')],
6+
output: {
7+
path: outputPath,
8+
filename: `${projectConfig.name}/app.js`,
9+
},
10+
resolve: {
11+
extensions: ['.js', '.json'],
12+
modules: [
13+
appRoot,
14+
pathResolve('src'),
15+
'node_modules',
16+
],
17+
alias: {
18+
'src': pathResolve('src'),
19+
},
20+
},
21+
module: {
22+
rules: [
23+
{
24+
test: /\.js$/,
25+
use: {
26+
loader: 'babel-loader',
27+
options: {
28+
presets: ['@babel/preset-env'],
29+
},
30+
},
31+
},
32+
],
33+
},
34+
plugins: [],
35+
}
36+
}

app/config/webpack.dev.config.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
const baseConfig = require('./webpack.config')
2+
const merge = require('webpack-merge')
3+
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
4+
5+
module.exports = () => {
6+
return merge(baseConfig(), {
7+
plugins: [
8+
new UglifyJsPlugin({
9+
uglifyOptions: {
10+
compress: {
11+
warnings: false
12+
}
13+
},
14+
sourceMap: true,
15+
parallel: true
16+
}),
17+
],
18+
})
19+
}

app/config/webpack.test.config.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
const baseConfig = require('./webpack.config')
2+
const merge = require('webpack-merge')
3+
4+
module.exports = () => {
5+
return merge(baseConfig(), {
6+
devtool: '#inline-source-map',
7+
})
8+
}

app/copyfile/.gitkeep

Whitespace-only changes.

app/package.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"name": "nodejs-webpack",
3+
"version": "1.0.0",
4+
"main": "index.js",
5+
"author": "Ciao Chung <[email protected]>",
6+
"license": "MIT",
7+
"scripts": {
8+
"unit": "node node_modules/mocha-webpack/bin/mocha-webpack test/unit/**/*.js --webpack-config config/webpack.test.config.js",
9+
"unit:single": "node node_modules/mocha-webpack/bin/mocha-webpack --webpack-config config/webpack.test.config.js",
10+
"dev": "node runner/dev.js; node dist/**/app.js",
11+
"start": "node dist/**/app.js",
12+
"prod": "node runner/dev.js --prod"
13+
},
14+
"devDependencies": {
15+
"@babel/core": "^7.2.0",
16+
"@babel/preset-env": "^7.2.0",
17+
"babel-loader": "^8.0.4",
18+
"babel-polyfill": "^6.26.0",
19+
"mocha": "^5.2.0",
20+
"mocha-webpack": "^1.1.0",
21+
"node-notifier": "^5.3.0",
22+
"ora": "^3.0.0",
23+
"shelljs": "^0.8.3",
24+
"uglifyjs-webpack-plugin": "1.2.7",
25+
"webpack": "3.11.0",
26+
"webpack-merge": "^4.1.5"
27+
},
28+
"dependencies": {
29+
"axios": "^0.18.0",
30+
"chalk": "^2.4.1",
31+
"cron": "^1.6.0",
32+
"moment": "^2.22.2",
33+
"nodemailer": "^5.1.1",
34+
"yargs-parser": "^11.1.1"
35+
}
36+
}

app/runner/dev.js

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
require('../src/Global')
2+
const { existsSync } = require('fs')
3+
const asyncWebpackConfig = require('../config/webpack.config')
4+
const webpack = require('webpack')
5+
const spinner = require('ora')('Start Build App')
6+
7+
class dev {
8+
constructor() {
9+
this.start()
10+
}
11+
12+
async start() {
13+
this.seconds = 0
14+
clearInterval(this.interval)
15+
this.interval = setInterval(() => this.seconds++, 1000)
16+
await this.build()
17+
}
18+
19+
async build() {
20+
notify('Start Build App')
21+
22+
if(existsSync(outputPath)) {
23+
await execAsync(`rm -rf ./*`, { cwd: outputPath })
24+
}
25+
26+
spinner.start()
27+
await this.webpackBuild()
28+
29+
if(args.prod == true) {
30+
await this.production()
31+
}
32+
33+
log(`Spent ${this.seconds} seconds`, 'green')
34+
clearInterval(this.interval)
35+
}
36+
37+
async production() {
38+
const distFolderPath = pathResolve(outputPath, projectConfig.name)
39+
const productionAppPath = pathResolve(productionPath, projectConfig.name)
40+
const copyfileFolderPath = pathResolve(appRoot, 'copyfile')
41+
const readmeFilePath = pathResolve(projectRoot, 'README.md')
42+
43+
await execAsync(`rm -rf ${productionAppPath}`)
44+
mkdir('-p', productionAppPath)
45+
await execAsync(`cp ${readmeFilePath} ./`, { cwd: productionAppPath })
46+
try {
47+
await execAsync(`cp -r ${copyfileFolderPath}/* ./`, { cwd: productionAppPath })
48+
} catch(error) {
49+
log(error, 'yellow')
50+
}
51+
await execAsync(`cp -r ${distFolderPath}/* ./`, { cwd: productionAppPath })
52+
}
53+
54+
webpackBuild() {
55+
return new Promise((resolve) => {
56+
webpack(asyncWebpackConfig(), (error, stats) => {
57+
spinner.stop()
58+
if(!error) {
59+
log('Build Success')
60+
notify('Build Success')
61+
}
62+
63+
else {
64+
log(`Build Fail: ${error}`, 'red')
65+
notify(`Build Fail: ${error}`)
66+
}
67+
68+
resolve()
69+
})
70+
})
71+
}
72+
}
73+
74+
module.exports = new dev()

app/runner/test.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
require('../src/Global')
2+
const asyncWebpackConfig = require('../config/webpack.test.config')
3+
const webpack = require('webpack')
4+
const spinner = require('ora')('Start Build App')
5+
6+
class dev {
7+
constructor() {
8+
this.start()
9+
}
10+
11+
async start() {
12+
this.startWebpack()
13+
}
14+
15+
startWebpack() {
16+
return new Promise((resolve) => {
17+
webpack(asyncWebpackConfig(), (error, stats) => {
18+
spinner.stop()
19+
if(!error) {
20+
log('Build Success')
21+
notify('Build Success')
22+
}
23+
24+
else {
25+
log(`Build Fail: ${error}`, 'red')
26+
notify(`Build Fail: ${error}`)
27+
}
28+
29+
resolve()
30+
})
31+
})
32+
}
33+
}
34+
35+
module.exports = new dev()

app/src/App.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import 'Global'
2+
import { CronJob } from 'cron'
3+
import Runner from 'Modules/Runner'
4+
import { readFileSync } from 'fs'
5+
class App {
6+
constructor() {
7+
this.init()
8+
}
9+
10+
async init() {
11+
try {
12+
global.config = JSON.parse(readFileSync(args.config, 'utf8'))
13+
} catch (error) {
14+
process.exit()
15+
}
16+
this.runner = Runner(config)
17+
this.start()
18+
}
19+
20+
async start() {
21+
console.log(chalk.cyan(`App start... \t ${now()}`))
22+
for(const jobName in config.jobs) {
23+
const jobConfig = config.jobs[jobName]
24+
this.setupSchedule(jobName, jobConfig)
25+
26+
if(jobConfig.runAtStart) this.startJob(jobName, jobConfig)
27+
}
28+
}
29+
30+
setupSchedule(jobName, jobConfig) {
31+
if(!Array.isArray(jobConfig.schedule)) {
32+
const job = new CronJob(jobConfig.schedule, () => this.startJob(jobName, jobConfig))
33+
job.start()
34+
return
35+
}
36+
37+
for(const schedule of jobConfig.schedule) {
38+
const job = new CronJob(schedule, () => this.startJob(jobName, jobConfig))
39+
job.start()
40+
}
41+
}
42+
43+
/**
44+
* log style(white, red, green, yellow, cyan, magenta)
45+
*/
46+
log(content, style = 'cyan') {
47+
console.log(chalk[`${style}Bright`](content)+chalk.whiteBright(`\t at ${now()}`))
48+
}
49+
50+
now() {
51+
return moment(new Date).format('YYYY-MM-DD HH:mm:ss')
52+
}
53+
54+
async startJob(jobName, jobConfig) {
55+
log(`[Cron Service] Runner execute ${jobConfig.name} \t\tat ${now()}`)
56+
this.runner.execute(jobName, jobConfig)
57+
}
58+
}
59+
60+
new App()

0 commit comments

Comments
 (0)