Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion docs/05.PORT-API.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ void jerry_port_print_char (char c);

### ES2015 Module system helper functions

The import statement requires two specific functions for opening and closing files (the modules) port specific.
The module system requires two specific functions for opening and closing files.
It also requires a platform specific way of normalizing file paths.

```c
/**
Expand All @@ -108,6 +109,21 @@ jerry_port_release_source (uint8_t *buffer_p) /**< buffer to free */
{
free (buffer_p);
} /* jerry_port_release_source */

/**
* Normalize a file path
*
* @return length of the path written to the output buffer
*/
size_t
jerry_port_normalize_path (const char *in_path_p, /**< input file path */
char *out_buf_p, /**< output buffer */
size_t out_buf_size) /**< size of output buffer */
{
// normalize in_path_p by expanding relative paths etc.
// write to out_buf_p the normalized path
// return length of written path
} /* jerry_port_normalize_path */
```

## Date
Expand Down
100 changes: 63 additions & 37 deletions docs/15.MODULE-SYSTEM.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,48 @@
# ES6 module support for JerryScript

The module system allows users to write import and export statements in scripts. Therefore the logic of the application could be separated in custom modules.
The module system allows users to write import and export statements in scripts, which can be used to separate the logic of the application into custom modules.
The standard's relevant part can be found [here](https://www.ecma-international.org/ecma-262/6.0/#sec-modules).

## General

If the main script contains import statements, then Jerry opens and runs the appropriate scripts before the main script (as the standard says). The script's and the module's extension is `.js`, custom extensions are unnecessary.
If a script contains import statements, then JerryScript will open and evaluate the the referenced modules before the main script runs, resolving and creating bindings for the referenced identifiers in the process.
It is not necessary to use any specific filename extensions for modules, JerryScript will try to open the given file paths as they are, but will try to normalize them before doing so. The exact normalization process is dependant on the port implementation provided. It is the user's responsibility to verify that the given files are valid EcmaScript modules.

main.js

```js
import { secret_number } from "./module.js"
import { exported_value } from "./module.js"

print (secret_number);
print (exported_value);
```

module.js

```js
var secret_number = 42;
var exported_value = 42;

export secret_number;
export exported_value;
```

## Supported features

* import variable or function
* add alias name to the imported variable (function)
* export variable or function
* add alias name to the exported variable (function)
* exporting identifiers from the module's lexical environment
* specifying export names for the exported values
* importing exported identifiers from a module
* specifying local binding names for the imported values
* module namespace imports
* `import * as module from 'module.js`
* indirect export statements
* `export {variable} from 'module.js'`
* star export statements
* `export * from 'module.js'`
* importing a module for side-effects
* `import 'module.js'`
* default import and export statements
* `export default local_identifier`
* `import def from 'module.js'`
* anonymous default exports
* `export default function () {}`

### Example

Expand Down Expand Up @@ -69,22 +83,20 @@ export function getFeatureDetails() {
}
```

## Unsupported features
### Module namespace import statements

* **snapshot**
* errors from the imported scripts
* redirection ( `export { a, b } from 'module.js'` )
* default import and export
* `import b from 'module.js'`
* `export default b`,
* whole module import statements
* `import * from 'module.js`
* `import { * as module } from 'module.js`
* object freezing ( `Object.freeze (this)` )
A module namespace object can be imported. In this case the local binding will contain an object holding the exported values of the module, including local exports and all indirect exports. Ambiguous exported names are exluded from the namespace object.

```js
import * as module from './module.js';

print(">> Engine: " + module.engine);
print(">> Version: " + module.version);
```

### Redirection
### Indirect export statements

An export statement can import variables from a custom module and export it directly from the current script. This statement is called redirection. In this case the `export { b } from 'module2.js'` works as the `b` was imported before then exported as a local variable.
An export statement can transitively export variables from another module, either via named indirect exports or a star export statement. In this case the resolving process will follow the chain until it reaches a module containing a local binding for that export name. If there are multiple modules which satisfy the export, that means the export is ambiguous, and will result in a SyntaxError.

```js
import { a, b } from 'module.js'
Expand All @@ -105,28 +117,42 @@ export var b = 40;

### Default imports and exports

TODO: This part is going to be written in the next part of the patch.
Each module can optionally provide a single default export by using the `export default` statement. Default exports can either reference identifiers in the module's lexical environment, or be an anonymous default export, in which case they will only be accessible by an importing script.

### Import the whole module
```js
import defaultExport, { b as c } from 'module.js'

The whole module can be imported. In this case the `m` object would contain the exported parts of the module. If the import is not aliased, the `global object` would contain the exports.
print (defaultExport); // 2
print (c ()); // 42
```

```js
import { * as m } from "./module.js"
// module.js
export default 2;
export function b () {
return 42;
}
```

### Importing modules for side-effects

Evaluate a module without importing anything. Any errors encountered in the module will be propagated.

print (m.secret_number);
print (m.getPrettifiedNumber());
print (m.api.version);
```js
import 'module.js' // > module.js
// "> module.js" is printed
b (); // (ReferenceError) b is not defined
```

```js
// module.js
var secret_number = 42;
export secret_number;

export function getPrettifiedNumber() {
return "*** " + secret_number + " ***";
export function b () {
print ("> module.js");
return 42;
}

export { ble as api } from "./ble.js";
b ();
```

## Unsupported features

* **snapshot**
5 changes: 0 additions & 5 deletions jerry-core/ecma/base/ecma-init-finalize.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,6 @@ void
ecma_finalize (void)
{
jmem_unregister_free_unused_memory_callback (ecma_free_unused_memory);

#if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
ecma_module_finalize_lex_envs ();
#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */

ecma_finalize_global_lex_env ();
ecma_finalize_builtins ();
ecma_gc_run (JMEM_FREE_UNUSED_MEMORY_SEVERITY_LOW);
Expand Down
Loading