"Object.defineProperty(exports, "__esModule", { value: true });" blocks functions execution in FunctionFile

Viewed 9185

I started a Office Web Add-in with Typescript&React project by following this tutorial: https://github.com/OfficeDev/office-js-docs-pr/blob/master/docs/includes/file-get-started-excel-react.md . Any taskpane function and page works properly, but functions on the function-file page cannot be properly executed.

By deleting code, I found Object.defineProperty(exports, "__esModule", { value: true }); is one of line in compiled function-file.js casing the problem. Whenever it presents, any function in the file won't be executed. Fiddler shows the script is correctly loaded in Excel without any warning. Status bar shows "[add-in name] is working on your [function name]".

This line of code is generated by Typescript Compiler, in this case, for loading Node module '@microsoft/office-js-helpers'. I tried to modify tsconfig.json file to avoid generating that line, but then the import of '@microsoft/office-js-helpers' fails. In addition, Webpack 4 will add webpackBootstrap code blocking functions in this file. At this point, I can only avoid any import in function-file.ts and do a 'tsc' after building the project by Webpack.

My question is: what is the correct way to setup this project so function-file.js does not contain any code blocking its functions being executed? If there is no clear answer, at least, why this line of code causes problem where other pages work fine?

The following is my tsconfig.json which can avoid that line but cannot load any module:

  "compilerOptions": {
    "target": "es5",
    "module": "es2015",
    "moduleResolution": "node",
    "lib": ["es2015", "dom"],
    "typeRoots": ["node_modules/@types"]
  },

I manually edit the compiled function-file.js into two versions:

Object.defineProperty(exports, "__esModule", { value: true });
(function () {
    Office.initialize = function () { }
    };
})();
function writeText(event) {
    Office.context.document.setSelectedDataAsync('test');
    event.completed();
}

VS

(function () {
    Office.initialize = function () { }
    };
})();
function writeText(event) {
    Office.context.document.setSelectedDataAsync('test');
    event.completed();
}

The first one has this problem whereas the second one doesn't.

1 Answers

With some hints from my colleague who used to work on JavaScript during a lunch talk, I made some progress of calling functions in function-file.ts. I wish my path of getting this work would help other people suffering the same pain as I did and still do on this project.

First of all, once I got the function-file.js works properly, I noticed there are two different behaviours when a function does not work:

  1. status bar shows "[add-in name] is working on your [function name]" and stays with it, I believe the function is called but not the line of event.completed() couldn't be reached;

  2. status bar flashes the same message and becomes blank, which indicates the function is not even been found.

Please correct me if there is a better way to diagnose this file.

The original Yeoman generated Webpack configuration of function-file.html is something like this:

new HtmlWebpackPlugin({
        title: 'demo',
        filename: 'function-file/function-file.html',
        template: '../function-file/function-file.html',
        chunks: ['function-file']
}),

In order to use any module, 'vendor'(not necessary for my custom modules, but needed by 'office-js-helpers'?) and 'polyfills' entry needs to be included in chunks as well. Mine Webpack 4 configuration is:

new HtmlWebpackPlugin({
  title: "demo",
  filename: "function-file/function-file.html",
  template: "../function-file/function-file.html",
  chunks: ["babel-polyfill", "function-file/function-file"]
}),

The last step is making sure functions declared in function-file.ts can be found: asking Webpack to export global functions in function-file.ts, which I am still not sure if I am hacking Typescript development or doing fine. Sample function-file.ts:

import * as OfficeHelpers from '@microsoft/office-js-helpers';
(() => {
  Office.initialize = () => {};
})();

declare global {
  namespace NodeJS {
    interface Global {
      writeText: (event: Office.AddinCommands.Event) => void;
    }
  }
}

global.writeText = (event: Office.AddinCommands.Event) => {
  Office.context.document.setSelectedDataAsync('test');
  event.completed();
};

Notice: even office-js-helpers is imported, some of functions are still not working. I tested my custom modules, they are working properly.

I really wish there are some function-file examples on NodeJS hosted React&Typescript project for Office Web Add-in, as detail configuration is really different from ordinary NodeJS + JavaScript project.

Related