typescriptgoogle-apps-scriptwebpackbabel-loaderclasp

Transpiled JavaScript code fails when I use decorator with gas-webpack-plugin


EDIT1:I made a minimum reproduction repository here
code & reproduction steps are available at the repository.
EDIT2: Same error occurs when I embeded the transpiled code on html file.

EDIT3: I tracked down the main cause of this problem.
When I use gas-webpack-plugin, output file pukes this error. Simply removing the plugin solves the problem, but then I cannot access my main function on GAS.
I created a github issue on the official gas-webpack-plugin . Hope there's a workaround for this.

---Original question from here---

I'm using Clasp + Typescript + Webpack + Babel to locally develop GAS with npm libraries.
Until I used decorator in my project, it was working fine. However, using decorator(more precisely, class-validator) results in following error on GAS...

TypeError: (0 , _metadata_MetadataStorage__WEBPACK_IMPORTED_MODULE_1__.getMetadataStorage)(...).addConstraintMetadata is not a function(line 482, file "index")

Does anyone know how to avoid above error?

here's the sample code and configs.

// index.ts

import { IsOptional, IsString } from 'class-validator';

declare const global: {
  [x: string]: any;
};

class Foo {
  @IsOptional()
  @IsString()
  foo: string;
}

// ENTRYPOINT
global.main = function (e: any) {
  console.log('Hello World!');
  const hoge = new Foo();
};

// .babelrc (with babel-loader v8.2.3)
{
  "presets": ["@babel/preset-typescript"],
  "plugins": [
    ["@babel/plugin-proposal-optional-chaining"],
    ["@babel/plugin-proposal-decorators", { "decoratorsBeforeExport": true }],
    ["@babel/plugin-proposal-class-properties", { "loose": true }]
  ]
}
// tsconfig.json (with TypeScript v4.1.3)
{
  "compilerOptions": {
    "lib": ["es5"], // changing this to es6 or esnext doesn't fix the problem
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}

Solution

  • I talked to the author of the gas-webpack-plugin. https://github.com/fossamagna/gas-webpack-plugin/issues/685

    When using decorators, gas-webpack-plugin exposes not only main() but also classValidatorMetadataStorage() to the top level. By simply removing this from the transpiled file, I was able to run the code with decorators.

    But we now don't have to do this manually now. The author already took care of the situation. As of gas-webpack-plugin@2.2.0, it has include option to avoid unnecessary function exposure.

    Usase:

    new GasPlugin({
      // Only functions written here is moved to the top level.
      include: ["src/**/*.ts"]
    })