Webpack Encore with Symfony 3 - headzoo.io

Featured

I decided to give Webpack Encore a whirl while I was building this site, and I thought I would document my experience.

Webpack Encore is a simpler way to integrate Webpack into your application. It wraps Webpack, giving you a clean & powerful API for bundling JavaScript modules, pre-processing CSS & JS and compiling and minifying assets. Encore gives you professional asset system that's a delight to use.

Webpack Encore configures Webpack with sensible defaults, and it also configures Webpack using method calls instead of a JSONish configuration script. You can use it any time you would normally use Webpack, and it also appears to be a replacement for Assetic in Symonfy projects. Which means Symfony developers should get ready to use it.

Configuration

I'm using the following configuration script which I saved in the Symfony project root directory as webpack.config.js.

var Encore  = require('@symfony/webpack-encore');
var webpack = require('webpack');

Encore
.setOutputPath('./web/build/')
.setPublicPath('/build')
.cleanupOutputBeforeBuild()
.addEntry('js/app', './web/src/js/index.jsx')
.addStyleEntry('css/app', './web/src/scss/app.scss')
.enableReactPreset()
.enableSassLoader()
.enablePostCssLoader()
.autoProvidejQuery()
.enableSourceMaps(!Encore.isProduction())
.enableVersioning(Encore.isProduction())
;

let config = Encore.getWebpackConfig();
module.exports = config;

Versioning

Webpack Encore supports versioning assets through the use of a JSON manifest file. Versioning renames the asset files when they change, which forces browsers to re-download them. Webpack Encore and the template asset() function handles everything for you.

The following template:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>headzoo.io</title>
    <meta charset="utf-8">
    <meta content="width=device-width, initial-scale=1" name="viewport">
    <link href="" rel="stylesheet" media="screen">
</head>
<body>
    <div id="mount"></div>
    <script src=""></script>
</body>
</html>

Will render as the following HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>headzoo.io</title>
    <meta charset="utf-8">
    <meta content="width=device-width, initial-scale=1" name="viewport">
    <link href="/build/css/app.0cbc3ec83fb34ac256fba3b70cb78067.css" rel="stylesheet" media="screen">
</head>
<body>
    <div id="mount"></div>
    <script src="/build/js/app.bb3cb705fc87f2a5570e.js"></script>
</body>
</html>

Versioning needs to be enabled in app/config/config.yml.

framework:
  assets:
json_manifest_path: "%kernel.project_dir%/web/build/manifest.json"

Running

During development I run the following command in the PhpStorm terminal to have Webpack Encore to rebuild the js & scss files as they change.

node_modules/.bin/encore dev --watch

To save myself a bit of typing I saved the command in a bash script as bin/encore.

#!/usr/bin/env bash
./node_modules/.bin/encore $@

Which I ran using this command.

bin/encore dev --watch

Conclusion

I give Webpack Encore a solid B+. I found the method calls easier to work with because PhpStorm was able to provide type hints for each possible setting. When using Webpack's own configuration script, I find myself constantly checking the Webpack documentation. Which is a pain.

The Evolution of a Software Engineer - headzoo.io

Featured

The First Year

class HelloWorld
{
public static void main(String args[])
{
// Displays "Hello World!" on the console.
System.out.println("Hello World!");
}
}

The Second Year

/**
* Hello world class
*
* Used to display the phrase "Hello World" in a console.
*
* @author Sean
*/
class HelloWorld
{
/**
* The phrase to display in the console
*/
public static final string PHRASE = "Hello World!";

/**
* Main method
*
* @param args Command line arguments
* @return void
*/
public static void main(String args[])
{
// Display our phrase in the console.
System.out.println(PHRASE);
}
}

The Third Year

