Migrating front end AMD (Require.js) modules to ECMAScript6 (ES6) classes

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • telecastg
    Active Community Member
    • Jun 2018
    • 907

    Migrating front end AMD (Require.js) modules to ECMAScript6 (ES6) classes

    This tutorial will use the "checklist" field view script and it's parent/protoype field "array" to illustrate how an existing AMD module was converted to an ES6 class, which is the modern syntax used to write Javascript code.

    As full disclosure the new ES6 class syntax is ONLY "syntactic sugar", meaning that it really does not improve anything in the actual Javascript language, and it doesn't provide any improvement in performance over AMD modules.

    However, ES6 provides Javascript with a syntax that is more like Java or Python or C# syntax, so it is much more attractive for coders who are not familiar with AMD (or don't like it's syntax), and for organizations looking to attract those candidates.

    yuri has said that AMD will stay operational in EspoCRM "possibly forever", so there is not a pressing need to change all your custom view classes (AMD modules) but it would be good practice to start using ES6 classes since that is the direction in which Espo is going.

    Key Differences:

    1.- Declaration

    client/src/views/fields/checklist.js (ES6)
    Code:
    import Dep from 'views/fields/array';
    
    export default Dep.extend({
    
        CLASS/MODULE CODE
    
    });
    client/src/views/fields/checklist.js (AMD)
    Code:
    define('views/fields/checklist', ['views/fields/array'], function (Dep) {
    
        return Dep.extend({
    
        CLASS/MODULE CODE
    
        });
    
    });
    client/src/views/fields/array.js (ES6)
    Code:
    import BaseFieldView from 'views/fields/base';
    import RegExpPattern from 'helpers/reg-exp-pattern';
    import MultiSelect from 'ui/multi-select';​
    
    class ArrayFieldView extends BaseFieldView {
    
        CLASS/MODULE CODE
    
    ​}
    
    export default ArrayFieldView;
    client/src/views/fields/array.js (AMD)
    Code:
    define('views/fields/array', ['views/fields/base', 'helpers/reg-exp-pattern', 'ui/multi-select'], function (Dep, RegExpPattern, MultiSelect) {
    
        return Dep.extend({
    
        CLASS/MODULE CODE
    ​
        });
    
    ​});

    2.- Spread (...) Operator and key word "super"

    client/src/views/fields/checklist.js (ES6)
    Code:
        data: function () {
            return {
                optionDataList: this.getOptionDataList(),
                ...Dep.prototype.data.call(this),
            };
        },
    ​
    client/src/views/fields/checklist.js (AMD)
    Code:
            data: function () {
                return _.extend({
                    optionDataList: this.getOptionDataList(),
                }, Dep.prototype.data.call(this));
            },
    ​
    client/src/views/fields/array.js (ES6)
    Code:
        setup() {
            super.setup();
    
             FUNCTION CODE​
        }
    
        data() {
            let itemHtmlList = [];
    
            (this.selected || []).forEach(value => {
                itemHtmlList.push(this.getItemHtml(value));
            });
    
            return {
                ...super.data(),
                selected: this.selected,
                translatedOptions: this.translatedOptions,
                hasOptions: !!this.params.options,
                itemHtmlList: itemHtmlList,
                isEmpty: (this.selected || []).length === 0,
                valueIsSet: this.model.has(this.name),
                maxItemLength: this.maxItemLength || this.MAX_ITEM_LENGTH,
                allowCustomOptions: this.allowCustomOptions,
            };
        }​
    client/src/views/fields/array.js (AMD)
    Code:
            setup: function () {
                Dep.prototype.setup.call(this);
    ​
                FUNCTION CODE
            }
    
            data: function () {
                let itemHtmlList = [];
    
                (this.selected || []).forEach(value => {
                    itemHtmlList.push(this.getItemHtml(value));
                });
    
                return _.extend({
                    selected: this.selected,
                    translatedOptions: this.translatedOptions,
                    hasOptions: this.params.options ? true : false,
                    itemHtmlList: itemHtmlList,
                    isEmpty: (this.selected || []).length === 0,
                    valueIsSet: this.model.has(this.name),
                    maxItemLength: this.maxItemLength || this.MAX_ITEM_LENGTH,
                    allowCustomOptions: this.allowCustomOptions,
                }, Dep.prototype.data.call(this));
            },
    ​
    The article below, provides general information about the modules approach in Javascript and its different implementations such as AMD an ES6.

    Additionally, it provides a simple example of the use of "module bundlers" which yuri has said will be implemented in the near future and will be a must if you are modifying original front end code.

    I‘m a software engineer living in Cincinnati, OH. I’m the lead maintainer of Maybe, a COSS personal finance app. I also run several golf websites and apps that I created while playing college golf.
    Last edited by telecastg; 07-13-2023, 04:07 PM.
  • item
    Active Community Member
    • Mar 2017
    • 1476

    #2
    Hi telecastg
    i hope i can migrate from AMD to ES
    but just for information, this ehancement is for V8 ?
    Gradual migrating frontend to ES modules. The current AMD module system will still be supported (maybe forever). import View from 'view'; import DetailRecordView from 'views/record/detail'; class M...


    If you could give the project a star on GitHub. EspoCrm believe our work truly deserves more recognition. Thanks.​

    Comment

    • telecastg
      Active Community Member
      • Jun 2018
      • 907

      #3
      Hello @item,

      No, this change has begun already, the sample code that I posted was taken from the current files at GitHub.

      As I mentioned though, this change offers really no benefit as far as system performance or new features, it is essentially a change in syntax coding style that makes it more friendly for new coders who might not be familiar with the AMD syntax or simply don't want to learn it because it is "old" and "difficult".

      (By the way, neither approach is really "new", AMD was released in 2010 and ES6 in 2015 )

      ES6 is an attempt to make Javascript coding syntax closer to the most popular languages, like Java and Python, but Javascript as a language remains the same as it has always been.
      Last edited by telecastg; 07-14-2023, 12:46 AM.

      Comment


      • item
        item commented
        Editing a comment
        Haa ok,
        Will try
        I have not skill in python or java but in the past i was fluent in C# ..?
        Best Regard telecatg

      • telecastg
        telecastg commented
        Editing a comment
        Here's an article that describes the most relevant features of ES6 in case you want to learn about it.

        By Cristian Salcescu ES6 brings more features to the JavaScript language. Some new syntax allows you to write code in a more expressive way, some features complete the functional programming toolbox, and some features are questionable. let and const ...


        Best regards

      • item
        item commented
        Editing a comment
        Hi @telecastg,

        i have read your link.. i think i am out of front-end now
        i understand maybe at 25% :S

        waouwww how javascript have changed/evolution... i need to return to school

        Best Regards
    • bandtank
      Active Community Member
      • Mar 2017
      • 379

      #4
      This is super useful. Thank you.

      Comment

      Working...