首页 > 解决方案 > 仅适用于实例的范围导入

问题描述

大家晚上好。

我不确定如何解释我的问题。我将通过代码示例和预期结果向您展示。我无法使用实际问题中的代码,因为该代码已获得许可。对此我感到非常抱歉,我很高兴有人可以帮助我解决我的问题。

我正在使用最新版本的webpack, babel

我的应用程序被拼接成三个部分,它们是相互动态导入的。这意味着如果我运行 split chunks 插件,它将真正创建三个清晰的文件。

零件是Core, Shared, Application. 其中Core唯一创建应用程序的实例。

零件的结果被捆绑到单个文件中。所以它是由一个html的脚本标签链接的。

项目结构为:

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

在 webpack 配置中,我正在解析 import ˙Editor$˙ 的别名。我重命名变量,因为它们包括项目名称。

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

核心文件的内容是

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

在应用程序类中(在框架内实例化的内容)是这个导入

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 依赖解决。因为 webpack 将所有导入统一放在文件的顶部。

因此,在程序的生命周期中对导入进行一次评估。

但我需要告诉 webpack 类似:有一个实例创建。为此范围声明新的 Editor 单例。不要使用已经缓存的。

我如何解决这个问题的另一个想法是为实例设置上下文。new Map<Context, Editor>如果你明白我的意思,在编辑器中单例创建类似的东西。但是我没有找到如何为实例设置上下文或仅为它设置导入范围的方法。

我将不胜感激。我在谷歌上搜索了两天,但仍然不知道如何在不重写所有导入的情况下做到这一点。

对不起,我的英语有错误。我不是母语人士,我的大脑不适用于语言。

感谢所有关注我的问题的人。

标签: javascriptwebpackecmascript-6scopesingleton

解决方案


如何重新创建编辑器:

  // 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 和s。import


推荐阅读