简体   繁体   中英

Node.js - Impact of declaring module.exports twice for WebStorm intellisense

What is the impact of the following declaration in a Sails JavaScript application?

var DataService = {};
module.exports = DataService;

module.exports = {
    // module code
}

I understand this is a "hack" that allows WebStorm intellisense to recognize DataService and its members globally, but will the code behave exactly the same with and without the 2 first lines?

Tks!

First, you define a variable called DataService and you equals it to an empty object. After that, you are assigning to the module.exports object the value of the DataService variable, which is an empty object. Finally, your are overriding the module.exports object with again an empty object, but directly defined. It will have the same behavior, because in the two cases, the object has the same data, which is an empty object.

The variable name DataService is used as a reference to the empty object in the local namespace. Assigning a value to the module.exports object is giving it the data of the variable, not the name. For example, when you will want to use the module, you will require it,

var dataService = require('./data-service');

If DataService was an object, then you could access its properties

var example = dataService.example;

But in your case, dataService is directly an empty object, not a DataService object. So you can not

var example = dataService.DataService ; 

Short answer:

Probably (because of the optimizer).

Long answer:

This horrible hack probably won't create any perceivable differences in how the code functions. In theory, you create a new object, which would take up space in memory and cost some CPU cycles, but in all likelihood the optimizer will simply elide that part of the code as long as you don't reference the created object anywhere (I am guessing...)

Suggestion:

Try to use https://www.jetbrains.com/help/webstorm/2016.1/configuring-javascript-libraries.html#configure to register your library in a more robust fashion.

An aside about intellisense in javascript

Note that this behaviour appears to be due to Webstorm not really understanding about JavaScript modules yet. For a node.js-based project, anything declared inside an imported context (like DataService.js) is scoped to that import (file), unless you explicitly export it. However, the same piece of code, running in the browser in a SCRIPT tag src file, would end up in the global context.

When you declare var DataService = {} in your application, WebStorm incorrectly assumes that you are placing the DataService variable into global scope, meaning that any other file which adds members (props/methods) to the referenced variable would end up as members of the DataService object you created.

You will note that this assumption wouldn't be strictly true, even if the variable did end up in global scope, because more than one file would declare the variable, thus overwriting the object you create in your file. JavaScript intellisense always involves a bit of guesswork because the language is very loosely typed and an object's properties can't really be determined without actually executing the code.

In general, if you declare a member in a file or against a variable named DataService somewhere in the indexed codebase, WebStorm (and most other IDEs) will bring it up as a potential member of the variable you are referencing. You can't rely on intellisense to guarantee the presence of a property through static analysis like you would in a more statically typed language like Java or C#.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM