Drupal, meet Assetic

114
assetic

description

Drupal 8 leverages Assetic for managing Javascript and CSS assets. This library abstracts the headaches of integrating with the burgeoning universe of asset pre-processors and optimization tools available to the modern developer. The lead developer of Assetic will give a tour of the library and discuss the current state of the project, its strengths, and its weaknesses, and also touch on the future: Assetic 2.0.

Transcript of Drupal, meet Assetic

Page 1: Drupal, meet Assetic

assetic

Page 2: Drupal, meet Assetic

@kriswallsmith

Page 3: Drupal, meet Assetic

things are pretty good

Page 4: Drupal, meet Assetic

things could be better

Page 5: Drupal, meet Assetic

problems

Page 6: Drupal, meet Assetic

solutions

Page 7: Drupal, meet Assetic

past

Page 8: Drupal, meet Assetic

present

Page 9: Drupal, meet Assetic

future

Page 10: Drupal, meet Assetic

kriswallsmith/assetic

Page 11: Drupal, meet Assetic

inspired by python’s webassetshttp://github.com/miracle2k/webassets

Page 12: Drupal, meet Assetic

2,500+ stars

Page 13: Drupal, meet Assetic

400+ forks

Page 14: Drupal, meet Assetic

2.4 million installs

Page 15: Drupal, meet Assetic

the team• kriswallsmith

• stof

• schmittjoh

• everzet

• 88 other contributors

Page 16: Drupal, meet Assetic

boring

Page 17: Drupal, meet Assetic
Page 18: Drupal, meet Assetic
Page 19: Drupal, meet Assetic

css

Page 20: Drupal, meet Assetic
Page 21: Drupal, meet Assetic

javascript

Page 22: Drupal, meet Assetic
Page 23: Drupal, meet Assetic
Page 24: Drupal, meet Assetic
Page 25: Drupal, meet Assetic

such assetsso wait

wow

Page 26: Drupal, meet Assetic

model the problem

Page 27: Drupal, meet Assetic

assets

Page 28: Drupal, meet Assetic

images stylesheets javascripts

Page 29: Drupal, meet Assetic

• path • last modified • content

Page 30: Drupal, meet Assetic

an object-oriented api

Page 31: Drupal, meet Assetic

