Es6-导入没有别名的所有命名模块

我知道我们可以导入所有具有别名的模块,如下所示,

import * as name from "module-name";

档号: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import

事实上,我已经用 A.js 重新导出了我的模块 Bjs 也继承了我的模块。PFB.现在,它是两个继承级别,所以导入命名模块并不是什么大问题。但是,当我将这个过程提升到5级继承(A-> B-> C-> D-> E)时,我需要导入所有文件中的所有命名模块,并且需要(重新)导出所有文件中的所有模块。与其这么做,

  • 是否有其他方法可以将所有命名模块的作用域复制到所有级别,而无需重复车轮(导入和导出)
  • 这种设计的背后是为了使它们遵循 Opps 的概念,避免重新声明相同的模块。

A.js

import React from 'react';
import I18n from 'i18n-js';
import m1 from 'module1';
import m2 from 'module2';


export default class A extends React.Component {}


export {React, I18n, m1, m2)

口交

import BaseComponent from './A';
import {React, I18n, m1, m2) from './A;


export default class B extends A {}

有没有办法导入所有命名的模块,而不使用像 import {*} from './A'这样的别名(而不是 B.js 中的第2个)

107304 次浏览

Is there any way to import all named modules without alias like import {*} from './A' (instead of 2nd in B.js)

No.

And the whole idea of re-exporting more than you need to save the "number of lines" in the final js file as you stated at

Because, It's putting two lines for each import in the final js file. Consider If there are 10 import lines than, 20 lines will be added in final js. When you are thinking for production it will too cost

Does not make much sense, since that's what JS minifiers are for.

To summarise: one should not do that at the very first place:

  1. You export only what you need to export
  2. You import whatever you need wherever you need.
  3. You use JS minifiers to optimise the output JS file size.

Here's a crazy experiment I did, that works, but it's probably dangerous in ways I don't fully understand. Would somebody explain to me why we don't do this?

var lodash = require("lodash");


function $localizeAll(name) {
return `eval("var " + Object.getOwnPropertyNames(${name}).reduce((code, prop)=>{
if (/^[a-zA-Z$_][a-zA-Z$_0-9]*$/.test(prop)) {
return code.concat(\`\${prop} = ${name}["\${prop}"]\n\`);
} else {
console.warn("did not import '" + prop + "'");
return code;
}
}, []).join(", ")+";")`
}


// this will make all exports from lodash available
eval($localizeAll("lodash"));


console.log(add(indexOf([1,2,6,7,12], 6), 5)); // => 7

It's a bit complicated as it evals in two levels, but it basically iterates of all the properties of an object with the given name in scope and binds all properties that have names qualified to be identifiers to an identifier by that name:

var length = lodash["length"]
, name = lodash["name"]
, arguments = lodash["arguments"]
, caller = lodash["caller"]
, prototype = lodash["prototype"]
, templateSettings = lodash["templateSettings"]
, after = lodash["after"]
, ary = lodash["ary"]
, assign = lodash["assign"]
, assignIn = lodash["assignIn"]
, assignInWith = lodash["assignInWith"]
, assignWith = lodash["assignWith"]
, at = lodash["at"]
, before = lodash["before"]
, bind = lodash["bind"]
, bindAll = lodash["bindAll"]
, bindKey = lodash["bindKey"]
//...
, upperCase = lodash["upperCase"]
, upperFirst = lodash["upperFirst"]
, each = lodash["each"]
, eachRight = lodash["eachRight"]
, first = lodash["first"]
, VERSION = lodash["VERSION"]
, _ = lodash["_"]
;

There are some examples in this list of why this is a bad idea (e.g. it shadows arguments).

You should be able to use this as follows (though you probably shouldn't like they say above).

B.js

import BaseComponent, * as extras from './A';


eval($localizeAll("extras"));


export default class B extends BaseComponent {}

Anyways, couldn't resist trying this out ;)

For Now, there is no clean way to do this. But you can overcome the problem by :

1) defining an alias

import * as foo from "foo"

2) writing all modules

import {a,b,c,d,...} from "foo"

JavaScript solution:

import * as exports from 'foo';
Object.entries(exports).forEach(([name, exported]) => window[name] = exported);

Note: the imported wrapper object remains there.


Node.js solution:

Object.entries(require('foo')).forEach(([name, exported]) => global[name] = exported);

global is your current scope in node.js, similar to the window object in the browser, so you can import into this object.

To import all symbols from util module:

import * as util from "./util";
util.importAll(util, global);

In util.js:

/**
* Takes all functions/objects from |sourceScope|
* and adds them to |targetScope|.
*/
function importAll(sourceScope, targetScope) {
for (let name in sourceScope) {
targetScope[name] = sourceScope[name];
}
}

... and a number of other functions like assert() etc., which I need everywhere, and which should be part of the JavaScript language, but are not yet. But as others said, use this sparingly.