laravel-mix: [6*.] mix.js() is not converting ES6 to ES5

  • Laravel Mix Version: 6.0.0-beta.11 (npm list --depth=0)
  • Node Version (node -v): 14.13.0
  • NPM Version (npm -v): 6.14.8
  • OS: macOS 10.15.7 (Catalina)

Description:

Arrow functions (and possibly other ES6 features) are not being converted to ES5.

With v5, the output of mix.js() starts with this: !function(t){var i={};function n(s){

With v6, the output of mix.js() starts with this: (()=>{var t={20:(t,e,i)=>{"use strict";function s(t){

Steps To Reproduce:

Here is my webpack.mix.js

const mix = require('laravel-mix');
const path = require('path');
const postCss = namespace => {
  return [
    require('postcss-import'),
    require('precss')(),
    require('postcss-calc')({preserve: false}),
    require('postcss-hexrgba'),
    require('postcss-custom-properties')({preserve: false}),
    require('./+/postcss/postcss-selector-namespaces')({namespace: namespace}),
    require('autoprefixer'),
  ];
};

require('laravel-mix-bundle-analyzer');

mix.babelConfig({
  plugins: [
    ['prismjs', {
        'languages': ['javascript', 'php', 'html', 'css'],
        'plugins': ['line-numbers'],
        'css': false,
    }],
  ],
  presets: [
    "@wordpress/default",
  ],
});

mix.disableSuccessNotifications();

mix.options({
  clearConsole: false,
  cssNano: {
    minifyFontValues: false,
    discardComments: {removeAll: true},
    zindex: false,
  },
  hmrOptions: {
    host: 'localhost',
    port: 3000,
  },
  processCssUrls: false,
  purifyCss: false,
  terser: {
    terserOptions: {
      compress: {
        drop_console: mix.inProduction(),
      },
      mangle: {
        properties: {regex: /[a-zA-Z]+_$/},
      },
    },
  },
});

mix.webpackConfig({
  resolve: {
    alias: {'@': path.resolve(__dirname, '+/scripts/')},
    modules: ['node_modules'],
  },
});

mix
  .babel('+/scripts/mce-plugin.js', 'assets/scripts/mce-plugin.js')
  .js('+/scripts/plugin.js', 'assets/scripts/plugin.js')
  .js('+/scripts/plugin-admin.js', 'assets/scripts/plugin-admin.js')
  .js('+/scripts/plugin-blocks.js', 'assets/scripts/plugin-blocks.js')
  .sass('+/styles/admin.scss', 'assets/styles/admin')
  .postCss('+/styles/default.css', 'assets/styles', postCss('.style-default'))
  .postCss('+/styles/minimal.css', 'assets/styles', postCss('.style-minimal'))

if (mix.inProduction()) {
  mix.bundleAnalyzer();
}

And here is my package.js file

{
  "dependencies": {
    "prismjs": "^1.22.0",
  },
  "devDependencies": {
    "@babel/compat-data": "^7.12.1",
    "@wordpress/babel-preset-default": "^4.19.0",
    "babel-plugin-prismjs": "^2.0.1",
    "browser-sync": "^2.26.13",
    "browser-sync-webpack-plugin": "^2.0.1",
    "cross-env": "^7.0.2",
    "gulp": "^4.0.2",
    "gulp-bump": "^3.2.0",
    "gulp-checktextdomain": "^2.2.2",
    "gulp-potomo": "^1.1.0",
    "gulp-pottopo": "^1.0.1",
    "gulp-sort": "^2.0.0",
    "gulp-wp-pot": "^2.5.0",
    "imports-loader": "^1.2.0",
    "laravel-mix": "next",
    "laravel-mix-bundle-analyzer": "^1.0.5",
    "npm-check": "^5.9.2",
    "postcss-calc": "^7.0.5",
    "postcss-custom-properties": "^10.0.0",
    "postcss-hexrgba": "^2.0.1",
    "postcss-import": "^12.0.1",
    "precss": "^4.0.0",
    "pump": "^3.0.0",
    "resolve-url-loader": "^3.1.0",
    "sass": "^1.27.0",
    "sass-loader": "^10.0.3",
    "vue-template-compiler": "^2.6.12",
    "yamljs": "^0.3.0",
    "yargs": "^16.1.0"
  },
  "peerDependencies": {
    "postcss": "^8.1.4"
  },
  "private": true,
  "scripts": {
    "build": "gulp && npm run production",
    "development": "mix",
    "watch": "mix watch",
    "watch-poll": "mix watch -- --watch-options-poll=1000",
    "hot": "mix watch --hot",
    "production": "mix --production"
  }
}

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 21 (2 by maintainers)

Most upvoted comments

Just to throw this into the mix (heh), you can also resolve this issue using the target property:

When multiple targets are passed, then common subset of features will be used. webpack will generate a runtime code for web platform and will use only ES5 features.

mix.webpackConfig({
    target: ['web, 'es5'],
});

Adding the following to my package.json fixes the problem. With this in mind, I’m assuming that webpack is not honoring the default config (@thecrypticace).

 "browserslist": [
   "IE 11"
 ],

@pryley

This is not an issue with Laravel Mix itself. This should be solved if you declare your target browsers by adding a browserslist configuration (e.g. in a .browserslistrc file).


While Babel’s preset-env is configured in a way that it applies all transforms if no targets list is provided, other parts of Mix’ toolchain behave differently. The wrapping arrow function you see in your result is not created by Babel (which only transforms your actual source files) but by webpack itself.

This different interpretation of the absence of a concrete targets list is the reason you see parts of your code transpiled to ES5 and others staying ES2015+. Good news is: just like Babel, webpack will recognize the browserslist configuration and adjujst its wrapper code accordingly.

@JeffreyWay Sorry for the delayed response, I’ve been out of action for the last few weeks.

  1. I removed all dependencies from the package.json except for "laravel-mix": "next", (and any dependencies that laravel mix adds after running npm install).

  2. I reduced the mix file down to this:

const mix = require('laravel-mix')

mix.webpackConfig({
  resolve: {
    alias: {'@': path.resolve(__dirname, '+/scripts/')},
    modules: ['node_modules'],
  },
})

mix.js('+/scripts/main.js', 'assets/scripts')
  1. And I made a barebones javascript example:

main.js

import Test from '@/test.js'

document.addEventListener('DOMContentLoaded', () => {
    window.TEST = new Test();
})

test.js

const Test = () => {
    this.hello();
}
Test.prototype = {
    hello: () => 'hello',
}
export default Test

This is the result:

(()=>{"use strict";var n=void 0,o=function(){n.hello()};o.prototype={hello:function(){return"hello"}};const t=o;document.addEventListener("DOMContentLoaded",(function(){window.TEST=new t}))})();

As you can see, the minified result starts with (()=>{ instead of (function(){. It also still contains const in the output.

This is with Laravel Mix v6.0.0-beta.14.

This is how I am doing it in the webpack.mix.js file:

Screenshot 2021-01-27 at 08 56 35