From 69c7d6333a484db51896018ad3d6fa9478c4383c Mon Sep 17 00:00:00 2001 From: brenden adamczak Date: Mon, 18 Dec 2023 01:18:51 -0500 Subject: [PATCH] build modules in now javascript script --- bin/buildmodules.js | 73 ++++++++++++++++++++++++++++ bin/minify.js | 116 +++++++++++++++++++------------------------- buildmodules.sh | 50 ------------------- moduleignore | 1 - package.json | 4 +- 5 files changed, 127 insertions(+), 117 deletions(-) create mode 100644 bin/buildmodules.js delete mode 100755 buildmodules.sh delete mode 100644 moduleignore diff --git a/bin/buildmodules.js b/bin/buildmodules.js new file mode 100644 index 000000000..37527ac9a --- /dev/null +++ b/bin/buildmodules.js @@ -0,0 +1,73 @@ +// Copyright (c) 2023 Brenden Adamczak, Pur3 Ltd. See the file LICENSE for copying permission. +const fs = require('fs'); +const fse = require('fs-extra'); +const path = require('path'); +const minify = require('./minify'); + +function same(file1,file2){ + if(!fs.existsSync(file1)) return false; + if(!fs.existsSync(file2)) return false; + const f1 = fs.readFileSync(file1, 'utf8'); + const f2 = fs.readFileSync(file2, 'utf8'); + return f1 === f2; +} + +function older(file1,file2){ + if(!fs.existsSync(file1)) return false; + if(!fs.existsSync(file2)) return false; + return fs.statSync(file1).mtime > fs.statSync(file2).mtime; +} + +const DIR= process.cwd(); +const HOME = process.env.HOME; +const WEBSITE = `${HOME}/workspace/espruinowebsite` +const MODULEDIR= `${WEBSITE}/www/modules`; + +var modules = []; +// Minify all modules +if(typeof process.env.npm_config_file === 'undefined'){ + const dirList = ["devices","modules","boards"]; + modules = dirList.map((dir)=>{return fs.readdirSync(dir).map((name)=>`${dir}/${name}`)}).flat(); + modules = modules.filter(name => name.endsWith('.js') ); +} +else{ +//mifify a single module + modules[0] = process.env.npm_config_file; +} + +modules.forEach(function (module) { + console.log(module); + if(!fs.existsSync(module)) {console.log(`${module} - doesn't exist`); return;} + + const BNAME = path.basename(module) //'DS18B20.js' + const MINJS = `${path.parse(BNAME).name}.min.js` // e.g. 'DS18B20.min.js' + const FULL_NAME = `${MODULEDIR}/${BNAME}`; + const FULL_MINJS = `${MODULEDIR}/${MINJS}`; + // An optional externs-file must be in the same directory as the module file. + // Example devices/.../DS18B20.js → devices/.../DS18B20.externs + const externsFile = `${path.dirname(module)}/${path.parse(BNAME).name}.externs` // e.g. /DS18B20.externs + + // do nothing if .. + // .. the module code haven't changed and + // .. the target module file is newer than an existing externs file (or the externs file does not exist) + if(same(module, FULL_NAME) && older(FULL_NAME, externsFile)){ + console.log("already made") + return; + } + + //console.log(`Module [${BNAME}] is different or doesn't exist`); + fse.copySync(module, FULL_NAME); + + + minify(FULL_NAME,FULL_MINJS,externsFile); + console.log(FULL_MINJS) + + if (fs.existsSync(FULL_MINJS) && fs.statSync(FULL_MINJS).size > 0) { + console.log(`${FULL_MINJS} compile successful`); + } + else { + if(fs.existsSync(FULL_MINJS)) fs.unlinkSync(FULL_MINJS); + console.log(`${BNAME} compile FAILED.`); + process.exit(); + } +}); diff --git a/bin/minify.js b/bin/minify.js index e385e1a6d..1fd0a6a60 100755 --- a/bin/minify.js +++ b/bin/minify.js @@ -13,43 +13,9 @@ var fs = require("fs"); const os = require('os'); const path = require('path'); const child_process = require("child_process"); +const CLOSURE_JAR = path.join(__dirname, "..", "closure-compiler.jar"); -var CLOSURE_JAR = path.join(__dirname, "..", "closure-compiler.jar"); - -if (process.argv.length!=4 && process.argv.length!=5) { - console.log("USAGE: node minify.js fileIn.js fileOut.min.js [fileIn.externs]"); - process.exit(1); -} - -var fileIn = process.argv[2]; -var fileOut = process.argv[3]; -var fileExterns = process.argv[4]; - -console.log("Minifying ",fileIn,"to",fileOut); -var js = fs.readFileSync(fileIn).toString(); - -// check if advanced optimization is possible -var advancedOptimisation = false; -var jsExterns = fs.readFileSync( JSEXTERNS_FILE ); -if (fs.existsSync(fileExterns)) { - jsExterns += ("\n" + fs.readFileSync(fileExterns).toString()); - advancedOptimisation = true; -} - -// Now wrap up the JS so that the compiler will strip out any locals in simple optimization mode. -// This is not necessary with advance optimization. -if (!advancedOptimisation) { - js = wrapSelfInvocation( js ); -} - -var compilation_level = advancedOptimisation ? 'ADVANCED_OPTIMIZATIONS' : 'SIMPLE_OPTIMIZATIONS'; -if (js.includes("MINIFY_WHITESPACE_ONLY")) - compilation_level = "WHITESPACE_ONLY"; -var language_out = (js.includes('ECMASCRIPT_2015')?'ECMASCRIPT_2015':'STABLE'); -console.log("compilation_level =",compilation_level, - "\nlanguage_out =",language_out); - -function closureOnline() { +function closureOnline(js,jsExterns,fileOut, compilation_level,advancedOptimisation) { var https = require("https"); var options = [ ['compilation_level',compilation_level], @@ -120,7 +86,7 @@ function closureOnline() { var minified = jsonResult.compiledCode + '\n'; console.log('Minification complete! ' ); - codeMinified( minified ); + codeMinified(fileOut, minified,advancedOptimisation ); }); }); // post the data @@ -129,7 +95,7 @@ function closureOnline() { } -function closureOffline() { +function closureOffline(js,jsExterns,fileOut,compilation_level,advancedOptimisation) { // wow. closure CLI doesn't like binary literals?? //js = js.replace(/(0b[01]+)/g, n => parseInt(n.substr(2),2)); // create files @@ -152,25 +118,17 @@ function closureOffline() { var cli;// = "closure-compiler"; cli = "java -jar "+'"'+CLOSURE_JAR+'"'; cli += " "+options.map( o => "--"+o[0]+" "+o[1]).join(" "); - child_process.exec(cli, (error, stdout, stderr) => { - fs.unlinkSync(tmpPath+".js", js) - fs.unlinkSync(tmpPath+".ext.js", js) - if (error) { - console.log(`error: ${error.message}`); - return; - } - if (stderr) { - console.log(`stderr: ${stderr}`); - } - console.log(`stdout: ${stdout}`); - var finalJS = fs.readFileSync(tmpPath+".out.js").toString(); - fs.unlinkSync(tmpPath+".out.js", js) - codeMinified(finalJS); - }); + child_process.execSync(cli); + + fs.unlinkSync(tmpPath+".js", js) + fs.unlinkSync(tmpPath+".ext.js", js) + var finalJS = fs.readFileSync(tmpPath+".out.js").toString(); + fs.unlinkSync(tmpPath+".out.js", js) + codeMinified(fileOut,finalJS,advancedOptimisation); } -function codeMinified(minified) { +function codeMinified(fileOut, minified,advancedOptimisation) { if (!advancedOptimisation) { minified = unwrapSelfInvocation( minified ); } @@ -200,17 +158,45 @@ function unwrapSelfInvocation( wrappedJs ) { } } -// any other way to test for existence?? -if (!fs.existsSync(CLOSURE_JAR)) { - console.log(CLOSURE_JAR); - console.log("==================================================================="); - console.log("Using online closure compiler. To use faster offline version download"); - console.log("the closure compiler jar to closure-compiler.jar"); - console.log("==================================================================="); - closureOnline(); -} else { - console.log("Using offline closure compiler"); - closureOffline(); +module.exports = function(fileIn,fileOut,fileExterns){ + + + console.log("Minifying ",fileIn,"to",fileOut); + var js = fs.readFileSync(fileIn).toString(); + + // check if advanced optimization is possible + var advancedOptimisation = false; + var jsExterns = fs.readFileSync( JSEXTERNS_FILE ); + if (fs.existsSync(fileExterns)) { + jsExterns += ("\n" + fs.readFileSync(fileExterns).toString()); + advancedOptimisation = true; + } + + // Now wrap up the JS so that the compiler will strip out any locals in simple optimization mode. + // This is not necessary with advance optimization. + if (!advancedOptimisation) { + js = wrapSelfInvocation( js ); + } + + var compilation_level = advancedOptimisation ? 'ADVANCED_OPTIMIZATIONS' : 'SIMPLE_OPTIMIZATIONS'; + if (js.includes("MINIFY_WHITESPACE_ONLY")) + compilation_level = "WHITESPACE_ONLY"; + var language_out = (js.includes('ECMASCRIPT_2015')?'ECMASCRIPT_2015':'STABLE'); + console.log("compilation_level =",compilation_level, + "\nlanguage_out =",language_out); + + // any other way to test for existence?? + if (!fs.existsSync(CLOSURE_JAR)) { + console.log(CLOSURE_JAR); + console.log("==================================================================="); + console.log("Using online closure compiler. To use faster offline version download"); + console.log("the closure compiler jar to closure-compiler.jar"); + console.log("==================================================================="); + closureOnline(js,jsExterns,fileOut,compilation_level,advancedOptimisation); + } else { + console.log("Using offline closure compiler"); + closureOffline(js,jsExterns,fileOut,compilation_level,advancedOptimisation); + } } diff --git a/buildmodules.sh b/buildmodules.sh deleted file mode 100755 index 5080120a4..000000000 --- a/buildmodules.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/bash -# Copyright (c) 2013 Gordon Williams, Pur3 Ltd. See the file LICENSE for copying permission. -cd `dirname $0` -DIR=`pwd` -WEBSITE="$HOME/workspace/espruinowebsite" - -MODULEDIR=$WEBSITE/www/modules -mkdir -p $MODULEDIR - -# Minify all modules -MODULES=`find devices modules boards -name "*.js" | grep -v -f moduleignore` - -for module in $MODULES; do - if [ -f $module ]; then - echo ">>>>" $module # e.g. /DS18B20.js - - BNAME=`basename $module .js` # e.g. 'DS18B20' - MINJS=${BNAME}.min.js # e.g. 'DS18B20.min.js' - - # An optional externs-file must be in the same directory as the module file. - # Example devices/.../DS18B20.js → devices/.../DS18B20.externs - externsFile="`dirname $module`/`basename -s .js $module`.externs" # e.g. /DS18B20.externs - TARGET_MODULE="$MODULEDIR/$BNAME.js" # e.g. ~/workspace/espruinowebsite/www/modules/DS18B20.js - - # do nothing if .. - # .. the module code haven't changed and - # .. the target module file is newer than an existing externs file (or the externs file does not exist) - - if (diff $module $MODULEDIR/$BNAME.js >/dev/null 2>&1) && [[ (! -e $externsFile) || ($TARGET_MODULE -nt $externsFile) ]]; then - echo "Module $BNAME hasn't changed, leaving" - continue - fi - - echo "Module $BNAME is different or doesn't exist" - - rm -f $MODULEDIR/$MINJS - cp $module $MODULEDIR/$BNAME.js - - echo min $MODULEDIR/$module to $MINJS - node bin/minify.js "$MODULEDIR/$BNAME.js" "$MODULEDIR/$MINJS" "$externsFile" - - if [[ -s $MODULEDIR/$MINJS ]] ; then - echo "$MODULEDIR/$MINJS compile successful" - else - rm $MODULEDIR/$BNAME.js - echo "$module compile FAILED." - exit 1 - fi - fi -done diff --git a/moduleignore b/moduleignore deleted file mode 100644 index 7835c5af0..000000000 --- a/moduleignore +++ /dev/null @@ -1 +0,0 @@ -boards/PixljsMulticolour/simple.js diff --git a/package.json b/package.json index 0f53fa33a..27ebd10a4 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,8 @@ "eslintdevices": "./node_modules/.bin/eslint devices/*.js", "eslintmodules": "./node_modules/.bin/eslint modules/*.js", "eslintboards": "./node_modules/.bin/eslint boards/*.js", - "start": "node app.js" + "start": "node app.js", + "build_modules": "node ./bin/buildmodules.js" }, "repository": { "type": "git", @@ -33,6 +34,7 @@ "acorn-walk": "^6.1.0", "eslint": "^5.14.1", "express": "^4.13.3", + "fs-extra": "^11.2.0", "highlight.js": "^8.9.1", "marked": "^0.3.6", "tern": "^0.16.0"