从ES6导入带有名称空间的旧JavaScript

时间:2018-12-28 18:08:59

标签: javascript webpack ecmascript-6 namespaces

我正在使用babel和webpack将旧的javascript转换为ES6。 在多个文件中,我有类似的东西

var BLOG = BLOG || {};
BLOG.myClass1 = ...

和另一个文件

var BLOG = BLOG || {};
BLOG.myClass2 = ...

因此,我已经向这些文件添加了export {BLOG},但是如何多次导入BLOG?看来这是不允许的,而我想做类似的事情

import {BLOG} from 'file1.js'
import {BLOG} from 'file2.js'

并将myClass1和myClass2放入BLOG。

有没有办法做到这一点?

2 个答案:

答案 0 :(得分:3)

  

因此,我已经向这些文件添加了export {BLOG},但是如何多次导入BLOG

您必须为它们使用不同的导入绑定:

import {BLOG as BLOG1} from 'file1.js';
import {BLOG as BLOG2} from 'file2.js';

...然后使用BLOG1BLOG2。或者,如果让您感到困扰,请添加

const BLOG = Object.assign({}, BLOG1, BLOG2);

导入后继续使用BLOG

如果具有循环依赖性,则BLOG1BLOG2可能不会立即被完全填充。如果使用真实的import / export,在这种情况下,您收到的对象将具有其属性,但是这些属性不会被初始化。因此,如果使用真实的import / export或良好的模拟,您可以使用访问器属性来处理它:

// In a true ES2015+ module environment, or a simulated one that
// creates the properties up-front like the real one does
const BLOG = (() => {
    const b = {};
    for (const blog of [BLOG1, BLOG2]) {
        for (const key of Object.keys(blog)) {
            Object.defineProperty(b, key, {
                get(name) {
                    return blog[name];
                }
            });
        }
    }
    return b;
})();

(很显然,您将其包装在一个函数中并重新使用。)

在模拟模块环境中,它不会像真正的那样预先创建属性,因此您可以使用代理(当然,如果要在ES2015之前的环境中运行该代理,将没有Proxy):

const BLOGS = [BLOG1, BLOG2];
const BLOG = new Proxy({}, {
  get(target, propName, receiver) {
    const b = BLOGS.find(b => propName in b) || target;
    return Reflect.get(b, propName, receiver);
  }
});

然后,事后添加到BLOG1BLOG2的属性仍然可以正确解析。

所有这些都是 令人讨厌的 ,只是为了避免接下来提到的搜索和替换。


但是: ,而不是导出BLOGas SLaks says,而是导出类并导入它们。使用适当的模块时,无需“命名空间对象”。

export { myClass1 };

export { myClass2 };

然后

import { myClass1 } from "file1.js";
import { myClass2 } from "file2.js";

您甚至可以按照定义的方式导出类:

export function myClass1() { /* ... */ }

,或者使用class表示法:

export class myClass1 { /* ... */ }

在多个文件中将new BLOG.myClass1更改为new MyClass1是一个非常简单的搜索和替换。在* nix上,您可以向其扔sed并制作整个目录树...


侧面说明:JavaScript中的压倒性约定是构造函数(通常称为“类”,例如,与new一起使用的函数)以大写的初始字符编写。例如MyClass1MyClass2

答案 1 :(得分:0)

您需要通过以下方式使用导入

{BLOG as variable name} from file