Code Monkey home page Code Monkey logo

Comments (8)

rensbaardman avatar rensbaardman commented on May 21, 2024

What do you mean with 'both of these variables are available before rewiring'? Looking at the source code of component.js, they don't get declared or imported there, so somehow they have been declared before when running Materialize in the usual way.

Even if in the file you are currently working in, you have declared Element and cash, that doesn't mean rewire makes them automagically available to component.js (nor should it, else you would get a very confusing mess of implicitly declared globals). So I don't think there is an issue with rewire, and your fix seems the way to go.

from rewire.

bugy avatar bugy commented on May 21, 2024

Hi @rensbaardman, thanks for the answer.

Even if in the file you are currently working in, you have declared Element and cash, that doesn't mean rewire makes them automagically available to component.js

I didn't declare them locally. They are already available in the global declarations. The example which I gave here is the full listing of the file.

from rewire.

rensbaardman avatar rensbaardman commented on May 21, 2024

Hi @rensbaardman, thanks for the answer.

Even if in the file you are currently working in, you have declared Element and cash, that doesn't mean rewire makes them automagically available to component.js

I didn't declare them locally. They are already available in the global declarations. The example which I gave here is the full listing of the file.

I see. Element is part of a standard webbrowser environment, cash seems to be a utility which has been loading into a webpage. But are you using this with Node? Then where do these globals get declared? Because they are not standard Node globals.

The problem probably lies with the different scope of component.js. Are you sure Element and cash get defined as globals? Because then component.js should have access to them.

By the way, I have to say that modifying the global variable is probably not the way to go for exporting Component. It's usually cleaner to use the module.exports-pattern.

from rewire.

bugy avatar bugy commented on May 21, 2024

Hi @rensbaardman, sorry, I had to provide a little bit more context:
I was writing Jest tests, with node + jsdom

My file (which I test) depends on 3rd party materializecss library. This library is quite old-school and doesn't export much. In most cases it relies on global nature of declarations inside a browser. I.e. it just sets window.abc = abc (for example, the cash function), usually.
Or declares a class without any exports (as in this source)

And my file depends on a Select class, from this library, which depends on global Component class, which depends on global cash method.
Also, all of them depend on the global Element class

Are you sure Element and cash get defined as globals? Because then component.js should have access to them.

I had a setup.js file for Jest (it's just any file, which runs before any tests) which looked like this:

import 'materialize-css/js/cash';

const ComponentModule = require('rewire')('materialize-css/js/component');
global.Component = ComponentModule.__get__('Component');

I could assume, that this import could be available only inside setup.js
But as you can see, I don't do anything with Element here, it comes from jsdom, which I don't import here at all (it's already injected by Jest).

By the way, I have to say that modifying the global variable is probably not the way to go for exporting Component. It's usually cleaner to use the module.exports-pattern.

The problem, that I'm not using this class directly. It's used in another .js from that library (e.g. select.js:13)
Otherwise, I fully agree with you, I try to use exports/imports where it's possible

from rewire.

rensbaardman avatar rensbaardman commented on May 21, 2024

Alright, but where/how are Element and cash defined as globals? Because if Jest injects Element into your test, then that (probably) doesn't make it global. And importing cash also doesn't make it global. So then it is expected that component.js doesn't have access to it.

from rewire.

bugy avatar bugy commented on May 21, 2024

Maybe I'm confusing something here, I'm not that good with JS. Here is my reasoning, may be I understand JS variable scoping wrong:

I don't know how Jest (or jsdom) injects the Element in my setup and tests. But this Element is also accessible in all 3rd party imported modules. I don't think, that Jest will inject Element everywhere

Also, Jest has no clue about cash, I just import it in one place and it magically works everywhere, except that component.js rewiring :(
I believe it's defined as a global this way (first lines in cash.js):

(function (factory) {
  window.cash = factory();
})

Also, if I remember correctly, I tried to debug this rewiring. Before entering require('rewire') I added a watch on global.Element and global.cash and they were there. However, somewhere during rewire initialisation, those globals became undefined.
And then somewhere during method call chain of rewire, these watches became undefined.

PS thanks for your time and trying to understand the issue!

from rewire.

rensbaardman avatar rensbaardman commented on May 21, 2024

Hmmm... that's interesting. I wouldn't know why calling rewire() would undefine global variables. I think I now understand what your problem is 😅 And now I see why it could be related to #99. If you could make a minimal reproducible example, that might help sorting this thing out!

from rewire.

bugy avatar bugy commented on May 21, 2024

Hi @rensbaardman could you check this one, please?
https://github.com/bugy/rewire-181

There is an entry point: case_181.test.js, where I import a file, which sets global variable
Then I rewire a class
And then I print global variable from 3 places:

  • common util
  • rewired class
  • test

Only rewired class fails to print it

npm run test

Output:

someGlobalVar in test: abc
someGlobalVar in MyClass: undefined
someGlobalVar in another_file: abc

from rewire.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.