Search code examples
javascriptes6-modulesiife

How do i export an es6 IIFE?


const renderTask = (task) => {
  if (task) {
    const li = `<div class="li"><span><input type="checkbox">${task.description}</span><svg height="15" width="15" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 5v.01M12 12v.01M12 19v.01M12 6a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2z" />
          </svg></div>`;
    ul.innerHTML += li;
  }
};

renderTask();

export { renderTask as default };

The above code works very well, but when I refactor it to the code below, I get an eslint error saying Parsing error: Export 'renderTask' is not defined. .

const ul = document.querySelector('.ul');

(renderTask = (task) => {
  if (task) {
    const li = `<div class="li"><span><input type="checkbox">${task.description}</span><svg height="15" width="15" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 5v.01M12 12v.01M12 19v.01M12 6a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2z" />
          </svg></div>`;
    ul.innerHTML += li;
  }
})();

export { renderTask as default };

Do I need a loader or there is a special way to export these kinds of functions?


Solution

  • Since you want a default export, you can put the whole thing after an export default. Since you also want to be able to reference the function and call it, in addition to exporting it, if you really want to go the IIFE route, define it inside the IIFE, call it, and return it.

    export default (() => {
        const renderTask = (task) => {
            if (task) {
                const li = `<div class="li"><span><input type="checkbox">${task.description}</span><svg height="15" width="15" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 5v.01M12 12v.01M12 19v.01M12 6a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2z" />
              </svg></div>`;
                ul.innerHTML += li;
            }
        };
        renderTask();
        return renderTask;
    })();
    

    But there's no need for an IIFE in ES6 modules - the top level of modules is scoped only to the module anyway. Nothing is leaking into the global scope in your first snippet, and it's clearer what's going on, so you might prefer it instead.

    IIFEs are useful outside of modules, when defining something at the top level will pollute the global scope, but it's not something you have to worry about in modules. The only variables that are global inside modules are those you explicitly assign to window (or whatever the global object is), which isn't being done here.