admin管理员组

文章数量:1023738

In my react application, I want to use a library (money.js) in 2 ponents which have different settings.

This library:
.js/
.js/money.js

I checked that javascript is using reference so the 2 ponents are actually referencing the same thing.

Does import create a new copy of imported library?

ES6 variable import by reference or copy

Is that possible without changing the source code (ideally), I can do something like the following

// a.js
import fx from 'money'
fx.rates={USD:1, EUR: 2.001}

// b.js
import fx from 'money'
fx.rates={USD:1, EUR: 2.002}

In my situation, I noticed that changing the rates in b.js, it also affect a.js.

In my react application, I want to use a library (money.js) in 2 ponents which have different settings.

This library:
http://openexchangerates.github.io/money.js/
http://openexchangerates.github.io/money.js/money.js

I checked that javascript is using reference so the 2 ponents are actually referencing the same thing.

Does import create a new copy of imported library?

ES6 variable import by reference or copy

Is that possible without changing the source code (ideally), I can do something like the following

// a.js
import fx from 'money'
fx.rates={USD:1, EUR: 2.001}

// b.js
import fx from 'money'
fx.rates={USD:1, EUR: 2.002}

In my situation, I noticed that changing the rates in b.js, it also affect a.js.

Share Improve this question edited Jun 27, 2018 at 9:18 severus256 1,73317 silver badges29 bronze badges asked Jun 27, 2018 at 8:20 pk028382pk028382 952 silver badges10 bronze badges 4
  • 1 A great explanation of the JS module ecosystem can be found here - medium.freecodecamp/…. Since ES6 modules are live and read-only copies, you have to maintain your "rates" or whatever module specific config in another jS object ( service if you may ). Just use the utilities provided my your specific library in the service thus created. Hope this help ! – Shobhit Chittora Commented Jun 27, 2018 at 8:27
  • Possible duplicate of How do I correctly clone a JavaScript object? – Amanshu Kataria Commented Jun 27, 2018 at 8:44
  • 1 @AmanshuKataria - No, modules are much more plicated than simple objects. – T.J. Crowder Commented Jun 27, 2018 at 12:57
  • @ShobhitChittora - ES2015 modules aren't read-only. They are shared. – T.J. Crowder Commented Jun 27, 2018 at 12:57
Add a ment  | 

5 Answers 5

Reset to default 3

No, there's no general one-size-fits-all way to clone a module or load separate copies of it. You may be able to do it, but it will be dependent on the specific way the module is coded.

It's unfortunate that the library you're using doesn't have the concept of an instance rather than making everything global to the library. You might consider adding that concept to the library and sending the original repo a pull request (if they decline it, you can always create a fork).

You can do it simply by adding query-param to module filepath:

// a.js
import fx from 'money?first'
fx.rates={USD:1, EUR: 2.001}

// b.js
import fx from 'money?second'
fx.rates={USD:1, EUR: 2.002}

you can clone that rates object in each file :-

var localRatesVariable = Object.assign({}, fx.rates);

Modules are evaluated once, that's one of their main properties. It's possible to re-evaluate a module in some environment that supports it (Node.js) but not in client-side application.

In this case the library is hard-coded to use fx.rates object. Even if it's copied, it will continue to use it.

A proper way is to modify library source code to support multiple instances.

An alternative is to create a wrapper that hacks the library to behave like expected. Considering that it's convert method that uses fx.rates and it's synchronous, it can be patched to swap rates property during a call:

import fx from 'money'

export default function fxFactory(rates) {
  return Object.assign({}, fx, {
    convert(...args) {
      let convertResult;
      const ratesOriginal = fx.rates;
      try {
        fx.rates = rates;
        convertResult = fx.convert(...args);
      } finally {
        fx.rates = ratesOriginal;
      }
      return convertResult;
    }
  });
}

// a.js
import fxFactory from './fx'
const rates={USD:1, EUR: 2.001};
const fx1 = fxFactory(rates);

You can deep copy object:

let localRatesVariable = JSON.parse(JSON.stringify(fx.rates));

