Fork me on GitHub

@kovas.palunas I don't expect a development build to work. as I said it expects not and as such uses node features. shadow-cljs release app might.


instead of resolve use exists? js/SpreadsheetApp


can you point me to some documentation about apps scripts? do they support ES modules? ie. import/export?


the whole point of the shadow-cljs :target abstraction is to make target specific builds. there could absolutely be a :target :google-apps-script. I just have never used that so I don't know how it needs to be bundled

Kovas Palunas17:05:50

thanks for the gist link! i ended up solving that problem with a simple defn that takes in anonymous functions to execute: the resolve call i'm using now works well - is exists? just a better name for the same functionality?

Kovas Palunas17:05:41

apps script is interesting in that it's a (AFAIK) totally self contained development environment:

Kovas Palunas17:05:23

usually you would write code in their browser editor and run it. it interacts with various google products via its own special API

Kovas Palunas17:05:14

it has a CLI utility for local development (not in their browser editor)

Kovas Palunas17:05:40

my understanding is that apps script code should be bundled as just one big flat js file with everything in it

Kovas Palunas17:05:06

and no undefined names (that would otherwise be defined in other places)

Kovas Palunas17:05:47

AFAIK apps script does not support js dependencies of any kind (although if they were inlined in the bit flat file that would work)

Kovas Palunas17:05:27

one interesting quirk of apps script also is that it doesn't like namespaced names. describes a workaround. i'm currently just appending some non-namespaced functions that call my core functionality to my big js file in a bash script

Kovas Palunas19:05:35

btw it looks like shadow-cljs release app does not work due to google apps script seeing a syntax error in the generated js file. perhaps this is because of subtle differences between javascript and google apps script

Kovas Palunas19:05:24

strangely, the lein cljsbuild once command's output is interpreted just fine. i think this has to do with the clojurescript version. I'm using "1.10.439" in my project.clj and saw that using "1.10.773" led to this syntax error


define syntax error

Kovas Palunas19:05:43

i should probably try using this older version in my shadow-cljs


it really is much easier to answer question if you provide the actual errors


no just say that there is an error 😛

Kovas Palunas19:05:05

yeah i know, one sec

Kovas Palunas19:05:28

the message is 'Syntax error: Missing ; before statement. line: 24 file: Code',, let me get a link to the file


try with shadow-cljs release app --pseudo-names or --debug


also whats in line 24?

Kovas Palunas19:05:14

getting it, one sec


also try :compiler-options {:output-feature-set :es5} in your build config. maybe it doesn't like newer syntax


this also only applies to dev builds. release will be a single file

👍 1
Kovas Palunas19:05:36

i just tried a release build here, but got the same syntax errors

Kovas Palunas19:05:58

