最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Using transpiled ES6 in Google Apps Script => ReferenceError: "SomeClass" is not defined -

programmeradmin0浏览0评论

I'm trying to use ES6 in a Google Spreadsheet (in the script.google part). I'm pretty new to JavaScript and maybe the error is trivial ...


  • 28/09: The error for the post as changed as I was just using a Google Apps Script library name (Logger), I switch to SomeClass. I'm looking to module as my declaration is not the good one

What I have done:

  • Created a webpack project
  • Created a Logger class
  • Created a main.js where I import the Logger class
  • WebPack generate a bundle from my main.js
  • I copy/paste the bundle.js in a bundle file on script.google
  • I try to run a test in script.google but got ReferenceError:SomeClass is not define.`

Here is my code:

SomeClass.js

export default class SomeClass {
    constructor() {
        this.loggerSheet = SpreadsheetApp.getActiveSpreadsheet()
                                    .getSheetByName("ImportLog");
    }

    LogInfo(data) {
      Logger.log(data);
      loggerSheet.appendRow([new Date(), "INFO", data]);
    }
}

Main.js

import SomeClass from './SomeClass.js';

Test in script.google

function test_bundle() {
  var someClass = new SomeClass(); //<== breaks here
}

Bundle.js => copy/paste to script.google

/******/ (function(modules) { // webpackBootstrap
/******/    // The module cache
/******/    var installedModules = {};

/******/    // The require function
/******/    function __webpack_require__(moduleId) {

/******/        // Check if module is in cache
/******/        if(installedModules[moduleId])
/******/            return installedModules[moduleId].exports;

/******/        // Create a new module (and put it into the cache)
/******/        var module = installedModules[moduleId] = {
/******/            exports: {},
/******/            id: moduleId,
/******/            loaded: false
/******/        };

/******/        // Execute the module function
/******/        modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

/******/        // Flag the module as loaded
/******/        module.loaded = true;

/******/        // Return the exports of the module
/******/        return module.exports;
/******/    }


/******/    // expose the modules object (__webpack_modules__)
/******/    __webpack_require__.m = modules;

/******/    // expose the module cache
/******/    __webpack_require__.c = installedModules;

/******/    // __webpack_public_path__
/******/    __webpack_require__.p = "";

/******/    // Load entry module and return exports
/******/    return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {

    'use strict';

    function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

    var _SomeClassJs = __webpack_require__(4);

    var _SomeClassJs2 = _interopRequireDefault(_SomeClassJs);

/***/ },
/* 1 */,
/* 2 */,
/* 3 */,
/* 4 */
/***/ function(module, exports) {

    "use strict";

    Object.defineProperty(exports, "__esModule", {
        value: true
    });

    var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();

    function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

    var SomeClass = (function () {
        function SomeClass(option) {
            _classCallCheck(this, SomeClass);

            this.loggerSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("ImportLog");
        }

        _createClass(SomeClass, [{
            key: "logInfo",
            value: function logInfo(data) {
                loggerSheet.appendRow([new Date(), "INFO", data]);
            }
        }]);

        return SomeClass;
    })();

    exports["default"] = SomeClass;
    module.exports = exports["default"];

/***/ }
/******/ ]);

I'm trying to use ES6 in a Google Spreadsheet (in the script.google.com part). I'm pretty new to JavaScript and maybe the error is trivial ...


  • 28/09: The error for the post as changed as I was just using a Google Apps Script library name (Logger), I switch to SomeClass. I'm looking to module as my declaration is not the good one

What I have done:

  • Created a webpack project
  • Created a Logger class
  • Created a main.js where I import the Logger class
  • WebPack generate a bundle from my main.js
  • I copy/paste the bundle.js in a bundle file on script.google
  • I try to run a test in script.google but got ReferenceError:SomeClass is not define.`

Here is my code:

SomeClass.js

export default class SomeClass {
    constructor() {
        this.loggerSheet = SpreadsheetApp.getActiveSpreadsheet()
                                    .getSheetByName("ImportLog");
    }

    LogInfo(data) {
      Logger.log(data);
      loggerSheet.appendRow([new Date(), "INFO", data]);
    }
}

Main.js

import SomeClass from './SomeClass.js';

Test in script.google

function test_bundle() {
  var someClass = new SomeClass(); //<== breaks here
}

Bundle.js => copy/paste to script.google

