Импорт области только для экземпляра - PullRequest
0 голосов
/ 26 октября 2018

Добрый вечер всем.

Я не уверен, как я могу объяснить мою проблему. Я покажу вам это, показывая примеры кода и ожидаемые результаты. Я не мог использовать код из реальной проблемы, потому что код по лицензии. Мне очень жаль, и я буду рад, что кто-то может помочь мне решить мою проблему.

Я использую последнюю версию webpack, babel.

Мое приложение разделено на три части, которые динамически импортируются друг другом. Это значит, что если я запустлю плагин split chunks, он действительно создаст три чистых файла.

Детали: Core, Shared, Application. Где Core только создает экземпляр приложения.

Результат частей объединен в один файл. Так что он связан одним тегом html-скрипта.

Структура проекта:

src/app    // For Application
src/core   // For Core
src/shared // For Shared

В конфигурации веб-пакета я разрешаю псевдоним для импорта «Редактор $». Я переименовал имена переменных, потому что они включают имя проекта.

resolve: {
    alias: {
        "Editor$": path.resolve('./src/app/statics/Editor.js'),
    }
},

Содержимое файла Core:

function createInstance(name, id) {
    import("app").then(App => {
        App(name, id)
    });
}

Немного файла приложения

imports...
import Framework from "./framework"
function createApp(name, id) {
    new Framework({name, id}).$mount(...)
}

export default createApp

В классах Application (которые создаются внутри Framework) Это импорт

import Editor from "Editor"

Класс Editor является одноэлементным. Но только для созданного экземпляра.

class Editor {
    static instance;

    id = null;

    constructor(){
        if(this.constructor.instance){
            return this.constructor.instance
        }

        this.constructor.instance = this
    }

    static get Instance() {
        return this.instance || (this.instance = new this())
    }

    static get Id {
        return this.Instance.id;
    }

}

export default Editor

Проблема заключается в разрешении зависимости от веб-пакета. Потому что webpack помещает и объединяет все импортные файлы в начало файла.

Таким образом, импорт оценивается один раз в течение жизненного цикла программы.

Но мне нужно сказать вебпаку что-то вроде: создание экземпляра. Объявите новый редактор Singleton для этой области. Не используйте уже кэшированный.

Моя другая идея, как это исправить, - установить контекст для экземпляра. А в редакторе синглтона создайте что-то вроде new Map<Context, Editor>, если вы понимаете, о чем я. Но я не нашел способа установить контекст для экземпляра или ограничить импорт только для него.

Буду признателен за любую помощь. Я гуглю два дня и до сих пор не знаю, как это сделать, не переписав все импортные данные.

Извините за ошибки в моем английском. Я не являюсь носителем языка, и мой мозг не для языков.

Спасибо всем, кто заглядывает в мою проблему.

1 Ответ

0 голосов
/ 26 октября 2018

Как насчет воссоздания Редактора:

  // Editor.js
  class Editor {
   // ...
  }

  let instance;

 export function scope(cb) {
     instance = new Editor();
     cb();
     instance = null;
 }

 export default function createEditor() { 
    if(!instance) throw Error("Editor created out of scope!");
    return instance;
 }

Таким образом, вы можете легко настроить различные области:

 // index.js
 import {scope} from "./editor";

 scope(() => {
    require("A");
    require("B");
 });

 scope(() => {
   require("C");
 });

 // A
 import Editor from "./editor";
 (new Editor()).sth = 1;

  // B
 import Editor from "./editor";
 console.log((new Editor()).sth); // 1

 // C
 import Editor from "./editor";
 console.log((new Editor()).sth); // undefined

 // note that this will fail:
 setTimeout(() => {
   new Editor(); // error: Editor created out of scope
 }, 0);

Это также работает для вложенных require s и importдо тех пор, пока они не являются динамическими.

...