1

I'm trying to transpile ES6 files to ES5 by using Babel. These output files are being used by RequireJS (Magento 2) and I'm stuck on one issue.

Configuration for Babel:

const presets = [
    [
        "@babel/env",
        {
            "targets": {
                "edge": "17",
                "firefox": "60",
                "chrome": "67",
                "safari": "11.1",
                "ie": "11"
            },
            "useBuiltIns": "entry",
            "corejs": "3",
            "modules": 'cjs'
        }
    ]
];

const plugins = [
    [
        "@babel/plugin-transform-runtime",
        {
            "regenerator": true,
            "useESModules": false,
            "helpers": false
        },
    ]
]

module.exports = { presets, plugins };

Package.json:

    "name": "project",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "directories": {
        "test": "test"
    },
    "scripts": {
        "build": "babel --plugins @babel/plugin-transform-modules-amd web/js/source --out-dir web/js/build && terser-folder web/js/build -e -o web/js/build -x .js",
        "watch": "babel --plugins @babel/plugin-transform-modules-amd --watch web/js/source --out-dir web/js/build"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "devDependencies": {
        "@babel/cli": "^7.13.10",
        "@babel/core": "^7.13.10",
        "@babel/preset-env": "^7.13.5",
        "terser-folder": "^2.0.0"
    },
    "dependencies": {
        "@babel/plugin-transform-runtime": "^7.14.5",
        "@babel/runtime": "^7.14.0"
    }
}

Javascript files in Magento generally look like this:

define([
        'jquery',
        'matchMedia',
    ],
    function($, matchMedia) {
        /* SCRIPTS HERE */
    }
)

Now I'd like to use ES6 in these files (arrow functions, const, let, etc. However whenever I try to transpile these files currently Babel adds another define AROUND the entire transpiled file like this:

define([], function () {
  "use strict";

  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

  define(['jquery', 'matchMedia'], function ($, matchMedia) {
     /* TRANSPILED SCRIPTS HERE */
  });
});

When I remove the outer define, everything works perfectly. But I don't really feel like removing the outer define everytime I compile a file.

What's the setting that prevents this outer define from being added?

Daniel V.
  • 161
  • 10
  • Were you able to workaround it? I'm right now trying to figure it out a babel config to prevent it. I've found some babel generated scripts that has a `define(function(){})` instead, that different from the `define([], function () {})`, I believe would work fine. – Nevitones Jul 22 '21 at 13:54

2 Answers2

1

ES6 code has two processing modes:

  1. ""script"" - When you load a file via a , or any other standard ES5 way of loading a file
  2. ""module"" - When a file is processed as an ES6 module You can read more here: https://stackoverflow.com/a/34983495
  • Thanks a lot! It guided me to the solution. I was loading/embedding a Babel transpiled script into a project that uses RequireJS and it was not working. So I changed it to load the script using RequireJS and Voilà... Now I'm wondering if it was too stupid for trying to load it with a script tag, or if it should work this way also. – Nevitones Jul 22 '21 at 15:12
  • RequireJS is a JavaScript file and module loader. It improves perceived page load times because it allows JavaScript to load in the background. In particular, it enables asynchronous JavaScript loading. So you are doing the right way Magento works – LitExtension Magento Migration Jul 31 '21 at 15:05
0

Use different plugin for AMD modules. I've tried several and finally found one which was good for me, from what I remember it was this one: https://www.npmjs.com/package/babel-plugin-transform-modules-simple-amd

Damian Dziaduch
  • 2,107
  • 1
  • 15
  • 16