microsoft / vss-web-extension-sdk

Visual Studio Teams Service Web Extension SDK
https://www.visualstudio.com/docs/integrate/extensions/overview
MIT License
133 stars 87 forks source link

Package not working with Angular #72

Open spirosvp opened 6 years ago

spirosvp commented 6 years ago

I have the following Angular project: AngularVSTS

After installing the package and needed typings I get the following error

ERROR in ./src/app/app.module.ts Module not found: Error: Can't resolve 'TFS/WorkItemTracking/RestClient' in 'C:\Users\spirosvp\Desktop\angular\home\sampleProject\src\app' resolve 'TFS/WorkItemTracking/RestClient' in 'C:\Users\spirosvp\Desktop\angular\home\sampleProject\src\app' Parsed request is a module using description file: C:\Users\spirosvp\Desktop\angular\home\sampleProject\package.json (relative path: ./src/app) Field 'browser' doesn't contain a valid alias configuration after using description file: ...\angular\home\sampleProject\package.json (relative path: ./src/app) resolve as module

Is the package compatible with Angular? And if yes what needs to be defined?

concept-hf commented 6 years ago

Unfortunately the whole VSTS extension world is very-very poorly documented.

There might be better approaches, but as I understand, you have to use VSS.require([...], (...)=>{}) to load anything from and for your extension. So anything else has to be bundled up which is what ng-cli does anyways in default configuration. So you don't have to do anything special.

But this package only gets you the typings. The scripts will not be bundled by ng-cli/webpack. (Because namespaces / module names doesn't align. It seems TFS wants you to request for the scripts, instead of bundling... )

For this to work you have to do 2 things:

  1. Tell webpack that the VSS/... and TFS/... are to be loaded externally. Here is how we configured in webpack (without the ng-cli):
var webpackConfig = {
 ...

externals:
 [
    function(context, request, callback) {
      // capture VSS.Require 
      if (/^(VSS|TFS)\//.test(request)){
        return callback(null, 'root window.VSSLoad(\'' + request + '\')');
      }
      callback();
    }
  ],

...
}

With the root ... you tell webpack to invoke a function when it encounters something matching a the regex.

  1. Create a loader wrapper around VSS.require

The window.VSSLoad(...) is a custom function put into the browser global scope which can return references to the loaded modules with VSS.require(...) It's up to you to implement this 'loader' function. Keep in mind that every time any of your scripts wants a reference for the module this function will be called. I advise you to keep a little cache around...

I can't give you more concrete examples, but the method above works in every major browser and on-premise TFS2015 and TFS2017.

janriemer commented 6 years ago

But this package only gets you the typings. The scripts will not be bundled by ng-cli/webpack. (Because namespaces / module names doesn't align. It seems TFS wants you to request for the scripts, instead of bundling... )

Thanks for pointing that out. I was wondering why TS compiler had no issues, but bundling itself failed. If this has been done on purpose to prevent bundling (as you have pointed out), it would be great to have this in the README.

sergey-koryshev commented 3 years ago

Hi, could you please help me here. I faced with the same error:

ERROR in ./src/Widget/Widget.tsx
Module not found: Error: Can't resolve 'TFS/Dashboards/WidgetHelpers' in 'D:\widget_example\src\Widget'
 @ ./src/Widget/Widget.tsx 12:0-46:2

How should I implement function window.VSSLoad(...) properly to get it work?

With provided code by concept-hf I get follow error:

Uncaught ReferenceError: TFS is not defined
    WidgetHelpers WidgetHelpers":1
    Webpack 7