Skip to content
Closed
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
2 changes: 0 additions & 2 deletions content/developer/howtos/javascript_client_action.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ framework and use services, core components, hooks,...
.. code-block:: js
:caption: :file:`my_client_action.js`

/** @odoo-module **/

import { registry } from "@web/core/registry";

import { Component } from "@odoo/owl";
Expand Down
4 changes: 0 additions & 4 deletions content/developer/howtos/javascript_field.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ displaying "Late!" in red whenever the checkbox is checked.
.. code-block:: javascript
:caption: :file:`late_order_boolean_field.js`

/** @odoo-module */

import { registry } from "@web/core/registry";
import { BooleanField } from "@web/views/fields/boolean/boolean_field";
import { Component, xml } from "@odoo/owl";
Expand Down Expand Up @@ -63,8 +61,6 @@ Assume that we want to create a field that displays a simple text in red.
.. code-block:: js
:caption: :file:`my_text_field.js`

/** @odoo-module */

import { standardFieldProps } from "@web/views/fields/standard_field_props";
import { Component, xml } from "@odoo/owl";
import { registry } from "@web/core/registry";
Expand Down
10 changes: 0 additions & 10 deletions content/developer/howtos/javascript_view.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ can be done in a few steps:
.. code-block:: js
:caption: :file:`custom_kanban_controller.js`

/** @odoo-module */

import { KanbanController } from "@web/views/kanban/kanban_controller";
import { kanbanView } from "@web/views/kanban/kanban_view";
import { registry } from "@web/core/registry";
Expand Down Expand Up @@ -82,8 +80,6 @@ Creating a new view is an advanced topic. This guide highlight only the essentia
.. code-block:: js
:caption: :file:`beautiful_controller.js`

/** @odoo-module */

import { Layout } from "@web/search/layout";
import { useService } from "@web/core/utils/hooks";
import { Component, onWillStart, useState} from "@odoo/owl";
Expand Down Expand Up @@ -161,8 +157,6 @@ Creating a new view is an advanced topic. This guide highlight only the essentia
.. code-block:: js
:caption: :file:`beautiful_model.js`

/** @odoo-module */

import { KeepLast } from "@web/core/utils/concurrency";

