UNPKG

6.81 kBJavaScriptView Raw
1#! /usr/bin/env node
2'use strict'
3
4const log = require('@rola/log')
5
6/**
7 * fresh console
8 */
9console.clear()
10
11log({ actions: [ 'initializing' ] })
12
13const fs = require('fs-extra')
14const path = require('path')
15const exit = require('exit')
16const onExit = require('exit-hook')
17const React = require('react')
18
19const rolaCompiler = require('@rola/compiler')
20const rolaStatic = require('@rola/static')
21const { getModule, createDocument } = require('@rola/util')
22
23const createServer = require('./util/createServer.js')
24const createConfig = require('./util/createConfig.js')
25
26const cwd = process.cwd()
27
28const pkg = require('./package.json')
29const userPkg = require(path.join(cwd, './package.json'))
30
31const PORT = process.env.PORT || 3000
32const prog = require('commander')
33 .version(pkg.version)
34
35process.env.ROLA_VERSION = pkg.version
36
37let clientEntry
38let serverEntry
39
40try {
41 clientEntry = require.resolve(path.join(cwd, 'client.js'))
42} catch (e) {}
43
44try {
45 serverEntry = require.resolve(path.join(cwd, 'server.js'))
46} catch (e) {}
47
48/**
49 * clean up outdir
50 */
51fs.removeSync(path.join(cwd, 'build'))
52
53/**
54 * remove temp dir on exit
55 */
56onExit(() => {
57 fs.removeSync(path.join(cwd, '.rola'))
58})
59
60let server
61
62function serve () {
63 if (!server) {
64 server = createServer({
65 file: path.join(cwd, '/build/server.js'),
66 port: PORT
67 })
68
69 server.init()
70
71 log({ server: [ PORT ] })
72
73 onExit(() => {
74 server && server.close()
75 })
76 }
77}
78
79function createGenerator (config, plugins) {
80 const generator = rolaStatic({
81 env: config.env,
82 alias: config.alias,
83 presets: config.presets,
84 plugins
85 })
86
87 generator.on('rendered', pages => {
88 log({ static: pages })
89 })
90 generator.on('warn', e => {
91 log(state => ({
92 warn: state.warn.concat(e)
93 }))
94 })
95 generator.on('error', e => {
96 log(state => ({
97 error: state.error.concat(e)
98 }))
99 })
100
101 return generator
102}
103
104function createServerProps ({ presets }) {
105 const tags = createDocument({
106 context: {
107 version: userPkg.version
108 },
109 plugins: presets
110 })
111
112 const props = {
113 context: {
114 version: userPkg.version
115 },
116 tags
117 }
118
119 fs.outputFileSync(
120 path.join(cwd, '.rola', 'props.js'),
121 `module.exports = ${JSON.stringify(props, null, ' ')}`
122 )
123}
124
125prog
126 .command('build')
127 .action(async () => {
128 log({ actions: [ 'build' ] })
129
130 const config = await getModule(path.join(cwd, 'rola.config.js'), path.join(cwd, '.rola'))
131 const plugins = await getModule(path.join(cwd, 'rola.plugins.js'), path.join(cwd, '.rola')).default
132
133 for (let key in (config.env || {})) {
134 process.env[key] = config.env[key]
135 }
136
137 const configs = []
138
139 if (clientEntry) configs.push(createConfig({
140 entry: clientEntry,
141 env: config.env,
142 alias: config.alias,
143 presets: config.presets
144 }))
145
146 if (serverEntry) configs.push(createConfig({
147 entry: serverEntry,
148 env: config.env,
149 alias: config.alias,
150 presets: config.presets
151 }))
152
153 createServerProps({
154 presets: [
155 ...config.presets,
156 (clientEntry ? {
157 createDocument ({ context }) {
158 return {
159 body: `<script src='/client.js?v${context.version}'></script>`
160 }
161 }
162 } : {})
163 ]
164 })
165
166 async function done () {
167 /**
168 * for api requests, if needed
169 */
170 if (serverEntry) serve()
171
172 await createGenerator(config, plugins).render('/static', '/build/assets')
173
174 exit()
175 }
176
177 if (configs.length) {
178 let allstats = []
179 const compiler = rolaCompiler(configs)
180
181 compiler.on('error', e => {
182 log(state => ({
183 error: state.error.concat(e)
184 }))
185 })
186
187 compiler.on('warn', e => {
188 log(state => ({
189 warn: state.warn.concat(e)
190 }))
191 })
192
193 compiler.on('stats', async stats => {
194 stats.map(_stats => {
195 const server = _stats.assets.reduce((bool, asset) => {
196 if (/server/.test(asset.name)) bool = true
197 return bool
198 }, false)
199
200 if (server) {
201 allstats[1] = _stats
202 } else {
203 allstats[0] = _stats
204 }
205 })
206
207 log({
208 actions: [],
209 stats: allstats
210 })
211
212 done()
213 })
214
215 compiler.build()
216 } else {
217 done()
218 }
219 })
220
221prog
222 .command('watch')
223 .action(async () => {
224 log({ actions: [ 'watch' ] })
225
226 const config = await getModule(path.join(cwd, 'rola.config.js'), path.join(cwd, '.rola'))
227 const plugins = await getModule(path.join(cwd, 'rola.plugins.js'), path.join(cwd, '.rola')).default
228
229 for (let key in (config.env || {})) {
230 process.env[key] = config.env[key]
231 }
232
233 let compiled = false
234 const configs = []
235
236 if (clientEntry) configs.push(createConfig({
237 entry: clientEntry,
238 env: config.env,
239 alias: config.alias,
240 banner: require('./util/clientReloader.js')(PORT),
241 presets: config.presets
242 }))
243
244 if (serverEntry) configs.push(createConfig({
245 entry: serverEntry,
246 env: config.env,
247 alias: config.alias,
248 presets: config.presets
249 }))
250
251 let allstats = []
252
253 createServerProps({
254 presets: [
255 ...config.presets,
256 (clientEntry ? {
257 createDocument ({ context }) {
258 return {
259 body: `<script src='/client.js?v${context.version}'></script>`
260 }
261 }
262 } : {})
263 ]
264 })
265
266 if (configs.length) {
267 const compiler = rolaCompiler(configs)
268
269 compiler.on('error', e => {
270 log(state => ({
271 error: state.error.concat(e)
272 }))
273 })
274
275 compiler.on('warn', e => {
276 log(state => ({
277 warn: state.warn.concat(e)
278 }))
279 })
280
281 compiler.on('stats', stats => {
282 stats.map(_stats => {
283 const isServer = _stats.assets.reduce((bool, asset) => {
284 if (/server/.test(asset.name)) bool = true
285 return bool
286 }, false)
287
288 if (isServer) {
289 allstats[1] = _stats
290 } else {
291 allstats[0] = _stats
292 }
293 })
294
295 server && server.update()
296
297 serve()
298
299 if (!compiled) {
300 createGenerator(config, plugins).watch('/static', '/build/assets')
301
302 compiled = true
303 }
304
305 /**
306 * reset logs
307 */
308 log({
309 error: [],
310 warn: [],
311 log: [],
312 stats: allstats
313 })
314 })
315
316 compiler.watch()
317 } else {
318 serve()
319 createGenerator(config, plugins).watch('/static', '/build/assets')
320 }
321 })
322
323if (!process.argv.slice(2).length) {
324 prog.outputHelp(txt => {
325 console.log(txt)
326 exit()
327 })
328} else {
329 prog.parse(process.argv)
330}
331
332