Developing a plugin using DI and TDD 09

Webpacking for good.

The front-end detour

While out of scope of the dependency injection argument I would like to take the time and experiment with Webpack to handle the plugin front-end side.
The small scale this currently implies makes for an excellent starting point and I’m as ignorant as one could be about it.
Following along the lines of the getting started guide and looking up code and examples here and there I was able to put together an npm configuration file and with it a first Webpack configuration file as well

module.exports = {
    entry: './assets/js/idlikethis.js',
    output: {filename: './assets/js/dist/idlikethis-bundle.js'},
    module: {
        loaders: [
            {test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/},
            {test: /\.css$/, loader: 'style!css'},
            {test: /\.scss$/, loaders: ['style', 'css', 'sass']}
        ]
    }
};

I’m essentially telling Webpack to funnel all of its magic into the final idlikethis-bundle.js file and to take care of loading .css, .scss and .js files when required.
That “final result” file I will load into the front-end relying on well known WordPress functionalities in the Scripts service provider

<?php

class idlikethis_ServiceProviders_Scripts extends tad_DI52_ServiceProvider
{

    /**
     * Binds and sets up implementations.
     */
    public function register()
    {
        $this->container->singleton('idlikethis_Scripts_FrontEndScriptsQInterface', 'idlikethis_Scripts_FrontEndScriptsQ');

        add_action('wp_enqueue_scripts', array($this->container->make('idlikethis_Scripts_FrontEndScriptsQInterface'), 'enqueue'));
    }

    /**
     * Binds and sets up implementations at boot time.
     */
    public function boot()
    {
        // TODO: Implement boot() method.
    }
}

the idlikethis_Scripts_FrontEndScriptsQ class will then take care to queue the scripts I will need

<?php

class idlikethis_Scripts_FrontEndScriptsQ implements idlikethis_Scripts_FrontEndScriptsQInterface
{
    /**
     * @var idlikethis_Plugin
     */
    protected $plugin;

    /**
     * idlikethis_Scripts_FrontEndScriptsQ constructor.
     * @param idlikethis_Plugin $plugin
     */
    public function __construct(idlikethis_Plugin $plugin)
    {
        $this->plugin = $plugin;
    }

    /**
     * Enqueues the needed scripts and styles.
     */
    public function enqueue()
    {
        $bundle_url = $this->plugin->dir_url('assets/js/dist/idlikethis-bundle.js');
        wp_enqueue_script('idlikethis-bundle', $bundle_url, array('backbone'), null, true);
    }
}

While I’m not going into each file the idlikethis.js file is merely requiring other modules to create a Backbone View on each button on the page.

require("./../css/modules/idlikethis-button-simple.scss");

var Backbone = require('./modules/backbone.js'),
    $ = require('./modules/jquery.js'),
    idlikethis_ButtonView = require('./modules/views/Button.js');


function idlikethis_bootstrap() {
    // create a Backbone view on each button
    $('.idlikethis-button').each(function (button) {
        new idlikethis_ButtonView({el: button});
    });
};

$(idlikethis_bootstrap);

The code current to this post is on GitHub.

Next

Now that a good JS base is in place it’s time to build the front-end part.