/******/ (function(modules) { // webpackBootstrap
/******/    // The module cache
/******/    var installedModules = {};

/******/    // The require function
/******/    function __webpack_require__(moduleId) {

/******/        // Check if module is in cache
/******/        if(installedModules[moduleId])
/******/            return installedModules[moduleId].exports;

/******/        // Create a new module (and put it into the cache)
/******/        var module = installedModules[moduleId] = {
/******/            exports: {},
/******/            id: moduleId,
/******/            loaded: false
/******/        };

/******/        // Execute the module function
/******/        modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

/******/        // Flag the module as loaded
/******/        module.loaded = true;

/******/        // Return the exports of the module
/******/        return module.exports;
/******/    }


/******/    // expose the modules object (__webpack_modules__)
/******/    __webpack_require__.m = modules;

/******/    // expose the module cache
/******/    __webpack_require__.c = installedModules;

/******/    // __webpack_public_path__
/******/    __webpack_require__.p = "";

/******/    // Load entry module and return exports
/******/    return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {

    'use strict';

    function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

    var _SomeClassJs = __webpack_require__(4);

    var _SomeClassJs2 = _interopRequireDefault(_SomeClassJs);

/***/ },
/* 1 */,
/* 2 */,
/* 3 */,
/* 4 */
/***/ function(module, exports) {

    "use strict";

    Object.defineProperty(exports, "__esModule", {
        value: true
    });

    var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();

    function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

    var SomeClass = (function () {
        function SomeClass(option) {
            _classCallCheck(this, SomeClass);

            this.loggerSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("ImportLog");
        }

        _createClass(SomeClass, [{
            key: "logInfo",
            value: function logInfo(data) {
                loggerSheet.appendRow([new Date(), "INFO", data]);
            }
        }]);

        return SomeClass;
    })();

    exports["default"] = SomeClass;
    module.exports = exports["default"];

/***/ }
/******/ ]);
Share Improve this question edited Oct 19, 2015 at 15:12 Mogsdad 45.7k21 gold badges162 silver badges285 bronze badges asked Sep 28, 2015 at 9:52 Thibault DeheurlesThibault Deheurles 1,2691 gold badge13 silver badges21 bronze badges 4
  • 1 I dunno what transpiling is exactly and what your final goal is, but Logger is a reserved Google Apps Script class, you can't change it (or shouldn't). Also, keep in mind that GAS isn't your everyday Asynchronous/Client-side Javascript, Google's compiler has several changes that you may have to work around, eg. you can't 2 functions simultaneously, there's no setTimeout not webWorkers. – Kriggs Commented Sep 28, 2015 at 12:28
  • Thanks for informations. Transpiling here is for writing ES5 code from ES6 code. – Thibault Deheurles Commented Sep 28, 2015 at 13:03
  • You remove me an error @Kriggs, as the Logger did exist in Google Apps Script, I was thinking my bundle import was good. It's not the case as changing the name make the error bcaoming ReferenceError: "SomeClass" is not defined. So I may just need to learn how to create a module now. Thank you – Thibault Deheurles Commented Sep 28, 2015 at 13:15
  • The response to this question can be found in this post. – Thibault Deheurles Commented Sep 29, 2015 at 11:28
Add a comment  | 

5 Answers 5

Reset to default 10

So I've been playing with this for a while now; using transpiled ES6 (even ES7/next features) in GAS. The main hurdle you need to overcome is exposing the functions in the modules to the global scope.

In browsers this could be window, or document. In GAS there is no such global. What I've tagged it to is the this context in the main Code.gs.

Webpack allows you to build stand alone modules to distribute libraries, etc. This is the link to the Webpack docs that covers changing the output module type.

output: {
    libraryTarget: "this",
    path: __dirname + '/dist',
    filename: 'Code.gs'
},

This is what your output config should look like.

You should then export functions from your main .js file to have them attach to the global context, like so:

export function onInstall(e) {
  onOpen(e);
}

From here you should copy and paste the script as you normally would into the GAS Script Editor and have it run the onInstall function to give it access to your drive/sheets/etc.

Hope this helps!

I tried several of the suggested ways mentioned above. However, utilizing this plugin with webpack 2.X is the only thing that worked for me.

https://github.com/fossamagna/gas-webpack-plugin

Please Note: This does not yet work with webpack 4.X.

I could regurgitate their Readme.md here, but I find that unnecessary.

In a nutshell you need to add this plugin to your webpack config and then add functions to global. These functions get added as top level functions.

Update as on 2018:

If you are craving for modern Javascript within GAS, you can either use Webpack as described by James or if you are comfortable using Typescript, you can use clasp for this.

Clasp is an official GAS deployment toolkit that lets you to develop your Apps Script projects locally and deploy it to Apps Script when you're done. Since the code is local, you can use your favorite IDE and development tools like git when building Apps Script projects.

As I told in the comments, GAS isn't your everyday Javascript, to overcome that error you can create a Global Var 'SomeClass', then remove the var keyword before the function you declare inside the main function. This will get rid of this error, but another one will arise.

What's your final goal with this webpack? Why it's important within GAS?

Using the new Apps Script v8 runtime, you can use modern javascript without any transformations by setting "runtimeVersion": "V8" in your appsscript.json file.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论