ES6模块和装饰模式

时间:2017-04-01 09:47:22

标签: d3.js rollup es6-modules

据我所知,import语句提供了对模块的只读绑定,我想这取决于模块加载器,但它是否可以使用ES6模块导入,装饰和重新导出?

例如,使用rollup.js时失败

test.plugin.js

import * as d3 from 'd3'    
d3.ui = {test: 1};    
export default d3;

index.js

import * as d3 from 'd3'
import './src/test.plugin'

汇总错误......

Illegal reassignment to import 'd3'
src\test.plugin.js (6:0)
4:
5: import * as d3 from 'd3'
6: d3.ui = {test: 1};

这也是......

test.plugin.js
export default (d3) => d3.ui = {test: 1};

index.js

import * as d3 from 'd3'
import test from './src/test.plugin'

test(d3);

第一个失败是因为导入是不可变的,第二个是因为模块解析是静态的。

是否可以在ES6模块中使用装饰器模式?

1 个答案:

答案 0 :(得分:4)

更新

问题是模块对象不可扩展。可扩展的是模块对象内的对象。

模块A

let mod = { a, b, c };
// Once exported the "mod" object cannot be extended from the outside
export mod;

index.js

// What you are saying here is 
import * as mod from "moduleA.js"

// mod cannot be extended here
// mod.b can be extended though
mod.b.ui = {test: 1};

默认导出

执行默认导出时,您可以扩展它,因为default实际上是嵌套属性。

模块A

let mod = { a, b, c };
// Once exported as default
export default mod;

index.js

 import mod from "moduleA.js"

 // mod is effectively a prop of the module object, so it can be extended
 mod.d = { ... };

在您的情况下,您可以执行以下操作:

test.plugin.js

// Import d3 as a composition of props
import * as d3 from 'd3';
// Create a new object using the Object.assign operator
// You can use the spread operator too
const d3plus = Object.assign({ui: () => 'test'}, d3);
// Now d3plus will be extendable!
export default d3plus;

index.js

import d3plus from 'test.plugin.js';

console.log(d3plus.ui);

错误的答案

当我读错了规格时,这是我的答案。另外,事先some other module bundler got it wrong为es6模块are pretty hard

如果你有模块A而你想用新功能/东西装饰它,你有两个选择:

  • 包装模块A,然后稍后才使用包装
  • 编写您需要时应用的装饰器功能(如第二个示例所示)。

在前一种情况下,您可以这样做:

test.plugin.js

import * as d3 from 'd3'    
d3.ui = {test: 1};    
export default d3;

index.js

// Note that using this wrapper makes sure you have the extra stuff all the time
import d3plus from './src/test.plugin';

console.log(d3plus.ui);

使用第二种方法,你必须得到装饰器操作的结果:

test.plugin.js

export default (d3) => {
  d3.ui = {test: 1};
  // Do not forget to return the new object
  return d3;
};

index.js

import * as d3 from 'd3'
import pluginify from './src/test.plugin'

// Note that this change is local to this module only
const d3plus = pluginify(d3);
console.log(d3plus.ui);

您可以使用更多技巧来达到相同的效果,但我建议明确说明您正在应用于模块的浓缩过程。