errors: [
      message: 'Syntax error: Missing ) after formal parameters. line: 1420 file: Code',
      domain: 'global',
      reason: 'badRequest'

Kovas Palunas19:05:04

goog.loadModule(function(exports) {
  "use strict";
  function DebugError(msg = undefined, cause = undefined) {  // <- 1420
    if (Error.captureStackTrace) {
      Error.captureStackTrace(this, DebugError);
    } else {
      const stack = (new Error()).stack;
      if (stack) {
        this.stack = stack;

Kovas Palunas19:05:35

the :es5 option didn't work

Kovas Palunas19:05:45

but i feel like that might be the right idea

Kovas Palunas19:05:18

it would make sense that apps script is equivalent to a certain version of javascript that is not the latest one

Kovas Palunas19:05:40

--pseudo-names didn't work either

Kovas Palunas19:05:53

i figured out that I can set the javascript version used by apps script to use Chrome V8 instead of rhino, which makes the syntax errors go away!

Kovas Palunas19:05:47

now i'm simply getting ErrorReferenceError: global is not defined when i try to run my code

Kovas Palunas19:05:31

using :target :browser gives

12:35:01 PM	Error	Cannot use default debug loader outside of HTML documents.
12:35:01 PM	Error	Consider setting CLOSURE_IMPORT_SCRIPT before loading base.js, or setting CLOSURE_NO_DEPS to true.
12:35:01 PM	Error	
TypeError: Cannot set property 'NodeType' of undefined

Kovas Palunas19:05:31

so yeah i think the syntax error problem is solved, but there is still an issue with shadow-cljs output expecting names that are not provided by the apps script environment (the global name at least)


this is with a release build?


watch/compile assumes browser environment. so not expected to work.


global comes from the assumption of running in node

Kovas Palunas19:05:20

yes this is a release build

Kovas Palunas19:05:24

that makes sense

Kovas Palunas19:05:49

if i add var global = {}; to the top i get another error:


Kovas Palunas19:05:57

TypeError: Cannot set property 'NodeType' of undefined

Kovas Palunas19:05:23

because i think

var goog = goog || {}; = global;


there is no more goog.module or goog.provide in the file right?


> the javascript version used by apps script to use Chrome V8

Kovas Palunas19:05:15

goog.module.get = function(name) {
  return goog.module.getInternal_(name);


are there docs on this? I mean what the runtime is capable of?


I mean goog.module(...) calls

Kovas Palunas19:05:53

yes those lines exist goog.module("goog.debug.Error");

Kovas Palunas19:05:00

should they not exist in a release build?


this is not a release build no?

Kovas Palunas19:05:24

i'm calling (run "npx" "shadow-cljs" "release" "autojournal")


welll :optimizations :whitespace


don't do that


at least :simple

Kovas Palunas19:05:16

i still have the missing global problem without :optimizations :whitespace


just add the var global = {} again?

Kovas Palunas19:05:24

i get ErrorReferenceError: process is not defined

Kovas Palunas19:05:41


;af(function() {
  return dt();
}, process.argv.slice(2));

Kovas Palunas19:05:08

this is the very last bit of code in the file!


again. :node-script assumes node. try :browser


I'm not asking about v8 in general. I need to know in the context of google apps script what features it supports


node is also v8 and that has global and process just fine


so, are there any docs specifically about what the google apps script runtime is capable of?

Kovas Palunas19:05:52

i haven't found them yet


I would write a custom :target for this that handles all the appscript specific stuff. I just don't have time to look into that currently


maybe the v8 supports import, then dev builds might work. otherwise release only again


but that should not have any process or global references


although it may have globalThis. which may or may not be present in that v8 variant

Kovas Palunas20:05:17

no dice on the :esm yet: message: "Syntax error: SyntaxError: Unexpected token 'export' line: 14202 file: ",

Kovas Palunas20:05:35

no worries!! I'm super grateful for all the tips so far!


if you remove that export line? should be like the last one


I believe you can also just leave out exports in the build config and just use :entries [your.ns]

Kovas Palunas20:05:31

ok i got something working

Kovas Palunas20:05:01

i needed to add "var global = {}; var process = {\"argv\": [\"one\", \"two\"]};" to the top of my file

Kovas Palunas20:05:01

and i needed to remove the (function(){ ... })();

Kovas Palunas20:05:07

wrapping the entire file

Kovas Palunas20:05:21

hacky but it seems to work

Kovas Palunas20:05:41

haha this is kinda silly but i'm glad the problem is solved. i'll make a note to myself to write this up somewhere. or would you take this hack as a contribution for :target :apps-script


well with a custom target it would be less hacky


because the process thing is added by :node-script


as well as all the other stuff pretty much

Kovas Palunas20:05:58

ok that makes sense


you can try to create your own impl. can be in your repo. doesn't need to be part of shadow-cljs itself. no fork or so needed

Kovas Palunas20:05:24

how can i reference my own impl from my shadow-cljs.edn?


if you create a ns or so


just :target :google-apps-script


or :target your.ns with (ns your.ns)


it looks for a process fn just like in the :node-script impl

Kovas Palunas20:05:43

this namespace is in a clj file that I reference with shadow-cljs?

Kovas Palunas20:05:05

or in a fork of shadow-cljs i make?


it is just a clj file in your repo


as I said no fork or anything


just copy the node-script file from above and rename it


then start hacking 😉


run a shadow-cljs clj-repl or work on it from your editor

Kovas Palunas20:05:03

right i guess when you say "your repo" do you mean my own copy of the shadow-cljs repo, or my project repo?


project repo


just needs to be on the classpath. no modification in shadow-cljs required whatsoever

Kovas Palunas20:05:52

can i specify the classpath in shadow-cljs.edn?

Kovas Palunas20:05:08

(i've not worked with clj much, only cljs)


you already do. :source-paths ["src"] so just src/shadow/build/targets/google_apps_script.clj or whatever name you want


sorry way too late to walk you through this. that part happens in the flush call, so the node/flush-optimized