首页 > 解决方案 > 编译 Azure DevOps 小部件期间发生错误:无法解析“TFS/Dashboards/WidgetHelpers”

问题描述

我是 React 和 TypeScript 的新手。你能帮我理解我的代码发生了什么吗?

HTML 文件:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
    <script type="text/javascript" src="../lib/VSS.SDK.min.js"></script>
    <script type="text/javascript">
        VSS.init({
            explicitNotifyLoaded: true,
            usePlatformStyles: true
        });
        // Entry point to widget
        VSS.require(["dist/Widget/Widget"], function () {
            VSS.notifyLoadSucceeded();
        });
    </script>
</head>

<body>
    <div id="root" class="widget"></div>
</body>

</html>

TSX 文件:

/// <reference types="vss-web-extension-sdk" />

import * as React from 'react';
import ReactDOM = require('react-dom');

import WidgetHelpers = require('TFS/Dashboards/WidgetHelpers');
import WidgetContracts = require('TFS/Dashboards/WidgetContracts');

interface IHelloWorldViewModelProps {
    name: string
}

export class HelloWorldViewModel extends React.Component<IHelloWorldViewModelProps> {
    render(): JSX.Element {
        return (
            <span>Hello, {this.props.name}</span>
        )
    }
}

export class Widget {

    public load(widgetSettings: WidgetContracts.WidgetSettings) {
        return this.render(widgetSettings);
    }

    private render(widgetSettings: WidgetContracts.WidgetSettings) : IPromise<WidgetContracts.WidgetStatus> {

        let userName = VSS.getWebContext().user.name;

        ReactDOM.render(
            <HelloWorldViewModel name={userName} />,
            document.getElementById('root'));

        return WidgetHelpers.WidgetStatusHelper.Success();
    }
}

WidgetHelpers.IncludeWidgetStyles();

VSS.register("Widget", function () {
    return new Widget();
});

webpack.config.js

const path = require("path");
const fs = require("fs");
const CopyWebpackPlugin = require("copy-webpack-plugin");

// Webpack entry points. Mapping from resulting bundle name to the source file entry.
const entries = {};

// Loop through subfolders in the "Samples" folder and add an entry for each one
const samplesDir = path.join(__dirname, "src");
fs.readdirSync(samplesDir).filter(dir => {
    if (fs.statSync(path.join(samplesDir, dir)).isDirectory()) {
        entries[dir] = "./" + path.relative(process.cwd(), path.join(samplesDir, dir, dir));
    }
});

module.exports = {
    target: "web",
    entry: entries,
    output: {
        filename: "[name]/[name].js"
    },
    devtool: "inline-source-map",
    devServer: {
        https: true,
        port: 3000,
        publicPath: "/dist/"
    },
    resolve: {
        extensions: [".ts", ".tsx", ".js"],
        alias: {
            "vss-web-extension-sdk": path.resolve("node_modules/vss-web-extension-sdk")
        },
    },
    stats: {
        warnings: false
    },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                loader: "ts-loader"
            },
            {
                test: /\.html$/,
                loader: "file-loader"
            },
            {
                test: /\.scss$/,
                use: ["style-loader", "css-loader", "azure-devops-ui/buildScripts/css-variables-loader", "sass-loader"]
            },
            {
                test: /\.css$/,
                use: ["style-loader", "css-loader"],
            }
        ]
    },
    plugins: [
        new CopyWebpackPlugin([{ from: "**/*.html", context: "src" }])
    ]
};

tsconfig.json

{
    "compilerOptions": {
        "charset": "utf8",
        "experimentalDecorators": true,
        "module": "amd",
        "moduleResolution": "node",
        "noImplicitAny": true,
        "noImplicitThis": true,
        "strict": true,
        "target": "es5",
        "rootDir": "src/",
        "outDir": "dist/",
        "jsx": "react",
        "lib": [
            "es5",
            "es6",
            "dom",
            "es2015.promise"
        ],
        "types": [
            "react"
        ]
    }
}

它给了我这样的错误:

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
i 「wdm」: Failed to compile.

但是如果我删除对WidgetHelpers模块的引用,它工作正常:

/// <reference types="vss-web-extension-sdk" />

import * as React from 'react';
import ReactDOM = require('react-dom');

import WidgetHelpers = require('TFS/Dashboards/WidgetHelpers');
import WidgetContracts = require('TFS/Dashboards/WidgetContracts');

interface IHelloWorldViewModelProps {
    name: string
}

export class HelloWorldViewModel extends React.Component<IHelloWorldViewModelProps> {
    render(): JSX.Element {
        return (
            <span>Hello, {this.props.name}</span>
        )
    }
}

export class Widget {

    public load(widgetSettings: WidgetContracts.WidgetSettings) {
        return this.render(widgetSettings);
    }

    private render(widgetSettings: WidgetContracts.WidgetSettings) : boolean {

        let userName = VSS.getWebContext().user.name;

        ReactDOM.render(
            <HelloWorldViewModel name={userName} />,
            document.getElementById('root'));

        return true;
    }
}

VSS.register("Widget", function () {
    return new Widget();
});

没有 WidgetHelpers 的小部件

我从这里引用示例

你能指出我错过了什么吗?

如果您需要一些额外的信息,请告诉我。

更新 1

我确实设法TFS/Build/RestClient通过这种方式解析模块:

/// <reference types="vss-web-extension-sdk" />

import * as React from 'react';
import ReactDOM = require('react-dom');

import WidgetHelpers = require('TFS/Dashboards/WidgetHelpers');
import WidgetContracts = require('TFS/Dashboards/WidgetContracts');
import AdoBuildClient = require('TFS/Build/RestClient');
import AdoBuildContracts = require('TFS/Build/Contracts');

let buildClient: AdoBuildClient.BuildHttpClient4;

VSS.require("TFS/Build/RestClient", function (AdoBuildClient: { getClient: () => AdoBuildClient.BuildHttpClient4; }) {
    buildClient = AdoBuildClient.getClient();
    buildClient.getDefinitions("MyFirstProject", "TestWidget").then(definitions => {
        console.log(definitions[0].id);
    })
});

...

但是我不明白发生了什么,代码变得一团糟,但它可以工作。

更新 2

可以在此处找到重现该问题的项目

更新 3

模块TFS/...是在运行时加载的,所以我认为在编译期间无法解决它们。我已经放弃了旧版本的 SDKvss-web-extension-sdk并将我的项目移到了新的azure-devops-extension-sdk. 新版本没有此类问题。

标签: htmltypescriptwebpackazure-devops-extensionsreact-typescript

解决方案


我知道这听起来可能很愚蠢,但请仔细检查 WidgetHelpers 实际上是否在您提供的“TFS/Dashboards/WidgetHelpers”路径中。我遇到了一个问题,我必须再次对该路径执行另存为,但是您收到错误“./src/Widget/Widget.tsx 中的错误未找到模块:错误:无法解析 'TFS/Dashboards/ 'D:\widget_example\src\Widget' 中的 WidgetHelpers' @ ./src/Widget/Widget.tsx 12:0-46:2 i 「wdm」:编译失败。” ./src/Widget/Widget.tsx是回购吗?该错误的意思是它无法编译,因为它可以找到它认为在D:\widget_example\src\Widget中的路径TFS/Dashboards/WidgetHelpers然后它抛出@ ./src/Widget/Widget.tsx再次作为它的目标。因此,您可以检查并确保路径正确(模块在那里并且拼写正确),该路径中的文件没有损坏。


推荐阅读