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