Имя модуля - это глобальное имя для теневого копирования. - PullRequest
0 голосов
/ 21 февраля 2019

tl; dr: Как изменить следующую привязку, чтобы можно было писать Intl.DateTimeFormat.make() вместо Intl_.DateTimeFormat.make()?

type dateTimeFormat;

[@bs.deriving abstract]
type formatOptions = {
  [@bs.optional]
  weekday: string,
  [@bs.optional]
  day: string,
  [@bs.optional]
  month: string,
};

module Intl_ {
    module DateTimeFormat {
      module Impl {
        type t;
      };

      [@bs.new] external make: unit => Impl.t = "Intl.DateTimeFormat";
      [@bs.send] external format: (Impl.t, Js.Date.t) => string = "";
    };
}

Intl_.DateTimeFormat.make()
  ->Intl_.DateTimeFormat.format(Js.Date.make())
  ->Js.log;

Проблема

Без подчеркивания это скомпилировалось бы в:

var Impl = /* module */[];

var DateTimeFormat = /* module */[/* Impl */Impl];

var Intl = /* module */[/* DateTimeFormat */DateTimeFormat];

console.log(new Intl.DateTimeFormat().format(new Date()));

exports.Intl = Intl;

Проблема в том, что var Intl = ... затеняет глобальный Intl и таким образом нарушает new Intl.DateTimeFormat().

1 Ответ

0 голосов
/ 21 февраля 2019

Прежде всего, я бы посчитал это ошибкой в ​​BuckleScript.Эта проблема была недавно поднята в выпуске # 3268 и частично решена в этой фиксации , но она по-прежнему оставляет множество имен без изменений.Вы должны рассмотреть вопрос об этом или в новом выпуске.

Тем временем, вы можете обойти это, полностью уточнив имя.Intl на самом деле не является глобальным объектом, но присоединен к глобальному объекту , который в контексте веб-страницы имеет значение window.Но поскольку JavaScript будет искать имена в глобальном объекте, когда он не найден в локальной среде, он очень похож на глобальное имя.

Так что если вы измените make на:

[@bs.new] external make: unit => Impl.t = "window.Intl.DateTimeFormat";

должно работать нормально.

...