Относительный путь для импорта модуля Typescript, указывающий на неправильный каталог
У меня есть прикладной уровень, написанный на /questions/tagged/visual-studio-2017 с использованием машинописи. У меня также есть веб-ресурсы, которые построены с использованием JavaScript и HTML. HTML для веб-ресурсов использует requirejs для включения скомпилированного кода Typescript, где это необходимо. Проблема, которую я вижу, связана с относительными путями, которые я использую в своем Typescript. Когда я публикую веб-ресурсы в Microsoft Dynamics, RequireJS пытается загрузить относительные пути из моего Typescript относительно файла html, а не относительно переданного файла Javascript.
WebAPI
Транспортируется в build/CCSEQ/WebAPI.js (Model.js находится в build/CCSEQ/Model.js)
"use strict";
import * as Model from "./Model.js";
export class WebAPI{
// Code here
}
main.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
расширение!
Если вы хотите узнать больше о разнице между именами модулей (или идентификаторами модулей) и путями, у меня есть ответ, который касается этого конкретно.