最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Converting code to ES6 modules - Stack Overflow

programmeradmin1浏览0评论

I have just started learning es6 module system. I have some es5 javascript code which I want to transform to es6 modules. There are 3 javascript files

workflow-designer.js

var WorkflowDesigner = (function () {
  var constructor = function (element, options) {
    var ponent = this;
    if ($(element).hasClass('panel')) {
      ponent.panel = $(element);
    } else {
      ponent.panel = $(element).closest('.panel');
    }
  };

  extend(Object, constructor, {
    getWorkflowName: function () {
      return 'WorkflowName001';
    },

    nextStep: function () {
      var o = {};
      o['id'] = -1;
      //some code here
      return o;
    },

    prevStep: function () {
      var o = {};
      o['id'] = -1;
      //some code here
      return o;
    }
  });

  return constructor;

})();

(function ($) {    
    $.fn.createWorkflowDesigner = function (options) {
        debugger;
        return this.map(function (index, element) {
            return new WorkflowDesigner($(element), options);
        });
    };

}(jQuery));

extend.js

function extend(parent, child, methods) {
    debugger;
    let Surrogate = function () {};
    Surrogate.prototype = parent.prototype;
    child.prototype = new Surrogate();
    child.prototype.constructor = child;
    // Add a reference to the parent's constructor
    child.parentConstructor = parent;

    // Copy the methods passed in to the prototype
    for (let name in methods) {
        if (methods.hasOwnProperty(name)) {
            child.prototype[name] = methods[name];
        }
    }
    // so we can define the constructor inline
    return child;
}

There a third file utils.js which contain extension methods like

if (!Array.prototype.find) {
    Array.prototype.find = function (predicate) {
        //some code here

    }
}

if (!Array.prototype.doSomething) {
    Array.prototype.doSomething = function (predicate) {
        //some code here

    }
}

$(document).keyup(function (event) {
    //somthing here.        
});

I know that to convert the code to es6 modules, I can simply export the extend function like export function extend(.....) in the extend.js file. However, I am not 100% sure how to convert the workflow-designer and utils.js to es6 modules.

I suspect that I need to something like below to convert my workflow-designer.js to es6 module:

export default function workflowDesigner() {
    let constructor = function (element, options) {
        options = options || {};
        let ponent = this;
        if ($(element).hasClass('panel')) {
            ponent.panel = $(element);
        } else {
            ponent.panel = $(element).closest('.panel');
        }
    };
    //rest of the code here....

    return constructor;

};

Please let me know if I am moving into the right direction or not.

UPDATE: As per @Bergi's suggesion I changed the extend function like below:

export default function extend(parent, child, methods) {

  child.prototype = Object.create(parent.prototype);
  child.prototype.constructor = child;

  // Add a reference to the parent's constructor
  child.parentConstructor = parent;

  // Copy the methods passed in to the prototype
  Object.assign(child, methods);

  // so we can define the constructor inline
  return child;
} 

However, now I am getting error message that "workflowDesigner.getWorkflowName is not a function"

In the debug mode I can see that this function is available at workflowDesigner.__proto__.constructor.getWorkflowName. With the old code it works fine.

I have just started learning es6 module system. I have some es5 javascript code which I want to transform to es6 modules. There are 3 javascript files

workflow-designer.js

var WorkflowDesigner = (function () {
  var constructor = function (element, options) {
    var ponent = this;
    if ($(element).hasClass('panel')) {
      ponent.panel = $(element);
    } else {
      ponent.panel = $(element).closest('.panel');
    }
  };

  extend(Object, constructor, {
    getWorkflowName: function () {
      return 'WorkflowName001';
    },

    nextStep: function () {
      var o = {};
      o['id'] = -1;
      //some code here
      return o;
    },

    prevStep: function () {
      var o = {};
      o['id'] = -1;
      //some code here
      return o;
    }
  });

  return constructor;

})();

(function ($) {    
    $.fn.createWorkflowDesigner = function (options) {
        debugger;
        return this.map(function (index, element) {
            return new WorkflowDesigner($(element), options);
        });
    };

}(jQuery));

extend.js

