@vindo/cli 0.0.1 → 0.0.2
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/build.js +126 -93
- package/bin/config.js +49 -37
- package/bin/development.js +9 -0
- package/bin/index.js +30 -78
- package/bin/template.js +29 -0
- package/bin/util.js +131 -0
- package/package.json +4 -3
- package/bin/bundle.js +0 -83
- package/bin/reload.js +0 -6
package/bin/build.js
CHANGED
|
@@ -1,137 +1,170 @@
|
|
|
1
1
|
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
2
|
+
const es = require('esbuild')
|
|
3
|
+
const {
|
|
4
|
+
path,
|
|
5
|
+
read,
|
|
6
|
+
exists,
|
|
7
|
+
string,
|
|
8
|
+
unlink,
|
|
9
|
+
makedir,
|
|
10
|
+
resolve,
|
|
11
|
+
readdir,
|
|
12
|
+
promises,
|
|
13
13
|
}
|
|
14
|
+
= require('./util')
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
|
-
*
|
|
18
|
+
* Get basename
|
|
19
|
+
* @param {string} file
|
|
18
20
|
*/
|
|
19
|
-
function
|
|
20
|
-
return path.
|
|
21
|
+
function getname(file) {
|
|
22
|
+
return path.parse(file).name
|
|
21
23
|
}
|
|
22
24
|
|
|
23
|
-
|
|
24
25
|
/**
|
|
25
|
-
*
|
|
26
|
+
* Get imported files
|
|
27
|
+
* @param {object} opt
|
|
28
|
+
* @param {string} data
|
|
26
29
|
*/
|
|
27
|
-
function
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
async function getImports(entry, data) {
|
|
31
|
+
var imp = []
|
|
32
|
+
var matches = data.matchAll(/import\s(.*)\sfrom.*('|"|\/)([a-zA-Z_-]+)('|")/g)
|
|
30
33
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const build_ = /@build/
|
|
41
|
-
|
|
42
|
-
if(path.match(/^node_modules\//)) {
|
|
43
|
-
var absPath = resolve(path, 'index.js')
|
|
44
|
-
|
|
45
|
-
if(!file.exists(absPath)) {
|
|
46
|
-
absPath = resolve(path.concat('.js'))
|
|
47
|
-
}
|
|
48
|
-
return {path: absPath}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if(path.match(build_)) {
|
|
52
|
-
return {
|
|
53
|
-
path: resolve(path.replace(build_, buildPath).concat('.js'))
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
return null
|
|
57
|
-
})
|
|
34
|
+
for(var item of matches) {
|
|
35
|
+
if(/(\.\/|)components\//.test(item[0])) {
|
|
36
|
+
imp.push(`var ${item[1]} = ${item[3]}`)
|
|
37
|
+
}
|
|
38
|
+
else if(/(\.\/)/.test(item[0])) {
|
|
39
|
+
imp.push(item[0].replace(/('|")(\.\/)/, `$1${resolve.dirname(entry)}/`))
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
imp.push(item[0])
|
|
58
43
|
}
|
|
59
44
|
}
|
|
45
|
+
return imp
|
|
60
46
|
}
|
|
61
47
|
|
|
62
48
|
|
|
63
49
|
/**
|
|
64
|
-
*
|
|
65
|
-
* @param {object}
|
|
50
|
+
* Get all codes from components
|
|
51
|
+
* @param {object} opt
|
|
66
52
|
*/
|
|
67
|
-
async function
|
|
68
|
-
var
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
53
|
+
async function getComponents(opt) {
|
|
54
|
+
var files = await readdir(opt.components, {recursive: true})
|
|
55
|
+
var files = files.filter(file => {
|
|
56
|
+
return /\.(tsx|jsx)$/.test(file.name)
|
|
57
|
+
})
|
|
73
58
|
|
|
74
|
-
|
|
75
|
-
const dir_ = conf.entries.split('/')
|
|
59
|
+
var code = []
|
|
76
60
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
imp += `import ${name}_ from '${dir_.slice(1).join('/')}/${name}'\n`
|
|
86
|
-
imp += `export const ${name} = ${name}_\n`
|
|
61
|
+
for(var {name, parentPath} of files) {
|
|
62
|
+
var name = getname(name)
|
|
63
|
+
if(name) {
|
|
64
|
+
var file = path.join(parentPath, name)
|
|
65
|
+
|
|
66
|
+
if(name == 'index') {
|
|
67
|
+
file = parentPath
|
|
68
|
+
name = getname(parentPath)
|
|
87
69
|
}
|
|
70
|
+
code.push(`import ${name} from '${file}'`, `chunk.${name} = ${name}`)
|
|
88
71
|
}
|
|
89
72
|
}
|
|
73
|
+
return code
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Collect components and assemble before building
|
|
79
|
+
*
|
|
80
|
+
* @param {object} opt option
|
|
81
|
+
*/
|
|
82
|
+
async function build(opt) {
|
|
83
|
+
const data = read(opt.entry)
|
|
84
|
+
const temp = read(opt.template)
|
|
90
85
|
|
|
91
|
-
await
|
|
92
|
-
await
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
]
|
|
99
|
-
allowOverwrite: true
|
|
86
|
+
const impo = await getImports(opt.entry, data)
|
|
87
|
+
const comp = await getComponents(opt)
|
|
88
|
+
|
|
89
|
+
const code = string.replace(temp, {
|
|
90
|
+
CHUNK_IMPORTS: comp.join('\n'),
|
|
91
|
+
ENTRY_IMPORTS: impo.join('\n'),
|
|
92
|
+
HEAD_COMPONENT: data.match(/<head.*>((.|\n)*)<\/head>/g)[0],
|
|
93
|
+
BODY_COMPONENT: data.match(/<Provider.*>((.|\n)*)<\/Provider>/g)[0]
|
|
100
94
|
})
|
|
101
95
|
|
|
102
|
-
|
|
96
|
+
await promises.writeFile(opt.chunk, code, {flag: 'w'})
|
|
103
97
|
}
|
|
104
98
|
|
|
105
99
|
|
|
106
100
|
/**
|
|
107
101
|
* Create a bundle file
|
|
108
|
-
*
|
|
109
|
-
* @param {object}
|
|
102
|
+
*
|
|
103
|
+
* @param {object} opt option
|
|
110
104
|
*/
|
|
111
|
-
async function bundle(
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
105
|
+
async function bundle(opt) {
|
|
106
|
+
if(!exists(opt.chunk)) {
|
|
107
|
+
return
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const {metafile} = await es.build({
|
|
111
|
+
...opt.settings,
|
|
112
|
+
metafile: true,
|
|
113
|
+
minify: opt.minify,
|
|
114
|
+
outfile: opt.bundle,
|
|
115
|
+
entryPoints: [opt.chunk],
|
|
116
|
+
entryNames: '[name]-[hash]'
|
|
122
117
|
})
|
|
123
118
|
|
|
124
|
-
|
|
119
|
+
const file = Object.keys(metafile.outputs)[0]
|
|
120
|
+
const data = {
|
|
121
|
+
file,
|
|
122
|
+
hash: file.match(/-(.*).js/)[1],
|
|
123
|
+
bundle: file.match(/.*(\/.*)$/)[1]
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Delete old bundle
|
|
128
|
+
*/
|
|
129
|
+
const manifest = resolve.main(opt.output, 'manifest.json')
|
|
130
|
+
if(exists(manifest)) {
|
|
131
|
+
const files = readdir(resolve.main(opt.output))
|
|
132
|
+
|
|
133
|
+
files.forEach((file) => {
|
|
134
|
+
const matched = file.name.match(/^bundle-([A-Z0-9+]{8})\.js$/)
|
|
135
|
+
if(matched) {
|
|
136
|
+
if(data.hash == matched[1]) {
|
|
137
|
+
return
|
|
138
|
+
}
|
|
139
|
+
unlink(path.resolve(file.parentPath, file.name))
|
|
140
|
+
}
|
|
141
|
+
})
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
await promises.writeFile(manifest, JSON.stringify(data), {flag: 'w'})
|
|
145
|
+
unlink(opt.chunk)
|
|
125
146
|
}
|
|
126
147
|
|
|
127
148
|
|
|
128
149
|
/**
|
|
129
150
|
*
|
|
130
|
-
* @param {object}
|
|
151
|
+
* @param {object} config
|
|
131
152
|
*/
|
|
132
|
-
module.exports = async function
|
|
153
|
+
module.exports = async function(opt) {
|
|
154
|
+
/**
|
|
155
|
+
* Create build directory
|
|
156
|
+
*/
|
|
157
|
+
await makedir(resolve.main(opt.output))
|
|
158
|
+
|
|
159
|
+
opt.entry = resolve.main(opt.entry)
|
|
160
|
+
opt.chunk = resolve.main(opt.output, 'chunk.jsx')
|
|
161
|
+
opt.bundle = resolve.main(opt.output, 'bundle.js')
|
|
162
|
+
opt.template = resolve.dirname(__filename, 'template.js')
|
|
163
|
+
opt.components = resolve.dirname(opt.entry, 'components')
|
|
164
|
+
|
|
133
165
|
try {
|
|
134
|
-
await
|
|
166
|
+
await build(opt)
|
|
167
|
+
await bundle(opt)
|
|
135
168
|
}
|
|
136
169
|
catch(e) {
|
|
137
170
|
console.log(e)
|
package/bin/config.js
CHANGED
|
@@ -1,26 +1,5 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const port = 2001
|
|
5
|
-
const args = {}
|
|
6
|
-
const argv = process.argv
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const vindo = file.read(file.join(process.cwd(), 'vindo.json'))
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
for(var i in argv) {
|
|
13
|
-
const pat = /^([a-z-]+)=/
|
|
14
|
-
|
|
15
|
-
if(i < 2) {
|
|
16
|
-
continue
|
|
17
|
-
}
|
|
18
|
-
var arg = argv[i].split(pat, 3).filter(String)
|
|
19
|
-
|
|
20
|
-
if(arg) {
|
|
21
|
-
args[arg[0].substring(2)] = arg[1] ? arg[1] : true
|
|
22
|
-
}
|
|
23
|
-
}
|
|
1
|
+
const util = require('./util')
|
|
2
|
+
const config = util.use('@vindo/core/lib/config')
|
|
24
3
|
|
|
25
4
|
|
|
26
5
|
module.exports = {
|
|
@@ -28,31 +7,64 @@ module.exports = {
|
|
|
28
7
|
* Development script
|
|
29
8
|
*/
|
|
30
9
|
get devScript() {
|
|
31
|
-
return `http://127.0.0.1:${this.option.port}/
|
|
10
|
+
return `http://127.0.0.1:${this.option.port}/development`
|
|
11
|
+
},
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Vindo config
|
|
15
|
+
*/
|
|
16
|
+
get vindo() {
|
|
17
|
+
|
|
18
|
+
return config.config({
|
|
19
|
+
buildOption: {
|
|
20
|
+
port: 2001,
|
|
21
|
+
minify: true,
|
|
22
|
+
watch: [
|
|
23
|
+
'./src'
|
|
24
|
+
],
|
|
25
|
+
output: './public'
|
|
26
|
+
}
|
|
27
|
+
})
|
|
32
28
|
},
|
|
33
29
|
|
|
34
30
|
/**
|
|
35
31
|
* Build Options
|
|
36
32
|
*/
|
|
37
33
|
get option() {
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
34
|
+
const opt = this.vindo.buildOption
|
|
35
|
+
const args = this.argv()
|
|
36
|
+
|
|
37
|
+
return Object.assign(opt, {
|
|
41
38
|
...args,
|
|
42
|
-
|
|
39
|
+
settings: {
|
|
40
|
+
bundle: true,
|
|
41
|
+
format: 'esm',
|
|
42
|
+
logLevel: 'error',
|
|
43
|
+
allowOverwrite: true,
|
|
44
|
+
},
|
|
45
|
+
output: typeof args.output == 'string' ? args.output : opt.output,
|
|
43
46
|
})
|
|
44
47
|
},
|
|
45
48
|
|
|
46
49
|
/**
|
|
47
|
-
*
|
|
50
|
+
* Get args
|
|
48
51
|
*/
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
argv() {
|
|
53
|
+
const args = {}
|
|
54
|
+
const argv = process.argv
|
|
55
|
+
|
|
56
|
+
for(var i in argv) {
|
|
57
|
+
const pat = /^([a-z-]+)=/
|
|
58
|
+
|
|
59
|
+
if(i < 2) {
|
|
60
|
+
continue
|
|
61
|
+
}
|
|
62
|
+
var arg = argv[i].split(pat, 3).filter(String)
|
|
63
|
+
|
|
64
|
+
if(arg) {
|
|
65
|
+
args[arg[0].substring(2)] = arg[1] ? arg[1] : true
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return args
|
|
57
69
|
}
|
|
58
70
|
}
|
package/bin/index.js
CHANGED
|
@@ -1,78 +1,38 @@
|
|
|
1
1
|
#! /usr/bin/env node
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
const {file} = require('@vindo/utility')
|
|
6
|
-
const {exec, spawn} = require('node:child_process')
|
|
7
|
-
const {watch:watcher} = require('chokidar')
|
|
8
|
-
const {styleText:color} = require('node:util')
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
var evt = {}
|
|
12
|
-
var cwd = process.cwd()
|
|
13
|
-
var child = null
|
|
14
|
-
|
|
15
|
-
|
|
4
|
+
const util = require('./util')
|
|
16
5
|
const build = require('./build')
|
|
17
6
|
const server = require('./server')
|
|
18
|
-
const
|
|
7
|
+
const config = require('./config')
|
|
19
8
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
*/
|
|
24
|
-
process.env.DEV_SERVER = devScript
|
|
25
|
-
process.env.DEV_SERVER_PORT = option.port
|
|
9
|
+
const {watch} = require('chokidar')
|
|
10
|
+
const kill = require('tree-kill')
|
|
11
|
+
const {exec, spawn} = require('node:child_process')
|
|
26
12
|
|
|
27
13
|
|
|
28
|
-
|
|
29
|
-
* Add event
|
|
30
|
-
*/
|
|
31
|
-
function on(name, cb) {
|
|
32
|
-
evt[name] = cb
|
|
33
|
-
}
|
|
14
|
+
const {log, read, events, colors, resolve} = util
|
|
34
15
|
|
|
35
|
-
/**
|
|
36
|
-
* Call the event
|
|
37
|
-
*/
|
|
38
|
-
function emit(name, ...args) {
|
|
39
|
-
if(evt[name]) {
|
|
40
|
-
evt[name].call(...args)
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
16
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
*/
|
|
47
|
-
function log(name, text) {
|
|
48
|
-
if(name) {
|
|
49
|
-
return console.log(color(name, text.toString().trim()))
|
|
50
|
-
}
|
|
51
|
-
return console.log(text)
|
|
52
|
-
}
|
|
17
|
+
var child = null
|
|
18
|
+
var option = config.option
|
|
53
19
|
|
|
54
20
|
/**
|
|
55
|
-
*
|
|
21
|
+
* Set to global environment
|
|
56
22
|
*/
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
for(var item of Object.values(pattern)) {
|
|
61
|
-
text = text.replace(item.pat, color(item.color, item.text))
|
|
62
|
-
}
|
|
63
|
-
return text.trim()
|
|
64
|
-
}
|
|
23
|
+
process.env.DEV_SERVER = config.devScript
|
|
24
|
+
process.env.DEV_SERVER_PORT = config.option.port
|
|
65
25
|
|
|
66
26
|
|
|
67
27
|
/**
|
|
68
28
|
*
|
|
69
29
|
*/
|
|
70
|
-
async function
|
|
30
|
+
async function watcher(dirs, cb) {
|
|
71
31
|
try {
|
|
72
32
|
if(!Array.isArray(dirs)) {
|
|
73
33
|
throw TypeError('Expected a value of type `Array` but received a `String`.')
|
|
74
34
|
}
|
|
75
|
-
|
|
35
|
+
watch(dirs, {
|
|
76
36
|
// ignored: (path, stats) => stats?.isFile() && !path.endsWith('.js'), // only watch js files
|
|
77
37
|
persistent: true
|
|
78
38
|
})
|
|
@@ -90,8 +50,8 @@ async function watch(dirs, cb) {
|
|
|
90
50
|
function execute() {
|
|
91
51
|
var i = 0
|
|
92
52
|
var sp = exec(option.execute, {
|
|
93
|
-
|
|
94
|
-
|
|
53
|
+
env: process.env,
|
|
54
|
+
cwd: process.cwd(),
|
|
95
55
|
})
|
|
96
56
|
log('green', `[vindo] Running ${option.execute}`)
|
|
97
57
|
|
|
@@ -105,9 +65,9 @@ function execute() {
|
|
|
105
65
|
* It means the server runs successfully.
|
|
106
66
|
*/
|
|
107
67
|
if(i == 1) {
|
|
108
|
-
emit('change')
|
|
68
|
+
events.emit('change')
|
|
109
69
|
}
|
|
110
|
-
console.log(
|
|
70
|
+
console.log(colors.colorize(data))
|
|
111
71
|
})
|
|
112
72
|
|
|
113
73
|
/**
|
|
@@ -118,11 +78,11 @@ function execute() {
|
|
|
118
78
|
|
|
119
79
|
for(var i in text) {
|
|
120
80
|
if(i == 0) {
|
|
121
|
-
text[0] =
|
|
81
|
+
text[0] = colors.set('red', text[0])
|
|
122
82
|
}
|
|
123
|
-
text[i] = text[i].replace(/(at.*)/,
|
|
124
|
-
text[i] = text[i].replace(/:\s('.*')/,
|
|
125
|
-
text[i] = text[i].replace(/\s(-?\d+)/,
|
|
83
|
+
text[i] = text[i].replace(/(at.*)/, colors.set('gray', '$1'))
|
|
84
|
+
text[i] = text[i].replace(/:\s('.*')/, colors.set('green', ': $1'))
|
|
85
|
+
text[i] = text[i].replace(/\s(-?\d+)/, colors.set('yellow', ' $1'))
|
|
126
86
|
}
|
|
127
87
|
log(null, text.join('\r\n'))
|
|
128
88
|
})
|
|
@@ -138,16 +98,10 @@ function restart(event) {
|
|
|
138
98
|
log('green', `[vindo] Rebuilding...`)
|
|
139
99
|
log('green', `[vindo] Restarting server...`)
|
|
140
100
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}
|
|
101
|
+
build(option)
|
|
102
|
+
|
|
144
103
|
if(child) {
|
|
145
|
-
|
|
146
|
-
spawn('taskkill', ['/pid', child.pid, '/f', '/t'])
|
|
147
|
-
}
|
|
148
|
-
else {
|
|
149
|
-
child.kill('SIGINT')
|
|
150
|
-
}
|
|
104
|
+
kill(child.pid)
|
|
151
105
|
}
|
|
152
106
|
child = execute()
|
|
153
107
|
}
|
|
@@ -156,19 +110,19 @@ function restart(event) {
|
|
|
156
110
|
/**
|
|
157
111
|
* Create server
|
|
158
112
|
*/
|
|
159
|
-
const http = server((req, res) => {
|
|
113
|
+
const http = server(async (req, res) => {
|
|
160
114
|
if(req.isStream()) {
|
|
161
|
-
on('change', () => {
|
|
115
|
+
events.on('change', () => {
|
|
162
116
|
res.write(`data: {changed: true}\n\n`)
|
|
163
117
|
})
|
|
164
118
|
}
|
|
165
119
|
|
|
166
|
-
if(req.is('
|
|
120
|
+
if(req.is('development')) {
|
|
167
121
|
res.headers({
|
|
168
122
|
'Content-Type':
|
|
169
123
|
'application/javascript'
|
|
170
124
|
})
|
|
171
|
-
res.end(
|
|
125
|
+
res.end(await read(resolve.curr('development.js')))
|
|
172
126
|
}
|
|
173
127
|
})
|
|
174
128
|
|
|
@@ -177,15 +131,13 @@ const http = server((req, res) => {
|
|
|
177
131
|
http.listen(option.port, function() {
|
|
178
132
|
child = execute()
|
|
179
133
|
|
|
180
|
-
|
|
181
|
-
build(option)
|
|
182
|
-
}
|
|
134
|
+
build(option)
|
|
183
135
|
|
|
184
136
|
if(option.watch) {
|
|
185
137
|
log('yellow', '[vindo] v0.0.1')
|
|
186
138
|
log('yellow', `[vindo] Watching at ${option.watch}`)
|
|
187
139
|
log('yellow', `[vindo] Building at ${option.output}`)
|
|
188
140
|
|
|
189
|
-
|
|
141
|
+
watcher(option.watch, restart)
|
|
190
142
|
}
|
|
191
143
|
})
|
package/bin/template.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
|
|
2
|
+
import React from 'react'
|
|
3
|
+
import client from '@vindo/react/client'
|
|
4
|
+
|
|
5
|
+
const chunk = {}
|
|
6
|
+
|
|
7
|
+
{CHUNK_IMPORTS}
|
|
8
|
+
{ENTRY_IMPORTS}
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
if(chunk.head || chunk.body) {
|
|
12
|
+
throw new SyntaxError(`Component name '${chunk.head ? 'head' : 'body'}' is a reserved name for SSR client components.`)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
chunk.head = function head(meta) {
|
|
16
|
+
const {props:{children}} = React.cloneElement((
|
|
17
|
+
{HEAD_COMPONENT}
|
|
18
|
+
))
|
|
19
|
+
return children
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
chunk.body = function body(props) {
|
|
23
|
+
const {props:{children}, type} = React.cloneElement((
|
|
24
|
+
{BODY_COMPONENT}
|
|
25
|
+
))
|
|
26
|
+
return type({children, ...props})
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
client.render(document, chunk)
|
package/bin/util.js
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
const {styleText:color} = require('util')
|
|
2
|
+
const {file, events, string} = require('@vindo/utility')
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
module.exports = exports = Object.create(file, {
|
|
7
|
+
string: {value: string},
|
|
8
|
+
events: {value: events},
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Set colors
|
|
13
|
+
*/
|
|
14
|
+
const colors = {
|
|
15
|
+
set(name, text) {
|
|
16
|
+
return color(name, text)
|
|
17
|
+
},
|
|
18
|
+
colorize(text) {
|
|
19
|
+
var text = text.toString()
|
|
20
|
+
/**
|
|
21
|
+
* Console log color pattern
|
|
22
|
+
*/
|
|
23
|
+
const pattern = {
|
|
24
|
+
ref: {color: 'cyan', pat: /(<.*>)/g, text: '$1'},
|
|
25
|
+
string: {color: 'green', pat: /('.*')/g, text: '$1'},
|
|
26
|
+
symbol: {color: 'green', pat: /(Symbol\(.*\))/g, text: '$1'},
|
|
27
|
+
number: {color: 'yellow', pat: /:\s(-?\d+)/g, text: ': $1'},
|
|
28
|
+
boolean: {color: 'yellow', pat: /(false|true)/g, text: '$1'},
|
|
29
|
+
function: {color: 'cyan', pat: /\[(.*)\]/g, text: '[$1]'},
|
|
30
|
+
undefined: {color: 'gray', pat: /(undefined)/g, text: '$1'},
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
for(var item of Object.values(pattern)) {
|
|
34
|
+
text = text.replace(item.pat, color(item.color, item.text))
|
|
35
|
+
}
|
|
36
|
+
return text.trim()
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function replace(string, data = {}) {
|
|
41
|
+
if(Object.keys(data).length == 0) {
|
|
42
|
+
return string
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function repl(v) {
|
|
46
|
+
var value = data[v.match(/([a-z_]+)/g)]
|
|
47
|
+
if(value) {
|
|
48
|
+
return value
|
|
49
|
+
}
|
|
50
|
+
return ''
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if(string) {
|
|
54
|
+
var patt = string.match(/(\{[a-z_]+\})/g)
|
|
55
|
+
if(patt) {
|
|
56
|
+
return string.replace(new RegExp(patt.join('|'), 'g'), repl)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return string
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Resolve path
|
|
64
|
+
*/
|
|
65
|
+
const resolve = {
|
|
66
|
+
main(...args) {
|
|
67
|
+
return file.path.resolve(process.cwd(), ...args)
|
|
68
|
+
},
|
|
69
|
+
curr(...args) {
|
|
70
|
+
return file.path.resolve(__dirname, ...args)
|
|
71
|
+
},
|
|
72
|
+
dirname(path, ...args) {
|
|
73
|
+
return resolve.main(file.path.dirname(path), ...args)
|
|
74
|
+
},
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Log with colors
|
|
79
|
+
*/
|
|
80
|
+
function log(name, text) {
|
|
81
|
+
if(name) {
|
|
82
|
+
return console.log(color(name, text.toString().trim()))
|
|
83
|
+
}
|
|
84
|
+
return console.log(text)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Use module
|
|
89
|
+
*/
|
|
90
|
+
function use(name) {
|
|
91
|
+
return require(resolve.main('node_modules', name))
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
*
|
|
96
|
+
* File system utilities
|
|
97
|
+
*
|
|
98
|
+
*/
|
|
99
|
+
async function copy(dest) {
|
|
100
|
+
const src = resolve.curr(
|
|
101
|
+
path.basename(dest)
|
|
102
|
+
)
|
|
103
|
+
return await file.promises.cp(src, dest)
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
*
|
|
107
|
+
*/
|
|
108
|
+
async function makedir(path) {
|
|
109
|
+
try {
|
|
110
|
+
await file.promises.mkdir(path)
|
|
111
|
+
}
|
|
112
|
+
catch(e) {}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
*
|
|
116
|
+
*/
|
|
117
|
+
async function unlink(path) {
|
|
118
|
+
try {
|
|
119
|
+
await file.promises.unlink(path)
|
|
120
|
+
}
|
|
121
|
+
catch(e) {}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
exports.log = log
|
|
126
|
+
exports.use = use
|
|
127
|
+
exports.copy = copy
|
|
128
|
+
exports.unlink = unlink
|
|
129
|
+
exports.makedir = makedir
|
|
130
|
+
exports.colors = colors
|
|
131
|
+
exports.resolve = resolve
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vindo/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "Command line for running vindo server and react SSR for development.",
|
|
5
5
|
"main": "bin/index.js",
|
|
6
6
|
"publishConfig": {
|
|
@@ -24,8 +24,9 @@
|
|
|
24
24
|
},
|
|
25
25
|
"homepage": "https://github.com/rmindo/vindo/tree/main/packages/cli",
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@vindo/utility": "^0.0.
|
|
27
|
+
"@vindo/utility": "^0.0.7",
|
|
28
28
|
"chokidar": "^4.0.3",
|
|
29
|
-
"esbuild": "^0.25.4"
|
|
29
|
+
"esbuild": "^0.25.4",
|
|
30
|
+
"tree-kill": "^1.2.2"
|
|
30
31
|
}
|
|
31
32
|
}
|
package/bin/bundle.js
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import * as chunk from '@build/chunk'
|
|
2
|
-
|
|
3
|
-
import ReactDom from 'node_modules/react-dom/client'
|
|
4
|
-
import {
|
|
5
|
-
createElement as element,
|
|
6
|
-
isValidElement as isValid,
|
|
7
|
-
}
|
|
8
|
-
from 'node_modules/react'
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const url = new URL(document.scripts.bundle.src)
|
|
12
|
-
|
|
13
|
-
const hash = url.searchParams.get('hash')
|
|
14
|
-
const port = url.searchParams.get('port')
|
|
15
|
-
const name = url.searchParams.get('name')
|
|
16
|
-
|
|
17
|
-
const get = fetch(
|
|
18
|
-
hash.concat('?',
|
|
19
|
-
(new URLSearchParams({name})).toString()
|
|
20
|
-
)
|
|
21
|
-
)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Set element type
|
|
26
|
-
*/
|
|
27
|
-
function children(data) {
|
|
28
|
-
if(isValid(data)) {
|
|
29
|
-
return data
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
if(!Array.isArray(data)) {
|
|
33
|
-
data = [data]
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return data.map((item, key) => {
|
|
37
|
-
const props = item.props
|
|
38
|
-
|
|
39
|
-
if(!props) {
|
|
40
|
-
return item
|
|
41
|
-
}
|
|
42
|
-
if(props.children) {
|
|
43
|
-
props.children = children(props.children)
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if(!item.type) {
|
|
47
|
-
var name = props.name
|
|
48
|
-
if(!name) {
|
|
49
|
-
throw ReferenceError('Component name is not defined.')
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const comp = chunk[name.toLowerCase()]
|
|
53
|
-
if(comp) {
|
|
54
|
-
return element.bind(null, comp)({...props, key})
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
return {...item, key, $$typeof: Symbol.for('react.transitional.element')}
|
|
58
|
-
})
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Get the props in the backend
|
|
64
|
-
*/
|
|
65
|
-
async function map(res) {
|
|
66
|
-
var data = await res.json()
|
|
67
|
-
if(data) {
|
|
68
|
-
ReactDom.hydrateRoot(document.getElementById('root'), children(data))
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
get.then(map)
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Live reload for development
|
|
75
|
-
*/
|
|
76
|
-
function reload({origin}) {
|
|
77
|
-
if(port) {
|
|
78
|
-
(new EventSource(origin.replace(/\d+/, port))).onmessage = function() {
|
|
79
|
-
location.reload()
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
reload(location)
|