1 | const browserify = require('browserify');
|
2 | const fse = require('fs-extra');
|
3 | const path = require('path');
|
4 | const watchify = require('watchify');
|
5 | const sourceMaps = require('source-map-support');
|
6 | const livereload = require('livereload');
|
7 |
|
8 | const utils = require('./lib/utils.js');
|
9 | const transform = require('./lib/transforms');
|
10 | const codeTransform = require('./lib/transforms/code.js');
|
11 | const renderer = require('./lib/renderer.js');
|
12 | const getOpts = require('./lib/getopts.js');
|
13 | const log = require('./lib/utils/log.js');
|
14 | const Less = require('./lib/utils/less.js');
|
15 |
|
16 |
|
17 | const startApp = async (opts)=>{
|
18 | if(!opts.app){
|
19 | console.log(`A server app was not specified, dev server will not run. Set 'main' in your package.json to enable this.`);
|
20 | return;
|
21 | }
|
22 | const nodemon = require('nodemon');
|
23 | return new Promise((resolve, reject)=>{
|
24 | let deps = [];
|
25 | browserify({ require : opts.app, bundleExternal : false,
|
26 | postFilter : (id, filepath, pkg)=>{
|
27 | if(id.indexOf(opts.paths.build) !== -1) return false;
|
28 | deps.push(filepath);
|
29 | return true;
|
30 | }
|
31 | })
|
32 | .transform((file)=>transform(file, opts, [codeTransform]), {global : true})
|
33 | .bundle((err)=>err?reject(err):resolve(deps));
|
34 | })
|
35 | .then((appDeps)=>{
|
36 | return nodemon({ script:opts.app, watch:appDeps, delay:2 })
|
37 | .on('restart', (files)=>log.restartServer(opts.app, files));
|
38 | })
|
39 | };
|
40 |
|
41 | const devEntryPoint = async (entryPoint, Opts)=>{
|
42 | let opts = Object.assign({
|
43 | entry : {
|
44 | name : path.basename(entryPoint).split('.')[0],
|
45 | dir : path.dirname(entryPoint)
|
46 | }
|
47 | }, Opts);
|
48 |
|
49 | if(!fse.pathExistsSync(path.resolve(process.cwd(), opts.paths.build, opts.entry.name))){
|
50 | throw log.notBuilt(opts.entry);
|
51 | }
|
52 |
|
53 | const bundler = browserify({
|
54 | cache : {},
|
55 | packageCache : {},
|
56 | debug : true,
|
57 | standalone : opts.entry.name,
|
58 | paths : opts.shared,
|
59 | plugin : [watchify],
|
60 | ignoreMissing : true,
|
61 | postFilter : (id, filepath, pkg)=>{
|
62 | return utils.shouldBundle(filepath, id, opts);
|
63 | },
|
64 | })
|
65 | .require(entryPoint)
|
66 | .transform((file)=>transform(file, opts), {global : true})
|
67 | .on('update', (files)=>{
|
68 | log.rebundle(opts.entry, files);
|
69 | bundle();
|
70 | });
|
71 |
|
72 | let lastBundle;
|
73 | const bundle = async ()=>{
|
74 | const logEnd = log.buildEntryPoint(opts.entry);
|
75 | await utils.bundle(bundler).then((code)=>{
|
76 | if(lastBundle != code) fse.writeFileSync(paths.code, code);
|
77 | lastBundle = code;
|
78 | });
|
79 | await Less.compile(opts).then((css)=>fse.writeFile(paths.style, css));
|
80 | logEnd();
|
81 | };
|
82 |
|
83 | const paths = utils.paths(opts.paths, opts.entry.name);
|
84 | await renderer(Object.assign(opts, {dev : true}));
|
85 | await bundle();
|
86 | };
|
87 |
|
88 | module.exports = async (entryPoints, opts)=>{
|
89 | opts = getOpts(opts, entryPoints);
|
90 | log.beginDev(opts);
|
91 | sourceMaps.install();
|
92 | await opts.targets.reduce((flow, ep)=>flow.then(()=>devEntryPoint(ep, opts)), Promise.resolve());
|
93 | await livereload.createServer().watch(opts.paths.build);
|
94 | return await startApp(opts);
|
95 | };
|