Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

dojo build systems does not recognize es6 syntax

I am working on a dojo project (1.11.x) and recently started using ES6(ES2015) syntax such as const, let and template literals. It worked fine until I build the project using dojo-util. I have errors like below

ERROR - Parse error. TypeError: redeclaration of const {variable name}
ERROR - Parse error. illegal character
                     return `<a href="/xxx/xxx/${a}">${b}</a>`;
                            ^

Is there any way to make the build system recognize ES6 syntax or bypass the syntax checking?

like image 663
Harry Yoo Avatar asked Jul 24 '16 22:07

Harry Yoo


2 Answers

The latest release of Dojo 1.12 from December 2016 is updated to use Closure Compiler 20160911 which supports transpiling ES6 to ES5.

I have in one project older ES5 modules and new ones in ES6.

In ES6 modules you must add "use strict" at the beginning, otherwise building fails.

error(307) Failed to evaluate module tagged as pure AMD 
(fell back to processing with regular expressions). module: app/es6/Test;
error: SyntaxError: Block-scoped declarations (let, const, function, class)  
not yet supported outside strict mode

app/es6/Dialog.js

"use strict"    
define(["dijit/ConfirmDialog"], (ConfirmDialog) => {
let id = '1'
const dialog = new ConfirmDialog({
    title: "Delete",
    content: `Are you sure you want to delete ${id} ?`,
    style: "width: 300px"
    })
    dialog.show()
})

Then in your app.profile.js add optimizeOptions object

...
optimizeOptions: {
    languageIn: 'ECMASCRIPT6',
    languageOut: 'ECMASCRIPT5'
},
layerOptimize: "closure.keeplines",
optimize: "closure.keeplines",
cssOptimize: "comments",
mini: true,
stripConsole: "all",
selectorEngine: "lite",
useSourceMaps: false,
...
layers: {
    "dojo/dojo": {
        includeLocales: [ 'en-us' ],
        include: [ "dojo/dojo", "dojo/hash" ],
        boot: true,
        customBase: true    
    }
    "app/Main": {
        includeLocales: [ 'en-us' ],
        include: [
            'app/Header',
            'app/Main'
        ]
    },
...

app/Main.js

define(["app/es6/Dialog"], function(Dialog) {
    Dialog.show();
});

This way you can integrate ES6 into your current Dojo project.

I was also trying to avoid "use strict" in ES6 modules by setting languageOut: ECMASCRIPT5_STRICT as mention here but it breaks Dojo itself.

like image 190
keemor Avatar answered Nov 01 '22 21:11

keemor


Since development on Dojo 1.x seems to have stalled and easy migration to Dojo 2.x is not available, we had to come up with a solution to this. It was getting ridiculous that we as developers are stuck on ES5 features, only because the build process cannot handle it.

That's why i came up with a workaround, which as of now is in test in our company. For the ones interested, this is how we work around this issue (and still use the core part of the dojo build process):

  • disable optimization in the build profile (layerOptimize: false, optimize: false)
  • mark all widgets as non-AMD in package.js (amd: function(){ return false;})
  • this causes all widgets to get a warning in the build, but no failure
  • after the build process is done, all "layers" files are complete (including ES6 features possibly), but not minified, and thus very big in size.
  • in maven (or your build tool of choice), run any minifier that works for you.
  • we use the latest Closure compiler with the following settings, which will transpile ES2017 code into ES5.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-antrun-plugin</artifactId>
  <executions>
    <execution>
      <exec executable="java" resolveexecutable="true" failonerror="true">
        <arg value="-jar" />
        <arg value="${google.closure.compiler.es2017}" />
        <arg value="--language_in=ECMASCRIPT_2017" />
        <arg value="--language_out=STABLE" />
        <arg value="--js" />
        <arg value="${dojo.build.path}/build/layers/OriginalLayer.js" />
        <arg value="--js_output_file" />
        <arg value="${dojo.build.path}/build/layers/MinifiedLayer.js" />
      </exec>
    </execution>
  </executions>
</plugin>

This is still experimental, but first results look good and seem to work without regression.

like image 1
PaulR Avatar answered Nov 01 '22 21:11

PaulR