/**
* Hello world class
*
* Used to display the phrase "Hello World" in a console.
*
* @author Sean
* @license LGPL
* @version 1.2
* @see System.out.println
* @see README
* @todo Create factory methods
* @link https://github.com/sean/helloworld
*/
class HelloWorld
{
/**
* The default phrase to display in the console
*/
public static final string PHRASE = "Hello World!";

/**
* The phrase to display in the console
*/
private string hello_world = null;

/**
* Constructor
*
* @param hw The phrase to display in the console
*/
public HelloWorld(string hw)
{
hello_world = hw;
}

/**
* Display the phrase "Hello World!" in a console
*
* @return void
*/
public void sayPhrase()
{
// Display our phrase in the console.
System.out.println(hello_world);
}

/**
* Main method
*
* @param args Command line arguments
* @return void
*/
public static void main(String args[])
{
HelloWorld hw = new HelloWorld(PHRASE);
try {
        hw.sayPhrase();
} catch (Exception e) {
        // Do nothing!
}
}
}

The Fifth Year

/**
* Enterprise Hello World class v2.2
*
* Provides an enterprise ready, scalable buisness solution
* for display the phrase "Hello World!" in a console.
*
* IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED
* TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER
* PARTY WHO MAY MODIFY AND/OR REDISTRIVUTE THE LIBRARY AS
* PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING
* ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
* DAMAGES ATRISING OUT OF THE USE OR INABILITY TO USE THE
* LIBRAY (INCLUDING BUT LIMITED TO LOSS OF DATA OR
* DATA BEINT RENDERED INACCURATE OR LOSSES SUSTAINED BY
* YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO
* OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER
* OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGES.
*
* @author Sean
* @license LGPL
* @version 2.2
* @see System.out.println
* @see README
* @see license.txt
* @todo Test of OS compatibility
* @link https://github.com/sean-inc/helloworld
*/
class HelloWorld
{
/**
* The first phrase
*/
public static final string PHRASE_HELLO = "Hello";

/**
* The second phrase
*/
public static final string PHRASE_WORLD = "World";

/**
* The first word in our phrase
*/
private Word hello = null;

/**
* The second word in our phrase
*/
private Word world = null;

/**
* Constructor
*
* @param hello First word to display in the console
* @param world Second word to display in the console
*/
public HelloWorld(Word hello, Word world)
{
this.hello = hello;
this.world = world;
}

/**
* Display the phrase "Hello World!" in a console
*
* @return void
*/
public void sayPhrase()
{
// Display our phrase in the console.
string first  = this.hello.toString();
string second = this.world.toString();
System.out.println(first + " " + second + "!");
}

/**
* Sets the phrase to use for hello
*
* @param h The first phrase
* @return void
*/
public void setHello(string h)
{
this.hello.setWord(h);
}

/**
* Gets the phrase to use for hello
*
* @return Word
*/
public Word getHello()
{
return this.hello;
}

/**
* Sets the phrase to use for world
*
* @param w The second phrase
* @return void
*/
public void setWorld(string w)
{
this.world.setWord(w);
}

/**
* Gets the phrase to use for world
*
* @return Word
*/
public Word getHello()
{
return this.world;
}

/**
* Main method
*
* @param args Command line arguments
* @return void
*/
public static void main(String args[])
{
// Create a new dic so we can display our phrase on the
// command line.
DIC d = DependencyInjectionContainer::factory();
HelloWorld hw = null;

try {
        hw = d.newInstance(HelloWorld.class);
} catch (DICInstanceException e) {
        System.err.println("There was an error creating an instance of HelloWorld.");
        return;
}

try {
        hw.setHello(PHRASE_HELLO);
        hw.setWorld(PHRASE_WORLD);
        hw.sayPhrase();
} catch (IOException e) {
        System.err.println("There was an IO error.");
} catch (ConsoleException e) {
        System.err.println("There was a console error.");
} catch (Exception e) {
        System.err.println("There was an unknown error.");
}
}
}
<beans xmlns="http://www.framework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.framework.org/schema/beans
http://www.framework.org/schema/beans/beans-2.5.xsd
http://www.framework.org/schema/context
http://www.framework.org/schema/context/context-2.5.xsd">
<context:annotation-config />
<bean id="HelloWorldBean" class="com.sean-inc">
<property name="hello" value="Word" />
<property name="world" value="Word" />
</bean>
</beans>

The Tenth Year

/**
* Used to display the phrase "Hello World!" in a console
*
* @author Sean
* @see README
*/
class HelloWorld
{
public static void main(String args[])
{
System.out.println("Hello World!");
}
}

