5

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.

mm90849491
  • 71
  • 1
  • 1
  • 5
  • As a troubleshooting step, comment out the line that imports `office-js-helpers`. Replace the two lines that call it in the `catch` block with a line that just sends errors to the console. Does the problem go away if you do this? – Rick Kirkham Jan 15 '19 at 01:36
  • I will update my original post to clarify the code I compared. The import of helper module will fail anyway if `Object.defineProperty(exports, "__esModule", { value: true });` is not in the compiled function-file.js. I am not familiar with importing module in javascript, is there a cleaner way to do the importing? – mm90849491 Jan 15 '19 at 18:15
  • My suggestion is that you NOT USE office-js-helpers. It is only being used to send errors to a message banner, but you can report errors with console.log instead. – Rick Kirkham Jan 15 '19 at 18:24
  • I was planning to use the authentication provided in office-js-helpers, but I am okay to do it in a taskpane or dialog box. However, the main problem is I want to use node modules and share some code as module with other part of the project such as taskpane. Beside, I don't see `console.log("error");` prints anything in Excel or on the terminal where I run `node --inspect`. I can only debug the script in a browser? – mm90849491 Jan 15 '19 at 19:16

1 Answers1

2

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.

mm90849491
  • 71
  • 1
  • 1
  • 5