Upgrade Your Drupal Skills
We trained 1,000+ Drupal Developers over the last decade.
See Advanced Courses NAH, I know EnoughHow to use ES6 in Drupal 8
I bet many of you doesn't understand what is ES6, being honest I didn't know this term until a few days ago.
ES6 stands for ECMAScript v6 or ES2015, but in simple words, is just Javascript; Correct Javascript as simple as that.
So, ES6 one of the latest version of Javascript specification, but is not supported by all browsers, because was released in June 2015, even worst in June 2016 we got ES7 and as you can imagine not supported yet.
Right now all browsers support ES5, then, if it's not compatible with all browsers, why ES6+ is a big thing? Because, now Javascript is more OOP, using classes, constants, and modules, enabling to create more complex and organized projects.
So, how we could use ES6 in our web projects like Drupal, to avoid to have a particular version of our site based on our client's browser? The solution is Babel
Babel transforms your code to ES5 to be used in your web applications.
Babel works using plugins that allow the transformation and enable to use a particular plugin based on the source of your code like React that requires an especial plugin to do the conversion.
Let me show an example that creates a simple ReactJS.
1. Install Node.js
The first thing we need to do is install Node.js in your system, the easy way to do that is downloading the proper installer for our platform from https://nodejs.org/en/download
We need to install Node.js because we are going to use the NPM which is a package manager for javascript libraries
2. Modify gitignore file
Drupal 8 projects include their own .gitignore file, but because we are about to include npm in our development process, we need to add some extra rules listed below:
# Node.js
# Logs
logs
*.log
npm-debug.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules
jspm_packages
# Optional npm cache directory
.npm
# Optional REPL history
.node_repl_history
3. Create a package.json file
To be able to distribute later your javascript library you need to create a package.json file, you create that file in interactive mode using the command:
$ npm init
In the end, you will get a file similar to the following file.
{
"name": "drupalreactform",
"version": "1.0.0",
"description": "ReactJS form to be embed in Drupal 8 Controller",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
}
"author": "enzo - Eduardo Garcia",
"license": "ISC"
}
4. Install Webpack
To expose our library in Drupal we need to create a distribution package, for that purpose, we will use [Webpack](webpack.github.io) that is a module bundler which takes modules with dependencies to generates static assets by bundling them together.
$ npm install webpack --save
The command about will install webpack with all required libraries and modify our package.json, in the same way that we use in Composer the composer.json file.
5. Configuring Webpack & creating bundle
It's necessary to inform to Webpack using file webpack.config.js, how we can to create our bundle to be used Drupal, the following configuration assumes we have a custom module located in web/modules/custom/mysearch.
var webpack = require('webpack');
var path = require('path');
var MODULE_BUILD_DIR = path.resolve(__dirname, 'web/modules/custom/mysearch/js');
var MODULE_APP_DIR = path.resolve(__dirname, 'web/modules/custom/mysearch/js/es6');
var config = {
entry: MODULE_APP_DIR + '/mysearch.form.jsx',
output: {
path: MODULE_BUILD_DIR,
filename: 'mysearch.form.js'
}
};
module.exports = config;
With the configuration above, we are saying we will load the file mysearch.form.jsx and all included files in mysearch.form.js file
If you write something simple like
console.log('Hello ES6!');
You don't need any special transformation and you can create the bundle, for that propose you need to execute the following command:
$ ./node_modules/.bin/webpack -d
You will get an output similar to this image:
The generation will work correctly because the source in ES5 and the output too; So, no transformation was required.
6. Testing transformation
I know I said we would embed the file generated in Drupal, but in a development process is faster if we could test first outside Drupal, for that, we could create a file named test/es62es5/index.htm inside module directory with the following content.
<html>
<head>
<meta charset="utf-8">
<title>Testing transformation ES6 -> ES5</title>
</head>
<body>
<div id="app" />
<script src="http://www.anexusit.com/blog/how-to-use-es6-drupal-8/../js/mysearch.form.js" type="text/javascript"></script>
</body>
</html>
Opening that file in our browser would enable any possible error and reduce the change to blame Drupal 8 for a malfunction in our code.
7. Use Babel to transform ES6
Now we need to install Babel and Babel loaders to be able to transform our ReactJS form into ES5; the next command installs the required packages.
$ npm install babel-loader babel-preset-es2015 babel-preset-react --save
Also, we need to create a .babelrc file, to inform to Babel what presents will be used in transformation, check and example of that file below:
{
"presets" : ["es2015", "react"]
}
Finally, we need to modify out webpack configuration to report what loader we are going to use in our transformation, the new aspect of webpack.config.js will be like this:
var webpack = require('webpack');
var path = require('path');
var MODULE_BUILD_DIR = path.resolve(__dirname, 'web/modules/custom/mysearch/js');
var MODULE_APP_DIR = path.resolve(__dirname, 'web/modules/custom/mysearch/js/es6');
var config = {
entry: MODULE_APP_DIR + '/mysearch.form.jsx',
output: {
path: MODULE_BUILD_DIR,
filename: 'mysearch.form.js'
},
module : {
loaders : [
{
test : /\.jsx?/,
include : MODULE_APP_DIR,
loader : 'babel'
}
]
}
};
8. Create React form
Before to create the form we need to install some libraries to build our form.
$ npm install react react-dom antd --save
If we plan to embed CSS or LESS files in our app, need to install loaders for that using the following instructions, and register the loader in webpack
$ npm install css-loader less less-loader style-loader --save-dev
The code of our form will be an example form React created in a previous blog post:
import React, { PropTypes } from 'react';
import ReactDOM from 'react-dom';
var Search = React.createClass({
render: function(){
return (
React.createElement('form', {onSubmit: this.onSubmit, className: 'SearchForm', noValidate: true},
React.createElement('input', {
type: 'text',
placeholder: 'Search'
}),
React.createElement("select", { placeholder: 'Category', value: '', onChange: this.changeHandler },
React.createElement("option", { value: 1 }, "Software"),
React.createElement("option", { value: 2 }, "Movie")
),
React.createElement('button', {type: 'submit'}, "Go")
)
);
},
});
ReactDOM.render(React.createElement(Search), document.getElementById("app"));
Of course, you can create a more advanced form, importing other libraries.
9. Include form in a Drupal controller
After "compile" our form in one file, the remaining step is to include it in a Drupal Controller, to do that you just need to follow the blog entry www.anexusit.com/blog/how-to-load-js-and-css-libraries-a-drupal-8-controller.
I hope did you find this blog entry useful.
About Drupal Sun
Drupal Sun is an Evolving Web project. It allows you to:
- Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
- Facet based on tags, author, or feed
- Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
- View the entire article text inline, or in the context of the site where it was created
See the blog post at Evolving Web