5

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?

Harry Yoo
  • 341
  • 2
  • 9
  • I assume you expect your code to run only on browser supporting ES6 (So no IE10 for instance) ? Otherwise, you have to transpile your ES6 into ES5 first, and it will solve your issue – ben Jul 25 '16 at 07:14
  • BTW, I think the problem is due to the optimization (shrinksafe, closure, or uglifyjs) – ben Jul 25 '16 at 07:20
  • Looks like this ticket https://bugs.dojotoolkit.org/ticket/19020#ticket was created one year ago and they still hadn't time for this. Sad... – soeik May 11 '18 at 15:24

2 Answers2

5

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.

Community
  • 1
  • 1
keemor
  • 1,149
  • 15
  • 16
  • 1
    Since this is still not working for me, i asked Dojo to help out and clarify this. See https://bugs.dojotoolkit.org/ticket/19020#ticket – PaulR May 11 '17 at 12:32
  • They confirmed that this is still an open issue, so i guess we have to wait. – PaulR May 12 '17 at 10:53
  • 1
    There is another topic at http://dojo-toolkit.33424.n3.nabble.com/Dojo-build-fails-on-ES6-spread-operator-td4007121.html since Feb. – keemor May 12 '17 at 12:55
  • 1
    Hmm, I get `Java class "com.google.javascript.jscomp.CompilerOptions$LanguageMode" has no public instance field or method named "ECMASCRIPT6"` when doing this – chitzui Oct 26 '18 at 08:55
  • Take a look how integrate Dojo with Webpack and have full ES6 support https://github.com/keemor/dojo-webpack-plugin-sample – keemor Oct 26 '18 at 14:09
  • @keemor Thank you. But I’ve hard times implementing it. Do you have a step by step tutorial maybe? That would be golden, thanks :) – chitzui Dec 04 '18 at 15:39
  • Also @keemor, I tried running your sample GitHub code and get errors. I reported them here: https://github.com/OpenNTF/dojo-webpack-plugin-sample/issues/72 – chitzui Dec 05 '18 at 09:17
1

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.

PaulR
  • 306
  • 1
  • 7