Относительный путь для импорта модуля Typescript, указывающий на неправильный каталог

У меня есть прикладной уровень, написанный на visual-studio-2017 с использованием typescript . У меня также есть веб-ресурсы, созданные с использованием javascript и html. HTML-код для веб-ресурсов использует requirejs, чтобы включить скомпилированный код Typescript везде, где это необходимо. Проблема, которую я вижу, связана с относительными путями, которые я использую в своем Typescript. Когда я публикую веб-ресурсы в Microsoft Dynamics, RequireJS пытается загрузить относительные пути из моего Typescript относительно файла html, а не относительно переданного файла Javascript.

веб-API

Перенесено в build/CCSEQ/WebAPI.js (Model.js находится в build/CCSEQ/Model.js)

"use strict";

import * as Model from "./Model.js";

export class WebAPI{
  // Code here
}

Основной.html

Находится в /WebResources/html/Main.html

<!DOCTYPE html>

<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>Main</title>   
</head>
<body>
    <script src="require.js" data-main="../js/Main.js"></script>
</body>
</html>

Main.js

Находится в /WebResources/js/Main.js

"use strict";

// Require fails because it is looking for /WebResources/html/Model.js rather than /build/CCSEQ/Model.js
require(["WebAPI.js"], function(WebApi){
  // Code Here
});



Ответы (1)


Первое, что вы должны сделать, это удалить .js из имен ваших модулей (как вашего вызова require, так и вашего оператора import). Имена, которые вы передаете в require и define, являются именами модулей. Они выглядят как пути, но на самом деле это не пути. RequireJS берет имена модулей и преобразует их в пути, используя параметры конфигурации map, paths и baseUrl (чтобы назвать наиболее часто используемые). Когда вы не используете эти параметры, используются разумные значения по умолчанию.

Если вы используете .js в имени модуля, RequireJS предполагает, что вы передаете путь, а не фактическое имя модуля. (То же самое верно, если вы начинаете строку с косой черты, используете параметр запроса, например (foo?blah), или если в строке есть двоеточие, которое RequireJS воспринимает как указание на то, что вы используете протокол (например, http://). ) В этом случае нет преобразования имени модуля в путь, поэтому map, paths и baseUrl игнорируются. Вот фрагмент кода :

        //If a colon is in the URL, it indicates a protocol is used and it is just
        //an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?)
        //or ends with .js, then assume the user meant to use an url and not a module id.
        //The slash is important for protocol-less URLs as well as full paths.
        if (req.jsExtRegExp.test(moduleName)) {
            //Just a plain path, not module name lookup, so just return it.
            //Add extension if it is included. This is a bit wonky, only non-.js things pass
            //an extension, this method probably needs to be reworked.
            url = moduleName + (ext || '');
        } else {

Значение req.jsExtRegExp равно /^\/|:|\?|\.js$/.

(Вы можете сохранить .js в значении, которое вы передаете data-main, потому что data-main является особенным.)

Более того, вам нужно что-то сделать, чтобы require(["WebAPI"]... преобразовался в правильный путь. Это можно сделать, установив baseUrl в конфигурации RequireJS, указывающий на каталог, содержащий файл WebAPI.js. Или вы можете использовать paths:

paths: {
  WebAPI: '../../build/CCSEQ/WebAPI',
}

Обратите внимание, что в значении ключа WebAPI также отсутствует расширение .js. У вас и там его быть не должно. Значение там — это путь (а не имя модуля), и проблема, с которой вы столкнетесь, если поместите .js, заключается в том, что RequireJS попытается найти файл с расширением .js.js!

Если вы хотите узнать больше о разнице между именами модулей (они же идентификаторы модулей) и путями, у меня есть ответ, который идет конкретно над этим.

person Louis    schedule 15.06.2017