74 lines
3.0 KiB
Plaintext
74 lines
3.0 KiB
Plaintext
== Why is this an issue?
|
|
|
|
Assigning a value to an import variable will cause a runtime error and will raise a compilation error in TypeScript.
|
|
|
|
=== Named imports
|
|
|
|
When using named imports, the imported identifier is a _live binding_ exported by another module. Live bindings can be updated or reassigned by the exporting module, and the imported value would also change. The importing module cannot reassign it.
|
|
|
|
[source,javascript]
|
|
----
|
|
import { exportedObject } from 'module.js';
|
|
exportedObject = 'hello world!'; // Noncompliant: TypeError: Assignment to constant variable.
|
|
----
|
|
|
|
This rule will *not* raise an issue when a module mutates the imported object. Be aware that all other modules importing the same value will observe the mutated value.
|
|
|
|
[source,javascript]
|
|
----
|
|
import { exportedObject } from 'module.js';
|
|
exportedObject.newAttribute = 'hello world!'; // exportedObject now contains newAttribute and can be seen from all other modules importing it
|
|
----
|
|
|
|
=== Namespace and dynamic imports
|
|
|
|
This rule will raise an issue when modifying members of a https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import#module_namespace_object[_module namespace object_]. A module namespace object is a https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal[sealed object] that describes all exports from a module.
|
|
|
|
This can be done using
|
|
|
|
* a namespace import
|
|
[source,javascript]
|
|
----
|
|
import * as module from 'module.js';
|
|
module.newObject = module.exportedObject; // Noncompliant: TypeError: Cannot add property readPath, object is not extensible
|
|
----
|
|
|
|
* the fulfillment value of a dynamic import.
|
|
|
|
[source,javascript]
|
|
----
|
|
import('module.js').then(module => {
|
|
module.newObject = module.exportedObject; // Noncompliant: TypeError: Cannot add property readPath, object is not extensible
|
|
})
|
|
----
|
|
|
|
=== Default imports
|
|
|
|
Default imports are live bindings to the `default` export. As with the other forms of `import` declarations, the importing module cannot reassign it.
|
|
|
|
[source,javascript]
|
|
----
|
|
import module from 'module.js';
|
|
module = 'hello world!'; // Noncompliant: TypeError: Assignment to constant variable.
|
|
----
|
|
|
|
However, the object which `default` refers to is not a _live binding_ and may still be mutated by importing modules.
|
|
|
|
[source,javascript]
|
|
----
|
|
import moduleDefault from 'module.js';
|
|
moduleDefault.newAttribute = 'hello world!'; // module.default now contains newAttribute and can be seen from all other modules importing it
|
|
----
|
|
|
|
== Resources
|
|
|
|
=== Documentation
|
|
|
|
* MDN web docs - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import[import]
|
|
* MDN web docs - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import#module_namespace_object[Module namespace object]
|
|
* MDN web docs - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed#description[Sealed Objects]
|
|
|
|
//=== Articles & blog posts
|
|
//=== Conference presentations
|
|
//=== Standards
|