In my react application, I want to use a library (money.js) in 2 ponents which have different settings.

This library:
.js/
.js/money.js

I checked that javascript is using reference so the 2 ponents are actually referencing the same thing.

Does import create a new copy of imported library?

ES6 variable import by reference or copy

Is that possible without changing the source code (ideally), I can do something like the following

// a.js
import fx from 'money'
fx.rates={USD:1, EUR: 2.001}

// b.js
import fx from 'money'
fx.rates={USD:1, EUR: 2.002}

In my situation, I noticed that changing the rates in b.js, it also affect a.js.

In my react application, I want to use a library (money.js) in 2 ponents which have different settings.

This library:
http://openexchangerates.github.io/money.js/
http://openexchangerates.github.io/money.js/money.js

I checked that javascript is using reference so the 2 ponents are actually referencing the same thing.

Does import create a new copy of imported library?

ES6 variable import by reference or copy

Is that possible without changing the source code (ideally), I can do something like the following

// a.js
import fx from 'money'
fx.rates={USD:1, EUR: 2.001}

// b.js
import fx from 'money'
fx.rates={USD:1, EUR: 2.002}

In my situation, I noticed that changing the rates in b.js, it also affect a.js.

Share Improve this question edited Jun 27, 2018 at 9:18 severus256 1,73317 silver badges29 bronze badges asked Jun 27, 2018 at 8:20 pk028382pk028382 952 silver badges10 bronze badges 4
  • 1 A great explanation of the JS module ecosystem can be found here - medium.freecodecamp/…. Since ES6 modules are live and read-only copies, you have to maintain your "rates" or whatever module specific config in another jS object ( service if you may ). Just use the utilities provided my your specific library in the service thus created. Hope this help ! – Shobhit Chittora Commented Jun 27, 2018 at 8:27
  • Possible duplicate of How do I correctly clone a JavaScript object? – Amanshu Kataria Commented Jun 27, 2018 at 8:44
  • 1 @AmanshuKataria - No, modules are much more plicated than simple objects. – T.J. Crowder Commented Jun 27, 2018 at 12:57
  • @ShobhitChittora - ES2015 modules aren't read-only. They are shared. – T.J. Crowder Commented Jun 27, 2018 at 12:57
Add a ment  | 

5 Answers 5

Reset to default 3

No, there's no general one-size-fits-all way to clone a module or load separate copies of it. You may be able to do it, but it will be dependent on the specific way the module is coded.

It's unfortunate that the library you're using doesn't have the concept of an instance rather than making everything global to the library. You might consider adding that concept to the library and sending the original repo a pull request (if they decline it, you can always create a fork).

You can do it simply by adding query-param to module filepath:

// a.js
import fx from 'money?first'
fx.rates={USD:1, EUR: 2.001}

// b.js
import fx from 'money?second'
fx.rates={USD:1, EUR: 2.002}

you can clone that rates object in each file :-

var localRatesVariable = Object.assign({}, fx.rates);

Modules are evaluated once, that's one of their main properties. It's possible to re-evaluate a module in some environment that supports it (Node.js) but not in client-side application.

In this case the library is hard-coded to use fx.rates object. Even if it's copied, it will continue to use it.

A proper way is to modify library source code to support multiple instances.

An alternative is to create a wrapper that hacks the library to behave like expected. Considering that it's convert method that uses fx.rates and it's synchronous, it can be patched to swap rates property during a call:

import fx from 'money'

export default function fxFactory(rates) {
  return Object.assign({}, fx, {
    convert(...args) {
      let convertResult;
      const ratesOriginal = fx.rates;
      try {
        fx.rates = rates;
        convertResult = fx.convert(...args);
      } finally {
        fx.rates = ratesOriginal;
      }
      return convertResult;
    }
  });
}

// a.js
import fxFactory from './fx'
const rates={USD:1, EUR: 2.001};
const fx1 = fxFactory(rates);

You can deep copy object:

let localRatesVariable = JSON.parse(JSON.stringify(fx.rates));

本文标签: javascriptHow to import as a new copy of objectStack Overflow