html - 编译 Azure DevOps Widget : Can't resolve 'TFS/Dashboards/WidgetHelpers' 时出错

标签 html typescript webpack azure-devops-extensions react-typescript

我是 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();
});

Widget without WidgetHelpers

我引用了 here 中的示例

你能指出我遗漏了什么地方吗?

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

更新 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

可以找到重现问题的项目 here

更新 3

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

最佳答案

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

关于html - 编译 Azure DevOps Widget : Can't resolve 'TFS/Dashboards/WidgetHelpers' 时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65061778/

相关文章:

javascript - Webpack/Babel 未删除 "const"

javascript - 如何在 jQuery 中引用一堆刚刚添加的列表项?

javascript - 当输入宽度在 Safari 中变小时,表单不会缩小

jquery - 视差背景图像全尺寸(宽度)

javascript - 延迟加载的 vue-router 组件不适用于 SSR

javascript - Webpack 中的同步需求

javascript - HTML5 范围输入值在 Bootstrap 弹出框内没有改变

angular - 如何将哈巴狗添加到 angular-cli?

javascript - 防止 Typescript 编译器检查整个类以节省时间?

reactjs - 由于 'Type '元素,React TypeScript无法对表进行排序元素'无法分配给 'string' .ts(2345)'类型