interface AssetInterface!{! function getContent();! function getSourceRoot();! function getSourcePath();! function getTargetPath();! function getLastModified();!!

// ...!}

Page 32: Drupal, meet Assetic

interface AssetInterface!{! // ...!!

function load();! function dump();!!

// ...!}

Page 33: Drupal, meet Assetic

implementations

• StringAsset

• FileAsset

• HttpAsset

Page 34: Drupal, meet Assetic

use Assetic\Asset\StringAsset;!!

$a = new StringAsset('alert("hi!")');!$a->load();!echo $a->dump();

Page 35: Drupal, meet Assetic

use Assetic\Asset\StringAsset;!!

$a = new StringAsset('alert("hi!")');!$a->load();!echo $a->dump();

Page 36: Drupal, meet Assetic

use Assetic\Asset\StringAsset;!!

$a = new StringAsset('alert("hi!")');!!

echo $a->dump();

Page 37: Drupal, meet Assetic

use Assetic\Asset\FileAsset;!!

$a = new FileAsset('/path/to/hi.js');!!

echo $a->dump();

Page 38: Drupal, meet Assetic

use Assetic\Asset\HttpAsset;!!

$a = new HttpAsset('//example.com/hi.js');!!

echo $a->dump();

Page 39: Drupal, meet Assetic

special implementations

• AssetCollection

• GlobAsset

• AssetCache

• AssetReference

Page 40: Drupal, meet Assetic

use Assetic\Asset\AssetCollection;!use Assetic\Asset\FileAsset;!use Assetic\Asset\StringAsset;!!

$a = new AssetCollection(array(! new StringAsset('// (c) me'),! new FileAsset('/path/to/main.js'),!));!!

echo $a->dump();

Page 41: Drupal, meet Assetic

use Assetic\Asset\GlobAsset;!!

$a = new GlobAsset('/path/to/js/*.js');!!

echo $a->dump();

Page 42: Drupal, meet Assetic

use Assetic\Asset\AssetCache;!use Assetic\Asset\HttpAsset;!use Assetic\Cache\ApcCache;!!

$a = new AssetCache(! new HttpAsset(‘//example.com/hi.js'),! new ApcCache()!);!!

echo $a->dump();

Page 43: Drupal, meet Assetic

use Assetic\Asset\AssetReference;!use Assetic\Asset\StringAsset;!use Assetic\AssetManager;!!

$am = new AssetManager();!$am->set('hi', new StringAsset('...'));!!

$a = new AssetReference($am, 'hi');!!

echo $a->dump();

Page 44: Drupal, meet Assetic

slow

Page 45: Drupal, meet Assetic
Page 46: Drupal, meet Assetic

fewer requests

Page 47: Drupal, meet Assetic

smaller responses

Page 48: Drupal, meet Assetic

tools

Page 49: Drupal, meet Assetic

• CssEmbed

• Google Closure

• jpegoptim

• jpegtran

• JSMin

• JSqueeze

• optipng

• PhpCssEmbed

• pngout

• UglifyCSS

• UglifyJS

• YUI Compressor

Page 50: Drupal, meet Assetic

tedious

Page 51: Drupal, meet Assetic

more tools

Page 52: Drupal, meet Assetic

• CoffeeScript

• Compass

• Dart

• Less

• Lessphp

• Packager

• Roole

• SASS

• Scssphp

• Sprockets

• Stylus

• TypeScript

Page 53: Drupal, meet Assetic
Page 54: Drupal, meet Assetic

model the problem

Page 55: Drupal, meet Assetic

use Assetic\Asset\AssetInterface as Asset;!!

interface FilterInterface!{! function filterLoad(Asset $asset);! function filterDump(Asset $asset);!}

Page 56: Drupal, meet Assetic

var myVariable var _a

dumpload

coffeescript javascript

Page 57: Drupal, meet Assetic

load javascript

• CoffeeScriptFilter

• DartFilter

• EmberPrecompileFilter

• HandlebarsFilter

• PackagerFilter

• SprocketsFilter

• TypeScriptFilter

Page 58: Drupal, meet Assetic

load css• CompassFilter

• CssImportFilter

• GssFilter

• LessFilter

• LessphpFilter

• PhpCssEmbedFilter

• RooleFilter

• Sass\SassFilter

• Sass\ScssFilter

• ScssphpFilter

• StylusFilter

Page 59: Drupal, meet Assetic

dump javascript• Google\CompilerApiFilter

• Google\CompilerJarFilter

• JSMinFilter

• JSMinPlusFilter

• JSqueezeFilter

• PackerFilter

• UglifyJsFilter

• UglifyJs2Filter

• Yui\JsCompressorFilter

Page 60: Drupal, meet Assetic

dump css• CssEmbedFilter

• CssMinFilter

• CssRewriteFilter

• UglifyCssFilter

• Yui\CssCompressorFilter

Page 61: Drupal, meet Assetic

dump images

• JpegoptimFilter

• JpegtranFilter

• OptiPngFilter

• PngoutFilter

Page 62: Drupal, meet Assetic

use Assetic\Filter\FilterInterface;!!

interface AssetInterface!{! function ensureFilter(! FilterInterface $filter);!!

// ...!}

Page 63: Drupal, meet Assetic

use Assetic\Asset\FileAsset;!use Assetic\Filter\CoffeeScriptFilter;!use Assetic\Filter\UglifyJs2Filter;!!

$a = new FileAsset('/path/to/app.coffee');!$a->ensureFilter(new CoffeeScriptFilter());!$a->ensureFilter(new UglifyJs2Filter());!!

echo $a->dump();

Page 64: Drupal, meet Assetic

use Assetic\Asset\FileAsset;!use Assetic\Filter\CoffeeScriptFilter;!use Assetic\Filter\UglifyJs2Filter;!!

$a = new FileAsset(! '/path/to/app.coffee',! array(! new CoffeeScriptFilter(),! new UglifyJs2Filter(),! )!);

Page 65: Drupal, meet Assetic

serve

Page 66: Drupal, meet Assetic

# /path/to/web/js/app.php!!

$a = new FileAsset('/path/to/app.coffee');!$a->ensureFilter(new CoffeeScriptFilter());!$a->ensureFilter(new UglifyJs2Filter());!!

header('Content-Type: text/javascript');!echo $a->dump();

Page 67: Drupal, meet Assetic

# /path/to/web/js/app.php!!

use Assetic\Asset\AssetCache;!use Assetic\Cache\ApcCache;!!

// ...!!

$a = new AssetCache($a, new ApcCache());!!

header('Content-Type: text/javascript');!echo $a->dump();

Page 68: Drupal, meet Assetic

flat

Page 69: Drupal, meet Assetic

use Assetic\Asset\FileAsset;!use Assetic\AssetManager;!use Assetic\AssetWriter;!!

$a = new FileAsset('/path/to/app.js');!$a->setTargetPath('js/app.js');!!

$am = new AssetManager();!$am->set('app_js', $a);!!

$writer = new AssetWriter('/path/to/web');!$writer->writeManagerAssets($am);

Page 70: Drupal, meet Assetic

reference

Page 71: Drupal, meet Assetic

<script src="/js/app.php"></script>

Page 72: Drupal, meet Assetic

<script src="/js/app.js"></script>

Page 73: Drupal, meet Assetic

<script src="<?= asset('app_js') ?>"></script>

Page 74: Drupal, meet Assetic

template as configuration

Page 75: Drupal, meet Assetic

<script src="<?=! assetic_javascripts(! array('js/app.coffee'),! array('coffee', 'uglifyjs2'),! array('output' => 'js/app.js')! )!?>"></script>

Page 76: Drupal, meet Assetic

use Assetic\Filter\CoffeeScriptFilter;!use Assetic\FilterManager;!!

$fm = new FilterManager();!$fm->set(! 'coffee',! new CoffeeScriptFilter()!);

Page 77: Drupal, meet Assetic

use Assetic\Factory\AssetFactory;!!

$factory = new AssetFactory('/www');!$factory->setFilterManager($fm);

Page 78: Drupal, meet Assetic

use ...\Loader\FunctionCallsFormulaLoader;!use ...\Resource\DirectoryResource;!!

$ldr = new FunctionCallsFormulaLoader();!$rsc = new DirectoryResource(! '/path/to/views',! '/\.php$/'!);

Page 79: Drupal, meet Assetic

use Assetic\Factory\LazyAssetManager;!!

$am = new LazyAssetManager($factory);!$am->setLoader('php', $ldr);!$am->addResource($rsc, 'php');

Page 80: Drupal, meet Assetic
Page 81: Drupal, meet Assetic

detect

Page 82: Drupal, meet Assetic

includesreferences

Page 83: Drupal, meet Assetic

while (true) {! foreach ($am->getNames() as $name) {! // ...! }!!

sleep(1);!}

Page 84: Drupal, meet Assetic

push

Page 85: Drupal, meet Assetic

henrikbjorn/lurker

Page 86: Drupal, meet Assetic

use Lurker\ResourceWatcher;!!

$watcher = new ResourceWatcher();!$watcher->track('twig', '/path/to/views');!$watcher->addListener('twig', function($e) {! // ...!});!!

$watcher->start();

Page 87: Drupal, meet Assetic

respond

Page 88: Drupal, meet Assetic

_colors.sass

Page 89: Drupal, meet Assetic

foreach ($am->getNames() as $name) {! $asset = $am->get($name);! // ...!!

if ($match) {! // ...! }!}

Page 90: Drupal, meet Assetic

graph

Page 91: Drupal, meet Assetic

profile.sass

_colors.sass background.gif

home.sass

includes

includes

references

references

included by

included byreferenced by

referenced by

Page 92: Drupal, meet Assetic

nodes

Page 93: Drupal, meet Assetic

edges

Page 94: Drupal, meet Assetic

profile.sass

_colors.sass background.gif

home.sass

includes

includes

references

references

included by

included byreferenced by

referenced by

Page 95: Drupal, meet Assetic

profile.sass

_colors.sass background.gif

home.sass

includes

includes

references

references

included by

included byreferenced by

referenced by

Page 96: Drupal, meet Assetic

profile.sass

_colors.sass background.gif

home.sass

includes

includes

references

references

included by

included byreferenced by

referenced by

Page 97: Drupal, meet Assetic
Page 98: Drupal, meet Assetic

use Assetic\Asset\HttpAsset;!!

$a = new HttpAsset('//example.com/hi.js');

Page 99: Drupal, meet Assetic

• proxy

• authentication

• errors

• ssl

• mock

• test

• logging

• profiling

• curl

• guzzle

Page 100: Drupal, meet Assetic

represent

Page 101: Drupal, meet Assetic

separate

Page 102: Drupal, meet Assetic
Page 103: Drupal, meet Assetic

• load

• filter

• reflection

• optimization

Page 104: Drupal, meet Assetic

maintain

Page 105: Drupal, meet Assetic

~40 filters

Page 106: Drupal, meet Assetic

ping

Page 107: Drupal, meet Assetic

opinion

Page 108: Drupal, meet Assetic

• engines

• javascript optimizer

• css optimizer

• jpeg optimizer

• png optimizer

Page 109: Drupal, meet Assetic
Page 110: Drupal, meet Assetic

sponsor

Page 111: Drupal, meet Assetic

follow@kriswallsmith

Page 112: Drupal, meet Assetic

hire

• workshops

• architecture

• audits

• performance

• symfony

• phpunit

• twig

• doctrine

Page 113: Drupal, meet Assetic

questions?