Skip to main content

Google Apps Script and ES Modules

Currently, Google Apps Script does not support ES modules - and any usage of export/import will fail.

One way of handling this is to use rollup.js to bundle your project into one single JavaScript file.

The trick here is to make sure not to export any functions in your entry point code, e.g. index.ts, and to prevent any generation of export statement in the final bundle (see the custom rollup plugin in the rollup.config.js below).

import { babel } from "@rollup/plugin-babel";
import { nodeResolve } from "@rollup/plugin-node-resolve";

const extensions = [".ts", ".js"];

const preventThreeShakingPlugin = () => {
    return {
      name: 'no-threeshaking',
      resolveId(id, importer) {
        if (!importer) {
            // let's not theeshake entry points, as we're not exporting anything in Apps Script files
          return {id, moduleSideEffects: "no-treeshake" }
        }
        return null;
      }
    }
  }

export default {
  input: "./src/index.ts",
  output: {
    dir: "build",
    format: "esm",
  },
  plugins: [
    preventThreeShakingPlugin(),
    nodeResolve({
      extensions,
    }),
    babel({ extensions, babelHelpers: "runtime" }),
  ],
};
In order to use babel to transpile the code, be sure to add a babel.config.js to the project:
module.exports = {
  presets: [
    [
      // ES features necessary for user's Node version
      require("@babel/preset-env").default,
      {
        targets: {
          node: "current",
        },
      },
    ],
    [require("@babel/preset-typescript").default],
  ],
};
In the above example, the resulting bundle created by transpiling the entry point in ./src will end up in the ./build-folder. To make sure Clasp picks the right files to push, a .claspignore-file must be added to the project:

# ignore all files…
**/**

# except the extensions…
!appsscript.json
!build/*.js

# ignore even valid files if in…
.git/**
node_modules/**
This should be enough to start developing a project using ES Modules.

Comments

Popular posts from this blog

GWT and Spring Security

Update! - Based on the post below, and my other post regarding Spring Security and OpenID, I have added Open-ID support to the sample application below. For those interested, here's the write-up of changes. I've spent quite some time digging into ways of integrating GWT and Spring Security. It all started by reading the following post in the GWT Forum - Best practices/ideas for GWT with Spring Security (or equivalent) , and then checking out this blog - GWT and Spring Security . To make matters worse, I started reading Security for GWT Applications and specifically about the "Cross-Site Request Forging"-attacks. Now, what could I do about it? Well, starting by setting up my own project (Maven-based) with all updated dependencies (GWT 2.0.3 etc) and started reading the Spring Security Reference Documentation (puh!). Instead of See Wah Cheng's approach of implementing a custom authentication service, I decided to rely on standard namespace configuration

Using Spring Security's OpenID implementation (openid4java) on Google App Engine

The goal with this exercise is to have a running example of an OpenID login on a simple Spring application, using Google as the OpenID Provider. Note that the application will be running on Google App Engine and that Spring Roo is only used for simplicity of creating the project files. Any Spring-based application could use the same implementation. First of all, create a simple project using Spring Roo (or any equivalent framework), including the default security setup: project --topLevelPackage com.technowobble persistence setup --provider DATANUCLEUS --database GOOGLE_APP_ENGINE entity --class ~.domain.MyEntity field string --fieldName name controller all --package com.technowobble.controller security setup This setup only provides us with a form-login, which is not what we wanted. So what about OpenID? Well, if it wasn't for Google App Engine, I would happily have added an <openid-login>-tag to applicationContext-security.xml, but things are never that easy, are the

Adding a custom GWT module in a Roo-project

So I started looking into Roo the other day. Seems like a nice tool (once it matures a little more). Anyway - I wanted to create a custom module in addition to the two being generated when adding GWT-support to the project. Not as easy as I thought, mainly because I hadn't seen the Url Rewrite Filter before. I ended up with a 404, no matter what I did, and couldn't figure out why. Frustration! After reading up on the url rewrite stuff, I was ready to give it another try. Let's create a module called Application, based on the standard sample application you'll get using the GWT wizard in Eclipse. First of all, create the Roo project using the following instructions: project --topLevelPackage com.technowobble persistence setup --provider HIBERNATE --database HYPERSONIC_IN_MEMORY entity --class com.technowobble.domain.MyEntity gwt setup (The "gwt setup" setup command generates some code that will not compile unless there's a persistence setup and at lea