Is Programming Art? - headzoo.io

Christopher Pitt asked a simple question: Can a developer be called a creative?

I am talking about whether systems architects or PHP developers (like me!) can be called a creative, even though we predominantly deal with code, and our grasp of colours, layout and iconography is limited to the unicode characters we appropriate for console and log messages.

To be honest it never crossed my mind that programming was anything but a creative pursuit, and I’m happy to call myself an artist to anyone that will listen, but I understand why civilians (non-programmers) could see things differently.

A girlfriend once told me programming “looks boring” when I suggested learning a bit of JavaScript and HTML, and many years ago I was roommates with a painter, who, on hearing me proclaim my code was artwork, replied with a condescending, “Yeah, uh huh, sure!”

Yes, I get it. To the casual observer it may appear terribly dreary staring at a monitor all day and night, with the steady drone of click, click, click coming from a keyboard, and I understand why a classic artist (writer, painter, musician) may scoff at the idea of programming as an art form. No one is going to look at my finished work in a gallery, and discuss the artist’s soul while sipping expensive wine.

What people don’t see is the explosion of activity happening in my head while I stare at those bright monitors with my bloodshot eyes. I’ve never surfed the waves of Hawaii, but I get an adrenaline rush from conquering problems. I’ve never played a hit single to a crowed of adoring fans — and certainly never had a hot groupie throw their bra at me — but I know the feeling of being taken to a higher conscience level when I get into a groove.

I know passion and excitement, and I know what it’s like to feel drained, exhausted, high, and elated when a project is finished. Most importantly though, I know how nerve-racking it can be to finally give my work to the world. Will people love it or hate it? Will people understand and appreciate the nuance of my work, or will they think it’s boring and stupid?

Make no mistake about it, programming is a creative pursuit, and I am an artist. I may work with a keyboard and IDE instead of a paint brush or guitar, but I have the same passion and dreams as an artist, and I live and die by the acceptance or rejection of my work by fans. My work may never be seen in a Soho art gallery, but it will be seen by millions of people.

Heck, I even occasionally sit back and admire my code while sipping expensive wine.

Slow Is Smooth; Smooth Is Fast - headzoo.io

Featured

I grew up being a big fan of horror movies. I enjoyed them all; from big blockbuster movies, to unheard of indie flicks, and there's one type of scene all horror movies have in common: The young heroine manages to escape from the masked killer's dungeon, and breathlessly makes back to her car. After fidgeting with her keys for what seems like an eternity, she finally gets the door open. She's almost home free! After spending another minute panicking and dropping the keys on the floor, she finally gets the right key into the ignition. But it's too late! All the time she wasted fidgeting with the car keys gave the killer a chance to catch up to her, and just as she's about to start the car and drive off to safety, the killer pulls her out of the driver side window kicking and screaming. She almost made it! She would have made it too had she remembered this:

Slow is smooth; smooth is fast

Or to put that in more familiar words, haste makes waste. The concept is simple: the faster you move while completing a task, the more mistakes you make, and the longer the task ultimately takes. On the other hand taking your time means fewer mistakes, which means you will get things done faster. The concept almost seems counter intuitive; Going slow and taking your time means tasks are finished quicker. Our horror movie maiden would have escaped the killer had she gone slower and not made so many mistakes.

Programmers are infamous for pulling all night coding sessions fueled by coffee and mountain dew. When I was young I could easily write a thousand lines of code in a single sitting, and dammit, it was fun! But there was one little problem: the code I wrote was total crap. It was unreadable, undocumented, untested, unmaintainable, and worst of all it was full of logic errors. The types of logic errors I could have avoided had I not been mentally traveling at warp speed. The time I gained on the front-end by writing my code so quickly, was lost on the back-end having to fix and rewrite it. Any happiness my clients felt from having their website finished in record time quickly evaporated when it crashed.

Slow down. Take your time. Remember to stay focused on the task at hand. Engineering requires continuous critical thinking. Rushing through a task on mental autopilot leads to mistakes, and the final code will be unorganized, unfocused, and bloated. Taking your time to do things right the first time is the difference between 40 lines of loops and if…then spaghetti code, and 10 lines of easy to maintain engineering excellence.