0

I wonder how to manipulate the global scope of imported file to some object. For example the imported file:

// File A.js
export const str = `hello ${world}`;

function export foo() {
 return n1 + n2;
}

Then I want to use an object for the global scope of the imported file, like:

const scope1 = {
  world: 'world',
  n1: 1,
  n2: 2
}

const scope2 = {
  world: 'to you',
  n1: 100,
  n2: 200
}

Then when I import import * as A from 'A', the global scope will be taken from the objects scope1 or scope2 (like bind but to import statement).

Is there an easy way to achieve this behavior?

nrofis
  • 8,975
  • 14
  • 58
  • 113

1 Answers1

0

You could export the template string as a string, then in the file where you're importing, you can execute return new Function("return"+templateString +";").call(templateVars); which will evaluate your expression (sample):

//A.ts
export const str = "hello ${this.world}";

export function foo() {
  return this.n1 + this.n2;
}
//index.ts
import * as A from "./A";

class Scope {
  n1: number;
  n2: number;
  _world: string;

  get world(): string {
    return this.getValue(this._world);
  }

  set world(newWorld) {
    this._world = newWorld;
  }

  constructor({ n1, n2, world }) {
    this.n1 = n1;
    this.n2 = n2;
    this._world = world;
  }

  getValue(accessVariable) {
    return new Function("return `" + accessVariable + "`;").bind(this).call();
  }

  getResult(fn: Function) {
    return fn.bind(this).call();
  }
}

const scope1 = new Scope({ world: "world", n1: 1, n2: 2 });
const scope2 = new Scope({ world: "to you", n1: 100, n2: 200 });
console.log(scope1.getValue(A.str), scope2.getValue(A.str));
//output: hello world hello to you
console.log(scope1.getResult(A.foo), scope2.getResult(A.foo));
//output: 3 300
shrys
  • 5,860
  • 2
  • 21
  • 36