enuchi / React-Google-Apps-Script

This is your boilerplate project for developing React apps inside Google Sheets, Docs, Forms and Slides projects. It's perfect for personal projects and for publishing complex add-ons in the Google Workspace Marketplace.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to create custom functions in V3 version?

kulovecc opened this issue · comments

/**

  • desc
  • @param {any} p1 p1.
  • @return text.
  • @customfunction
    */
    global.CUST_FUNC = (p1) => {
    return 'text';
    };

This is how it was created in previous versions, but it doesn't work in V3.

Correct. I don't yet have a way to support this in V3.

You could look at the vite config file if you want to tinker with it, but right now you can either add the docs manually after the build, or use V2.

You can modify the config to get it working like this:

Install gas-entry-generator:
yarn add -D gas-entry-generator

Add your custom function code in the format below:

// custom-functions.ts

export const MYCUSTOMFUNCTION1 = (a: number, b: number) => a * b;
export const MYCUSTOMFUNCTION2 = (a: number, b: number) => a ^ b;

/**
 * Returns the product of the two numbers
 * @param {number} a The first value to multiply.
 * @param {number} b The second value to multiply.
 * @returns The product of the two numbers.
 * @customfunction
 * @preserve
 */
// @ts-expect-error
exports.MYCUSTOMFUNCTION1 = (a: number, b: number) => MYCUSTOMFUNCTION1(a, b);

/**
 * Returns a to the power of b
 * @param {number} a The base number.
 * @param {number} b The number to raise a to.
 * @returns The number a to the power of b.
 * @customfunction
 * @preserve
 */
// @ts-expect-error
exports.MYCUSTOMFUNCTION2 = (a: number, b: number) => MYCUSTOMFUNCTION2(a, b);

Export in main server entrypoint:

// index.ts
...
export { MYCUSTOMFUNCTION1, MYCUSTOMFUNCTION2 } from './custom-functions';

Modify the serverBuildConfig's rollupOptions.output section in vite.config.ts:

// vite.config.ts
...
import { generate } from 'gas-entry-generator';
...
rollupOptions: {
    output: {
      entryFileNames: 'code.js',
      extend: true,
      footer: (chunk: RenderedChunk) => {
        const fullCode = chunk.moduleIds
          .map((moduleId) => chunk.modules[moduleId].code)
          .join('\n');

        const options = {
          comment: true,
          autoGlobalExports: true,
        };
        const output = generate(fullCode, options);
        const entryPointFunctionSnippet = output.entryPointFunctions;
        const globalAssignedFunctionNames = new Set([]);

        const functionNameRegex = /function (\w+)/g;
        let match = functionNameRegex.exec(entryPointFunctionSnippet);
        while (match !== null) {
          globalAssignedFunctionNames.add(match[1]);
          match = functionNameRegex.exec(entryPointFunctionSnippet);
        }
        return (
          chunk.exports
            .filter(
              (exportedFunction) =>
                !globalAssignedFunctionNames.has(exportedFunction)
            )
            .map((exportedFunction) => `function ${exportedFunction}() {};`)
            .join('\n') + output.entryPointFunctions
        );
      },
    },
  }
...

When you run yarn deploy it should show autocomplete options.

Thank you for sharing this solution!

I have a question regarding the generate method used in the vite.config.ts configuration. You mentioned:

const output = generate(fullCode, options);

However, I couldn't find any references to this generate method. Could you please provide more details on what this method is, where it comes from, or how it should be implemented?

Thank you in advance for your help!

Right, sorry, I forgot to add the import statement for the top of vite.config.ts:

import { generate } from 'gas-entry-generator';

I'll update the comment above.