Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialPatrick McKinney
13,151 PointsHow does importing another JavaScript file/library actually work?
This is a great workshop, but I'm still not exactly sure if I understand how different JavaScript files/modules are being imported. The self-invoking function below would be in a file called map.js. There are three other JS files that would be loaded in the HTML file before the map.js file.
Would the map.js function import whatever is returned from the layersModule.js, Geocoder.js, and GeoLocate.js? Do things have to be returned from those other files to be used in the map.js file?
I am trying to modalrize some map applictions to be more maintabile. I just don't fully understand how this works in practice?
Thanks for the help!
(function(){
// code that creates map
}(layersModule, Geocoder, GeoLocate));
3 Answers
Joel Kraft
Treehouse Guest TeacherPatrick, the module pattern, being a function, has access to any global variables that have been defined. This would include any globals layersModule.js, Geocoder.js, and GeoLocate.js have defined (I assume they defined layersModule
, Geocoder
and GeoLocate
).
The code you included at the bottom of the post attempts to pull those global variables into the module, but the function signature (function()
) provides no parameters to assign them to, so they are not provided to the module's scope by these means (though remember they are still available inside the module through the global scope). To provide them this way, you could add parameters, something like
(function(layers,coder,locate){
// layers === layersModule;
// coder === Geocoder;
// locate === GeoLocate;
}(layersModule, Geocoder, GeoLocate));
This would create aliases for those globals inside your module: layers
, coder
, and locate
, respectively. Again, the global names are still available, but now have a shorthand available for use as well. Outside of the module, those shorthand variable names don't exist, so they wouldn't conflict with other libraries or code present in your project.
The main use for the module pattern is to encapsulate the environment inside, and keep from polluting the global scope. Often a module will declare one global variable, an object, that contains all the functionality it wishes to expose as properties on that object.
Creating the global can be done explicitly by importing the global object into the module and assigning the module's variable as a property on that object. For example, let's say map.js wants to create a global called MyMap
that provides all its functionality to other code outside the module (Note: Try to choose a variable name you know will not collide with other names. Map
, for example, probably exists as a property on most js global environments.):
(function(exports){
var MyMap = {};
// code that augments MyMap
exports.MyMap = MyMap
}(window));
In this example, exports contains the window (or global) variable within the module. Keep in mind that creating a global variable is the same thing as creating a property on the global object. So for example, in Chrome DevTools, this
var animal = 'giraffe';
is the same thing as this
window.animal = 'giraffe';
You can also return an object exports that represents the module you're creating, and capture it into a global variable, MyMap. The following code accomplishes the same thing as the code above:
var MyMap = (function(exports){
// code that creates MyMap
return exports;
}({}));
With this second form, you can modify it a little bit to use the "loose augmentation" pattern Huston talks about (by just adding MyMap ||
at the bottom.) This way if the global variable MyMap already exists, it can be added to as opposed to overwritten:
var MyMap = (function(exports){
// code that creates MyMap
return exports;
}(MyMap || {}));
There are several ways to use a module pattern. The key is to remember that in the end it's just a function that runs immediately. So it follows all the same rules that any function does.
Hope this helps, let us know if you have other questions!
Jesus Mendoza
23,289 PointsI know this post is pretty old but I'd give my response in case someone else is wondering the same.
module.exports and export are basically objects whose content is being created or updated when using module.exports or exports. For example:
We have the module object and that object has a property called exports.
module = {
exports: {}
}
when we use
module.exports = {}
or
module.exports = function () {return {}; }
We are overwriting the initial property value of exports in our module object. Then when we use require, our program will search the file in the location that we passed as an argument, the file will be executed, the value of exports property in the module object is overwritten and that value will be stored in the variable we created (where we are assigning the require value to). For example:
newNameOfExportsValue var = require ( 'locationOfFile');
Now newNameOfExportsValue has the value of the property exports from the module object of our previous file.
jason chan
31,009 PointsI did video tutorial on it. :) Nodejs for life!
Patrick McKinney
13,151 PointsPatrick McKinney
13,151 PointsThanks Joel Kraft! This made a lot of sense. I'm going to experiment with it.
My goal is to have a web map application that is built in components, and I think I can use this module pattern to accomplish that.
Joel Kraft
Treehouse Guest TeacherJoel Kraft
Treehouse Guest TeacherGreat! Good luck. Let us know how you do!
PoJung Chen
5,856 PointsPoJung Chen
5,856 PointsVery clearly, thanks very much!