OfficeDev / office-js

A repo and NPM package for Office.js, corresponding to a copy of what gets published to the official "evergreen" Office.js CDN, at https://appsforoffice.microsoft.com/lib/1/hosted/office.js.
https://learn.microsoft.com/javascript/api/overview
Other
685 stars 95 forks source link

How to enable a SharedRuntime Environment in a custom function excel add-in with a separate vuejs taskpane #2689

Closed DaveWatson44 closed 7 months ago

DaveWatson44 commented 2 years ago

Message from office-js bot: We’re closing this issue because it has been inactive for a long time. We’re doing this to keep the issues list manageable and useful for everyone. If this issue is still relevant for you, please create a new issue. Thank you for your understanding and continued feedback.

I need to create a shared runtime environment so that my excel custom functions can have access to the workbook context.

Current Setup: The way the project seems to have been set up is, using the yeoman office generator to generate a custom function addin and then using vue-cli to generate a vue app to use as the taskpane.

Folder Structure: RootFolder -Add-In ----- manifest.xml ----- jest.config.js ----- package.json ----- tsconfig.json ----- webpack.config.js ----- src -------- functions -------- commands -Taskpane ----- package.json ----- tsconfig.json ----- vue.config.js ----- src

The Add-In folder holds the custom functions and the Taskpane folder holds the Vuejs app. I have left out other files and noted these because I believe they will help communicate my possible issue.

Steps To Merge: I have edited Manifest.xml following the steps provided on Microsofts documentation: https://docs.microsoft.com/en-us/office/dev/add-ins/develop/configure-your-add-in-to-use-a-shared-runtime

Updated name to use SharedRuntime

Added Runtimes tags within the Host tag

Updated the Page tag to use Taskpane.Url

Updated the FunctionFile tag with Taskpane.Url

In webpack.config.js: I have removed the HtmlWebpackPlugin references and replaced with the following:

new HtmlWebpackPlugin({ filename: "index.html", template: "../taskpane/public/index.html", chunks: ["polyfill", "taskpane", "commands", "functions"] })

Steps I did not provided in the Documentation: Since the project was created using the yeoman office generator with the customfunctions option selected, I believe I needed to add the following to the webpack.config.js file's entry object:

entry: { functions: "./src/functions/functions.ts", polyfill: "@babel/polyfill", commands: "./src/commands/commands.ts", taskpane: "../taskpane/src/main.ts" <----- new addition

When I try to build the addin with the new webpack configuration I get multiple errors, such as:

ERROR in ../taskpane/src/main.ts Module build failed Error: TypeScript emitted no output for main.ts

Module not found errors.

Property doesn't exist errors.

I'm thinking (but would love to confirm) that the steps I took to create the shared runtime provided by the documentation are indeed correct, along with adding the taskpane file to the entry object in the webpack config. But I just can't figure out why it won't compile. I'm thinking it has to do with the different tsconfig.json configurations, along with webpack only using the add-in folder's dependencies and not using the taskpane's dependencies as well. I don't know if its possible to instruct webpack to use the taskpanes node_modules for the taskpane and the add-in's node_modules for the addin? In the tsconfig, the addin is using target: "es5" while taskpane is using target: "esnext". There are other differences as well. I wasn't entirely sure what information would be needed here, so if somebody can help me with this and needs more information, I will be more than happy to add it.

JHJ-MS commented 2 years ago

The steps you took to create shared runtime look correct. To add the task pane, do not forget to Open manifest.xml and find the tags inside the tag. Locate the tag with the ID Taskpane.Url and update its DefaultValue attribute. Here is a related link for reference, Use Vue to build an Excel task pane add-in.

DaveWatson44 commented 2 years ago

Hi JHJ-MS, thanks for helping look into this.

This is the value I currently have for the bt:Url tag:

I have also tried it with:

Just to make sure it didn't need the index.html, but it still wasn't successful.

Here are some examples of the errors I'm getting after updating the manifest.xml file and the webpack file:

ERROR in ../taskpane/src/main.ts
Module build failed (from ./node_modules/ts-loader/index.js):
Error: TypeScript emitted no output for C:\Users\{{path}}\taskpane\src\main.ts.
    at makeSourceMapAndFinish (C:\Users\{{path}}\add-in\node_modules\ts-loader\dist\index.js:80:15)
    at successLoader (C:\Users\{{path}}\add-in\node_modules\ts-loader\dist\index.js:68:9)
    at Object.loader (C:\Users\{{path}}\add-in\node_modules\ts-loader\dist\index.js:22:12)
ERROR in chunk taskpane [entry]
taskpane.js
C:\Users\{{path}}\add-in\node_modules\babel-loader\lib\index.js!C:\Users\{{path}}\add-in\node_modules\ts-loader\index.js!C:\Users\{{path}}\taskpane\src\main.ts
Cannot read property 'endsWith' of undefined
ERROR in C:\Users\{{path}}\taskpane\src\main.ts
../taskpane/src/main.ts
[tsl] ERROR in C:\Users\{{path}}\taskpane\src\main.ts(2,17)
      TS2307: Cannot find module './App.vue' or its corresponding type declarations.
ERROR in C:\Users\{{path}}\taskpane\src\main.ts
../taskpane/src/main.ts
[tsl] ERROR in C:\Users\{{path}}\taskpane\src\main.ts(14,5)
      TS2769: No overload matches this call.
  Overload 1 of 3, '(options?: ThisTypedComponentOptionsWithArrayProps<Vue, object, object, object, never>): CombinedVueInstance<Vue, object, object, object, Record<...>>', gave the following error.
    Argument of type '{ router: VueRouter; store: Store<any>; vuetify: any; render: (h: CreateElement) => VNode; }' is not assignable to parameter of type 'ThisTypedComponentOptionsWithArrayProps<Vue, object, object, object, never>'.
      Object literal may only specify known properties, and 'vuetify' does not exist in type 'ThisTypedComponentOptionsWithArrayProps<Vue, object, object, object, never>'.
  Overload 2 of 3, '(options?: ThisTypedComponentOptionsWithRecordProps<Vue, object, object, object, object>): CombinedVueInstance<Vue, object, object, object, Record<...>>', gave the following error.
    Argument of type '{ router: VueRouter; store: Store<any>; vuetify: any; render: (h: CreateElement) => VNode; }' is not assignable to parameter of type 'ThisTypedComponentOptionsWithRecordProps<Vue, object, object, object, object>'.
      Object literal may only specify known properties, and 'vuetify' does not exist in type 'ThisTypedComponentOptionsWithRecordProps<Vue, object, object, object, object>'.
  Overload 3 of 3, '(options?: ComponentOptions<Vue, DefaultData<Vue>, DefaultMethods<Vue>, DefaultComputed, PropsDefinition<Record<string, any>>, Record<...>>): CombinedVueInstance<...>', gave the following error.
    Argument of type '{ router: VueRouter; store: Store<any>; vuetify: any; render: (h: CreateElement) => VNode; }' is not assignable to parameter of type 'ComponentOptions<Vue, DefaultData<Vue>, DefaultMethods<Vue>, DefaultComputed, PropsDefinition<Record<string, any>>, Record<...>>'.
      Object literal may only specify known properties, and 'vuetify' does not exist in type 'ComponentOptions<Vue, DefaultData<Vue>, DefaultMethods<Vue>, DefaultComputed, PropsDefinition<Record<string, any>>, Record<...>>'.
ERROR in C:\Users\{{path}}\taskpane\src\router\index.ts
[tsl] ERROR in C:\Users\{{path}}\taskpane\src\router\index.ts(3,27)
      TS2307: Cannot find module '../views/Documentation.vue' or its corresponding type declarations.
DaveWatson44 commented 2 years ago

Also just to note I've made the adjustments as outlined in the Microsoft Documentation, but also added the taskpane to the entry config as follows:

entry: {
      functions: "./src/functions/functions.ts",
      polyfill: "@babel/polyfill",
      commands: "./src/commands/commands.ts",
      taskpane: "../taskpane/src/main.ts"
    },

And this is how my HtmlWebpackPlugin section is formatted:

new HtmlWebpackPlugin({
        filename: "index.html",
        template: "../taskpane/public/index.html",
        chunks: ["polyfill", "taskpane", "commands", "functions"]
      }),
JHJ-MS commented 2 years ago

Involve documentation team member @Rick-Kirkham to see whether he has some ideas.

DaveWatson44 commented 2 years ago

Would still like to hear if there is a correct way to go about doing this. However, I was able to find a workaround which is actually noted in the microsoft docs as not recommended. Which is using 2 taskpanes. All I needed to do was display a web page in the taskpane which holds information and links to external sites for documentation. The taskpane wouldn't need to interact with anything in excel. Since that is all that the taskpane was needed for, I added another taskpane url to be used solely for the purpose of getting access to the shared runtime.

For example:

<bt:Urls>
<bt:Url id="Taskpane.UrlForUI" DefaultValue="link1" />
<bt:Url id="Taskpane.UrlForRunTime" DefaultValue="link2" />
</bt:Urls>

and then updated the values as outlined in the ms docs accordingly:

<Runtimes>
        <Runtime resid="Taskpane.UrlForRunTime" lifetime="long" />
</Runtimes>

<Page>
              <SourceLocation resid="Taskpane.UrlForRunTime"/>
</Page>

<FunctionFile resid="Taskpane.UrlForRunTime"/>

<Action xsi:type="ShowTaskpane">
                    <TaskpaneId>ButtonId1</TaskpaneId>
                    <SourceLocation resid="Taskpane.UrlForUI"/>             <---- only place UrlForUI taskpane is used.
</Action>