mikemorris 已修改 1 month ago. 還原成這個修訂版本
3 files changed, 0 insertions, 0 deletions
jade-watcher.js 重命名為 jade-compiler.js
檔案名稱與重新命名前相同
javascript-watcher.js 重命名為 javascript-compiler.js
檔案名稱與重新命名前相同
sass-watcher.js 重命名為 sass-compiler.js
檔案名稱與重新命名前相同
mikemorris 已修改 1 month ago. 還原成這個修訂版本
7 files changed, 9 insertions, 335 deletions
assets-watcher.js (檔案已刪除)
| @@ -1,140 +0,0 @@ | |||
| 1 | - | import chokidar from 'chokidar'; | |
| 2 | - | import fs from 'fs' | |
| 3 | - | import fse from 'fs-extra'; | |
| 4 | - | import child_process from 'child_process'; | |
| 5 | - | ||
| 6 | - | // ==================================================================== | |
| 7 | - | // | | |
| 8 | - | // ==================================================================== | |
| 9 | - | function log(message) { | |
| 10 | - | const options = { | |
| 11 | - | encoding: "utf-8", | |
| 12 | - | flag: "a+", | |
| 13 | - | }; | |
| 14 | - | const datetime = new Date().toISOString() | |
| 15 | - | message = `[${datetime}] ${message}\n` | |
| 16 | - | fse.outputFileSync('/logs/builder/assets.log', message, options); | |
| 17 | - | console.log(message) | |
| 18 | - | } | |
| 19 | - | ||
| 20 | - | // ==================================================================== | |
| 21 | - | // | | |
| 22 | - | // ==================================================================== | |
| 23 | - | function copyAllIntoWWW(paths) { | |
| 24 | - | return new Promise((resolve, reject) => { | |
| 25 | - | for(const path of paths) { | |
| 26 | - | log(path) | |
| 27 | - | if (!fs.existsSync(path)) { | |
| 28 | - | log(`Directory does not exist in project: ${path}`) | |
| 29 | - | continue; | |
| 30 | - | } | |
| 31 | - | ||
| 32 | - | var publicPath = path | |
| 33 | - | publicPath = publicPath.replace('/app','/www') | |
| 34 | - | try { | |
| 35 | - | child_process.execSync(`mkdir -p ${publicPath} & cp -rf ${path}/* ${publicPath}`); | |
| 36 | - | log(`Done copying: ${path}`) | |
| 37 | - | } catch (err) { | |
| 38 | - | console.error(err) | |
| 39 | - | } | |
| 40 | - | } | |
| 41 | - | }); | |
| 42 | - | } | |
| 43 | - | ||
| 44 | - | // ==================================================================== | |
| 45 | - | // | | |
| 46 | - | // ==================================================================== | |
| 47 | - | function copyIntoWWW(path) { | |
| 48 | - | ||
| 49 | - | // Do not compile inside .delete folders | |
| 50 | - | if (path.includes(".delete")) { | |
| 51 | - | return | |
| 52 | - | } | |
| 53 | - | ||
| 54 | - | log(path); | |
| 55 | - | ||
| 56 | - | var publicPath = path | |
| 57 | - | publicPath = publicPath.replace('/app','/www') | |
| 58 | - | ||
| 59 | - | try { | |
| 60 | - | child_process.execSync(`cp -rf ${path} ${publicPath}`); | |
| 61 | - | log(`Done copying: ${path}`) | |
| 62 | - | } catch (err) { | |
| 63 | - | console.error(err) | |
| 64 | - | } | |
| 65 | - | } | |
| 66 | - | ||
| 67 | - | // ==================================================================== | |
| 68 | - | // | | |
| 69 | - | // ==================================================================== | |
| 70 | - | function deleteFromWWW(path) { | |
| 71 | - | ||
| 72 | - | // Do not compile inside .delete folders | |
| 73 | - | if (path.includes(".delete")) { | |
| 74 | - | return | |
| 75 | - | } | |
| 76 | - | ||
| 77 | - | log(path); | |
| 78 | - | ||
| 79 | - | var publicPath = path | |
| 80 | - | publicPath = publicPath.replace('/app','/www') | |
| 81 | - | ||
| 82 | - | try { | |
| 83 | - | child_process.execSync(`rm -rf ${path} ${publicPath}`); | |
| 84 | - | log(`Done deleting: ${path}`) | |
| 85 | - | } catch (err) { | |
| 86 | - | console.error(err) | |
| 87 | - | } | |
| 88 | - | } | |
| 89 | - | ||
| 90 | - | ||
| 91 | - | // ==================================================================== | |
| 92 | - | // | | |
| 93 | - | // ==================================================================== | |
| 94 | - | function startWatcher(watchFolders) { | |
| 95 | - | // https://github.com/paulmillr/chokidar | |
| 96 | - | const options = { | |
| 97 | - | awaitFinish: true, | |
| 98 | - | ignoreInitial: true, | |
| 99 | - | usePolling: true, | |
| 100 | - | interval: 100, | |
| 101 | - | depth: 5 | |
| 102 | - | } | |
| 103 | - | ||
| 104 | - | const watcher = chokidar.watch(watchFolders, options).on('all', (event, path) => { | |
| 105 | - | log(event, path); | |
| 106 | - | }); | |
| 107 | - | ||
| 108 | - | watcher | |
| 109 | - | .on('add', path => copyIntoWWW(path)) | |
| 110 | - | .on('addDir', path => copyIntoWWW(path)) | |
| 111 | - | .on('change', path => copyIntoWWW(path)) | |
| 112 | - | .on('unlink', path => deleteFromWWW(path)) | |
| 113 | - | .on('unlinkDir', path => deleteFromWWW(path)); | |
| 114 | - | ||
| 115 | - | watcher | |
| 116 | - | .on('ready', () => log('********** Watch is running **********')); | |
| 117 | - | } | |
| 118 | - | ||
| 119 | - | ||
| 120 | - | // ==================================================================== | |
| 121 | - | // | MAIN | |
| 122 | - | // ==================================================================== | |
| 123 | - | async function go() { | |
| 124 | - | const watchFolders = [ | |
| 125 | - | '/app/css', | |
| 126 | - | '/app/docs', | |
| 127 | - | '/app/fonts', | |
| 128 | - | '/app/images', | |
| 129 | - | '/app/libs', | |
| 130 | - | '/app/lib' | |
| 131 | - | ] | |
| 132 | - | if (process.argv[2] == 'recompile') { | |
| 133 | - | await copyAllIntoWWW(watchFolders) | |
| 134 | - | startWatcher(watchFolders); | |
| 135 | - | } else { | |
| 136 | - | startWatcher(watchFolders); | |
| 137 | - | } | |
| 138 | - | } | |
| 139 | - | ||
| 140 | - | go() | |
builder-init.sh (檔案已刪除)
| @@ -1,23 +0,0 @@ | |||
| 1 | - | #!/bin/bash | |
| 2 | - | CANARY_FILE=/app/.provisioning/builder-rebuild | |
| 3 | - | ||
| 4 | - | if [ ! -f "$CANARY_FILE" ] ; then | |
| 5 | - | echo "Initialization incomplete! Running Builder Rebulid..." | |
| 6 | - | cd /opt/builder && bash ./clean-and-build.sh & | |
| 7 | - | mkdir -p /app/.provisioning && date +%F_%T >> /app/.provisioning/builder-rebuild | |
| 8 | - | else | |
| 9 | - | ||
| 10 | - | ln -sf /app/docs /www | |
| 11 | - | ln -sf /app/fonts /www | |
| 12 | - | ln -sf /app/images /www | |
| 13 | - | ln -sf /app/libs /www | |
| 14 | - | ln -sf /app/lib /www | |
| 15 | - | ||
| 16 | - | pm2 delete all | |
| 17 | - | pm2 start /opt/builder/sass-watcher.js | |
| 18 | - | pm2 start /opt/builder/javascript-watcher.js | |
| 19 | - | pm2 start /opt/builder/jade-watcher.js | |
| 20 | - | # pm2 start /opt/builder/pug-watcher.js | |
| 21 | - | # pm2 start /opt/builder/assets-watcher.js | |
| 22 | - | ||
| 23 | - | fi | |
clean-and-build.sh (檔案已刪除)
| @@ -1,16 +0,0 @@ | |||
| 1 | - | #!/bin/bash | |
| 2 | - | pm2 stop all | |
| 3 | - | ||
| 4 | - | ln -sf /app/docs /www | |
| 5 | - | ln -sf /app/fonts /www | |
| 6 | - | ln -sf /app/images /www | |
| 7 | - | ln -sf /app/libs /www | |
| 8 | - | ln -sf /app/lib /www | |
| 9 | - | ||
| 10 | - | # PM2 Style | |
| 11 | - | pm2 delete all | |
| 12 | - | pm2 start /opt/builder/sass-watcher.js -- recompile | |
| 13 | - | pm2 start /opt/builder/javascript-watcher.js -- recompile | |
| 14 | - | pm2 start /opt/builder/jade-watcher.js -- recompile | |
| 15 | - | # pm2 start /opt/builder/pug-watcher.js -- recompile | |
| 16 | - | # pm2 start /opt/builder/assets-watcher.js -- recompile | |
jade-watcher.js
| @@ -213,9 +213,11 @@ function startWatcher() { | |||
| 213 | 213 | // | MAIN | |
| 214 | 214 | // ==================================================================== | |
| 215 | 215 | async function go() { | |
| 216 | - | if (process.argv[2] == 'recompile') { | |
| 216 | + | if (process.argv[2] == 'compile-and-watch') { | |
| 217 | 217 | await compileAll('/app/views/**/*.jade'); | |
| 218 | 218 | startWatcher(); | |
| 219 | + | } else if(process.argv[2] == 'compile-only') { | |
| 220 | + | await compileAll('/app/views/**/*.jade'); | |
| 219 | 221 | } else { | |
| 220 | 222 | startWatcher(); | |
| 221 | 223 | } | |
javascript-watcher.js
| @@ -96,9 +96,11 @@ async function go() { | |||
| 96 | 96 | const watchFolders = [ | |
| 97 | 97 | '/app/js' | |
| 98 | 98 | ] | |
| 99 | - | if (process.argv[2] == 'recompile') { | |
| 99 | + | if (process.argv[2] == 'compile-and-watch') { | |
| 100 | 100 | await compileAll('/app/js/*/**.js') | |
| 101 | 101 | startWatcher(watchFolders); | |
| 102 | + | } else if(process.argv[2] == 'compile-only') { | |
| 103 | + | await compileAll('/app/js/*/**.js') | |
| 102 | 104 | } else { | |
| 103 | 105 | startWatcher(watchFolders); | |
| 104 | 106 | } | |
pug-watcher.js (檔案已刪除)
| @@ -1,153 +0,0 @@ | |||
| 1 | - | import chokidar from 'chokidar'; | |
| 2 | - | import fs from 'fs' | |
| 3 | - | import fse from 'fs-extra'; | |
| 4 | - | import pug from 'pug'; | |
| 5 | - | import klaw from 'klaw'; | |
| 6 | - | import pretty from 'pretty'; | |
| 7 | - | ||
| 8 | - | // ==================================================================== | |
| 9 | - | // | | |
| 10 | - | // ==================================================================== | |
| 11 | - | function log(message) { | |
| 12 | - | const options = { | |
| 13 | - | encoding: "utf-8", | |
| 14 | - | flag: "a+", | |
| 15 | - | }; | |
| 16 | - | const datetime = new Date().toISOString() | |
| 17 | - | message = `[${datetime}] ${message}\n` | |
| 18 | - | fse.outputFileSync('/logs/builder/pug.log', message, options); | |
| 19 | - | console.log(message) | |
| 20 | - | } | |
| 21 | - | ||
| 22 | - | // ==================================================================== | |
| 23 | - | // | | |
| 24 | - | // ==================================================================== | |
| 25 | - | function printChange(path) { | |
| 26 | - | log(path) | |
| 27 | - | } | |
| 28 | - | ||
| 29 | - | // ==================================================================== | |
| 30 | - | // | | |
| 31 | - | // ==================================================================== | |
| 32 | - | function compile(path) { | |
| 33 | - | ||
| 34 | - | // Do not compile inside .delete folders | |
| 35 | - | if (path.includes(".delete")) { | |
| 36 | - | return | |
| 37 | - | } | |
| 38 | - | ||
| 39 | - | // Do not compile partials (begins with _) | |
| 40 | - | const filename = path.split("/").slice(-1).toString() | |
| 41 | - | if (filename.startsWith("_")) { | |
| 42 | - | compileAll() | |
| 43 | - | return | |
| 44 | - | } | |
| 45 | - | ||
| 46 | - | // Do not compile inside _partials folders | |
| 47 | - | if (path.includes("_partials") || path.includes("partials")) { | |
| 48 | - | log('Partial Edited. Recompile all!') | |
| 49 | - | compileAll() | |
| 50 | - | return | |
| 51 | - | } | |
| 52 | - | ||
| 53 | - | // Do not compile if the file does not end with .pug | |
| 54 | - | if (!path.endsWith(".pug")) { | |
| 55 | - | log('Partial Edited. Recompile all!') | |
| 56 | - | return | |
| 57 | - | } | |
| 58 | - | ||
| 59 | - | log(`Recompiling ${path}`) | |
| 60 | - | const result = pug.renderFile(path); | |
| 61 | - | ||
| 62 | - | var publicPath = path | |
| 63 | - | publicPath = publicPath.replace('/app/views','/www') | |
| 64 | - | publicPath = publicPath.replace('.pug','.html') | |
| 65 | - | ||
| 66 | - | fse.outputFile(publicPath, pretty(result), err => { | |
| 67 | - | if (err) { | |
| 68 | - | console.error(err); | |
| 69 | - | } | |
| 70 | - | // file written successfully | |
| 71 | - | }); | |
| 72 | - | ||
| 73 | - | } | |
| 74 | - | ||
| 75 | - | // ==================================================================== | |
| 76 | - | // | | |
| 77 | - | // ==================================================================== | |
| 78 | - | function compileParents(path) { | |
| 79 | - | ||
| 80 | - | // Do not compile inside .delete folders | |
| 81 | - | if (path.includes(".delete")) { | |
| 82 | - | return | |
| 83 | - | } | |
| 84 | - | ||
| 85 | - | // Do not compile partials (begins with _) | |
| 86 | - | const filename = path.split("/").slice(-1).toString() | |
| 87 | - | if (filename.startsWith("_")) { | |
| 88 | - | return | |
| 89 | - | } | |
| 90 | - | ||
| 91 | - | // Do not compile inside _partials folders | |
| 92 | - | if (path.includes("_partials") || path.includes("partials")) { | |
| 93 | - | return | |
| 94 | - | } | |
| 95 | - | ||
| 96 | - | // Do not compile if the file does not end with .pug | |
| 97 | - | if (!path.endsWith(".pug")) { | |
| 98 | - | return | |
| 99 | - | } | |
| 100 | - | ||
| 101 | - | log(`Recompiling ${path}`) | |
| 102 | - | const result = pug.renderFile(path); | |
| 103 | - | ||
| 104 | - | var publicPath = path | |
| 105 | - | publicPath = publicPath.replace('/app/views','/www') | |
| 106 | - | publicPath = publicPath.replace('.pug','.html') | |
| 107 | - | ||
| 108 | - | fse.outputFile(publicPath, pretty(result), err => { | |
| 109 | - | if (err) { | |
| 110 | - | console.error(err); | |
| 111 | - | } | |
| 112 | - | // file written successfully | |
| 113 | - | }); | |
| 114 | - | ||
| 115 | - | } | |
| 116 | - | ||
| 117 | - | ||
| 118 | - | // ==================================================================== | |
| 119 | - | // | | |
| 120 | - | // ==================================================================== | |
| 121 | - | function compileAll() { | |
| 122 | - | klaw('/app/views') | |
| 123 | - | .on('data', item => compileParents(item.path)) | |
| 124 | - | } | |
| 125 | - | ||
| 126 | - | // ==================================================================== | |
| 127 | - | // | | |
| 128 | - | // ==================================================================== | |
| 129 | - | const watchFolders = [ | |
| 130 | - | '/app/views/**/*.pug', | |
| 131 | - | ] | |
| 132 | - | ||
| 133 | - | var ignoreInitial = true | |
| 134 | - | if (process.argv[2] == 'recompile') { | |
| 135 | - | ignoreInitial = false | |
| 136 | - | } | |
| 137 | - | ||
| 138 | - | // https://github.com/paulmillr/chokidar | |
| 139 | - | const options = { | |
| 140 | - | awaitFinish: true, | |
| 141 | - | ignoreInitial: true, | |
| 142 | - | usePolling: true, | |
| 143 | - | interval: 100 | |
| 144 | - | } | |
| 145 | - | ||
| 146 | - | const watcher = chokidar.watch(watchFolders, options).on('all', (event, path) => { | |
| 147 | - | // log(event, path); | |
| 148 | - | }); | |
| 149 | - | ||
| 150 | - | watcher | |
| 151 | - | .on('add', path => compile(path)) | |
| 152 | - | .on('change', path => compile(path)) | |
| 153 | - | .on('unlink', path => compile(path)); | |
sass-watcher.js
| @@ -168,9 +168,11 @@ async function go() { | |||
| 168 | 168 | const watchFolders = [ | |
| 169 | 169 | '/app/scss/**/*.scss' | |
| 170 | 170 | ] | |
| 171 | - | if (process.argv[2] == 'recompile') { | |
| 171 | + | if (process.argv[2] == 'compile-and-watch') { | |
| 172 | 172 | await compileAll('/app/scss/**/*.scss') | |
| 173 | 173 | startWatcher(watchFolders); | |
| 174 | + | } else if(process.argv[2] == 'compile-only') { | |
| 175 | + | await compileAll('/app/scss/**/*.scss') | |
| 174 | 176 | } else { | |
| 175 | 177 | startWatcher(watchFolders); | |
| 176 | 178 | } | |
mikemorris 已修改 1 month ago. 還原成這個修訂版本
8 files changed, 845 insertions, 849 deletions
assets-watcher.js
| @@ -1,140 +1,140 @@ | |||
| 1 | - | import chokidar from 'chokidar'; | |
| 2 | - | import fs from 'fs' | |
| 3 | - | import fse from 'fs-extra'; | |
| 4 | - | import child_process from 'child_process'; | |
| 5 | - | ||
| 6 | - | // ==================================================================== | |
| 7 | - | // | | |
| 8 | - | // ==================================================================== | |
| 9 | - | function log(message) { | |
| 10 | - | const options = { | |
| 11 | - | encoding: "utf-8", | |
| 12 | - | flag: "a+", | |
| 13 | - | }; | |
| 14 | - | const datetime = new Date().toISOString() | |
| 15 | - | message = `[${datetime}] ${message}\n` | |
| 16 | - | fse.outputFileSync('/logs/builder/assets.log', message, options); | |
| 17 | - | console.log(message) | |
| 18 | - | } | |
| 19 | - | ||
| 20 | - | // ==================================================================== | |
| 21 | - | // | | |
| 22 | - | // ==================================================================== | |
| 23 | - | function copyAllIntoWWW(paths) { | |
| 24 | - | return new Promise((resolve, reject) => { | |
| 25 | - | for(const path of paths) { | |
| 26 | - | log(path) | |
| 27 | - | if (!fs.existsSync(path)) { | |
| 28 | - | log(`Directory does not exist in project: ${path}`) | |
| 29 | - | continue; | |
| 30 | - | } | |
| 31 | - | ||
| 32 | - | var publicPath = path | |
| 33 | - | publicPath = publicPath.replace('/app','/www') | |
| 34 | - | try { | |
| 35 | - | child_process.execSync(`mkdir -p ${publicPath} & cp -rf ${path}/* ${publicPath}`); | |
| 36 | - | log(`Done copying: ${path}`) | |
| 37 | - | } catch (err) { | |
| 38 | - | console.error(err) | |
| 39 | - | } | |
| 40 | - | } | |
| 41 | - | }); | |
| 42 | - | } | |
| 43 | - | ||
| 44 | - | // ==================================================================== | |
| 45 | - | // | | |
| 46 | - | // ==================================================================== | |
| 47 | - | function copyIntoWWW(path) { | |
| 48 | - | ||
| 49 | - | // Do not compile inside .delete folders | |
| 50 | - | if (path.includes(".delete")) { | |
| 51 | - | return | |
| 52 | - | } | |
| 53 | - | ||
| 54 | - | log(path); | |
| 55 | - | ||
| 56 | - | var publicPath = path | |
| 57 | - | publicPath = publicPath.replace('/app','/www') | |
| 58 | - | ||
| 59 | - | try { | |
| 60 | - | child_process.execSync(`cp -rf ${path} ${publicPath}`); | |
| 61 | - | log(`Done copying: ${path}`) | |
| 62 | - | } catch (err) { | |
| 63 | - | console.error(err) | |
| 64 | - | } | |
| 65 | - | } | |
| 66 | - | ||
| 67 | - | // ==================================================================== | |
| 68 | - | // | | |
| 69 | - | // ==================================================================== | |
| 70 | - | function deleteFromWWW(path) { | |
| 71 | - | ||
| 72 | - | // Do not compile inside .delete folders | |
| 73 | - | if (path.includes(".delete")) { | |
| 74 | - | return | |
| 75 | - | } | |
| 76 | - | ||
| 77 | - | log(path); | |
| 78 | - | ||
| 79 | - | var publicPath = path | |
| 80 | - | publicPath = publicPath.replace('/app','/www') | |
| 81 | - | ||
| 82 | - | try { | |
| 83 | - | child_process.execSync(`rm -rf ${path} ${publicPath}`); | |
| 84 | - | log(`Done deleting: ${path}`) | |
| 85 | - | } catch (err) { | |
| 86 | - | console.error(err) | |
| 87 | - | } | |
| 88 | - | } | |
| 89 | - | ||
| 90 | - | ||
| 91 | - | // ==================================================================== | |
| 92 | - | // | | |
| 93 | - | // ==================================================================== | |
| 94 | - | function startWatcher(watchFolders) { | |
| 95 | - | // https://github.com/paulmillr/chokidar | |
| 96 | - | const options = { | |
| 97 | - | awaitFinish: true, | |
| 98 | - | ignoreInitial: true, | |
| 99 | - | usePolling: true, | |
| 100 | - | interval: 100, | |
| 101 | - | depth: 5 | |
| 102 | - | } | |
| 103 | - | ||
| 104 | - | const watcher = chokidar.watch(watchFolders, options).on('all', (event, path) => { | |
| 105 | - | log(event, path); | |
| 106 | - | }); | |
| 107 | - | ||
| 108 | - | watcher | |
| 109 | - | .on('add', path => copyIntoWWW(path)) | |
| 110 | - | .on('addDir', path => copyIntoWWW(path)) | |
| 111 | - | .on('change', path => copyIntoWWW(path)) | |
| 112 | - | .on('unlink', path => deleteFromWWW(path)) | |
| 113 | - | .on('unlinkDir', path => deleteFromWWW(path)); | |
| 114 | - | ||
| 115 | - | watcher | |
| 116 | - | .on('ready', () => log('********** Watch is running **********')); | |
| 117 | - | } | |
| 118 | - | ||
| 119 | - | ||
| 120 | - | // ==================================================================== | |
| 121 | - | // | MAIN | |
| 122 | - | // ==================================================================== | |
| 123 | - | async function go() { | |
| 124 | - | const watchFolders = [ | |
| 125 | - | '/app/css', | |
| 126 | - | '/app/docs', | |
| 127 | - | '/app/fonts', | |
| 128 | - | '/app/images', | |
| 129 | - | '/app/libs', | |
| 130 | - | '/app/lib' | |
| 131 | - | ] | |
| 132 | - | if (process.argv[2] == 'recompile') { | |
| 133 | - | await copyAllIntoWWW(watchFolders) | |
| 134 | - | startWatcher(watchFolders); | |
| 135 | - | } else { | |
| 136 | - | startWatcher(watchFolders); | |
| 137 | - | } | |
| 138 | - | } | |
| 139 | - | ||
| 1 | + | import chokidar from 'chokidar'; | |
| 2 | + | import fs from 'fs' | |
| 3 | + | import fse from 'fs-extra'; | |
| 4 | + | import child_process from 'child_process'; | |
| 5 | + | ||
| 6 | + | // ==================================================================== | |
| 7 | + | // | | |
| 8 | + | // ==================================================================== | |
| 9 | + | function log(message) { | |
| 10 | + | const options = { | |
| 11 | + | encoding: "utf-8", | |
| 12 | + | flag: "a+", | |
| 13 | + | }; | |
| 14 | + | const datetime = new Date().toISOString() | |
| 15 | + | message = `[${datetime}] ${message}\n` | |
| 16 | + | fse.outputFileSync('/logs/builder/assets.log', message, options); | |
| 17 | + | console.log(message) | |
| 18 | + | } | |
| 19 | + | ||
| 20 | + | // ==================================================================== | |
| 21 | + | // | | |
| 22 | + | // ==================================================================== | |
| 23 | + | function copyAllIntoWWW(paths) { | |
| 24 | + | return new Promise((resolve, reject) => { | |
| 25 | + | for(const path of paths) { | |
| 26 | + | log(path) | |
| 27 | + | if (!fs.existsSync(path)) { | |
| 28 | + | log(`Directory does not exist in project: ${path}`) | |
| 29 | + | continue; | |
| 30 | + | } | |
| 31 | + | ||
| 32 | + | var publicPath = path | |
| 33 | + | publicPath = publicPath.replace('/app','/www') | |
| 34 | + | try { | |
| 35 | + | child_process.execSync(`mkdir -p ${publicPath} & cp -rf ${path}/* ${publicPath}`); | |
| 36 | + | log(`Done copying: ${path}`) | |
| 37 | + | } catch (err) { | |
| 38 | + | console.error(err) | |
| 39 | + | } | |
| 40 | + | } | |
| 41 | + | }); | |
| 42 | + | } | |
| 43 | + | ||
| 44 | + | // ==================================================================== | |
| 45 | + | // | | |
| 46 | + | // ==================================================================== | |
| 47 | + | function copyIntoWWW(path) { | |
| 48 | + | ||
| 49 | + | // Do not compile inside .delete folders | |
| 50 | + | if (path.includes(".delete")) { | |
| 51 | + | return | |
| 52 | + | } | |
| 53 | + | ||
| 54 | + | log(path); | |
| 55 | + | ||
| 56 | + | var publicPath = path | |
| 57 | + | publicPath = publicPath.replace('/app','/www') | |
| 58 | + | ||
| 59 | + | try { | |
| 60 | + | child_process.execSync(`cp -rf ${path} ${publicPath}`); | |
| 61 | + | log(`Done copying: ${path}`) | |
| 62 | + | } catch (err) { | |
| 63 | + | console.error(err) | |
| 64 | + | } | |
| 65 | + | } | |
| 66 | + | ||
| 67 | + | // ==================================================================== | |
| 68 | + | // | | |
| 69 | + | // ==================================================================== | |
| 70 | + | function deleteFromWWW(path) { | |
| 71 | + | ||
| 72 | + | // Do not compile inside .delete folders | |
| 73 | + | if (path.includes(".delete")) { | |
| 74 | + | return | |
| 75 | + | } | |
| 76 | + | ||
| 77 | + | log(path); | |
| 78 | + | ||
| 79 | + | var publicPath = path | |
| 80 | + | publicPath = publicPath.replace('/app','/www') | |
| 81 | + | ||
| 82 | + | try { | |
| 83 | + | child_process.execSync(`rm -rf ${path} ${publicPath}`); | |
| 84 | + | log(`Done deleting: ${path}`) | |
| 85 | + | } catch (err) { | |
| 86 | + | console.error(err) | |
| 87 | + | } | |
| 88 | + | } | |
| 89 | + | ||
| 90 | + | ||
| 91 | + | // ==================================================================== | |
| 92 | + | // | | |
| 93 | + | // ==================================================================== | |
| 94 | + | function startWatcher(watchFolders) { | |
| 95 | + | // https://github.com/paulmillr/chokidar | |
| 96 | + | const options = { | |
| 97 | + | awaitFinish: true, | |
| 98 | + | ignoreInitial: true, | |
| 99 | + | usePolling: true, | |
| 100 | + | interval: 100, | |
| 101 | + | depth: 5 | |
| 102 | + | } | |
| 103 | + | ||
| 104 | + | const watcher = chokidar.watch(watchFolders, options).on('all', (event, path) => { | |
| 105 | + | log(event, path); | |
| 106 | + | }); | |
| 107 | + | ||
| 108 | + | watcher | |
| 109 | + | .on('add', path => copyIntoWWW(path)) | |
| 110 | + | .on('addDir', path => copyIntoWWW(path)) | |
| 111 | + | .on('change', path => copyIntoWWW(path)) | |
| 112 | + | .on('unlink', path => deleteFromWWW(path)) | |
| 113 | + | .on('unlinkDir', path => deleteFromWWW(path)); | |
| 114 | + | ||
| 115 | + | watcher | |
| 116 | + | .on('ready', () => log('********** Watch is running **********')); | |
| 117 | + | } | |
| 118 | + | ||
| 119 | + | ||
| 120 | + | // ==================================================================== | |
| 121 | + | // | MAIN | |
| 122 | + | // ==================================================================== | |
| 123 | + | async function go() { | |
| 124 | + | const watchFolders = [ | |
| 125 | + | '/app/css', | |
| 126 | + | '/app/docs', | |
| 127 | + | '/app/fonts', | |
| 128 | + | '/app/images', | |
| 129 | + | '/app/libs', | |
| 130 | + | '/app/lib' | |
| 131 | + | ] | |
| 132 | + | if (process.argv[2] == 'recompile') { | |
| 133 | + | await copyAllIntoWWW(watchFolders) | |
| 134 | + | startWatcher(watchFolders); | |
| 135 | + | } else { | |
| 136 | + | startWatcher(watchFolders); | |
| 137 | + | } | |
| 138 | + | } | |
| 139 | + | ||
| 140 | 140 | go() | |
builder-init.sh
| @@ -3,7 +3,7 @@ CANARY_FILE=/app/.provisioning/builder-rebuild | |||
| 3 | 3 | ||
| 4 | 4 | if [ ! -f "$CANARY_FILE" ] ; then | |
| 5 | 5 | echo "Initialization incomplete! Running Builder Rebulid..." | |
| 6 | - | cd /opt/builder/app && bash ./clean-and-build.sh & | |
| 6 | + | cd /opt/builder && bash ./clean-and-build.sh & | |
| 7 | 7 | mkdir -p /app/.provisioning && date +%F_%T >> /app/.provisioning/builder-rebuild | |
| 8 | 8 | else | |
| 9 | 9 | ||
| @@ -14,10 +14,10 @@ else | |||
| 14 | 14 | ln -sf /app/lib /www | |
| 15 | 15 | ||
| 16 | 16 | pm2 delete all | |
| 17 | - | pm2 start /opt/builder/app/sass-watcher.js | |
| 18 | - | pm2 start /opt/builder/app/javascript-watcher.js | |
| 19 | - | pm2 start /opt/builder/app/jade-watcher.js | |
| 20 | - | # pm2 start /opt/builder/app/pug-watcher.js | |
| 21 | - | # pm2 start /opt/builder/app/assets-watcher.js | |
| 17 | + | pm2 start /opt/builder/sass-watcher.js | |
| 18 | + | pm2 start /opt/builder/javascript-watcher.js | |
| 19 | + | pm2 start /opt/builder/jade-watcher.js | |
| 20 | + | # pm2 start /opt/builder/pug-watcher.js | |
| 21 | + | # pm2 start /opt/builder/assets-watcher.js | |
| 22 | 22 | ||
| 23 | 23 | fi | |
clean-and-build.sh
| @@ -1,20 +1,16 @@ | |||
| 1 | - | #!/bin/bash | |
| 2 | - | pm2 stop all | |
| 3 | - | ||
| 4 | - | mv /www/index.php /tmp/index.php | |
| 5 | - | rm -rf /www/* | |
| 6 | - | mv /tmp/index.php /www/index.php | |
| 7 | - | ||
| 8 | - | ln -sf /app/docs /www | |
| 9 | - | ln -sf /app/fonts /www | |
| 10 | - | ln -sf /app/images /www | |
| 11 | - | ln -sf /app/libs /www | |
| 12 | - | ln -sf /app/lib /www | |
| 13 | - | ||
| 14 | - | # PM2 Style | |
| 15 | - | pm2 delete all | |
| 16 | - | pm2 start sass-watcher.js -- recompile | |
| 17 | - | pm2 start javascript-watcher.js -- recompile | |
| 18 | - | pm2 start jade-watcher.js -- recompile | |
| 19 | - | # pm2 start pug-watcher.js -- recompile | |
| 20 | - | # pm2 start assets-watcher.js -- recompile | |
| 1 | + | #!/bin/bash | |
| 2 | + | pm2 stop all | |
| 3 | + | ||
| 4 | + | ln -sf /app/docs /www | |
| 5 | + | ln -sf /app/fonts /www | |
| 6 | + | ln -sf /app/images /www | |
| 7 | + | ln -sf /app/libs /www | |
| 8 | + | ln -sf /app/lib /www | |
| 9 | + | ||
| 10 | + | # PM2 Style | |
| 11 | + | pm2 delete all | |
| 12 | + | pm2 start /opt/builder/sass-watcher.js -- recompile | |
| 13 | + | pm2 start /opt/builder/javascript-watcher.js -- recompile | |
| 14 | + | pm2 start /opt/builder/jade-watcher.js -- recompile | |
| 15 | + | # pm2 start /opt/builder/pug-watcher.js -- recompile | |
| 16 | + | # pm2 start /opt/builder/assets-watcher.js -- recompile | |
jade-watcher.js
| @@ -1,224 +1,224 @@ | |||
| 1 | - | import chokidar from 'chokidar'; | |
| 2 | - | import fs from 'fs' | |
| 3 | - | import fse from 'fs-extra'; | |
| 4 | - | import jade from 'jade'; | |
| 5 | - | import klaw from 'klaw'; | |
| 6 | - | import beautify from 'beautify'; | |
| 7 | - | import cleaner from 'clean-html'; | |
| 8 | - | import fg from 'fast-glob'; | |
| 9 | - | import inliner from '@css-inline/css-inline'; | |
| 10 | - | ||
| 11 | - | // ==================================================================== | |
| 12 | - | // | | |
| 13 | - | // ==================================================================== | |
| 14 | - | function log(message) { | |
| 15 | - | const options = { | |
| 16 | - | encoding: "utf-8", | |
| 17 | - | flag: "a+", | |
| 18 | - | }; | |
| 19 | - | const datetime = new Date().toISOString() | |
| 20 | - | message = `[${datetime}] ${message}\n` | |
| 21 | - | fse.outputFileSync('/logs/builder/jade.log', message, options); | |
| 22 | - | console.log(message) | |
| 23 | - | } | |
| 24 | - | ||
| 25 | - | // ==================================================================== | |
| 26 | - | // | | |
| 27 | - | // ==================================================================== | |
| 28 | - | function compile(path) { | |
| 29 | - | ||
| 30 | - | log(`${path} was changed`) | |
| 31 | - | ||
| 32 | - | // Do not compile inside .delete folders | |
| 33 | - | if (path.includes(".delete")) { | |
| 34 | - | return | |
| 35 | - | } | |
| 36 | - | ||
| 37 | - | // Do not compile inside _partials folders | |
| 38 | - | if (path.includes("layouts")) { | |
| 39 | - | log("Recompiling /app/views/layouts") | |
| 40 | - | compileAll('/app/views/layouts/**/*.jade') | |
| 41 | - | return | |
| 42 | - | } | |
| 43 | - | ||
| 44 | - | // Do not compile inside _partials folders | |
| 45 | - | if (path.includes("_partials") || path.includes("partials")) { | |
| 46 | - | log("Recompiling /app/views") | |
| 47 | - | compileAll('/app/views/**/*.jade') | |
| 48 | - | return | |
| 49 | - | } | |
| 50 | - | ||
| 51 | - | // Do not compile partials (begins with _) | |
| 52 | - | const filename = path.split("/").slice(-1).toString() | |
| 53 | - | if (filename.startsWith("_")) { | |
| 54 | - | const underscorecount = (filename.match(/_/g) || []).length; | |
| 55 | - | const directoryIndex = 0 - underscorecount | |
| 56 | - | const parentDirectory = path.split("/").slice(0,directoryIndex).join("/")+'/**/*.jade' | |
| 57 | - | log("Recompiling "+parentDirectory) | |
| 58 | - | compileAll( parentDirectory ) | |
| 59 | - | return | |
| 60 | - | } | |
| 61 | - | ||
| 62 | - | // Do not compile if the file does not end with .jade | |
| 63 | - | if (!path.endsWith(".jade")) { | |
| 64 | - | return | |
| 65 | - | } | |
| 66 | - | ||
| 67 | - | log(` Recompiling ${path}`) | |
| 68 | - | const options = { | |
| 69 | - | basedir: '/app/views' | |
| 70 | - | } | |
| 71 | - | var result = ''; | |
| 72 | - | result = jade.renderFile(path,options); | |
| 73 | - | ||
| 74 | - | var publicPath = path | |
| 75 | - | publicPath = publicPath.replace('/app/views','/www') | |
| 76 | - | publicPath = publicPath.replace('.jade','.html') | |
| 77 | - | ||
| 78 | - | // Convert to CSS Inline for Email Templates | |
| 79 | - | // if (publicPath.includes("/www/emails")) { | |
| 80 | - | // console.log('Inlining Email Template CSS') | |
| 81 | - | // result = inliner.inline(result); | |
| 82 | - | // console.log('Inlining Email Template CSS Done'); | |
| 83 | - | // } | |
| 84 | - | ||
| 85 | - | //- | |
| 86 | - | //- Clean HTML Section. Could cause more harm then good. Disabled for now | |
| 87 | - | //- | |
| 88 | - | // try { | |
| 89 | - | // cleaner.clean(result, output => { | |
| 90 | - | // fse.outputFileSync(publicPath, output); | |
| 91 | - | // }); | |
| 92 | - | // } catch (err) { | |
| 93 | - | // try { | |
| 94 | - | // var pretty_options = {format: 'html'} | |
| 95 | - | // fse.outputFileSync(publicPath, beautify(result, pretty_options)); | |
| 96 | - | // } catch (err) { | |
| 97 | - | // fse.outputFileSync(publicPath, result); | |
| 98 | - | // log(`[ERROR] HTML Cleaner: ${path}`) | |
| 99 | - | // log(err) | |
| 100 | - | // log(`[ERROR] Unformatted jade file was saved`) | |
| 101 | - | // } | |
| 102 | - | // } | |
| 103 | - | fse.outputFileSync(publicPath, result); | |
| 104 | - | } | |
| 105 | - | ||
| 106 | - | // ==================================================================== | |
| 107 | - | // | | |
| 108 | - | // ==================================================================== | |
| 109 | - | function compileParents(path) { | |
| 110 | - | ||
| 111 | - | // Do not compile inside .delete folders | |
| 112 | - | if (path.includes(".delete")) { | |
| 113 | - | return | |
| 114 | - | } | |
| 115 | - | ||
| 116 | - | // Do not compile partials (begins with _) | |
| 117 | - | const filename = path.split("/").slice(-1).toString() | |
| 118 | - | if (filename.startsWith("_")) { | |
| 119 | - | return | |
| 120 | - | } | |
| 121 | - | ||
| 122 | - | // Do not compile inside _partials folders | |
| 123 | - | if (path.includes("_partials") || path.includes("partials")) { | |
| 124 | - | return | |
| 125 | - | } | |
| 126 | - | ||
| 127 | - | // Do not compile if the file does not end with .jade | |
| 128 | - | if (!path.endsWith(".jade")) { | |
| 129 | - | return | |
| 130 | - | } | |
| 131 | - | ||
| 132 | - | // log(` Recompiling ${path}`) | |
| 133 | - | const options = { | |
| 134 | - | basedir: '/app/views' | |
| 135 | - | } | |
| 136 | - | var result = ''; | |
| 137 | - | result = jade.renderFile(path, options); | |
| 138 | - | ||
| 139 | - | var publicPath = path | |
| 140 | - | publicPath = publicPath.replace('/app/views','/www') | |
| 141 | - | publicPath = publicPath.replace('.jade','.html') | |
| 142 | - | ||
| 143 | - | // Convert to CSS Inline for Email Templates | |
| 144 | - | // if (publicPath.includes("/www/emails")) { | |
| 145 | - | // console.log('Inlining Email Template CSS') | |
| 146 | - | // result = inliner.inline(result); | |
| 147 | - | // console.log('Inlining Email Template CSS Done'); | |
| 148 | - | // } | |
| 149 | - | ||
| 150 | - | //- | |
| 151 | - | //- Clean HTML Section. Could cause more harm then good. Disabled for now | |
| 152 | - | //- | |
| 153 | - | // try { | |
| 154 | - | // cleaner.clean(result, output => { | |
| 155 | - | // fse.outputFileSync(publicPath, output); | |
| 156 | - | // }); | |
| 157 | - | // } catch (err) { | |
| 158 | - | // try { | |
| 159 | - | // var pretty_options = {format: 'html'} | |
| 160 | - | // fse.outputFileSync(publicPath, beautify(result, pretty_options)); | |
| 161 | - | // } catch (err) { | |
| 162 | - | // fse.outputFileSync(publicPath, result); | |
| 163 | - | // log(`[ERROR] HTML Cleaner: ${path}`) | |
| 164 | - | // log(err) | |
| 165 | - | // log(`[ERROR] Unformatted jade file was saved`) | |
| 166 | - | // } | |
| 167 | - | // } | |
| 168 | - | fse.outputFileSync(publicPath, result); | |
| 169 | - | ||
| 170 | - | } | |
| 171 | - | ||
| 172 | - | // ==================================================================== | |
| 173 | - | // | | |
| 174 | - | // ==================================================================== | |
| 175 | - | function compileAll(glob) { | |
| 176 | - | return new Promise((resolve, reject) => { | |
| 177 | - | const jadeFiles = fg.globSync(glob) | |
| 178 | - | for (const file of jadeFiles) { | |
| 179 | - | compileParents(file); | |
| 180 | - | } | |
| 181 | - | }); | |
| 182 | - | } | |
| 183 | - | ||
| 184 | - | // ==================================================================== | |
| 185 | - | // | | |
| 186 | - | // ==================================================================== | |
| 187 | - | function startWatcher() { | |
| 188 | - | const watchFolders = [ | |
| 189 | - | '/app/views/**/*.jade', | |
| 190 | - | ] | |
| 191 | - | ||
| 192 | - | // https://github.com/paulmillr/chokidar | |
| 193 | - | const options = { | |
| 194 | - | awaitFinish: true, | |
| 195 | - | ignoreInitial: true, | |
| 196 | - | usePolling: true, | |
| 197 | - | interval: 100 | |
| 198 | - | } | |
| 199 | - | ||
| 200 | - | const watcher = chokidar.watch(watchFolders, options).on('all', (event, path) => { | |
| 201 | - | }); | |
| 202 | - | ||
| 203 | - | watcher | |
| 204 | - | .on('add', path => compile(path)) | |
| 205 | - | .on('change', path => compile(path)) | |
| 206 | - | .on('unlink', path => compile(path)); | |
| 207 | - | ||
| 208 | - | watcher | |
| 209 | - | .on('ready', () => log('********** Watch is running **********')); | |
| 210 | - | } | |
| 211 | - | ||
| 212 | - | // ==================================================================== | |
| 213 | - | // | MAIN | |
| 214 | - | // ==================================================================== | |
| 215 | - | async function go() { | |
| 216 | - | if (process.argv[2] == 'recompile') { | |
| 217 | - | await compileAll('/app/views/**/*.jade'); | |
| 218 | - | startWatcher(); | |
| 219 | - | } else { | |
| 220 | - | startWatcher(); | |
| 221 | - | } | |
| 222 | - | } | |
| 223 | - | ||
| 1 | + | import chokidar from 'chokidar'; | |
| 2 | + | import fs from 'fs' | |
| 3 | + | import fse from 'fs-extra'; | |
| 4 | + | import jade from 'jade'; | |
| 5 | + | import klaw from 'klaw'; | |
| 6 | + | import beautify from 'beautify'; | |
| 7 | + | import cleaner from 'clean-html'; | |
| 8 | + | import fg from 'fast-glob'; | |
| 9 | + | import inliner from '@css-inline/css-inline'; | |
| 10 | + | ||
| 11 | + | // ==================================================================== | |
| 12 | + | // | | |
| 13 | + | // ==================================================================== | |
| 14 | + | function log(message) { | |
| 15 | + | const options = { | |
| 16 | + | encoding: "utf-8", | |
| 17 | + | flag: "a+", | |
| 18 | + | }; | |
| 19 | + | const datetime = new Date().toISOString() | |
| 20 | + | message = `[${datetime}] ${message}\n` | |
| 21 | + | fse.outputFileSync('/logs/builder/jade.log', message, options); | |
| 22 | + | console.log(message) | |
| 23 | + | } | |
| 24 | + | ||
| 25 | + | // ==================================================================== | |
| 26 | + | // | | |
| 27 | + | // ==================================================================== | |
| 28 | + | function compile(path) { | |
| 29 | + | ||
| 30 | + | log(`${path} was changed`) | |
| 31 | + | ||
| 32 | + | // Do not compile inside .delete folders | |
| 33 | + | if (path.includes(".delete")) { | |
| 34 | + | return | |
| 35 | + | } | |
| 36 | + | ||
| 37 | + | // Do not compile inside _partials folders | |
| 38 | + | if (path.includes("layouts")) { | |
| 39 | + | log("Recompiling /app/views/layouts") | |
| 40 | + | compileAll('/app/views/layouts/**/*.jade') | |
| 41 | + | return | |
| 42 | + | } | |
| 43 | + | ||
| 44 | + | // Do not compile inside _partials folders | |
| 45 | + | if (path.includes("_partials") || path.includes("partials")) { | |
| 46 | + | log("Recompiling /app/views") | |
| 47 | + | compileAll('/app/views/**/*.jade') | |
| 48 | + | return | |
| 49 | + | } | |
| 50 | + | ||
| 51 | + | // Do not compile partials (begins with _) | |
| 52 | + | const filename = path.split("/").slice(-1).toString() | |
| 53 | + | if (filename.startsWith("_")) { | |
| 54 | + | const underscorecount = (filename.match(/_/g) || []).length; | |
| 55 | + | const directoryIndex = 0 - underscorecount | |
| 56 | + | const parentDirectory = path.split("/").slice(0,directoryIndex).join("/")+'/**/*.jade' | |
| 57 | + | log("Recompiling "+parentDirectory) | |
| 58 | + | compileAll( parentDirectory ) | |
| 59 | + | return | |
| 60 | + | } | |
| 61 | + | ||
| 62 | + | // Do not compile if the file does not end with .jade | |
| 63 | + | if (!path.endsWith(".jade")) { | |
| 64 | + | return | |
| 65 | + | } | |
| 66 | + | ||
| 67 | + | log(` Recompiling ${path}`) | |
| 68 | + | const options = { | |
| 69 | + | basedir: '/app/views' | |
| 70 | + | } | |
| 71 | + | var result = ''; | |
| 72 | + | result = jade.renderFile(path,options); | |
| 73 | + | ||
| 74 | + | var publicPath = path | |
| 75 | + | publicPath = publicPath.replace('/app/views','/www') | |
| 76 | + | publicPath = publicPath.replace('.jade','.html') | |
| 77 | + | ||
| 78 | + | // Convert to CSS Inline for Email Templates | |
| 79 | + | // if (publicPath.includes("/www/emails")) { | |
| 80 | + | // console.log('Inlining Email Template CSS') | |
| 81 | + | // result = inliner.inline(result); | |
| 82 | + | // console.log('Inlining Email Template CSS Done'); | |
| 83 | + | // } | |
| 84 | + | ||
| 85 | + | //- | |
| 86 | + | //- Clean HTML Section. Could cause more harm then good. Disabled for now | |
| 87 | + | //- | |
| 88 | + | // try { | |
| 89 | + | // cleaner.clean(result, output => { | |
| 90 | + | // fse.outputFileSync(publicPath, output); | |
| 91 | + | // }); | |
| 92 | + | // } catch (err) { | |
| 93 | + | // try { | |
| 94 | + | // var pretty_options = {format: 'html'} | |
| 95 | + | // fse.outputFileSync(publicPath, beautify(result, pretty_options)); | |
| 96 | + | // } catch (err) { | |
| 97 | + | // fse.outputFileSync(publicPath, result); | |
| 98 | + | // log(`[ERROR] HTML Cleaner: ${path}`) | |
| 99 | + | // log(err) | |
| 100 | + | // log(`[ERROR] Unformatted jade file was saved`) | |
| 101 | + | // } | |
| 102 | + | // } | |
| 103 | + | fse.outputFileSync(publicPath, result); | |
| 104 | + | } | |
| 105 | + | ||
| 106 | + | // ==================================================================== | |
| 107 | + | // | | |
| 108 | + | // ==================================================================== | |
| 109 | + | function compileParents(path) { | |
| 110 | + | ||
| 111 | + | // Do not compile inside .delete folders | |
| 112 | + | if (path.includes(".delete")) { | |
| 113 | + | return | |
| 114 | + | } | |
| 115 | + | ||
| 116 | + | // Do not compile partials (begins with _) | |
| 117 | + | const filename = path.split("/").slice(-1).toString() | |
| 118 | + | if (filename.startsWith("_")) { | |
| 119 | + | return | |
| 120 | + | } | |
| 121 | + | ||
| 122 | + | // Do not compile inside _partials folders | |
| 123 | + | if (path.includes("_partials") || path.includes("partials")) { | |
| 124 | + | return | |
| 125 | + | } | |
| 126 | + | ||
| 127 | + | // Do not compile if the file does not end with .jade | |
| 128 | + | if (!path.endsWith(".jade")) { | |
| 129 | + | return | |
| 130 | + | } | |
| 131 | + | ||
| 132 | + | // log(` Recompiling ${path}`) | |
| 133 | + | const options = { | |
| 134 | + | basedir: '/app/views' | |
| 135 | + | } | |
| 136 | + | var result = ''; | |
| 137 | + | result = jade.renderFile(path, options); | |
| 138 | + | ||
| 139 | + | var publicPath = path | |
| 140 | + | publicPath = publicPath.replace('/app/views','/www') | |
| 141 | + | publicPath = publicPath.replace('.jade','.html') | |
| 142 | + | ||
| 143 | + | // Convert to CSS Inline for Email Templates | |
| 144 | + | // if (publicPath.includes("/www/emails")) { | |
| 145 | + | // console.log('Inlining Email Template CSS') | |
| 146 | + | // result = inliner.inline(result); | |
| 147 | + | // console.log('Inlining Email Template CSS Done'); | |
| 148 | + | // } | |
| 149 | + | ||
| 150 | + | //- | |
| 151 | + | //- Clean HTML Section. Could cause more harm then good. Disabled for now | |
| 152 | + | //- | |
| 153 | + | // try { | |
| 154 | + | // cleaner.clean(result, output => { | |
| 155 | + | // fse.outputFileSync(publicPath, output); | |
| 156 | + | // }); | |
| 157 | + | // } catch (err) { | |
| 158 | + | // try { | |
| 159 | + | // var pretty_options = {format: 'html'} | |
| 160 | + | // fse.outputFileSync(publicPath, beautify(result, pretty_options)); | |
| 161 | + | // } catch (err) { | |
| 162 | + | // fse.outputFileSync(publicPath, result); | |
| 163 | + | // log(`[ERROR] HTML Cleaner: ${path}`) | |
| 164 | + | // log(err) | |
| 165 | + | // log(`[ERROR] Unformatted jade file was saved`) | |
| 166 | + | // } | |
| 167 | + | // } | |
| 168 | + | fse.outputFileSync(publicPath, result); | |
| 169 | + | ||
| 170 | + | } | |
| 171 | + | ||
| 172 | + | // ==================================================================== | |
| 173 | + | // | | |
| 174 | + | // ==================================================================== | |
| 175 | + | function compileAll(glob) { | |
| 176 | + | return new Promise((resolve, reject) => { | |
| 177 | + | const jadeFiles = fg.globSync(glob) | |
| 178 | + | for (const file of jadeFiles) { | |
| 179 | + | compileParents(file); | |
| 180 | + | } | |
| 181 | + | }); | |
| 182 | + | } | |
| 183 | + | ||
| 184 | + | // ==================================================================== | |
| 185 | + | // | | |
| 186 | + | // ==================================================================== | |
| 187 | + | function startWatcher() { | |
| 188 | + | const watchFolders = [ | |
| 189 | + | '/app/views/**/*.jade', | |
| 190 | + | ] | |
| 191 | + | ||
| 192 | + | // https://github.com/paulmillr/chokidar | |
| 193 | + | const options = { | |
| 194 | + | awaitFinish: true, | |
| 195 | + | ignoreInitial: true, | |
| 196 | + | usePolling: true, | |
| 197 | + | interval: 100 | |
| 198 | + | } | |
| 199 | + | ||
| 200 | + | const watcher = chokidar.watch(watchFolders, options).on('all', (event, path) => { | |
| 201 | + | }); | |
| 202 | + | ||
| 203 | + | watcher | |
| 204 | + | .on('add', path => compile(path)) | |
| 205 | + | .on('change', path => compile(path)) | |
| 206 | + | .on('unlink', path => compile(path)); | |
| 207 | + | ||
| 208 | + | watcher | |
| 209 | + | .on('ready', () => log('********** Watch is running **********')); | |
| 210 | + | } | |
| 211 | + | ||
| 212 | + | // ==================================================================== | |
| 213 | + | // | MAIN | |
| 214 | + | // ==================================================================== | |
| 215 | + | async function go() { | |
| 216 | + | if (process.argv[2] == 'recompile') { | |
| 217 | + | await compileAll('/app/views/**/*.jade'); | |
| 218 | + | startWatcher(); | |
| 219 | + | } else { | |
| 220 | + | startWatcher(); | |
| 221 | + | } | |
| 222 | + | } | |
| 223 | + | ||
| 224 | 224 | go() | |
javascript-watcher.js
| @@ -1,107 +1,107 @@ | |||
| 1 | - | import chokidar from 'chokidar'; | |
| 2 | - | import fs from 'fs' | |
| 3 | - | import fse from 'fs-extra'; | |
| 4 | - | import path from 'path'; | |
| 5 | - | import fg from 'fast-glob'; | |
| 6 | - | ||
| 7 | - | // ==================================================================== | |
| 8 | - | // | | |
| 9 | - | // ==================================================================== | |
| 10 | - | function log(message) { | |
| 11 | - | const options = { | |
| 12 | - | encoding: "utf-8", | |
| 13 | - | flag: "a+", | |
| 14 | - | }; | |
| 15 | - | const datetime = new Date().toISOString() | |
| 16 | - | message = `[${datetime}] ${message}\n` | |
| 17 | - | fse.outputFileSync('/logs/builder/javascript.log', message, options); | |
| 18 | - | console.log(message) | |
| 19 | - | } | |
| 20 | - | ||
| 21 | - | // ==================================================================== | |
| 22 | - | // | | |
| 23 | - | // ==================================================================== | |
| 24 | - | function concatJavascript(path) { | |
| 25 | - | log('-----------------------'); | |
| 26 | - | log(path); | |
| 27 | - | ||
| 28 | - | var publicPath = path | |
| 29 | - | publicPath = publicPath.replace('/app/js','/www/js') | |
| 30 | - | ||
| 31 | - | var jsFolder = path; | |
| 32 | - | jsFolder = jsFolder.split("/")[3]; | |
| 33 | - | ||
| 34 | - | const source = `/app/js/${jsFolder}` | |
| 35 | - | const destination = `/www/js/${jsFolder}.js` | |
| 36 | - | fs.readdir(source, (err, files) => { | |
| 37 | - | if (err) throw err; | |
| 38 | - | ||
| 39 | - | fse.ensureFileSync(destination) | |
| 40 | - | fs.writeFileSync(destination,'') | |
| 41 | - | var sortedfiles = files.sort() | |
| 42 | - | sortedfiles.forEach(file => { | |
| 43 | - | const filePath = `${source}/${file}` | |
| 44 | - | var contents = fs.readFileSync(filePath); | |
| 45 | - | const spacer = `\n// ====================================================================\n// |\n// |\n// | ${file}\n// |\n// |\n// ====================================================================\n` | |
| 46 | - | fs.appendFileSync(destination, spacer+contents) | |
| 47 | - | }); | |
| 48 | - | }); | |
| 49 | - | ||
| 50 | - | } | |
| 51 | - | ||
| 52 | - | // ==================================================================== | |
| 53 | - | // | | |
| 54 | - | // ==================================================================== | |
| 55 | - | function compileAll(glob) { | |
| 56 | - | return new Promise((resolve, reject) => { | |
| 57 | - | const javascriptFiles = fg.globSync(glob) | |
| 58 | - | for (const file of javascriptFiles) { | |
| 59 | - | concatJavascript(file); | |
| 60 | - | } | |
| 61 | - | log(`Done`) | |
| 62 | - | }); | |
| 63 | - | } | |
| 64 | - | ||
| 65 | - | // ==================================================================== | |
| 66 | - | // | | |
| 67 | - | // ==================================================================== | |
| 68 | - | function startWatcher(watchFolders) { | |
| 69 | - | ||
| 70 | - | // https://github.com/paulmillr/chokidar | |
| 71 | - | const options = { | |
| 72 | - | awaitFinish: true, | |
| 73 | - | ignoreInitial: true, | |
| 74 | - | usePolling: true, | |
| 75 | - | interval: 100 | |
| 76 | - | } | |
| 77 | - | ||
| 78 | - | const watcher = chokidar.watch(watchFolders, options).on('all', (event, path) => { | |
| 79 | - | log(event, path); | |
| 80 | - | }); | |
| 81 | - | ||
| 82 | - | watcher | |
| 83 | - | .on('add', path => concatJavascript(path)) | |
| 84 | - | .on('change', path => concatJavascript(path)) | |
| 85 | - | .on('unlink', path => concatJavascript(path)); | |
| 86 | - | ||
| 87 | - | watcher | |
| 88 | - | .on('ready', () => log('********** Watch is running **********')); | |
| 89 | - | ||
| 90 | - | } | |
| 91 | - | ||
| 92 | - | // ==================================================================== | |
| 93 | - | // | MAIN | |
| 94 | - | // ==================================================================== | |
| 95 | - | async function go() { | |
| 96 | - | const watchFolders = [ | |
| 97 | - | '/app/js' | |
| 98 | - | ] | |
| 99 | - | if (process.argv[2] == 'recompile') { | |
| 100 | - | await compileAll('/app/js/*/**.js') | |
| 101 | - | startWatcher(watchFolders); | |
| 102 | - | } else { | |
| 103 | - | startWatcher(watchFolders); | |
| 104 | - | } | |
| 105 | - | } | |
| 106 | - | ||
| 1 | + | import chokidar from 'chokidar'; | |
| 2 | + | import fs from 'fs' | |
| 3 | + | import fse from 'fs-extra'; | |
| 4 | + | import path from 'path'; | |
| 5 | + | import fg from 'fast-glob'; | |
| 6 | + | ||
| 7 | + | // ==================================================================== | |
| 8 | + | // | | |
| 9 | + | // ==================================================================== | |
| 10 | + | function log(message) { | |
| 11 | + | const options = { | |
| 12 | + | encoding: "utf-8", | |
| 13 | + | flag: "a+", | |
| 14 | + | }; | |
| 15 | + | const datetime = new Date().toISOString() | |
| 16 | + | message = `[${datetime}] ${message}\n` | |
| 17 | + | fse.outputFileSync('/logs/builder/javascript.log', message, options); | |
| 18 | + | console.log(message) | |
| 19 | + | } | |
| 20 | + | ||
| 21 | + | // ==================================================================== | |
| 22 | + | // | | |
| 23 | + | // ==================================================================== | |
| 24 | + | function concatJavascript(path) { | |
| 25 | + | log('-----------------------'); | |
| 26 | + | log(path); | |
| 27 | + | ||
| 28 | + | var publicPath = path | |
| 29 | + | publicPath = publicPath.replace('/app/js','/www/js') | |
| 30 | + | ||
| 31 | + | var jsFolder = path; | |
| 32 | + | jsFolder = jsFolder.split("/")[3]; | |
| 33 | + | ||
| 34 | + | const source = `/app/js/${jsFolder}` | |
| 35 | + | const destination = `/www/js/${jsFolder}.js` | |
| 36 | + | fs.readdir(source, (err, files) => { | |
| 37 | + | if (err) throw err; | |
| 38 | + | ||
| 39 | + | fse.ensureFileSync(destination) | |
| 40 | + | fs.writeFileSync(destination,'') | |
| 41 | + | var sortedfiles = files.sort() | |
| 42 | + | sortedfiles.forEach(file => { | |
| 43 | + | const filePath = `${source}/${file}` | |
| 44 | + | var contents = fs.readFileSync(filePath); | |
| 45 | + | const spacer = `\n// ====================================================================\n// |\n// |\n// | ${file}\n// |\n// |\n// ====================================================================\n` | |
| 46 | + | fs.appendFileSync(destination, spacer+contents) | |
| 47 | + | }); | |
| 48 | + | }); | |
| 49 | + | ||
| 50 | + | } | |
| 51 | + | ||
| 52 | + | // ==================================================================== | |
| 53 | + | // | | |
| 54 | + | // ==================================================================== | |
| 55 | + | function compileAll(glob) { | |
| 56 | + | return new Promise((resolve, reject) => { | |
| 57 | + | const javascriptFiles = fg.globSync(glob) | |
| 58 | + | for (const file of javascriptFiles) { | |
| 59 | + | concatJavascript(file); | |
| 60 | + | } | |
| 61 | + | log(`Done`) | |
| 62 | + | }); | |
| 63 | + | } | |
| 64 | + | ||
| 65 | + | // ==================================================================== | |
| 66 | + | // | | |
| 67 | + | // ==================================================================== | |
| 68 | + | function startWatcher(watchFolders) { | |
| 69 | + | ||
| 70 | + | // https://github.com/paulmillr/chokidar | |
| 71 | + | const options = { | |
| 72 | + | awaitFinish: true, | |
| 73 | + | ignoreInitial: true, | |
| 74 | + | usePolling: true, | |
| 75 | + | interval: 100 | |
| 76 | + | } | |
| 77 | + | ||
| 78 | + | const watcher = chokidar.watch(watchFolders, options).on('all', (event, path) => { | |
| 79 | + | log(event, path); | |
| 80 | + | }); | |
| 81 | + | ||
| 82 | + | watcher | |
| 83 | + | .on('add', path => concatJavascript(path)) | |
| 84 | + | .on('change', path => concatJavascript(path)) | |
| 85 | + | .on('unlink', path => concatJavascript(path)); | |
| 86 | + | ||
| 87 | + | watcher | |
| 88 | + | .on('ready', () => log('********** Watch is running **********')); | |
| 89 | + | ||
| 90 | + | } | |
| 91 | + | ||
| 92 | + | // ==================================================================== | |
| 93 | + | // | MAIN | |
| 94 | + | // ==================================================================== | |
| 95 | + | async function go() { | |
| 96 | + | const watchFolders = [ | |
| 97 | + | '/app/js' | |
| 98 | + | ] | |
| 99 | + | if (process.argv[2] == 'recompile') { | |
| 100 | + | await compileAll('/app/js/*/**.js') | |
| 101 | + | startWatcher(watchFolders); | |
| 102 | + | } else { | |
| 103 | + | startWatcher(watchFolders); | |
| 104 | + | } | |
| 105 | + | } | |
| 106 | + | ||
| 107 | 107 | go() | |
package.json
| @@ -1,26 +1,26 @@ | |||
| 1 | - | { | |
| 2 | - | "name": "workflowmasters-builder", | |
| 3 | - | "type": "module", | |
| 4 | - | "devDependencies": { | |
| 5 | - | "beautify": "0.0.8", | |
| 6 | - | "chokidar": "3.6.0", | |
| 7 | - | "character-parser": "4.0.0", | |
| 8 | - | "clean-html": "2.0.1", | |
| 9 | - | "concat-files": "0.1.1", | |
| 10 | - | "fast-glob": "3.3.1", | |
| 11 | - | "fs-extra": "11.1.1", | |
| 12 | - | "glob": "10.3.10", | |
| 13 | - | "html-prettify": "1.0.7", | |
| 14 | - | "jade": "1.11.0", | |
| 15 | - | "klaw": "4.1.0", | |
| 16 | - | "pug": "3.0.2", | |
| 17 | - | "sass": "1.64.1", | |
| 18 | - | "through2": "4.0.2", | |
| 19 | - | "@css-inline/css-inline":"0.14.1", | |
| 20 | - | "watcher": "2.2.2" | |
| 21 | - | }, | |
| 22 | - | "scripts": { | |
| 23 | - | "watch": "./watcher.js", | |
| 24 | - | "test": "gulp test" | |
| 25 | - | } | |
| 1 | + | { | |
| 2 | + | "name": "workflowmasters-builder", | |
| 3 | + | "type": "module", | |
| 4 | + | "devDependencies": { | |
| 5 | + | "beautify": "0.0.8", | |
| 6 | + | "chokidar": "3.6.0", | |
| 7 | + | "character-parser": "4.0.0", | |
| 8 | + | "clean-html": "2.0.1", | |
| 9 | + | "concat-files": "0.1.1", | |
| 10 | + | "fast-glob": "3.3.1", | |
| 11 | + | "fs-extra": "11.1.1", | |
| 12 | + | "glob": "10.3.10", | |
| 13 | + | "html-prettify": "1.0.7", | |
| 14 | + | "jade": "1.11.0", | |
| 15 | + | "klaw": "4.1.0", | |
| 16 | + | "pug": "3.0.2", | |
| 17 | + | "sass": "1.64.1", | |
| 18 | + | "through2": "4.0.2", | |
| 19 | + | "@css-inline/css-inline":"0.14.1", | |
| 20 | + | "watcher": "2.2.2" | |
| 21 | + | }, | |
| 22 | + | "scripts": { | |
| 23 | + | "watch": "./watcher.js", | |
| 24 | + | "test": "gulp test" | |
| 25 | + | } | |
| 26 | 26 | } | |
pug-watcher.js
| @@ -1,153 +1,153 @@ | |||
| 1 | - | import chokidar from 'chokidar'; | |
| 2 | - | import fs from 'fs' | |
| 3 | - | import fse from 'fs-extra'; | |
| 4 | - | import pug from 'pug'; | |
| 5 | - | import klaw from 'klaw'; | |
| 6 | - | import pretty from 'pretty'; | |
| 7 | - | ||
| 8 | - | // ==================================================================== | |
| 9 | - | // | | |
| 10 | - | // ==================================================================== | |
| 11 | - | function log(message) { | |
| 12 | - | const options = { | |
| 13 | - | encoding: "utf-8", | |
| 14 | - | flag: "a+", | |
| 15 | - | }; | |
| 16 | - | const datetime = new Date().toISOString() | |
| 17 | - | message = `[${datetime}] ${message}\n` | |
| 18 | - | fse.outputFileSync('/logs/builder/pug.log', message, options); | |
| 19 | - | console.log(message) | |
| 20 | - | } | |
| 21 | - | ||
| 22 | - | // ==================================================================== | |
| 23 | - | // | | |
| 24 | - | // ==================================================================== | |
| 25 | - | function printChange(path) { | |
| 26 | - | log(path) | |
| 27 | - | } | |
| 28 | - | ||
| 29 | - | // ==================================================================== | |
| 30 | - | // | | |
| 31 | - | // ==================================================================== | |
| 32 | - | function compile(path) { | |
| 33 | - | ||
| 34 | - | // Do not compile inside .delete folders | |
| 35 | - | if (path.includes(".delete")) { | |
| 36 | - | return | |
| 37 | - | } | |
| 38 | - | ||
| 39 | - | // Do not compile partials (begins with _) | |
| 40 | - | const filename = path.split("/").slice(-1).toString() | |
| 41 | - | if (filename.startsWith("_")) { | |
| 42 | - | compileAll() | |
| 43 | - | return | |
| 44 | - | } | |
| 45 | - | ||
| 46 | - | // Do not compile inside _partials folders | |
| 47 | - | if (path.includes("_partials") || path.includes("partials")) { | |
| 48 | - | log('Partial Edited. Recompile all!') | |
| 49 | - | compileAll() | |
| 50 | - | return | |
| 51 | - | } | |
| 52 | - | ||
| 53 | - | // Do not compile if the file does not end with .pug | |
| 54 | - | if (!path.endsWith(".pug")) { | |
| 55 | - | log('Partial Edited. Recompile all!') | |
| 56 | - | return | |
| 57 | - | } | |
| 58 | - | ||
| 59 | - | log(`Recompiling ${path}`) | |
| 60 | - | const result = pug.renderFile(path); | |
| 61 | - | ||
| 62 | - | var publicPath = path | |
| 63 | - | publicPath = publicPath.replace('/app/views','/www') | |
| 64 | - | publicPath = publicPath.replace('.pug','.html') | |
| 65 | - | ||
| 66 | - | fse.outputFile(publicPath, pretty(result), err => { | |
| 67 | - | if (err) { | |
| 68 | - | console.error(err); | |
| 69 | - | } | |
| 70 | - | // file written successfully | |
| 71 | - | }); | |
| 72 | - | ||
| 73 | - | } | |
| 74 | - | ||
| 75 | - | // ==================================================================== | |
| 76 | - | // | | |
| 77 | - | // ==================================================================== | |
| 78 | - | function compileParents(path) { | |
| 79 | - | ||
| 80 | - | // Do not compile inside .delete folders | |
| 81 | - | if (path.includes(".delete")) { | |
| 82 | - | return | |
| 83 | - | } | |
| 84 | - | ||
| 85 | - | // Do not compile partials (begins with _) | |
| 86 | - | const filename = path.split("/").slice(-1).toString() | |
| 87 | - | if (filename.startsWith("_")) { | |
| 88 | - | return | |
| 89 | - | } | |
| 90 | - | ||
| 91 | - | // Do not compile inside _partials folders | |
| 92 | - | if (path.includes("_partials") || path.includes("partials")) { | |
| 93 | - | return | |
| 94 | - | } | |
| 95 | - | ||
| 96 | - | // Do not compile if the file does not end with .pug | |
| 97 | - | if (!path.endsWith(".pug")) { | |
| 98 | - | return | |
| 99 | - | } | |
| 100 | - | ||
| 101 | - | log(`Recompiling ${path}`) | |
| 102 | - | const result = pug.renderFile(path); | |
| 103 | - | ||
| 104 | - | var publicPath = path | |
| 105 | - | publicPath = publicPath.replace('/app/views','/www') | |
| 106 | - | publicPath = publicPath.replace('.pug','.html') | |
| 107 | - | ||
| 108 | - | fse.outputFile(publicPath, pretty(result), err => { | |
| 109 | - | if (err) { | |
| 110 | - | console.error(err); | |
| 111 | - | } | |
| 112 | - | // file written successfully | |
| 113 | - | }); | |
| 114 | - | ||
| 115 | - | } | |
| 116 | - | ||
| 117 | - | ||
| 118 | - | // ==================================================================== | |
| 119 | - | // | | |
| 120 | - | // ==================================================================== | |
| 121 | - | function compileAll() { | |
| 122 | - | klaw('/app/views') | |
| 123 | - | .on('data', item => compileParents(item.path)) | |
| 124 | - | } | |
| 125 | - | ||
| 126 | - | // ==================================================================== | |
| 127 | - | // | | |
| 128 | - | // ==================================================================== | |
| 129 | - | const watchFolders = [ | |
| 130 | - | '/app/views/**/*.pug', | |
| 131 | - | ] | |
| 132 | - | ||
| 133 | - | var ignoreInitial = true | |
| 134 | - | if (process.argv[2] == 'recompile') { | |
| 135 | - | ignoreInitial = false | |
| 136 | - | } | |
| 137 | - | ||
| 138 | - | // https://github.com/paulmillr/chokidar | |
| 139 | - | const options = { | |
| 140 | - | awaitFinish: true, | |
| 141 | - | ignoreInitial: true, | |
| 142 | - | usePolling: true, | |
| 143 | - | interval: 100 | |
| 144 | - | } | |
| 145 | - | ||
| 146 | - | const watcher = chokidar.watch(watchFolders, options).on('all', (event, path) => { | |
| 147 | - | // log(event, path); | |
| 148 | - | }); | |
| 149 | - | ||
| 150 | - | watcher | |
| 151 | - | .on('add', path => compile(path)) | |
| 152 | - | .on('change', path => compile(path)) | |
| 1 | + | import chokidar from 'chokidar'; | |
| 2 | + | import fs from 'fs' | |
| 3 | + | import fse from 'fs-extra'; | |
| 4 | + | import pug from 'pug'; | |
| 5 | + | import klaw from 'klaw'; | |
| 6 | + | import pretty from 'pretty'; | |
| 7 | + | ||
| 8 | + | // ==================================================================== | |
| 9 | + | // | | |
| 10 | + | // ==================================================================== | |
| 11 | + | function log(message) { | |
| 12 | + | const options = { | |
| 13 | + | encoding: "utf-8", | |
| 14 | + | flag: "a+", | |
| 15 | + | }; | |
| 16 | + | const datetime = new Date().toISOString() | |
| 17 | + | message = `[${datetime}] ${message}\n` | |
| 18 | + | fse.outputFileSync('/logs/builder/pug.log', message, options); | |
| 19 | + | console.log(message) | |
| 20 | + | } | |
| 21 | + | ||
| 22 | + | // ==================================================================== | |
| 23 | + | // | | |
| 24 | + | // ==================================================================== | |
| 25 | + | function printChange(path) { | |
| 26 | + | log(path) | |
| 27 | + | } | |
| 28 | + | ||
| 29 | + | // ==================================================================== | |
| 30 | + | // | | |
| 31 | + | // ==================================================================== | |
| 32 | + | function compile(path) { | |
| 33 | + | ||
| 34 | + | // Do not compile inside .delete folders | |
| 35 | + | if (path.includes(".delete")) { | |
| 36 | + | return | |
| 37 | + | } | |
| 38 | + | ||
| 39 | + | // Do not compile partials (begins with _) | |
| 40 | + | const filename = path.split("/").slice(-1).toString() | |
| 41 | + | if (filename.startsWith("_")) { | |
| 42 | + | compileAll() | |
| 43 | + | return | |
| 44 | + | } | |
| 45 | + | ||
| 46 | + | // Do not compile inside _partials folders | |
| 47 | + | if (path.includes("_partials") || path.includes("partials")) { | |
| 48 | + | log('Partial Edited. Recompile all!') | |
| 49 | + | compileAll() | |
| 50 | + | return | |
| 51 | + | } | |
| 52 | + | ||
| 53 | + | // Do not compile if the file does not end with .pug | |
| 54 | + | if (!path.endsWith(".pug")) { | |
| 55 | + | log('Partial Edited. Recompile all!') | |
| 56 | + | return | |
| 57 | + | } | |
| 58 | + | ||
| 59 | + | log(`Recompiling ${path}`) | |
| 60 | + | const result = pug.renderFile(path); | |
| 61 | + | ||
| 62 | + | var publicPath = path | |
| 63 | + | publicPath = publicPath.replace('/app/views','/www') | |
| 64 | + | publicPath = publicPath.replace('.pug','.html') | |
| 65 | + | ||
| 66 | + | fse.outputFile(publicPath, pretty(result), err => { | |
| 67 | + | if (err) { | |
| 68 | + | console.error(err); | |
| 69 | + | } | |
| 70 | + | // file written successfully | |
| 71 | + | }); | |
| 72 | + | ||
| 73 | + | } | |
| 74 | + | ||
| 75 | + | // ==================================================================== | |
| 76 | + | // | | |
| 77 | + | // ==================================================================== | |
| 78 | + | function compileParents(path) { | |
| 79 | + | ||
| 80 | + | // Do not compile inside .delete folders | |
| 81 | + | if (path.includes(".delete")) { | |
| 82 | + | return | |
| 83 | + | } | |
| 84 | + | ||
| 85 | + | // Do not compile partials (begins with _) | |
| 86 | + | const filename = path.split("/").slice(-1).toString() | |
| 87 | + | if (filename.startsWith("_")) { | |
| 88 | + | return | |
| 89 | + | } | |
| 90 | + | ||
| 91 | + | // Do not compile inside _partials folders | |
| 92 | + | if (path.includes("_partials") || path.includes("partials")) { | |
| 93 | + | return | |
| 94 | + | } | |
| 95 | + | ||
| 96 | + | // Do not compile if the file does not end with .pug | |
| 97 | + | if (!path.endsWith(".pug")) { | |
| 98 | + | return | |
| 99 | + | } | |
| 100 | + | ||
| 101 | + | log(`Recompiling ${path}`) | |
| 102 | + | const result = pug.renderFile(path); | |
| 103 | + | ||
| 104 | + | var publicPath = path | |
| 105 | + | publicPath = publicPath.replace('/app/views','/www') | |
| 106 | + | publicPath = publicPath.replace('.pug','.html') | |
| 107 | + | ||
| 108 | + | fse.outputFile(publicPath, pretty(result), err => { | |
| 109 | + | if (err) { | |
| 110 | + | console.error(err); | |
| 111 | + | } | |
| 112 | + | // file written successfully | |
| 113 | + | }); | |
| 114 | + | ||
| 115 | + | } | |
| 116 | + | ||
| 117 | + | ||
| 118 | + | // ==================================================================== | |
| 119 | + | // | | |
| 120 | + | // ==================================================================== | |
| 121 | + | function compileAll() { | |
| 122 | + | klaw('/app/views') | |
| 123 | + | .on('data', item => compileParents(item.path)) | |
| 124 | + | } | |
| 125 | + | ||
| 126 | + | // ==================================================================== | |
| 127 | + | // | | |
| 128 | + | // ==================================================================== | |
| 129 | + | const watchFolders = [ | |
| 130 | + | '/app/views/**/*.pug', | |
| 131 | + | ] | |
| 132 | + | ||
| 133 | + | var ignoreInitial = true | |
| 134 | + | if (process.argv[2] == 'recompile') { | |
| 135 | + | ignoreInitial = false | |
| 136 | + | } | |
| 137 | + | ||
| 138 | + | // https://github.com/paulmillr/chokidar | |
| 139 | + | const options = { | |
| 140 | + | awaitFinish: true, | |
| 141 | + | ignoreInitial: true, | |
| 142 | + | usePolling: true, | |
| 143 | + | interval: 100 | |
| 144 | + | } | |
| 145 | + | ||
| 146 | + | const watcher = chokidar.watch(watchFolders, options).on('all', (event, path) => { | |
| 147 | + | // log(event, path); | |
| 148 | + | }); | |
| 149 | + | ||
| 150 | + | watcher | |
| 151 | + | .on('add', path => compile(path)) | |
| 152 | + | .on('change', path => compile(path)) | |
| 153 | 153 | .on('unlink', path => compile(path)); | |
sass-watcher.js
| @@ -1,179 +1,179 @@ | |||
| 1 | - | import chokidar from 'chokidar'; | |
| 2 | - | import fs from 'fs' | |
| 3 | - | import fse from 'fs-extra'; | |
| 4 | - | import * as sass from 'sass'; | |
| 5 | - | import fg from 'fast-glob'; | |
| 6 | - | ||
| 7 | - | // ==================================================================== | |
| 8 | - | // | | |
| 9 | - | // ==================================================================== | |
| 10 | - | function log(message) { | |
| 11 | - | const options = { | |
| 12 | - | encoding: "utf-8", | |
| 13 | - | flag: "a+", | |
| 14 | - | }; | |
| 15 | - | const datetime = new Date().toISOString() | |
| 16 | - | message = `[${datetime}] ${message}\n` | |
| 17 | - | fse.outputFileSync('/logs/builder/sass.log', message, options); | |
| 18 | - | console.log(message) | |
| 19 | - | } | |
| 20 | - | ||
| 21 | - | // ==================================================================== | |
| 22 | - | // | | |
| 23 | - | // ==================================================================== | |
| 24 | - | function compile(path) { | |
| 25 | - | log('-----------------------'); | |
| 26 | - | ||
| 27 | - | // Do not compile inside .delete folders | |
| 28 | - | if (path.includes(".delete")) { | |
| 29 | - | return | |
| 30 | - | } | |
| 31 | - | ||
| 32 | - | const filename = path.split("/").slice(-1).toString() | |
| 33 | - | if (filename.startsWith("_")) { | |
| 34 | - | compileAll() | |
| 35 | - | return | |
| 36 | - | } | |
| 37 | - | ||
| 38 | - | const options = { | |
| 39 | - | logger: { | |
| 40 | - | warn(message, options) { | |
| 41 | - | if (options.span) { | |
| 42 | - | log('====================================================================================================================') | |
| 43 | - | log(`Warning when compiling: ${options.span.url.pathname}:`) | |
| 44 | - | log(` ${message}\n`) | |
| 45 | - | } | |
| 46 | - | }, | |
| 47 | - | debug(message, options) { | |
| 48 | - | if (options.span) { | |
| 49 | - | log('====================================================================================================================') | |
| 50 | - | log(`Debug message compiling: ${options.span.url.pathname}:`) | |
| 51 | - | log(` ${message}\n`) | |
| 52 | - | } | |
| 53 | - | } | |
| 54 | - | } | |
| 55 | - | } | |
| 56 | - | ||
| 57 | - | try { | |
| 58 | - | const result = sass.compile(path, options); | |
| 59 | - | var publicPath = path | |
| 60 | - | publicPath = publicPath.replace('/app/scss','/www/css') | |
| 61 | - | publicPath = publicPath.replace('.scss','.css') | |
| 62 | - | fse.outputFileSync(publicPath, result.css); | |
| 63 | - | } catch (err) { | |
| 64 | - | log(`[ERROR] SASS Compile: ${path}`) | |
| 65 | - | log(err) | |
| 66 | - | } | |
| 67 | - | ||
| 68 | - | } | |
| 69 | - | ||
| 70 | - | // ==================================================================== | |
| 71 | - | // | | |
| 72 | - | // ==================================================================== | |
| 73 | - | function compileParents(path) { | |
| 74 | - | ||
| 75 | - | // Do not compile inside .delete folders | |
| 76 | - | if (path.includes(".delete")) { | |
| 77 | - | return | |
| 78 | - | } | |
| 79 | - | ||
| 80 | - | // Do not compile partials (begins with _) | |
| 81 | - | const filename = path.split("/").slice(-1).toString() | |
| 82 | - | if (filename.startsWith("_")) { | |
| 83 | - | return | |
| 84 | - | } | |
| 85 | - | ||
| 86 | - | // Do not compile if the file does not end with .scss | |
| 87 | - | if (!path.endsWith(".scss")) { | |
| 88 | - | return | |
| 89 | - | } | |
| 90 | - | ||
| 91 | - | const options = { | |
| 92 | - | logger: { | |
| 93 | - | warn(message, options) { | |
| 94 | - | if (options.span) { | |
| 95 | - | log('=============================') | |
| 96 | - | log(`Warning when compiling: ${options.span.url.pathname}:`) | |
| 97 | - | log(` ${message}\n`) | |
| 98 | - | } | |
| 99 | - | }, | |
| 100 | - | debug(message, options) { | |
| 101 | - | if (options.span) { | |
| 102 | - | log('=============================') | |
| 103 | - | log(`Debug message compiling: ${options.span.url.pathname}:`) | |
| 104 | - | log(` ${message}\n`) | |
| 105 | - | } | |
| 106 | - | } | |
| 107 | - | } | |
| 108 | - | } | |
| 109 | - | ||
| 110 | - | try { | |
| 111 | - | const result = sass.compile(path, options); | |
| 112 | - | var publicPath = path | |
| 113 | - | publicPath = publicPath.replace('/app/scss','/www/css') | |
| 114 | - | publicPath = publicPath.replace('.scss','.css') | |
| 115 | - | fse.outputFileSync(publicPath, result.css); | |
| 116 | - | } catch (err) { | |
| 117 | - | log(`[ERROR] SASS Compile: ${path}`) | |
| 118 | - | log(err) | |
| 119 | - | } | |
| 120 | - | ||
| 121 | - | ||
| 122 | - | } | |
| 123 | - | ||
| 124 | - | // ==================================================================== | |
| 125 | - | // | | |
| 126 | - | // ==================================================================== | |
| 127 | - | function compileAll(glob) { | |
| 128 | - | return new Promise((resolve, reject) => { | |
| 129 | - | const sassFiles = fg.globSync(glob) | |
| 130 | - | for (const file of sassFiles) { | |
| 131 | - | compileParents(file); | |
| 132 | - | } | |
| 133 | - | log(`Done`) | |
| 134 | - | }); | |
| 135 | - | } | |
| 136 | - | ||
| 137 | - | // ==================================================================== | |
| 138 | - | // | | |
| 139 | - | // ==================================================================== | |
| 140 | - | function startWatcher(watchFolders) { | |
| 141 | - | ||
| 142 | - | // https://github.com/paulmillr/chokidar | |
| 143 | - | const options = { | |
| 144 | - | awaitFinish: true, | |
| 145 | - | ignoreInitial: true, | |
| 146 | - | usePolling: true, | |
| 147 | - | interval: 100 | |
| 148 | - | } | |
| 149 | - | ||
| 150 | - | const watcher = chokidar.watch(watchFolders, options).on('all', (event, path) => { | |
| 151 | - | log(`${path} was ${event}`); | |
| 152 | - | }); | |
| 153 | - | ||
| 154 | - | watcher | |
| 155 | - | .on('add', path => compile(path)) | |
| 156 | - | .on('change', path => compile(path)) | |
| 157 | - | .on('unlink', path => compile(path)); | |
| 158 | - | ||
| 159 | - | watcher | |
| 160 | - | .on('ready', () => log('********** Watch is running **********')); | |
| 161 | - | ||
| 162 | - | } | |
| 163 | - | ||
| 164 | - | // ==================================================================== | |
| 165 | - | // | MAIN | |
| 166 | - | // ==================================================================== | |
| 167 | - | async function go() { | |
| 168 | - | const watchFolders = [ | |
| 169 | - | '/app/scss/**/*.scss' | |
| 170 | - | ] | |
| 171 | - | if (process.argv[2] == 'recompile') { | |
| 172 | - | await compileAll('/app/scss/**/*.scss') | |
| 173 | - | startWatcher(watchFolders); | |
| 174 | - | } else { | |
| 175 | - | startWatcher(watchFolders); | |
| 176 | - | } | |
| 177 | - | } | |
| 178 | - | ||
| 1 | + | import chokidar from 'chokidar'; | |
| 2 | + | import fs from 'fs' | |
| 3 | + | import fse from 'fs-extra'; | |
| 4 | + | import * as sass from 'sass'; | |
| 5 | + | import fg from 'fast-glob'; | |
| 6 | + | ||
| 7 | + | // ==================================================================== | |
| 8 | + | // | | |
| 9 | + | // ==================================================================== | |
| 10 | + | function log(message) { | |
| 11 | + | const options = { | |
| 12 | + | encoding: "utf-8", | |
| 13 | + | flag: "a+", | |
| 14 | + | }; | |
| 15 | + | const datetime = new Date().toISOString() | |
| 16 | + | message = `[${datetime}] ${message}\n` | |
| 17 | + | fse.outputFileSync('/logs/builder/sass.log', message, options); | |
| 18 | + | console.log(message) | |
| 19 | + | } | |
| 20 | + | ||
| 21 | + | // ==================================================================== | |
| 22 | + | // | | |
| 23 | + | // ==================================================================== | |
| 24 | + | function compile(path) { | |
| 25 | + | log('-----------------------'); | |
| 26 | + | ||
| 27 | + | // Do not compile inside .delete folders | |
| 28 | + | if (path.includes(".delete")) { | |
| 29 | + | return | |
| 30 | + | } | |
| 31 | + | ||
| 32 | + | const filename = path.split("/").slice(-1).toString() | |
| 33 | + | if (filename.startsWith("_")) { | |
| 34 | + | compileAll() | |
| 35 | + | return | |
| 36 | + | } | |
| 37 | + | ||
| 38 | + | const options = { | |
| 39 | + | logger: { | |
| 40 | + | warn(message, options) { | |
| 41 | + | if (options.span) { | |
| 42 | + | log('====================================================================================================================') | |
| 43 | + | log(`Warning when compiling: ${options.span.url.pathname}:`) | |
| 44 | + | log(` ${message}\n`) | |
| 45 | + | } | |
| 46 | + | }, | |
| 47 | + | debug(message, options) { | |
| 48 | + | if (options.span) { | |
| 49 | + | log('====================================================================================================================') | |
| 50 | + | log(`Debug message compiling: ${options.span.url.pathname}:`) | |
| 51 | + | log(` ${message}\n`) | |
| 52 | + | } | |
| 53 | + | } | |
| 54 | + | } | |
| 55 | + | } | |
| 56 | + | ||
| 57 | + | try { | |
| 58 | + | const result = sass.compile(path, options); | |
| 59 | + | var publicPath = path | |
| 60 | + | publicPath = publicPath.replace('/app/scss','/www/css') | |
| 61 | + | publicPath = publicPath.replace('.scss','.css') | |
| 62 | + | fse.outputFileSync(publicPath, result.css); | |
| 63 | + | } catch (err) { | |
| 64 | + | log(`[ERROR] SASS Compile: ${path}`) | |
| 65 | + | log(err) | |
| 66 | + | } | |
| 67 | + | ||
| 68 | + | } | |
| 69 | + | ||
| 70 | + | // ==================================================================== | |
| 71 | + | // | | |
| 72 | + | // ==================================================================== | |
| 73 | + | function compileParents(path) { | |
| 74 | + | ||
| 75 | + | // Do not compile inside .delete folders | |
| 76 | + | if (path.includes(".delete")) { | |
| 77 | + | return | |
| 78 | + | } | |
| 79 | + | ||
| 80 | + | // Do not compile partials (begins with _) | |
| 81 | + | const filename = path.split("/").slice(-1).toString() | |
| 82 | + | if (filename.startsWith("_")) { | |
| 83 | + | return | |
| 84 | + | } | |
| 85 | + | ||
| 86 | + | // Do not compile if the file does not end with .scss | |
| 87 | + | if (!path.endsWith(".scss")) { | |
| 88 | + | return | |
| 89 | + | } | |
| 90 | + | ||
| 91 | + | const options = { | |
| 92 | + | logger: { | |
| 93 | + | warn(message, options) { | |
| 94 | + | if (options.span) { | |
| 95 | + | log('=============================') | |
| 96 | + | log(`Warning when compiling: ${options.span.url.pathname}:`) | |
| 97 | + | log(` ${message}\n`) | |
| 98 | + | } | |
| 99 | + | }, | |
| 100 | + | debug(message, options) { | |
| 101 | + | if (options.span) { | |
| 102 | + | log('=============================') | |
| 103 | + | log(`Debug message compiling: ${options.span.url.pathname}:`) | |
| 104 | + | log(` ${message}\n`) | |
| 105 | + | } | |
| 106 | + | } | |
| 107 | + | } | |
| 108 | + | } | |
| 109 | + | ||
| 110 | + | try { | |
| 111 | + | const result = sass.compile(path, options); | |
| 112 | + | var publicPath = path | |
| 113 | + | publicPath = publicPath.replace('/app/scss','/www/css') | |
| 114 | + | publicPath = publicPath.replace('.scss','.css') | |
| 115 | + | fse.outputFileSync(publicPath, result.css); | |
| 116 | + | } catch (err) { | |
| 117 | + | log(`[ERROR] SASS Compile: ${path}`) | |
| 118 | + | log(err) | |
| 119 | + | } | |
| 120 | + | ||
| 121 | + | ||
| 122 | + | } | |
| 123 | + | ||
| 124 | + | // ==================================================================== | |
| 125 | + | // | | |
| 126 | + | // ==================================================================== | |
| 127 | + | function compileAll(glob) { | |
| 128 | + | return new Promise((resolve, reject) => { | |
| 129 | + | const sassFiles = fg.globSync(glob) | |
| 130 | + | for (const file of sassFiles) { | |
| 131 | + | compileParents(file); | |
| 132 | + | } | |
| 133 | + | log(`Done`) | |
| 134 | + | }); | |
| 135 | + | } | |
| 136 | + | ||
| 137 | + | // ==================================================================== | |
| 138 | + | // | | |
| 139 | + | // ==================================================================== | |
| 140 | + | function startWatcher(watchFolders) { | |
| 141 | + | ||
| 142 | + | // https://github.com/paulmillr/chokidar | |
| 143 | + | const options = { | |
| 144 | + | awaitFinish: true, | |
| 145 | + | ignoreInitial: true, | |
| 146 | + | usePolling: true, | |
| 147 | + | interval: 100 | |
| 148 | + | } | |
| 149 | + | ||
| 150 | + | const watcher = chokidar.watch(watchFolders, options).on('all', (event, path) => { | |
| 151 | + | log(`${path} was ${event}`); | |
| 152 | + | }); | |
| 153 | + | ||
| 154 | + | watcher | |
| 155 | + | .on('add', path => compile(path)) | |
| 156 | + | .on('change', path => compile(path)) | |
| 157 | + | .on('unlink', path => compile(path)); | |
| 158 | + | ||
| 159 | + | watcher | |
| 160 | + | .on('ready', () => log('********** Watch is running **********')); | |
| 161 | + | ||
| 162 | + | } | |
| 163 | + | ||
| 164 | + | // ==================================================================== | |
| 165 | + | // | MAIN | |
| 166 | + | // ==================================================================== | |
| 167 | + | async function go() { | |
| 168 | + | const watchFolders = [ | |
| 169 | + | '/app/scss/**/*.scss' | |
| 170 | + | ] | |
| 171 | + | if (process.argv[2] == 'recompile') { | |
| 172 | + | await compileAll('/app/scss/**/*.scss') | |
| 173 | + | startWatcher(watchFolders); | |
| 174 | + | } else { | |
| 175 | + | startWatcher(watchFolders); | |
| 176 | + | } | |
| 177 | + | } | |
| 178 | + | ||
| 179 | 179 | go() | |
mikemorris 已修改 1 month ago. 還原成這個修訂版本
8 files changed, 872 insertions
assets-watcher.js(檔案已創建)
| @@ -0,0 +1,140 @@ | |||
| 1 | + | import chokidar from 'chokidar'; | |
| 2 | + | import fs from 'fs' | |
| 3 | + | import fse from 'fs-extra'; | |
| 4 | + | import child_process from 'child_process'; | |
| 5 | + | ||
| 6 | + | // ==================================================================== | |
| 7 | + | // | | |
| 8 | + | // ==================================================================== | |
| 9 | + | function log(message) { | |
| 10 | + | const options = { | |
| 11 | + | encoding: "utf-8", | |
| 12 | + | flag: "a+", | |
| 13 | + | }; | |
| 14 | + | const datetime = new Date().toISOString() | |
| 15 | + | message = `[${datetime}] ${message}\n` | |
| 16 | + | fse.outputFileSync('/logs/builder/assets.log', message, options); | |
| 17 | + | console.log(message) | |
| 18 | + | } | |
| 19 | + | ||
| 20 | + | // ==================================================================== | |
| 21 | + | // | | |
| 22 | + | // ==================================================================== | |
| 23 | + | function copyAllIntoWWW(paths) { | |
| 24 | + | return new Promise((resolve, reject) => { | |
| 25 | + | for(const path of paths) { | |
| 26 | + | log(path) | |
| 27 | + | if (!fs.existsSync(path)) { | |
| 28 | + | log(`Directory does not exist in project: ${path}`) | |
| 29 | + | continue; | |
| 30 | + | } | |
| 31 | + | ||
| 32 | + | var publicPath = path | |
| 33 | + | publicPath = publicPath.replace('/app','/www') | |
| 34 | + | try { | |
| 35 | + | child_process.execSync(`mkdir -p ${publicPath} & cp -rf ${path}/* ${publicPath}`); | |
| 36 | + | log(`Done copying: ${path}`) | |
| 37 | + | } catch (err) { | |
| 38 | + | console.error(err) | |
| 39 | + | } | |
| 40 | + | } | |
| 41 | + | }); | |
| 42 | + | } | |
| 43 | + | ||
| 44 | + | // ==================================================================== | |
| 45 | + | // | | |
| 46 | + | // ==================================================================== | |
| 47 | + | function copyIntoWWW(path) { | |
| 48 | + | ||
| 49 | + | // Do not compile inside .delete folders | |
| 50 | + | if (path.includes(".delete")) { | |
| 51 | + | return | |
| 52 | + | } | |
| 53 | + | ||
| 54 | + | log(path); | |
| 55 | + | ||
| 56 | + | var publicPath = path | |
| 57 | + | publicPath = publicPath.replace('/app','/www') | |
| 58 | + | ||
| 59 | + | try { | |
| 60 | + | child_process.execSync(`cp -rf ${path} ${publicPath}`); | |
| 61 | + | log(`Done copying: ${path}`) | |
| 62 | + | } catch (err) { | |
| 63 | + | console.error(err) | |
| 64 | + | } | |
| 65 | + | } | |
| 66 | + | ||
| 67 | + | // ==================================================================== | |
| 68 | + | // | | |
| 69 | + | // ==================================================================== | |
| 70 | + | function deleteFromWWW(path) { | |
| 71 | + | ||
| 72 | + | // Do not compile inside .delete folders | |
| 73 | + | if (path.includes(".delete")) { | |
| 74 | + | return | |
| 75 | + | } | |
| 76 | + | ||
| 77 | + | log(path); | |
| 78 | + | ||
| 79 | + | var publicPath = path | |
| 80 | + | publicPath = publicPath.replace('/app','/www') | |
| 81 | + | ||
| 82 | + | try { | |
| 83 | + | child_process.execSync(`rm -rf ${path} ${publicPath}`); | |
| 84 | + | log(`Done deleting: ${path}`) | |
| 85 | + | } catch (err) { | |
| 86 | + | console.error(err) | |
| 87 | + | } | |
| 88 | + | } | |
| 89 | + | ||
| 90 | + | ||
| 91 | + | // ==================================================================== | |
| 92 | + | // | | |
| 93 | + | // ==================================================================== | |
| 94 | + | function startWatcher(watchFolders) { | |
| 95 | + | // https://github.com/paulmillr/chokidar | |
| 96 | + | const options = { | |
| 97 | + | awaitFinish: true, | |
| 98 | + | ignoreInitial: true, | |
| 99 | + | usePolling: true, | |
| 100 | + | interval: 100, | |
| 101 | + | depth: 5 | |
| 102 | + | } | |
| 103 | + | ||
| 104 | + | const watcher = chokidar.watch(watchFolders, options).on('all', (event, path) => { | |
| 105 | + | log(event, path); | |
| 106 | + | }); | |
| 107 | + | ||
| 108 | + | watcher | |
| 109 | + | .on('add', path => copyIntoWWW(path)) | |
| 110 | + | .on('addDir', path => copyIntoWWW(path)) | |
| 111 | + | .on('change', path => copyIntoWWW(path)) | |
| 112 | + | .on('unlink', path => deleteFromWWW(path)) | |
| 113 | + | .on('unlinkDir', path => deleteFromWWW(path)); | |
| 114 | + | ||
| 115 | + | watcher | |
| 116 | + | .on('ready', () => log('********** Watch is running **********')); | |
| 117 | + | } | |
| 118 | + | ||
| 119 | + | ||
| 120 | + | // ==================================================================== | |
| 121 | + | // | MAIN | |
| 122 | + | // ==================================================================== | |
| 123 | + | async function go() { | |
| 124 | + | const watchFolders = [ | |
| 125 | + | '/app/css', | |
| 126 | + | '/app/docs', | |
| 127 | + | '/app/fonts', | |
| 128 | + | '/app/images', | |
| 129 | + | '/app/libs', | |
| 130 | + | '/app/lib' | |
| 131 | + | ] | |
| 132 | + | if (process.argv[2] == 'recompile') { | |
| 133 | + | await copyAllIntoWWW(watchFolders) | |
| 134 | + | startWatcher(watchFolders); | |
| 135 | + | } else { | |
| 136 | + | startWatcher(watchFolders); | |
| 137 | + | } | |
| 138 | + | } | |
| 139 | + | ||
| 140 | + | go() | |
builder-init.sh(檔案已創建)
| @@ -0,0 +1,23 @@ | |||
| 1 | + | #!/bin/bash | |
| 2 | + | CANARY_FILE=/app/.provisioning/builder-rebuild | |
| 3 | + | ||
| 4 | + | if [ ! -f "$CANARY_FILE" ] ; then | |
| 5 | + | echo "Initialization incomplete! Running Builder Rebulid..." | |
| 6 | + | cd /opt/builder/app && bash ./clean-and-build.sh & | |
| 7 | + | mkdir -p /app/.provisioning && date +%F_%T >> /app/.provisioning/builder-rebuild | |
| 8 | + | else | |
| 9 | + | ||
| 10 | + | ln -sf /app/docs /www | |
| 11 | + | ln -sf /app/fonts /www | |
| 12 | + | ln -sf /app/images /www | |
| 13 | + | ln -sf /app/libs /www | |
| 14 | + | ln -sf /app/lib /www | |
| 15 | + | ||
| 16 | + | pm2 delete all | |
| 17 | + | pm2 start /opt/builder/app/sass-watcher.js | |
| 18 | + | pm2 start /opt/builder/app/javascript-watcher.js | |
| 19 | + | pm2 start /opt/builder/app/jade-watcher.js | |
| 20 | + | # pm2 start /opt/builder/app/pug-watcher.js | |
| 21 | + | # pm2 start /opt/builder/app/assets-watcher.js | |
| 22 | + | ||
| 23 | + | fi | |
clean-and-build.sh(檔案已創建)
| @@ -0,0 +1,20 @@ | |||
| 1 | + | #!/bin/bash | |
| 2 | + | pm2 stop all | |
| 3 | + | ||
| 4 | + | mv /www/index.php /tmp/index.php | |
| 5 | + | rm -rf /www/* | |
| 6 | + | mv /tmp/index.php /www/index.php | |
| 7 | + | ||
| 8 | + | ln -sf /app/docs /www | |
| 9 | + | ln -sf /app/fonts /www | |
| 10 | + | ln -sf /app/images /www | |
| 11 | + | ln -sf /app/libs /www | |
| 12 | + | ln -sf /app/lib /www | |
| 13 | + | ||
| 14 | + | # PM2 Style | |
| 15 | + | pm2 delete all | |
| 16 | + | pm2 start sass-watcher.js -- recompile | |
| 17 | + | pm2 start javascript-watcher.js -- recompile | |
| 18 | + | pm2 start jade-watcher.js -- recompile | |
| 19 | + | # pm2 start pug-watcher.js -- recompile | |
| 20 | + | # pm2 start assets-watcher.js -- recompile | |
jade-watcher.js(檔案已創建)
| @@ -0,0 +1,224 @@ | |||
| 1 | + | import chokidar from 'chokidar'; | |
| 2 | + | import fs from 'fs' | |
| 3 | + | import fse from 'fs-extra'; | |
| 4 | + | import jade from 'jade'; | |
| 5 | + | import klaw from 'klaw'; | |
| 6 | + | import beautify from 'beautify'; | |
| 7 | + | import cleaner from 'clean-html'; | |
| 8 | + | import fg from 'fast-glob'; | |
| 9 | + | import inliner from '@css-inline/css-inline'; | |
| 10 | + | ||
| 11 | + | // ==================================================================== | |
| 12 | + | // | | |
| 13 | + | // ==================================================================== | |
| 14 | + | function log(message) { | |
| 15 | + | const options = { | |
| 16 | + | encoding: "utf-8", | |
| 17 | + | flag: "a+", | |
| 18 | + | }; | |
| 19 | + | const datetime = new Date().toISOString() | |
| 20 | + | message = `[${datetime}] ${message}\n` | |
| 21 | + | fse.outputFileSync('/logs/builder/jade.log', message, options); | |
| 22 | + | console.log(message) | |
| 23 | + | } | |
| 24 | + | ||
| 25 | + | // ==================================================================== | |
| 26 | + | // | | |
| 27 | + | // ==================================================================== | |
| 28 | + | function compile(path) { | |
| 29 | + | ||
| 30 | + | log(`${path} was changed`) | |
| 31 | + | ||
| 32 | + | // Do not compile inside .delete folders | |
| 33 | + | if (path.includes(".delete")) { | |
| 34 | + | return | |
| 35 | + | } | |
| 36 | + | ||
| 37 | + | // Do not compile inside _partials folders | |
| 38 | + | if (path.includes("layouts")) { | |
| 39 | + | log("Recompiling /app/views/layouts") | |
| 40 | + | compileAll('/app/views/layouts/**/*.jade') | |
| 41 | + | return | |
| 42 | + | } | |
| 43 | + | ||
| 44 | + | // Do not compile inside _partials folders | |
| 45 | + | if (path.includes("_partials") || path.includes("partials")) { | |
| 46 | + | log("Recompiling /app/views") | |
| 47 | + | compileAll('/app/views/**/*.jade') | |
| 48 | + | return | |
| 49 | + | } | |
| 50 | + | ||
| 51 | + | // Do not compile partials (begins with _) | |
| 52 | + | const filename = path.split("/").slice(-1).toString() | |
| 53 | + | if (filename.startsWith("_")) { | |
| 54 | + | const underscorecount = (filename.match(/_/g) || []).length; | |
| 55 | + | const directoryIndex = 0 - underscorecount | |
| 56 | + | const parentDirectory = path.split("/").slice(0,directoryIndex).join("/")+'/**/*.jade' | |
| 57 | + | log("Recompiling "+parentDirectory) | |
| 58 | + | compileAll( parentDirectory ) | |
| 59 | + | return | |
| 60 | + | } | |
| 61 | + | ||
| 62 | + | // Do not compile if the file does not end with .jade | |
| 63 | + | if (!path.endsWith(".jade")) { | |
| 64 | + | return | |
| 65 | + | } | |
| 66 | + | ||
| 67 | + | log(` Recompiling ${path}`) | |
| 68 | + | const options = { | |
| 69 | + | basedir: '/app/views' | |
| 70 | + | } | |
| 71 | + | var result = ''; | |
| 72 | + | result = jade.renderFile(path,options); | |
| 73 | + | ||
| 74 | + | var publicPath = path | |
| 75 | + | publicPath = publicPath.replace('/app/views','/www') | |
| 76 | + | publicPath = publicPath.replace('.jade','.html') | |
| 77 | + | ||
| 78 | + | // Convert to CSS Inline for Email Templates | |
| 79 | + | // if (publicPath.includes("/www/emails")) { | |
| 80 | + | // console.log('Inlining Email Template CSS') | |
| 81 | + | // result = inliner.inline(result); | |
| 82 | + | // console.log('Inlining Email Template CSS Done'); | |
| 83 | + | // } | |
| 84 | + | ||
| 85 | + | //- | |
| 86 | + | //- Clean HTML Section. Could cause more harm then good. Disabled for now | |
| 87 | + | //- | |
| 88 | + | // try { | |
| 89 | + | // cleaner.clean(result, output => { | |
| 90 | + | // fse.outputFileSync(publicPath, output); | |
| 91 | + | // }); | |
| 92 | + | // } catch (err) { | |
| 93 | + | // try { | |
| 94 | + | // var pretty_options = {format: 'html'} | |
| 95 | + | // fse.outputFileSync(publicPath, beautify(result, pretty_options)); | |
| 96 | + | // } catch (err) { | |
| 97 | + | // fse.outputFileSync(publicPath, result); | |
| 98 | + | // log(`[ERROR] HTML Cleaner: ${path}`) | |
| 99 | + | // log(err) | |
| 100 | + | // log(`[ERROR] Unformatted jade file was saved`) | |
| 101 | + | // } | |
| 102 | + | // } | |
| 103 | + | fse.outputFileSync(publicPath, result); | |
| 104 | + | } | |
| 105 | + | ||
| 106 | + | // ==================================================================== | |
| 107 | + | // | | |
| 108 | + | // ==================================================================== | |
| 109 | + | function compileParents(path) { | |
| 110 | + | ||
| 111 | + | // Do not compile inside .delete folders | |
| 112 | + | if (path.includes(".delete")) { | |
| 113 | + | return | |
| 114 | + | } | |
| 115 | + | ||
| 116 | + | // Do not compile partials (begins with _) | |
| 117 | + | const filename = path.split("/").slice(-1).toString() | |
| 118 | + | if (filename.startsWith("_")) { | |
| 119 | + | return | |
| 120 | + | } | |
| 121 | + | ||
| 122 | + | // Do not compile inside _partials folders | |
| 123 | + | if (path.includes("_partials") || path.includes("partials")) { | |
| 124 | + | return | |
| 125 | + | } | |
| 126 | + | ||
| 127 | + | // Do not compile if the file does not end with .jade | |
| 128 | + | if (!path.endsWith(".jade")) { | |
| 129 | + | return | |
| 130 | + | } | |
| 131 | + | ||
| 132 | + | // log(` Recompiling ${path}`) | |
| 133 | + | const options = { | |
| 134 | + | basedir: '/app/views' | |
| 135 | + | } | |
| 136 | + | var result = ''; | |
| 137 | + | result = jade.renderFile(path, options); | |
| 138 | + | ||
| 139 | + | var publicPath = path | |
| 140 | + | publicPath = publicPath.replace('/app/views','/www') | |
| 141 | + | publicPath = publicPath.replace('.jade','.html') | |
| 142 | + | ||
| 143 | + | // Convert to CSS Inline for Email Templates | |
| 144 | + | // if (publicPath.includes("/www/emails")) { | |
| 145 | + | // console.log('Inlining Email Template CSS') | |
| 146 | + | // result = inliner.inline(result); | |
| 147 | + | // console.log('Inlining Email Template CSS Done'); | |
| 148 | + | // } | |
| 149 | + | ||
| 150 | + | //- | |
| 151 | + | //- Clean HTML Section. Could cause more harm then good. Disabled for now | |
| 152 | + | //- | |
| 153 | + | // try { | |
| 154 | + | // cleaner.clean(result, output => { | |
| 155 | + | // fse.outputFileSync(publicPath, output); | |
| 156 | + | // }); | |
| 157 | + | // } catch (err) { | |
| 158 | + | // try { | |
| 159 | + | // var pretty_options = {format: 'html'} | |
| 160 | + | // fse.outputFileSync(publicPath, beautify(result, pretty_options)); | |
| 161 | + | // } catch (err) { | |
| 162 | + | // fse.outputFileSync(publicPath, result); | |
| 163 | + | // log(`[ERROR] HTML Cleaner: ${path}`) | |
| 164 | + | // log(err) | |
| 165 | + | // log(`[ERROR] Unformatted jade file was saved`) | |
| 166 | + | // } | |
| 167 | + | // } | |
| 168 | + | fse.outputFileSync(publicPath, result); | |
| 169 | + | ||
| 170 | + | } | |
| 171 | + | ||
| 172 | + | // ==================================================================== | |
| 173 | + | // | | |
| 174 | + | // ==================================================================== | |
| 175 | + | function compileAll(glob) { | |
| 176 | + | return new Promise((resolve, reject) => { | |
| 177 | + | const jadeFiles = fg.globSync(glob) | |
| 178 | + | for (const file of jadeFiles) { | |
| 179 | + | compileParents(file); | |
| 180 | + | } | |
| 181 | + | }); | |
| 182 | + | } | |
| 183 | + | ||
| 184 | + | // ==================================================================== | |
| 185 | + | // | | |
| 186 | + | // ==================================================================== | |
| 187 | + | function startWatcher() { | |
| 188 | + | const watchFolders = [ | |
| 189 | + | '/app/views/**/*.jade', | |
| 190 | + | ] | |
| 191 | + | ||
| 192 | + | // https://github.com/paulmillr/chokidar | |
| 193 | + | const options = { | |
| 194 | + | awaitFinish: true, | |
| 195 | + | ignoreInitial: true, | |
| 196 | + | usePolling: true, | |
| 197 | + | interval: 100 | |
| 198 | + | } | |
| 199 | + | ||
| 200 | + | const watcher = chokidar.watch(watchFolders, options).on('all', (event, path) => { | |
| 201 | + | }); | |
| 202 | + | ||
| 203 | + | watcher | |
| 204 | + | .on('add', path => compile(path)) | |
| 205 | + | .on('change', path => compile(path)) | |
| 206 | + | .on('unlink', path => compile(path)); | |
| 207 | + | ||
| 208 | + | watcher | |
| 209 | + | .on('ready', () => log('********** Watch is running **********')); | |
| 210 | + | } | |
| 211 | + | ||
| 212 | + | // ==================================================================== | |
| 213 | + | // | MAIN | |
| 214 | + | // ==================================================================== | |
| 215 | + | async function go() { | |
| 216 | + | if (process.argv[2] == 'recompile') { | |
| 217 | + | await compileAll('/app/views/**/*.jade'); | |
| 218 | + | startWatcher(); | |
| 219 | + | } else { | |
| 220 | + | startWatcher(); | |
| 221 | + | } | |
| 222 | + | } | |
| 223 | + | ||
| 224 | + | go() | |
javascript-watcher.js(檔案已創建)
| @@ -0,0 +1,107 @@ | |||
| 1 | + | import chokidar from 'chokidar'; | |
| 2 | + | import fs from 'fs' | |
| 3 | + | import fse from 'fs-extra'; | |
| 4 | + | import path from 'path'; | |
| 5 | + | import fg from 'fast-glob'; | |
| 6 | + | ||
| 7 | + | // ==================================================================== | |
| 8 | + | // | | |
| 9 | + | // ==================================================================== | |
| 10 | + | function log(message) { | |
| 11 | + | const options = { | |
| 12 | + | encoding: "utf-8", | |
| 13 | + | flag: "a+", | |
| 14 | + | }; | |
| 15 | + | const datetime = new Date().toISOString() | |
| 16 | + | message = `[${datetime}] ${message}\n` | |
| 17 | + | fse.outputFileSync('/logs/builder/javascript.log', message, options); | |
| 18 | + | console.log(message) | |
| 19 | + | } | |
| 20 | + | ||
| 21 | + | // ==================================================================== | |
| 22 | + | // | | |
| 23 | + | // ==================================================================== | |
| 24 | + | function concatJavascript(path) { | |
| 25 | + | log('-----------------------'); | |
| 26 | + | log(path); | |
| 27 | + | ||
| 28 | + | var publicPath = path | |
| 29 | + | publicPath = publicPath.replace('/app/js','/www/js') | |
| 30 | + | ||
| 31 | + | var jsFolder = path; | |
| 32 | + | jsFolder = jsFolder.split("/")[3]; | |
| 33 | + | ||
| 34 | + | const source = `/app/js/${jsFolder}` | |
| 35 | + | const destination = `/www/js/${jsFolder}.js` | |
| 36 | + | fs.readdir(source, (err, files) => { | |
| 37 | + | if (err) throw err; | |
| 38 | + | ||
| 39 | + | fse.ensureFileSync(destination) | |
| 40 | + | fs.writeFileSync(destination,'') | |
| 41 | + | var sortedfiles = files.sort() | |
| 42 | + | sortedfiles.forEach(file => { | |
| 43 | + | const filePath = `${source}/${file}` | |
| 44 | + | var contents = fs.readFileSync(filePath); | |
| 45 | + | const spacer = `\n// ====================================================================\n// |\n// |\n// | ${file}\n// |\n// |\n// ====================================================================\n` | |
| 46 | + | fs.appendFileSync(destination, spacer+contents) | |
| 47 | + | }); | |
| 48 | + | }); | |
| 49 | + | ||
| 50 | + | } | |
| 51 | + | ||
| 52 | + | // ==================================================================== | |
| 53 | + | // | | |
| 54 | + | // ==================================================================== | |
| 55 | + | function compileAll(glob) { | |
| 56 | + | return new Promise((resolve, reject) => { | |
| 57 | + | const javascriptFiles = fg.globSync(glob) | |
| 58 | + | for (const file of javascriptFiles) { | |
| 59 | + | concatJavascript(file); | |
| 60 | + | } | |
| 61 | + | log(`Done`) | |
| 62 | + | }); | |
| 63 | + | } | |
| 64 | + | ||
| 65 | + | // ==================================================================== | |
| 66 | + | // | | |
| 67 | + | // ==================================================================== | |
| 68 | + | function startWatcher(watchFolders) { | |
| 69 | + | ||
| 70 | + | // https://github.com/paulmillr/chokidar | |
| 71 | + | const options = { | |
| 72 | + | awaitFinish: true, | |
| 73 | + | ignoreInitial: true, | |
| 74 | + | usePolling: true, | |
| 75 | + | interval: 100 | |
| 76 | + | } | |
| 77 | + | ||
| 78 | + | const watcher = chokidar.watch(watchFolders, options).on('all', (event, path) => { | |
| 79 | + | log(event, path); | |
| 80 | + | }); | |
| 81 | + | ||
| 82 | + | watcher | |
| 83 | + | .on('add', path => concatJavascript(path)) | |
| 84 | + | .on('change', path => concatJavascript(path)) | |
| 85 | + | .on('unlink', path => concatJavascript(path)); | |
| 86 | + | ||
| 87 | + | watcher | |
| 88 | + | .on('ready', () => log('********** Watch is running **********')); | |
| 89 | + | ||
| 90 | + | } | |
| 91 | + | ||
| 92 | + | // ==================================================================== | |
| 93 | + | // | MAIN | |
| 94 | + | // ==================================================================== | |
| 95 | + | async function go() { | |
| 96 | + | const watchFolders = [ | |
| 97 | + | '/app/js' | |
| 98 | + | ] | |
| 99 | + | if (process.argv[2] == 'recompile') { | |
| 100 | + | await compileAll('/app/js/*/**.js') | |
| 101 | + | startWatcher(watchFolders); | |
| 102 | + | } else { | |
| 103 | + | startWatcher(watchFolders); | |
| 104 | + | } | |
| 105 | + | } | |
| 106 | + | ||
| 107 | + | go() | |
package.json(檔案已創建)
| @@ -0,0 +1,26 @@ | |||
| 1 | + | { | |
| 2 | + | "name": "workflowmasters-builder", | |
| 3 | + | "type": "module", | |
| 4 | + | "devDependencies": { | |
| 5 | + | "beautify": "0.0.8", | |
| 6 | + | "chokidar": "3.6.0", | |
| 7 | + | "character-parser": "4.0.0", | |
| 8 | + | "clean-html": "2.0.1", | |
| 9 | + | "concat-files": "0.1.1", | |
| 10 | + | "fast-glob": "3.3.1", | |
| 11 | + | "fs-extra": "11.1.1", | |
| 12 | + | "glob": "10.3.10", | |
| 13 | + | "html-prettify": "1.0.7", | |
| 14 | + | "jade": "1.11.0", | |
| 15 | + | "klaw": "4.1.0", | |
| 16 | + | "pug": "3.0.2", | |
| 17 | + | "sass": "1.64.1", | |
| 18 | + | "through2": "4.0.2", | |
| 19 | + | "@css-inline/css-inline":"0.14.1", | |
| 20 | + | "watcher": "2.2.2" | |
| 21 | + | }, | |
| 22 | + | "scripts": { | |
| 23 | + | "watch": "./watcher.js", | |
| 24 | + | "test": "gulp test" | |
| 25 | + | } | |
| 26 | + | } | |
pug-watcher.js(檔案已創建)
| @@ -0,0 +1,153 @@ | |||
| 1 | + | import chokidar from 'chokidar'; | |
| 2 | + | import fs from 'fs' | |
| 3 | + | import fse from 'fs-extra'; | |
| 4 | + | import pug from 'pug'; | |
| 5 | + | import klaw from 'klaw'; | |
| 6 | + | import pretty from 'pretty'; | |
| 7 | + | ||
| 8 | + | // ==================================================================== | |
| 9 | + | // | | |
| 10 | + | // ==================================================================== | |
| 11 | + | function log(message) { | |
| 12 | + | const options = { | |
| 13 | + | encoding: "utf-8", | |
| 14 | + | flag: "a+", | |
| 15 | + | }; | |
| 16 | + | const datetime = new Date().toISOString() | |
| 17 | + | message = `[${datetime}] ${message}\n` | |
| 18 | + | fse.outputFileSync('/logs/builder/pug.log', message, options); | |
| 19 | + | console.log(message) | |
| 20 | + | } | |
| 21 | + | ||
| 22 | + | // ==================================================================== | |
| 23 | + | // | | |
| 24 | + | // ==================================================================== | |
| 25 | + | function printChange(path) { | |
| 26 | + | log(path) | |
| 27 | + | } | |
| 28 | + | ||
| 29 | + | // ==================================================================== | |
| 30 | + | // | | |
| 31 | + | // ==================================================================== | |
| 32 | + | function compile(path) { | |
| 33 | + | ||
| 34 | + | // Do not compile inside .delete folders | |
| 35 | + | if (path.includes(".delete")) { | |
| 36 | + | return | |
| 37 | + | } | |
| 38 | + | ||
| 39 | + | // Do not compile partials (begins with _) | |
| 40 | + | const filename = path.split("/").slice(-1).toString() | |
| 41 | + | if (filename.startsWith("_")) { | |
| 42 | + | compileAll() | |
| 43 | + | return | |
| 44 | + | } | |
| 45 | + | ||
| 46 | + | // Do not compile inside _partials folders | |
| 47 | + | if (path.includes("_partials") || path.includes("partials")) { | |
| 48 | + | log('Partial Edited. Recompile all!') | |
| 49 | + | compileAll() | |
| 50 | + | return | |
| 51 | + | } | |
| 52 | + | ||
| 53 | + | // Do not compile if the file does not end with .pug | |
| 54 | + | if (!path.endsWith(".pug")) { | |
| 55 | + | log('Partial Edited. Recompile all!') | |
| 56 | + | return | |
| 57 | + | } | |
| 58 | + | ||
| 59 | + | log(`Recompiling ${path}`) | |
| 60 | + | const result = pug.renderFile(path); | |
| 61 | + | ||
| 62 | + | var publicPath = path | |
| 63 | + | publicPath = publicPath.replace('/app/views','/www') | |
| 64 | + | publicPath = publicPath.replace('.pug','.html') | |
| 65 | + | ||
| 66 | + | fse.outputFile(publicPath, pretty(result), err => { | |
| 67 | + | if (err) { | |
| 68 | + | console.error(err); | |
| 69 | + | } | |
| 70 | + | // file written successfully | |
| 71 | + | }); | |
| 72 | + | ||
| 73 | + | } | |
| 74 | + | ||
| 75 | + | // ==================================================================== | |
| 76 | + | // | | |
| 77 | + | // ==================================================================== | |
| 78 | + | function compileParents(path) { | |
| 79 | + | ||
| 80 | + | // Do not compile inside .delete folders | |
| 81 | + | if (path.includes(".delete")) { | |
| 82 | + | return | |
| 83 | + | } | |
| 84 | + | ||
| 85 | + | // Do not compile partials (begins with _) | |
| 86 | + | const filename = path.split("/").slice(-1).toString() | |
| 87 | + | if (filename.startsWith("_")) { | |
| 88 | + | return | |
| 89 | + | } | |
| 90 | + | ||
| 91 | + | // Do not compile inside _partials folders | |
| 92 | + | if (path.includes("_partials") || path.includes("partials")) { | |
| 93 | + | return | |
| 94 | + | } | |
| 95 | + | ||
| 96 | + | // Do not compile if the file does not end with .pug | |
| 97 | + | if (!path.endsWith(".pug")) { | |
| 98 | + | return | |
| 99 | + | } | |
| 100 | + | ||
| 101 | + | log(`Recompiling ${path}`) | |
| 102 | + | const result = pug.renderFile(path); | |
| 103 | + | ||
| 104 | + | var publicPath = path | |
| 105 | + | publicPath = publicPath.replace('/app/views','/www') | |
| 106 | + | publicPath = publicPath.replace('.pug','.html') | |
| 107 | + | ||
| 108 | + | fse.outputFile(publicPath, pretty(result), err => { | |
| 109 | + | if (err) { | |
| 110 | + | console.error(err); | |
| 111 | + | } | |
| 112 | + | // file written successfully | |
| 113 | + | }); | |
| 114 | + | ||
| 115 | + | } | |
| 116 | + | ||
| 117 | + | ||
| 118 | + | // ==================================================================== | |
| 119 | + | // | | |
| 120 | + | // ==================================================================== | |
| 121 | + | function compileAll() { | |
| 122 | + | klaw('/app/views') | |
| 123 | + | .on('data', item => compileParents(item.path)) | |
| 124 | + | } | |
| 125 | + | ||
| 126 | + | // ==================================================================== | |
| 127 | + | // | | |
| 128 | + | // ==================================================================== | |
| 129 | + | const watchFolders = [ | |
| 130 | + | '/app/views/**/*.pug', | |
| 131 | + | ] | |
| 132 | + | ||
| 133 | + | var ignoreInitial = true | |
| 134 | + | if (process.argv[2] == 'recompile') { | |
| 135 | + | ignoreInitial = false | |
| 136 | + | } | |
| 137 | + | ||
| 138 | + | // https://github.com/paulmillr/chokidar | |
| 139 | + | const options = { | |
| 140 | + | awaitFinish: true, | |
| 141 | + | ignoreInitial: true, | |
| 142 | + | usePolling: true, | |
| 143 | + | interval: 100 | |
| 144 | + | } | |
| 145 | + | ||
| 146 | + | const watcher = chokidar.watch(watchFolders, options).on('all', (event, path) => { | |
| 147 | + | // log(event, path); | |
| 148 | + | }); | |
| 149 | + | ||
| 150 | + | watcher | |
| 151 | + | .on('add', path => compile(path)) | |
| 152 | + | .on('change', path => compile(path)) | |
| 153 | + | .on('unlink', path => compile(path)); | |
sass-watcher.js(檔案已創建)
| @@ -0,0 +1,179 @@ | |||
| 1 | + | import chokidar from 'chokidar'; | |
| 2 | + | import fs from 'fs' | |
| 3 | + | import fse from 'fs-extra'; | |
| 4 | + | import * as sass from 'sass'; | |
| 5 | + | import fg from 'fast-glob'; | |
| 6 | + | ||
| 7 | + | // ==================================================================== | |
| 8 | + | // | | |
| 9 | + | // ==================================================================== | |
| 10 | + | function log(message) { | |
| 11 | + | const options = { | |
| 12 | + | encoding: "utf-8", | |
| 13 | + | flag: "a+", | |
| 14 | + | }; | |
| 15 | + | const datetime = new Date().toISOString() | |
| 16 | + | message = `[${datetime}] ${message}\n` | |
| 17 | + | fse.outputFileSync('/logs/builder/sass.log', message, options); | |
| 18 | + | console.log(message) | |
| 19 | + | } | |
| 20 | + | ||
| 21 | + | // ==================================================================== | |
| 22 | + | // | | |
| 23 | + | // ==================================================================== | |
| 24 | + | function compile(path) { | |
| 25 | + | log('-----------------------'); | |
| 26 | + | ||
| 27 | + | // Do not compile inside .delete folders | |
| 28 | + | if (path.includes(".delete")) { | |
| 29 | + | return | |
| 30 | + | } | |
| 31 | + | ||
| 32 | + | const filename = path.split("/").slice(-1).toString() | |
| 33 | + | if (filename.startsWith("_")) { | |
| 34 | + | compileAll() | |
| 35 | + | return | |
| 36 | + | } | |
| 37 | + | ||
| 38 | + | const options = { | |
| 39 | + | logger: { | |
| 40 | + | warn(message, options) { | |
| 41 | + | if (options.span) { | |
| 42 | + | log('====================================================================================================================') | |
| 43 | + | log(`Warning when compiling: ${options.span.url.pathname}:`) | |
| 44 | + | log(` ${message}\n`) | |
| 45 | + | } | |
| 46 | + | }, | |
| 47 | + | debug(message, options) { | |
| 48 | + | if (options.span) { | |
| 49 | + | log('====================================================================================================================') | |
| 50 | + | log(`Debug message compiling: ${options.span.url.pathname}:`) | |
| 51 | + | log(` ${message}\n`) | |
| 52 | + | } | |
| 53 | + | } | |
| 54 | + | } | |
| 55 | + | } | |
| 56 | + | ||
| 57 | + | try { | |
| 58 | + | const result = sass.compile(path, options); | |
| 59 | + | var publicPath = path | |
| 60 | + | publicPath = publicPath.replace('/app/scss','/www/css') | |
| 61 | + | publicPath = publicPath.replace('.scss','.css') | |
| 62 | + | fse.outputFileSync(publicPath, result.css); | |
| 63 | + | } catch (err) { | |
| 64 | + | log(`[ERROR] SASS Compile: ${path}`) | |
| 65 | + | log(err) | |
| 66 | + | } | |
| 67 | + | ||
| 68 | + | } | |
| 69 | + | ||
| 70 | + | // ==================================================================== | |
| 71 | + | // | | |
| 72 | + | // ==================================================================== | |
| 73 | + | function compileParents(path) { | |
| 74 | + | ||
| 75 | + | // Do not compile inside .delete folders | |
| 76 | + | if (path.includes(".delete")) { | |
| 77 | + | return | |
| 78 | + | } | |
| 79 | + | ||
| 80 | + | // Do not compile partials (begins with _) | |
| 81 | + | const filename = path.split("/").slice(-1).toString() | |
| 82 | + | if (filename.startsWith("_")) { | |
| 83 | + | return | |
| 84 | + | } | |
| 85 | + | ||
| 86 | + | // Do not compile if the file does not end with .scss | |
| 87 | + | if (!path.endsWith(".scss")) { | |
| 88 | + | return | |
| 89 | + | } | |
| 90 | + | ||
| 91 | + | const options = { | |
| 92 | + | logger: { | |
| 93 | + | warn(message, options) { | |
| 94 | + | if (options.span) { | |
| 95 | + | log('=============================') | |
| 96 | + | log(`Warning when compiling: ${options.span.url.pathname}:`) | |
| 97 | + | log(` ${message}\n`) | |
| 98 | + | } | |
| 99 | + | }, | |
| 100 | + | debug(message, options) { | |
| 101 | + | if (options.span) { | |
| 102 | + | log('=============================') | |
| 103 | + | log(`Debug message compiling: ${options.span.url.pathname}:`) | |
| 104 | + | log(` ${message}\n`) | |
| 105 | + | } | |
| 106 | + | } | |
| 107 | + | } | |
| 108 | + | } | |
| 109 | + | ||
| 110 | + | try { | |
| 111 | + | const result = sass.compile(path, options); | |
| 112 | + | var publicPath = path | |
| 113 | + | publicPath = publicPath.replace('/app/scss','/www/css') | |
| 114 | + | publicPath = publicPath.replace('.scss','.css') | |
| 115 | + | fse.outputFileSync(publicPath, result.css); | |
| 116 | + | } catch (err) { | |
| 117 | + | log(`[ERROR] SASS Compile: ${path}`) | |
| 118 | + | log(err) | |
| 119 | + | } | |
| 120 | + | ||
| 121 | + | ||
| 122 | + | } | |
| 123 | + | ||
| 124 | + | // ==================================================================== | |
| 125 | + | // | | |
| 126 | + | // ==================================================================== | |
| 127 | + | function compileAll(glob) { | |
| 128 | + | return new Promise((resolve, reject) => { | |
| 129 | + | const sassFiles = fg.globSync(glob) | |
| 130 | + | for (const file of sassFiles) { | |
| 131 | + | compileParents(file); | |
| 132 | + | } | |
| 133 | + | log(`Done`) | |
| 134 | + | }); | |
| 135 | + | } | |
| 136 | + | ||
| 137 | + | // ==================================================================== | |
| 138 | + | // | | |
| 139 | + | // ==================================================================== | |
| 140 | + | function startWatcher(watchFolders) { | |
| 141 | + | ||
| 142 | + | // https://github.com/paulmillr/chokidar | |
| 143 | + | const options = { | |
| 144 | + | awaitFinish: true, | |
| 145 | + | ignoreInitial: true, | |
| 146 | + | usePolling: true, | |
| 147 | + | interval: 100 | |
| 148 | + | } | |
| 149 | + | ||
| 150 | + | const watcher = chokidar.watch(watchFolders, options).on('all', (event, path) => { | |
| 151 | + | log(`${path} was ${event}`); | |
| 152 | + | }); | |
| 153 | + | ||
| 154 | + | watcher | |
| 155 | + | .on('add', path => compile(path)) | |
| 156 | + | .on('change', path => compile(path)) | |
| 157 | + | .on('unlink', path => compile(path)); | |
| 158 | + | ||
| 159 | + | watcher | |
| 160 | + | .on('ready', () => log('********** Watch is running **********')); | |
| 161 | + | ||
| 162 | + | } | |
| 163 | + | ||
| 164 | + | // ==================================================================== | |
| 165 | + | // | MAIN | |
| 166 | + | // ==================================================================== | |
| 167 | + | async function go() { | |
| 168 | + | const watchFolders = [ | |
| 169 | + | '/app/scss/**/*.scss' | |
| 170 | + | ] | |
| 171 | + | if (process.argv[2] == 'recompile') { | |
| 172 | + | await compileAll('/app/scss/**/*.scss') | |
| 173 | + | startWatcher(watchFolders); | |
| 174 | + | } else { | |
| 175 | + | startWatcher(watchFolders); | |
| 176 | + | } | |
| 177 | + | } | |
| 178 | + | ||
| 179 | + | go() | |