Загрузка модуля времени выполнения Typescript (с веб-пакетом) и поздняя привязка в стиле dll. - PullRequest
0 голосов
/ 02 июля 2018

Предположим, у меня есть постоянно растущий набор различных шаблонов, которые можно использовать с реагировать. Каждый шаблон extends React.Component визуализирует причудливую рамку вокруг своих дочерних элементов.

Я ожидаю генерировать такие шаблоны (с кэшированием и т. Д.) На лету из некоторых данных, известных только во время выполнения.

Во время выполнения я могу вычислить имя модуля, содержащего шаблон. Я могу сопоставить URL-адрес с кодом сервера, чтобы предоставить источник JavaScript, и ожидать, что браузер сможет его запустить.

Я полагаю, что я бы изолировал этот кусок кода простым методом, похожим на загрузку * .DLL по имени и вызов его экспортированного символа. Мое предположение ниже не работает.

private async templateLoader():Promise<React.ComponentType>{
    const templateModuleName:string = this.props.api.getTemplateName(this.props.user);
    return (await import(templateModuleName)) as React.ComponentType;
}

Я могу представить JavaScript, используя require.js, вот так

var propsMappedFromStore=this.props;
//...
require(["api","user"],function(api,user){
  var templateModuleName = api.getTemplateName(user);
  require([templateModuleName],function(tt){
   propsMappedFromStore.updateTemplate(tt);
  })
})

Но возможно ли это с Typescript и Webpack?

Как мне потребовать / импортировать модуль, идентифицируемый выражением?

1 Ответ

0 голосов
/ 04 июля 2018

Работая над приложением React, я столкнулся с этой проблемой. Приложение разбито на несколько модулей. Среди этих модулей есть набор с определенными свойствами. Эти модули не могут участвовать в процессе сборки веб-пакетов. Они не существуют во время проектирования и сборки. Вместо этого я знаю только форму их экспорта.

Для использования этих модулей браузер должен использовать загрузчик. RequireJS AMD loader - хороший выбор.

Мне потребовалось довольно много времени, чтобы понять, как заставить WebPack хорошо играть с асинхронной загрузкой. Ключевое слово здесь было requirejs вместо require или import .

Использование requirejs устраняет любую магию с помощью webpack.config.js или любую другую магию. Код ниже должен дать вам представление. Использование оператора requirejs (["locs /" + lang]…) приводит к запросу http * / {baseUrl} / locs / {lang} .js , который обрабатывается веб-сервером в соответствии с его умностью.

import { getLanguage, IGreetingFormatStrings } from "./lociface";
import { defGeetings } from "./config";

function getGreetings(lang: string): Promise<IGreetingFormatStrings> {
    return new Promise((resolve) => {
        requirejs(["locs/" + lang]
            , (m) => { resolve(m.locGreetings as IGreetingFormatStrings); }
            , () => { resolve(defGeetings) }
        )
    });
}

export async function greeter(person: string): Promise<string> {
    const hours = new Date().getHours();
    const greetings = await getGreetings(getLanguage());
    if (hours > 6 && hours < 12) {
        return greetings.morning + person;
    }
    if (hours < 19) {
        return greetings.afternoon + person;
    }
    return greetings.night + person;
}

enter image description here

...