export class BeautifulModel {
Expand Down Expand Up @@ -199,8 +193,6 @@ Creating a new view is an advanced topic. This guide highlight only the essentia
.. code-block:: js
:caption: :file:`beautiful_arch_parser.js`

/** @odoo-module */

import { XMLParser } from "@web/core/utils/xml";

export class BeautifulArchParser extends XMLParser {
Expand All @@ -219,8 +211,6 @@ Creating a new view is an advanced topic. This guide highlight only the essentia
.. code-block:: js
:caption: :file:`beautiful_view.js`

/** @odoo-module */

import { registry } from "@web/core/registry";
import { BeautifulController } from "./beautiful_controller";
import { BeautifulArchParser } from "./beautiful_arch_parser";
Expand Down
2 changes: 0 additions & 2 deletions content/developer/howtos/standalone_owl_application.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ Then create the JavaScript file for that component in :file:`/your_module/static

.. code-block:: js

/** @odoo-module */
import { Component } from "@odoo/owl";

export class Root extends Component {
Expand All @@ -50,7 +49,6 @@ file. Create the JavaScript file that will mount the app in :file:`/your_module/

.. code-block:: js

/** @odoo-module */
import { whenReady } from "@odoo/owl";
import { mountComponent } from "@web/env";
import { Root } from "./root";
Expand Down
10 changes: 0 additions & 10 deletions content/developer/howtos/website_themes/theming.rst
Original file line number Diff line number Diff line change
Expand Up @@ -591,16 +591,6 @@ Odoo supports three different kinds of JavaScript files:
Most new Odoo JavaScript codes should use the native JavaScript module system. It's simpler and
brings the benefit of a better developer experience with better integration with the IDE.

.. important::
Odoo needs to know which files should be translated into :ref:`Odoo modules
<frontend/js_modules>` and which files should not. It's an opt-in system: Odoo looks at the first
line of a JavaScript file and checks if it contains the string `@odoo-module`. If so,
it will automatically be converted to an Odoo module.

.. code-block:: javascript

/** @odoo-module **/

**Declaration**

.. code-block:: python
Expand Down
1 change: 0 additions & 1 deletion content/developer/reference/backend/testing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,6 @@ Javascript

.. code-block:: javascript

/** @odoo-module **/
import tour from 'web_tour.tour';
tour.register('rental_product_configurator_tour', {
url: '/web', // Here, you can specify any other starting url
Expand Down
122 changes: 47 additions & 75 deletions content/developer/reference/frontend/javascript_modules.rst
Original file line number Diff line number Diff line change
Expand Up @@ -51,50 +51,64 @@ execute them precisely in that order).
Native Javascript Modules
=========================

Most new Odoo javascript code should use the native javascript module system. This
is simpler, and brings the benefits of a better developer experience with a better
integration with the IDE.
Odoo javascript code uses the native javascript module system. This is simpler, and
brings the benefits of a better developer experience with a better integration with the IDE.

There is a very important point to know: Odoo needs to know which files
should be translated into :ref:`Odoo modules <frontend/modules/odoo_module>` and which
files should not be translated. This is an opt-in system: Odoo will look at the
first line of a JS file and check if it contains the string *@odoo-module*. If so, it will
automatically be converted to an Odoo module.

For example, let us consider the following module, located in :file:`web/static/src/file_a.js`:
Let us consider the following module, located in :file:`web/static/src/file_a.js`:

.. code-block:: javascript

/** @odoo-module **/
import { someFunction } from './file_b';
import { someFunction } from "./file_b";

export function otherFunction(val) {
return someFunction(val + 3);
}

Note the comment in the first line: it describes that this file should be converted.
Any file without this comment will be kept as-is (which will most likely be an
error). This file will then be translated into an Odoo module that look like this:
There is a very important point to know: by default Odoo transpiles files under
`/static/src` and `/static/tests` into :ref:`Odoo modules <frontend/modules/odoo_module>`.
This file will then be transpiled into an Odoo module that looks like this:

.. code-block:: javascript

odoo.define('@web/file_a', function (require) {
odoo.define('@web/file_a', ['@web/file_b'], function (require) {
'use strict';
let __exports = {};

const { someFunction } = require("@web/file_b");

__exports.otherFunction = function otherFunction(val) {
return someFunction(val + 3);
return someFunction(val + 3);
};

return __exports;
)};

So, as you can see, the transformation is basically adding `odoo.define` on top,
and updating the import/export statements.
So, as you can see, the transformation is basically adding `odoo.define` on top
and updating the import/export statements. This is an opt-out system, it's possible
to tell the transpiler to ignore the file.

.. code-block:: javascript

Another important point is that the translated module has an official name:
/** @odoo-module ignore **/
(function () {
const sum = (a, b) => a + b;
console.log(sum(1, 2));
)();

Note the comment in the first line: it describes that this file should be ignored.

In other folders, files aren't transpiled by default, it is opt-in. Odoo will look at the
first line of a JS file and check if it contains a comment with *@odoo-module* and without
the tag *ignore*. If so, it will automatically be converted to an Odoo module.

.. code-block:: javascript

/** @odoo-module **/
export function sum(a, b) {
return a + b;
}

Another important point is that the transpiled module has an official name:
*@web/file_a*. This is the actual name of the module. Every relative imports
will be converted as well. Every file located in an Odoo addon
:file:`some_addon/static/src/path/to/file.js` will be assigned a name prefixed by the
Expand All @@ -120,16 +134,13 @@ The file :file:`file_b` can import :file:`file_a` like this:

.. code-block:: javascript

/** @odoo-module **/
import {something} from `./file_a`
import {something} from `./file_a`;

But :file:`file_c` need to use the full name:

.. code-block:: javascript

/** @odoo-module **/
import {something} from `@web/file_a`

import {something} from `@web/file_a`;

Aliased modules
---------------
Expand All @@ -155,7 +166,7 @@ Then, the translated module will also create an alias with the requested name:

.. code-block:: javascript

odoo.define(`web.someName`, function(require) {
odoo.define(`web.someName`, ['@web/file_a'], function(require) {
return require('@web/file_a')[Symbol.for("default")];
});

Expand All @@ -180,7 +191,7 @@ original module:

.. code-block:: javascript

odoo.define(`web.someName`, function(require) {
odoo.define(`web.someName`, ["@web/file_a"], function(require) {
return require('@web/file_a');
});

Expand Down Expand Up @@ -279,7 +290,7 @@ As an example, it may look like this:
.. code-block:: javascript

// in file a.js
odoo.define('module.A', function (require) {
odoo.define('module.A', [], function (require) {
"use strict";

var A = ...;
Expand All @@ -288,7 +299,7 @@ As an example, it may look like this:
});

// in file b.js
odoo.define('module.B', function (require) {
odoo.define('module.B', ['module.A'], function (require) {
"use strict";

var A = require('module.A');
Expand All @@ -298,20 +309,6 @@ As an example, it may look like this:
return B;
});

An alternative way to define a module is to give explicitly a list of dependencies
in the second argument.

.. code-block:: javascript

odoo.define('module.Something', ['module.A', 'module.B'], function (require) {
"use strict";

var A = require('module.A');
var B = require('module.B');

// some code
});


If some dependencies are missing/non ready, then the module will simply not be
loaded. There will be a warning in the console after a few seconds.
Expand All @@ -332,12 +329,13 @@ The `odoo.define` method is given three arguments:
If the name is not unique, an exception will be thrown and displayed in the
console.

- `dependencies`: the second argument is optional. If given, it should be a list
of strings, each corresponding to a javascript module. This describes the
dependencies that are required to be loaded before the module is executed. If
the dependencies are not explicitly given here, then the module system will
extract them from the function by calling toString on it, then using a regexp
to find all the `require` statements.
- `dependencies`: It should be a list of strings, each corresponding to a
javascript module. This describes the dependencies that are required to
be loaded before the module is executed.

- finally, the last argument is a function which defines the module. Its return
value is the value of the module, which may be passed to other modules requiring
it.

.. code-block:: javascript

Expand All @@ -350,11 +348,6 @@ The `odoo.define` method is given three arguments:
return something;
});

- finally, the last argument is a function which defines the module. Its return
value is the value of the module, which may be passed to other modules requiring
it. Note that there is a small exception for asynchronous modules, see the
next section.

If an error happens, it will be logged (in debug mode) in the console:

* `Missing dependencies`:
Expand All @@ -369,24 +362,3 @@ If an error happens, it will be logged (in debug mode) in the console:
Modules who depend on a rejected module
* `Non loaded modules`:
Modules who depend on a missing or a failed module

Asynchronous modules
--------------------

It can happen that a module needs to perform some work before it is ready. For
example, it could do an rpc to load some data. In that case, the module can
simply return a promise. The module system will simply
wait for the promise to complete before registering the module.

.. code-block:: javascript

odoo.define('module.Something', function (require) {
"use strict";

var ajax = require('web.ajax');

return ajax.rpc(...).then(function (result) {
// some code here
return something;
});
});
2 changes: 0 additions & 2 deletions content/developer/reference/frontend/services.rst
Original file line number Diff line number Diff line change
Expand Up @@ -312,8 +312,6 @@ Let's say we want to add an effect that add a sepia look at the page.

.. code-block:: javascript

/** @odoo-module **/

import { registry } from "@web/core/registry";
const { Component, tags } = owl;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,6 @@ see how to create a `sub-component <{OWL_PATH}/doc/reference/component.md#sub-co
as the component. For example, if we have a `TodoList` component, its code should be in
`todo_list.js`, `todo_list.xml` and if necessary, `todo_list.scss`

.. important::
Don't forget :code:`/** @odoo-module **/` in your JavaScript files. More information on this can
be found :ref:`here <frontend/modules/native_js>`.

.. _tutorials/discover_js_framework/simple_card:

3. A simple `Card` component
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,6 @@ is hardcoded in the controller.

.. code-block:: js

/** @odoo-module */

import { registry } from '@web/core/registry';
import { galleryView } from '@awesome_gallery/gallery_view';
import { GalleryRenderer } from '@awesome_gallery/gallery_renderer';
Expand Down