Exporting from a Module

Primitives, functions, objects, and classes defined within a module are visible to the outside only if exported. JavaScript offers several options for exporting; choose the simplest option that meets your needs in a given situation.

Inlining Exports

You may declare a reference or a class and at the same time export it—that is, inline the export keyword in the declaration. This approach is the easiest and least noisy approach to exporting. To inline an export, prefix a declaration with the export keyword, which makes the declared reference available outside the module. The name of the declared reference becomes the name that is exported—this is called a named export.

For example, the following code exports a primitive, a function, an object, and a class, with their respective names. The primitive referenced by the variable FREEZINGPOINT_IN_F is not exported and is visible only within the module/file.

 export​ ​const​ FREEZING_POINT = 0;
 
 export​ ​function​ f2c(fahrenheit) {
 return​ (fahrenheit - 32) / 1.8;
 }
 
 export​ ​const​ temperaturePoints = { freezing: 0, boiling: 100 };
 
 export​ ​class​ Thermostat {
 constructor​() {
 //...initialization sequence
  }
 }
 
 const​ FREEZINGPOINT_IN_F = 32;

Marking references with export at the point of declaration makes the code transparent—we can readily see if a reference has been exported or not. However, since the exports are spread out in the file, it may make it hard to quickly get a glimpse of everything exported from a module. This is generally not a huge concern if the files are relatively small.

Exporting Explicitly

You’re not forced to export at the point of declaration. You can export an existing function, object, and so forth at any time by explicitly declaring an export. Although inlining exports is less noisy and avoids an extra line for export, explicitly exporting is necessary when we want to export select names when using multiple declarations.

In the following code, we explicitly export the c2f function, which we could have exported inline as well. However, we want to export only FREEZINGPOINT_IN_K, from the multiple declarations, and not export BOILINGPOINT_IN_K. Explicit export is a good choice for this.

 function​ c2f(celsius) {
 return​ celsius * 1.8 + 32;
 }
 
 const​ FREEZINGPOINT_IN_K = 273.15, BOILINGPOINT_IN_K = 373.15;
 
 export​ { c2f, FREEZINGPOINT_IN_K };

Prefer inline exports over explicit exports, and in general, use explicit exports only when an inline export is not suitable.

Exporting with a Different Name

So far we’ve exported the declarations with their name. However, we can export them with a different name if we desire. This is useful, for example, if we decide to give a more descriptive name for a function for the outside world to use but keep a shorter name for internal use.

Here’s an example to illustrate exporting with a different name:

 function​ c2k(celsius) {
 return​ celsius + 273.15;
 }
 
 export​ { c2k ​as​ celsiusToKelvin };

The name c2k is only visible within the module—kind of like nicknames used within families. However, outside the module this function is known by the name celsiusToKelvin and can be called only with that name.

Default Exports

A default export may signify a major, the most significant, or the only export a module may like to expose. Although a module can have zero or more named exports, it can have at most one default export. Use a default export if you have only one reference or class to export. Even when you have multiple things to export, you may use a default export if most users of your module will use a particular reference more frequently than other exported references.

To mark an export as default, follow the export keyword with the default keyword. Default exports have one restriction, however; export default is not permitted in front of the keywords const and let while export without default is allowed. In short, inlining of default exports is permitted for functions and classes, but not for variables and constants. You may explicitly export variables and constants as default. Let’s export as default a function from our module.

 export​ ​default​ ​function​ unitsOfMeasures() {
 return​ [​'Celsius'​, ​'Delisle scale'​, ​'Fahrenheit'​, ​'Kelvin'​, ​/*...*/​];
 }

The unitsOfMeasures() function is exported as default. Instead of exporting a function as default, we can similarly export a class as default.

In the previous code we used an inline default export on the function. We can also perform an explicit default export at a later time after declaring the function with no export, like so: export default unitsOfMeasures. As we discussed before, this approach is especially useful to export a variable that was declared using const or let; that’s because default can’t be followed by const or let.

When we create a named export, the name of the reference used in the file becomes the exported name. When we create a named export with a different name, that new name we provide becomes the name visible outside the module. When we create a default export, however, the name visible outside the module becomes default and the importing module may bind the name default to whatever name it likes. We’ll see this later when we explore imports.

If you mark an export as default when declaring a function or a class, the name you provide for the function or class is not visible outside the module. If you have no use for that name internally in your module, then you can omit the name entirely. So, for instance, instead of exporting a function like this:

 export​ ​default​ ​function​ unitsOfMeasures() {
 return​ [​'Celsius'​, ​'Delisle scale'​, ​'Fahrenheit'​, ​'Kelvin'​, ​/*...*/​];
 }

if you have no use for that function within your module, then you may omit the name of the function, like so:

 export​ ​default​ ​function​() {
 return​ [​'Celsius'​, ​'Delisle scale'​, ​'Fahrenheit'​, ​'Kelvin'​, ​/*...*/​];
 }

Likewise, we can omit the name of a class, if we like, when creating an inline default export for a class. For example, export default class { /*...*/ } will work instead of export default class SomeNameNoOneCares { /*...*/ } as well.

Reexporting from Another Module

You can reexport modules to reduce the number of imports and to make dependencies transitive. Occasionally you may want to make available to the users of your module some references that are contained in other modules.

For example, let’s say we create a weather module but we want to expose functions from the temperature module we created previously and also another hypothetical pressure module. The weather module may itself expose some references that it contains. Now suppose a module wants to use the references in the weather, temperature, and pressure modules. That user does not need three imports. Instead, by importing the weather module, thanks to reexport, the user will have access to references exported by all the three modules: weather, temperature, and pressure.

Here’s a way to reexport all exported references, except default, from temperature:

 export​ * ​from​ ​'./temperature'​;

Now, the modules that import weather can use all references exported by temperature as if they were exported by weather.

You can export select references from other modules instead of reexporting everything that’s exported. For example, the following reexport will export only Thermostat and celsiusToKelvin from temperature.

 export​ { Thermostat, celsiusToKelvin } ​from​ ​'./temperature'​;

An importer of the module that does this reexport will not have access to references like f2c in temperature unless it directly imports the temperature module.

Reexport all—that is, export *—does not reexport a default export. A module can reexport any reference, or the default, from another module as its own default if it chooses. Likewise, it may rename a reference from another module while exporting. This can be achieved using the facility to export with a different name we saw in Exporting with a Different Name. Here’s an example with export...as to reexport.

 export​ { Thermostat ​as​ Thermo, ​default​ ​as​ ​default​ } ​from​ ​'./temperature'​;

Here the weather module is reexporting the Thermostat class from temperature with a new name, Thermo. The user of the reexporting module will know Thermostat of temperature as Thermo. Likewise, it takes the default export of temperature—that is, the function unitsOfMeasures()—and exports as its own default.

Instead of reexporting another modules default as your own module’s default, you can use any exported reference from another module as your default, like so:

 export​ { Thermostat ​as​ Thermo, f2c ​as​ ​default​ } ​from​ ​'./temperature'​;

Here the function f2c, which is a named export and not a default export in temperature, is reexported from this module as its own default. In the same vein, your module can reexport the default from another module with a different name:

 export​ { Thermostat ​as​ Thermo, ​default​ ​as​ uom } ​from​ ​'./temperature'​;

The function unitsOfMeasures exported as default from temperature is now reexported as uom. This technique, renaming a default from another module, is useful when a module reexports multiple modules and wants to make the defaults from more than one module available to the user.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset