Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maven Plugin which transpiles ES6 to ES5 which uses Traceur or Babel

Is there already a preferred way how to transpile ECMAScript6 code to ECMAScript5 using traceur or Babel (formely named 6to5) in a maven project? I have already searched the net without any success.

like image 886
Daniel K. Avatar asked Feb 16 '15 11:02

Daniel K.


3 Answers

This might not be the exact solution to your problem, but the way I do this is by using https://github.com/eirslett/frontend-maven-plugin , which in turns allows me to use Grunt tasks during the build process (and in different phases of the build). Then by having Grunt available to me, I created a grunt task to use grunt-babel to convert my files.

The plugin also allows you to use gulp if that is your preference.

I also use the same setup to run Karma and JSHint during the test phase.

Hope this helps,

M

Edit: its worth noting that the node installation that the plugin does is local to the project. So no need to have node globally installed.

like image 126
Morné Louis de Jongh Avatar answered Nov 16 '22 02:11

Morné Louis de Jongh


I used the above awesome frontend-maven-plugin suggestion and got it all working but ran into a couple hitches so I figured I'd post a more complete solution that's ready to be blindly copy and pasted into your build files. I wrote a detailed blog post about it here and a slightly abridged version of it is below:

My frontend-maven-plugin section in my pom.xml ended up looking like this:

<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.2</version>

<configuration>
    <nodeVersion>v4.6.0</nodeVersion>
</configuration>

<executions>
    <execution>
        <goals>
            <goal>install-node-and-npm</goal>
        </goals>
        <phase>generate-resources</phase>
    </execution>

    <execution>
        <id>npm install</id>
        <goals>
            <goal>npm</goal>
        </goals>
        <configuration>
            <arguments>install</arguments>
        </configuration>
    </execution>

    <execution>
        <id>grunt build</id>
        <goals>
            <goal>grunt</goal>
        </goals>
        <phase>generate-sources</phase>
    </execution>
</executions>

After getting the Grunt transpile step all working I ran into the problem of getting those files in the packaged WAR file correctly. I tried the obvious copying the files to the target exploded war folder at various build phases and various similar things which all didn't work.

The solution ended up being to just overwrite the non transpiled js files by including the transpiled files in the webResources section of the maven-war-plugin section. Which ended up looking like this:

<plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-war-plugin</artifactId>
 <version>2.2</version>
 <configuration>
     <warName>Example-1.0-SNAPSHOT</warName>
     <webResources>
         <resource>
             <directory>${project.build.directory}/dist</directory>
         </resource>
     </webResources>
 </configuration>

I also bumped into the issue of corrupt packages being downloaded by npm and left in the global cache, which coming from Maven is ridiculous and something I've never had happen.

If you get something like a zip error or exception during the frontend-maven-plugin build step it's likely this and you can fix it with a “npm cache clean” and deleting the "node"and "node_modules" directories in your project directory and trying again (it took me 3 times until it grabbed the dependencies successfully!)

And my blog post includes what the package.json and GruntFile.js files looked like.

like image 29
meese Avatar answered Nov 16 '22 03:11

meese


Its been a few years since this was updated and the solution provided does not work from a clean install. After some fiddling this is what I came up with:

As described above, I used the frontend-maven-plugin to install Node, NPM, Grunt and Babel.

Node and NPM download/install Grunt and babel. Grunt calls Babel Babel does the transpiling.

Maven

To get this process started add this to the build section of your pom.xml

        <plugins>
        <plugin>
            <groupId>com.github.eirslett</groupId>
            <artifactId>frontend-maven-plugin</artifactId>
            <version>1.6</version>
            <executions>
                <execution>
                    <id>install node and npm</id>
                    <goals>
                        <goal>install-node-and-npm</goal>
                    </goals>
                    <phase>initialize</phase>
                </execution>
                <execution>
                    <id>npm</id>
                    <goals>
                        <goal>npm</goal>
                    </goals>
                    <configuration>
                        <arguments>install</arguments>
                    </configuration>
                    <phase>initialize</phase>
                </execution>
                <execution>
                    <id>grunt build</id>
                    <goals>
                        <goal>grunt</goal>
                    </goals>
                    <phase>generate-resources</phase>
                </execution>
            </executions>
            <configuration>
                <nodeVersion>v10.4.1</nodeVersion>
                <npmVersion>6.1.0</npmVersion>
            </configuration>
        </plugin>
        <!--- rest of your plugins follow -->

NPM

At the same level of your project as your pom.xml, create a package.json file. This file tells Node/NPM the dependencies it needs to install into the node_modules directory

    {
    "name": "npm-maven-base-project",
    "version": "0.0.1",
    "description": "Install Grunt and Babel to do some ES6 to ES5 transpiling",
    "devDependencies": {
        "@babel/core": "^7.0.0-beta.54",
        "@babel/preset-env": "^7.0.0-beta.54",
        "grunt-babel": "8.0.0-beta.0",
        "grunt": "~0.4.5",
        "grunt-cli": "1.2.0",
        "grunt-contrib-jshint": "~0.10.0",
        "grunt-contrib-nodeunit": "~0.4.1",
        "grunt-contrib-uglify": "~0.5.0",
        "load-grunt-tasks": "^3.5.2"
    },
    "main": "GruntFile.js",
    "dependencies": {

    },
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
    },
    "author": "",
    "license": "ISC"
    }

Grunt

Next we need to tell grunt what it needs to do. When executed, Grunt will call Babel to ctranspile your code. So create a 'Gruntfile.js' in the same directory as the pom.xml and the package.json.

    module.exports = function(grunt) {

    require('load-grunt-tasks')(grunt); // npm install --save-dev
    // load-grunt-tasks

    grunt.initConfig({
        babel : {
            options : {
                sourceMap : false
            },
            dist : {
                files : [{
                    'src/main/webapp/resources/scripts/destination.js' : 'src/main/webapp/resources/scripts/source.es6'
                },{
                    'src/main/webapp/resources/scripts/destination.js' : 'src/main/webapp/resources/scripts/source.es6'
                }]
            }
        }
    });

    grunt.registerTask('default', [ 'babel' ]);
};

The array of 'files' entries above lists all of the files that you want to transpile. It is the format {'destination' : 'source'}. Note: There is no flag to prevent accidental overwriting.

Note: When you finally run the mvn install, If you receive this error message....

Warning: The "path" argument must be of type string. Received type undefined Use --force to continue

....it means that either the path to the source file is spelled incorrectly or the destination is unwritable

Babel

Finally, we need to tell Babel that we want it to transpile from ES6 to ES5. To do this, create a '.babelrc' file in the same directory as your 'pom.xml', 'package.json' and 'Gruntfile.js'. Fill it with this:

{
    "presets": ["@babel/preset-env"]
}

Now just cross your fingers and run...

mvn install

...and your build should run and transpile your JS.

like image 31
user1005939 Avatar answered Nov 16 '22 02:11

user1005939