A simple way to use .js files both in node and on the front-end is to check for module and module.export objects before assigning to them.
Example convert-date.js file:
function convertDate(date) {
// blah blah
}
if(this && typeof module == "object" && module.exports && this === module.exports) {
module.exports = convertDate; // for example
}
which results in declaring convertDate as a global function name on the front-end while allowng it to be required in node using
const convertDate = require(pathOfConvertDate.js);
To limit the number of globals created put more complex code inside an IIFE which returns the value to be exported:
const convertDate = (()=>{..... return convertDate;})();
if( this etc...) module.exports = convertDate;
A variation of the above is to mandate the presence of a common utilities object on the front-end which must be declared before file inclusion. Using Util as an example name, the export code becomes more like
if(this && typeof module == "object" && module.exports && this === module.exports) {
module.exports = convertDate; // for example
}
else if(typeof Util == "object" && Util) {
Util.convertDate = convertDate;
}
else {
throw( Error("Front-end 'Util' export object not found'));
}
FWIW I don't know how common this kind of usage is. I do know it works with file:// protocol and simplifies writing test code that runs equally well on the back or front-end.