function extend(parent, child, methods) {
    debugger;
    let Surrogate = function () {};
    Surrogate.prototype = parent.prototype;
    child.prototype = new Surrogate();
    child.prototype.constructor = child;
    // Add a reference to the parent's constructor
    child.parentConstructor = parent;

    // Copy the methods passed in to the prototype
    for (let name in methods) {
        if (methods.hasOwnProperty(name)) {
            child.prototype[name] = methods[name];
        }
    }
    // so we can define the constructor inline
    return child;
}

There a third file utils.js which contain extension methods like

if (!Array.prototype.find) {
    Array.prototype.find = function (predicate) {
        //some code here

    }
}

if (!Array.prototype.doSomething) {
    Array.prototype.doSomething = function (predicate) {
        //some code here

    }
}

$(document).keyup(function (event) {
    //somthing here.        
});

I know that to convert the code to es6 modules, I can simply export the extend function like export function extend(.....) in the extend.js file. However, I am not 100% sure how to convert the workflow-designer and utils.js to es6 modules.

I suspect that I need to something like below to convert my workflow-designer.js to es6 module:

export default function workflowDesigner() {
    let constructor = function (element, options) {
        options = options || {};
        let ponent = this;
        if ($(element).hasClass('panel')) {
            ponent.panel = $(element);
        } else {
            ponent.panel = $(element).closest('.panel');
        }
    };
    //rest of the code here....

    return constructor;

};

Please let me know if I am moving into the right direction or not.

UPDATE: As per @Bergi's suggesion I changed the extend function like below:

export default function extend(parent, child, methods) {

  child.prototype = Object.create(parent.prototype);
  child.prototype.constructor = child;

  // Add a reference to the parent's constructor
  child.parentConstructor = parent;

  // Copy the methods passed in to the prototype
  Object.assign(child, methods);

  // so we can define the constructor inline
  return child;
} 

However, now I am getting error message that "workflowDesigner.getWorkflowName is not a function"

In the debug mode I can see that this function is available at workflowDesigner.__proto__.constructor.getWorkflowName. With the old code it works fine.

Share Improve this question edited Jan 30, 2018 at 22:25 A J Qarshi asked Jan 27, 2018 at 10:13 A J QarshiA J Qarshi 2,9927 gold badges43 silver badges54 bronze badges 5
  • I think you definitely should not have $(document).keyup(…) in a file called util.js. – Bergi Commented Jan 27, 2018 at 10:33
  • When moving to ES6, you'll also want to use class syntax. Also you should never need to extend(Object, …) - it's the default. Just Object.assign() the methods onto your prototype. Oh, and use ES5 Object.create instead of that Surrogate constructor thing. – Bergi Commented Jan 27, 2018 at 10:40
  • So what you are saying about the function in extend.js is that I need to replace the Surrogate thing with child.prototype = Object.create(parent.prototype); and child.prototype.constructor = child; and then finally copy the methods with Object.assign(child, methods);. Am I right? – A J Qarshi Commented Jan 28, 2018 at 7:51
  • You also mentioned that I don't need to extend(Object, .....) as it's the default. Now in my application this extend function inside extend.js file is always invoked like extend(Object, constructor, {......}). So by the look of it, I don't need Surrogate or child.prototype = Object.create(parent.prototype); at all. Is it true? – A J Qarshi Commented Jan 28, 2018 at 7:59
  • Yes, exactly that. – Bergi Commented Jan 28, 2018 at 9:57
Add a ment  | 

1 Answer 1

Reset to default 4

Just drop the IIFE from your module pattern - ES6 modules e with their own scope.

import extend from './extend.js';

export default function WorkflowDesigner(element, options) {
  if ($(element).hasClass('panel')) {
    this.panel = $(element);
  } else {
    this.panel = $(element).closest('.panel');
  }
}

extend(Object, WorkflowDesigner, {
  getWorkflowName: () => 'WorkflowName001',
  …
});

const $ = jQuery; // you might want to solve this with a proper `import`
$.fn.createWorkflowDesigner = function (options) {
  debugger;
  return this.map(function (index, element) {
    return new WorkflowDesigner($(element), options);
  });
};
发布评论

评论列表(0)

  1. 暂无评论