Google Apps Script ES-5 Engine + Coding Tips

Max Makhrov
3 min readOct 23, 2024

--

Why use this?

For a small project → stick with the Google App Script editor.

For a big project with lots of JS logic →

👋🏼Welcome go to local development!

Photo by GCP 3D on Unsplash

Try if you have a big project, or want these benefits:

  • Speed for MySQL connection (as the new ES-8 engine works slowly). This code is converted to ES-5.
  • Type checking. If you make a mistake in object property or return the wrong type → the editor will show you.
  • JS syntax. Yes, this engine uses the best of TypeScript—type checking—and JS—JSDocs. You can write code using JS or TypeScript if you like. The bundle will be a valid ES-5.
  • Unit tests with Vitest. Simple, but powerful
  • Install third-party JS libraries. I used slugify and it worked perfectly.
  • Real version control with Git and GitHub to preserve your code.
  • All the code will be compiled into 1 file. This will make it easy for you to use it as a library.

Disadvantages:

  • You’ll have to install it.

Installation Steps

Clone & Install

Open Terminal (or PowerShell on Windows)

Run:

git clone https://github.com/Max-Makhrov/gasfive.git --branch v1 MyProject

Move to the project directory:

cd MyProject

Open in VS Code:

code .

Setup in VS Code

  • Run: npm install
  • Build: npm run build (wait for completion)
  • Update project ID in .clasp.json. (Use script.new URL for standalone scripts)
  • Initialize Git: git init
  • Install CLASP if needed (see their docs).

Version Control

Verify the setup → open GitHub repo to see.

Tips & Best Practices

  • File Structure: Keep code clean by following a 1 file = 1 function rule.
  • Type Imports: Combine imports into one line; they’re removed in the build for GAS. Like below:
/** @typedef {import(“./type.js”).EngineTest} EngineTest */
  • Private Functions: End function names with “_”, e.g., testJsEngine_. Use unique function names!
  • JSDoc Comments: Use them for parameters. Like below:
/**
* @typedef {Object} EngineTest
* @prop {Boolean} is_error
* @prop {String} message
*/

/**
* @returns {String}
*/
export function getDefaultMessage_() {
return "ok";
}
  • Function Usage for ES-5 compatibility and autocomplete: Prefer functions over classes for compatibility and autocomplete. Like below:
/**
* @constructor
*
* @param {String} message
*/
export function BuildWithMe_(message) {
const self = this;
self.message = message;

console.info("👉🏼Constructor was just created!");

let countRuns = 0; // private

/**
* @method
* @returns {EngineTest}
*/
self.test = function () {
countRuns++;
return testJsEngine_(self.message);
};

/**
* @returns {Number}
*/
self.getCounter = function () {
return countRuns;
};
}
  • Testing: Use Vitest for tests. Test all (npm run test) or 1 file for better performance. Sample command for testing 1 file:
npm run test test\Sample\code.test.js --watch
  • In clasp.json, set "rootDir":".\\dist" and place appsscript.json there to use one GAS folder. Now you do not need to ignore files!

Utilities

  • Use clasp open if you lose the App Script URL.
  • Use console.info for key logs. Remove console.log before deploying to keep code clean and debugging easier.

Version Control

Save every build:

  • git add .
  • git commit -m "comment"
  • git push origin v1

What to add?

Did I miss a bit? Please comment, so I know of a mistake.

Happy coding! May your code run flawlessly and bugs always bypass.

Max.

--

--