SlideShare a Scribd company logo
WEBPACK ENCORE
Asset management for the rest of us
2
Stefan Adolf
Developer Ambassador
#javascript #mongodb #serverless
#blockchain #codingberlin #elastic
#aws #php #symfony2 #react
#digitalization #agile #b2b #marketplaces
#spryker #php #k8s #largescale
#turbinejetzt #iot #ux #vuejs
@stadolf
elmariachi111
3
4
•Many flavors
•ECMAScript 5-8 / 2009-2018,
TypeScript, CoffeeScript, Flow
•Many frameworks
•JQuery, Backbone, Ember
•React/JSX, Angular, Vue.js
•importing dependencies solved lately.
•it’s a moving target.
Frontend: the final frontier.
•Lots of quirks, lots of frameworks
•LESS, Sass / SCSS, Compass
•SMACSS, BEM, Atomic CSS
•Tools, tools, tools:
•PostCss,
•Autoprefixer
•Reboots
•css-modules
•styled
•CSSinJS
Projekttitel             30. Juni 2017 Kapitel5
monolithic assets, the naïve way
Your code
Libraries
6
BEEN THERE, DONE THAT.
Projekttitel             30. Juni 2017 Kapitel7
monolithic assets, discussion
•dependencies are loaded from a million external websites
•they can fail. They can track your user.
•You load everything on every page
•Some scripts depend on others
•or even have side effects
•or even rely on side effects (jquery plugins)
•loading order plays a role!
•later loaded styles overwrite earlier ones
•JS selectors rely on markup identifiers ($(‘.owl’).owl())
8
Asset usage in monolithic applications is… monolithic
Products
Checkout
CMS
Backend
API
specialization
shop.twig
products.twig
checkout.twig
layout.twig
admin.twig
product_partial.twig
edit_product.twig
layout.css
login.js
bootstrap.css
bootstrap.js
checkout.css
payment.js
products.css
filter.js
animations.css
swipe.js
jquery.js
Boot

strap
scssscss scss scss
$ lodashmoment Vue
Boot

strap.js
JS JS JS
JS
JS
JS
JS JS JS
JS
JS
JS
product.css product.js checkout.jscheckout.css
Today’s common fullstack build scenario
Checkout PageProduct List Page
10
What we expect from a modern
fullstack asset workflow
•latest Javascript language features
•dependency management
•SCSS compilation
•live browser reloading
•debugging in the browser
•support for legacy libraries
•support for state-of-the-art libraries
•automatic support for old browsers
•fast loading times on production
•fast build times
•instant onboarding of new team devs
11
12
Webpack is a module bundler
and not a “build” tool.
13
THEY ALL TRUST WEBPACK.
BECAUSE IT’S SO GREAT.
14
•initial setup = no brainer
•Javascript files are the root of truth


•webpack takes care of
•JS transpilation (via babel / tsc)
•browser compatibility & polyfilling
•SCSS compilation & extraction
•asset copying / concatenation
•naming & versioning
webpack at the core
import Vue from 'vue/dist/vue.esm.js';
require('bootstrap.scss');
const img = require('images/elephpant.png');
<img src={img} />
15
•babel integration
•write modern javascript
•sourcemaps
•enables framework syntaxes like
•JSX / Vue single file components

•Typescript transpilation

•style inlining / css components
•versioning
•long term caching
•tree shaking
•~ dead code removal
•chunk splitting
•common chunks
•entrypoint asset collections
•developer experience
•file watching
•dev-server (reload on build)
•HMR (inject changes)
•code metrics
webpack++
16
FINALLY WE CAN WRITE NICE JAVASCRIPT
Demo
17
const path = require("path");
const webpack = require("webpack");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const ManifestPlugin = require("webpack-manifest-plugin");
const provide = new webpack.ProvidePlugin({
$: "cash-dom",
jQuery: "cash-dom"
});
module.exports = {
entry: {
index: "./assets/js/index.js"
},
output: {
filename: "[name].[hash].js",
publicPath: "/dist/",
path: path.resolve(__dirname, "public/dist")
},
plugins: [
new CleanWebpackPlugin(["public/dist"]),
new ManifestPlugin({
writeToFileEmit: true
}),
provide
],
module: {
rules: [
{
test: /.(sa|sc|c)ss$/,
use: [
"style-loader",
"css-loader",
{
loader: "postcss-loader",
options: {
ident: "postcss",
plugins: [require("autoprefixer")()]
}
},
"sass-loader"
]
},
{
test: /.js$/,
exclude: /(node_modules|bower_components)/,
const merge = require("webpack-merge");
const common = require("./webpack.common.js");
const webpack = require("webpack");
module.exports = merge(common, {
mode: "development",
devtool: "cheap-module-eval-source-map", //inline-source-map,
output: {
publicPath: "http://localhost:8080/dist/"
},
devServer: {
host: "localhost",
publicPath: "/dist/",
https: false,
contentBase: "./public/dist",
hot: true,
inline: true,
headers: {
"Access-Control-Allow-Origin": "*"
}
},
plugins: [
new webpack.NamedModulesPlugin(),
new webpack.HotModuleReplacementPlugin()
]
});
const merge = require("webpack-merge");
const common = require("./webpack.common.js");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin")
const OptimizeCssAssetsPlugin = require("optimize-css-ass
const MiniCssExtractPlugin = require("mini-css-extract-pl
module.exports = merge(common, {
mode: "production",
//devtool: "source-map",
plugins: [
new MiniCssExtractPlugin({
filename: "[name].[hash].css",
chunkFilename: "[id].[hash].css"
})
],
optimization: {
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true,
sourceMap: false // set to true if you want JS so
}),
new OptimizeCssAssetsPlugin({})
],
runtimeChunk: "single",
splitChunks: {
cacheGroups: {
vendor: {
test: /[/]node_modules[/]/,
name: "vendors",
chunks: "all"
}
}
}
},
module: {
rules: [
{
test: /.(sa|sc|c)ss$/,
use: [
MiniCssExtractPlugin.loader,
//"style-loader",
"css-loader",
//'postcss-loader',
"sass-loader"
]
}
]
}
});
FINALLY WE CAN WRITE NICE JAVASCRIPT?
encore
is a webpack configuration generator
composer require symfony/webpack-encore-pack
install
npm i -D @symfony/webpack-encore
or
21
const path = require("path");
const webpack = require("webpack");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const ManifestPlugin = require("webpack-manifest-plugin");
const provide = new webpack.ProvidePlugin({
$: "cash-dom",
jQuery: "cash-dom"
});
module.exports = {
entry: {
index: "./assets/js/index.js"
},
output: {
filename: "[name].[hash].js",
publicPath: "/dist/",
path: path.resolve(__dirname, "public/dist")
},
plugins: [
new CleanWebpackPlugin(["public/dist"]),
new ManifestPlugin({
writeToFileEmit: true
}),
provide
],
module: {
rules: [
{
test: /.(sa|sc|c)ss$/,
use: [
"style-loader",
"css-loader",
{
loader: "postcss-loader",
options: {
ident: "postcss",
plugins: [require("autoprefixer")()]
}
},
"sass-loader"
]
},
{
test: /.js$/,
exclude: /(node_modules|bower_components)/,
const merge = require("webpack-merge");
const common = require("./webpack.common.js");
const webpack = require("webpack");
module.exports = merge(common, {
mode: "development",
devtool: "cheap-module-eval-source-map", //inline-source-map,
output: {
publicPath: "http://localhost:8080/dist/"
},
devServer: {
host: "localhost",
publicPath: "/dist/",
https: false,
contentBase: "./public/dist",
hot: true,
inline: true,
headers: {
"Access-Control-Allow-Origin": "*"
}
},
plugins: [
new webpack.NamedModulesPlugin(),
new webpack.HotModuleReplacementPlugin()
]
});
const merge = require("webpack-merge");
const common = require("./webpack.common.js");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin")
const OptimizeCssAssetsPlugin = require("optimize-css-ass
const MiniCssExtractPlugin = require("mini-css-extract-pl
module.exports = merge(common, {
mode: "production",
//devtool: "source-map",
plugins: [
new MiniCssExtractPlugin({
filename: "[name].[hash].css",
chunkFilename: "[id].[hash].css"
})
],
optimization: {
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true,
sourceMap: false // set to true if you want JS so
}),
new OptimizeCssAssetsPlugin({})
],
runtimeChunk: "single",
splitChunks: {
cacheGroups: {
vendor: {
test: /[/]node_modules[/]/,
name: "vendors",
chunks: "all"
}
}
}
},
module: {
rules: [
{
test: /.(sa|sc|c)ss$/,
use: [
MiniCssExtractPlugin.loader,
//"style-loader",
"css-loader",
//'postcss-loader',
"sass-loader"
]
}
]
}
});
FINALLY WE CAN WRITE NICE JAVASCRIPT?
const path = require("path");
const webpack = require("webpack");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const ManifestPlugin = require("webpack-manifest-plugin");
const provide = new webpack.ProvidePlugin({
$: "cash-dom",
jQuery: "cash-dom"
});
module.exports = {
entry: {
index: "./assets/js/index.js"
},
output: {
filename: "[name].[hash].js",
publicPath: "/dist/",
path: path.resolve(__dirname, "public/dist")
},
plugins: [
new CleanWebpackPlugin(["public/dist"]),
new ManifestPlugin({
writeToFileEmit: true
}),
provide
],
module: {
rules: [
{
test: /.(sa|sc|c)ss$/,
use: [
"style-loader",
"css-loader",
{
loader: "postcss-loader",
options: {
ident: "postcss",
plugins: [require("autoprefixer")()]
}
},
"sass-loader"
]
},
{
test: /.js$/,
exclude: /(node_modules|bower_components)/,
const merge = require("webpack-merge");
const common = require("./webpack.common.js");
const webpack = require("webpack");
module.exports = merge(common, {
mode: "development",
devtool: "cheap-module-eval-source-map", //inline-source-map,
output: {
publicPath: "http://localhost:8080/dist/"
},
devServer: {
host: "localhost",
publicPath: "/dist/",
https: false,
contentBase: "./public/dist",
hot: true,
inline: true,
headers: {
"Access-Control-Allow-Origin": "*"
}
},
plugins: [
new webpack.NamedModulesPlugin(),
new webpack.HotModuleReplacementPlugin()
]
});
const merge = require("webpack-merge");
const common = require("./webpack.common.js");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin")
const OptimizeCssAssetsPlugin = require("optimize-css-ass
const MiniCssExtractPlugin = require("mini-css-extract-pl
module.exports = merge(common, {
mode: "production",
//devtool: "source-map",
plugins: [
new MiniCssExtractPlugin({
filename: "[name].[hash].css",
chunkFilename: "[id].[hash].css"
})
],
optimization: {
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true,
sourceMap: false // set to true if you want JS so
}),
new OptimizeCssAssetsPlugin({})
],
runtimeChunk: "single",
splitChunks: {
cacheGroups: {
vendor: {
test: /[/]node_modules[/]/,
name: "vendors",
chunks: "all"
}
}
}
},
module: {
rules: [
{
test: /.(sa|sc|c)ss$/,
use: [
MiniCssExtractPlugin.loader,
//"style-loader",
"css-loader",
//'postcss-loader',
"sass-loader"
]
}
]
}
});
22
the same thing in encore.
multiple entries
css loading & transformation
dev tools & mode check
global variable shimming
chunking / splitting
all dev tools included
automatic manifests / entrypoints
23
asset versioning old webpack.common/prod.js
old manifest.json (generated)
enables infinite cache times for things that never change
24
entrypoints asset helper
product-list.twig
entrypoints.json (generated)
every page loads only assets it needs!
25
tree shaking
only used modules are exported!
26
tree shaking
only used modules are exported!
Demo
28
.enableReactPreset()
npm install @babel/preset-react@^7.0.0 --save-dev
.enableVueLoader()
npm install vue vue-loader@^15.0.11 vue-template-compiler --save-dev
using .vue template / components
out of the box!
encore
using .vue components (vtw!)
out of the box!
bonus: lazy load / defer imports
load modules only when you really need them!
34
Demo
35
•enables modern frontend coding
•by being super opinionated

•integrates webpack killer features into Symfony applications
•tree-shaking, chunking, versioning, manifests, entrypoints
•is a perfect tool to start migrating
•not so great to start a SPA/PWA/AMP project (use vue/cli or c-r-app instead)

•just generates configuration
•you can always add your own config
•simple to “down”grade to plain webpack (aka “ejecting”)

•can absolutely be used outside a Symfony context
wrap up
encore…
Turbine Kreuzberg GmbH
Ohlauer Straße 43
10999 Berlin
ASSET MANAGEMENT
FOR THE REST OF US.
@stadolf
#turbinejetzt
hello@turbinekreuzberg.com
https://github.com/elmariachi111/encore-demo

More Related Content

PDF
(2018) Webpack Encore - Asset Management for the rest of us
PDF
OSGi, Scripting and REST, Building Webapps With Apache Sling
PDF
Asynchronous Module Definition (AMD)
PDF
Native-Javascript Bridging Using WKWebViews in iOS8
KEY
Let's run JavaScript Everywhere
PPTX
Webpack Introduction
PPTX
Improving build solutions dependency management with webpack
(2018) Webpack Encore - Asset Management for the rest of us
OSGi, Scripting and REST, Building Webapps With Apache Sling
Asynchronous Module Definition (AMD)
Native-Javascript Bridging Using WKWebViews in iOS8
Let's run JavaScript Everywhere
Webpack Introduction
Improving build solutions dependency management with webpack

What's hot (20)

PDF
Bundle your modules with Webpack
PDF
Node.js 기반 정적 페이지 블로그 엔진, 하루프레스
PPTX
A few good JavaScript development tools
PDF
遠端團隊專案建立與管理 remote team management 2016
PDF
Vue 淺談前端建置工具
PPTX
Lecture: Webpack 4
PPTX
Webpack
PPTX
An Intro into webpack
PDF
Node.js & Twitter Bootstrap Crash Course
PPTX
Vue business first
PPTX
Vue Introduction
PDF
Grunt.js and Yeoman, Continous Integration
PDF
Treinamento frontend
PPTX
Webpack and Web Performance Optimization
PDF
WKWebView in Production
PDF
Command Line Tool in swift
PDF
PPTX
Bundling your front-end with Webpack
PDF
The SPDY Protocol
PDF
Devfest09 Cschalk Gwt
Bundle your modules with Webpack
Node.js 기반 정적 페이지 블로그 엔진, 하루프레스
A few good JavaScript development tools
遠端團隊專案建立與管理 remote team management 2016
Vue 淺談前端建置工具
Lecture: Webpack 4
Webpack
An Intro into webpack
Node.js & Twitter Bootstrap Crash Course
Vue business first
Vue Introduction
Grunt.js and Yeoman, Continous Integration
Treinamento frontend
Webpack and Web Performance Optimization
WKWebView in Production
Command Line Tool in swift
Bundling your front-end with Webpack
The SPDY Protocol
Devfest09 Cschalk Gwt
Ad

Similar to Webpack Encore - Asset Management for the rest of us (20)

PDF
How to replace rails asset pipeline with webpack?
PDF
Symfony Live 2018 - Développez votre frontend avec ReactJS et Symfony Webpack...
PDF
Front-end build tools - Webpack
PDF
Keeping the frontend under control with Symfony and Webpack
PDF
Webpack Encore Symfony Live 2017 San Francisco
PPTX
Packing for the Web with Webpack
PDF
Webpack DevTalk
PPTX
Javascript Bundling and modularization
PPTX
WEBPACK
PDF
Webpack
PDF
A re introduction to webpack - reactfoo - mumbai
PDF
Everything is Awesome - Cutting the Corners off the Web
PDF
Warsaw Frontend Meetup #1 - Webpack
PDF
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
PDF
How we improved performance at Mixbook
PDF
AFUP Lorraine - Symfony Webpack Encore
PDF
Webpack: What it is, What it does, Whether you need it
PDF
Hitchhiker's guide to the front end development
PDF
Building and deploying React applications
PPTX
webpack introductionNotice Demystifyingf
How to replace rails asset pipeline with webpack?
Symfony Live 2018 - Développez votre frontend avec ReactJS et Symfony Webpack...
Front-end build tools - Webpack
Keeping the frontend under control with Symfony and Webpack
Webpack Encore Symfony Live 2017 San Francisco
Packing for the Web with Webpack
Webpack DevTalk
Javascript Bundling and modularization
WEBPACK
Webpack
A re introduction to webpack - reactfoo - mumbai
Everything is Awesome - Cutting the Corners off the Web
Warsaw Frontend Meetup #1 - Webpack
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
How we improved performance at Mixbook
AFUP Lorraine - Symfony Webpack Encore
Webpack: What it is, What it does, Whether you need it
Hitchhiker's guide to the front end development
Building and deploying React applications
webpack introductionNotice Demystifyingf
Ad

More from Stefan Adolf (20)

PDF
Blockchains - Technical foundations
PDF
HOW TO SURVIVE A 2DAY HACKATHON?
PDF
Digitale Selbstbestimmung mit Hilfe dezentraler Technologien
PDF
Digitale Selbstbestimmung | Anwendungsfälle der Dezentralität
PDF
Decentralized technology: a (short) survey
PDF
Productive web applications that run only on the frontend
PDF
DePA - die dezentrale Patientenakte (29.1. FU Berlin)
PDF
DePA - die dezentrale Patientenakte
PDF
Was ist eine Datenbank - und was hat Blockchain damit zu tun?
PDF
Never Code Alone: Von Symfony Forms zu einer SPA auf APIs
PDF
Decentralize all the things
PDF
Indexing Decentralized Data with Ethereum, IPFS & The Graph
PDF
Gatsby (Code.Talks) 2019
PDF
A micro service story
PDF
Api Platform: the ultimate API Platform
PDF
Pump up the JAM with Gatsby (2019)
PDF
Testing API platform with Behat BDD tests
PDF
Hack it like its hot!
PDF
api-platform: the ultimate API platform
PDF
Pump up the JAM with Gatsby
Blockchains - Technical foundations
HOW TO SURVIVE A 2DAY HACKATHON?
Digitale Selbstbestimmung mit Hilfe dezentraler Technologien
Digitale Selbstbestimmung | Anwendungsfälle der Dezentralität
Decentralized technology: a (short) survey
Productive web applications that run only on the frontend
DePA - die dezentrale Patientenakte (29.1. FU Berlin)
DePA - die dezentrale Patientenakte
Was ist eine Datenbank - und was hat Blockchain damit zu tun?
Never Code Alone: Von Symfony Forms zu einer SPA auf APIs
Decentralize all the things
Indexing Decentralized Data with Ethereum, IPFS & The Graph
Gatsby (Code.Talks) 2019
A micro service story
Api Platform: the ultimate API Platform
Pump up the JAM with Gatsby (2019)
Testing API platform with Behat BDD tests
Hack it like its hot!
api-platform: the ultimate API platform
Pump up the JAM with Gatsby

Recently uploaded (20)

PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
PDF
Softaken Excel to vCard Converter Software.pdf
PDF
Understanding Forklifts - TECH EHS Solution
PDF
How Creative Agencies Leverage Project Management Software.pdf
PDF
System and Network Administraation Chapter 3
PPTX
ManageIQ - Sprint 268 Review - Slide Deck
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PDF
PTS Company Brochure 2025 (1).pdf.......
PPT
Introduction Database Management System for Course Database
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PDF
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PPTX
Online Work Permit System for Fast Permit Processing
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PPTX
CHAPTER 12 - CYBER SECURITY AND FUTURE SKILLS (1) (1).pptx
PPTX
L1 - Introduction to python Backend.pptx
PDF
System and Network Administration Chapter 2
PDF
Which alternative to Crystal Reports is best for small or large businesses.pdf
PPTX
CHAPTER 2 - PM Management and IT Context
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
Softaken Excel to vCard Converter Software.pdf
Understanding Forklifts - TECH EHS Solution
How Creative Agencies Leverage Project Management Software.pdf
System and Network Administraation Chapter 3
ManageIQ - Sprint 268 Review - Slide Deck
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PTS Company Brochure 2025 (1).pdf.......
Introduction Database Management System for Course Database
Adobe Illustrator 28.6 Crack My Vision of Vector Design
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
Wondershare Filmora 15 Crack With Activation Key [2025
Online Work Permit System for Fast Permit Processing
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
CHAPTER 12 - CYBER SECURITY AND FUTURE SKILLS (1) (1).pptx
L1 - Introduction to python Backend.pptx
System and Network Administration Chapter 2
Which alternative to Crystal Reports is best for small or large businesses.pdf
CHAPTER 2 - PM Management and IT Context

Webpack Encore - Asset Management for the rest of us

  • 1. WEBPACK ENCORE Asset management for the rest of us
  • 2. 2 Stefan Adolf Developer Ambassador #javascript #mongodb #serverless #blockchain #codingberlin #elastic #aws #php #symfony2 #react #digitalization #agile #b2b #marketplaces #spryker #php #k8s #largescale #turbinejetzt #iot #ux #vuejs @stadolf elmariachi111
  • 3. 3
  • 4. 4 •Many flavors •ECMAScript 5-8 / 2009-2018, TypeScript, CoffeeScript, Flow •Many frameworks •JQuery, Backbone, Ember •React/JSX, Angular, Vue.js •importing dependencies solved lately. •it’s a moving target. Frontend: the final frontier. •Lots of quirks, lots of frameworks •LESS, Sass / SCSS, Compass •SMACSS, BEM, Atomic CSS •Tools, tools, tools: •PostCss, •Autoprefixer •Reboots •css-modules •styled •CSSinJS
  • 5. Projekttitel             30. Juni 2017 Kapitel5 monolithic assets, the naïve way Your code Libraries
  • 7. Projekttitel             30. Juni 2017 Kapitel7 monolithic assets, discussion •dependencies are loaded from a million external websites •they can fail. They can track your user. •You load everything on every page •Some scripts depend on others •or even have side effects •or even rely on side effects (jquery plugins) •loading order plays a role! •later loaded styles overwrite earlier ones •JS selectors rely on markup identifiers ($(‘.owl’).owl())
  • 8. 8 Asset usage in monolithic applications is… monolithic Products Checkout CMS Backend API specialization shop.twig products.twig checkout.twig layout.twig admin.twig product_partial.twig edit_product.twig layout.css login.js bootstrap.css bootstrap.js checkout.css payment.js products.css filter.js animations.css swipe.js jquery.js
  • 9. Boot
 strap scssscss scss scss $ lodashmoment Vue Boot
 strap.js JS JS JS JS JS JS JS JS JS JS JS JS product.css product.js checkout.jscheckout.css Today’s common fullstack build scenario Checkout PageProduct List Page
  • 10. 10 What we expect from a modern fullstack asset workflow •latest Javascript language features •dependency management •SCSS compilation •live browser reloading •debugging in the browser •support for legacy libraries •support for state-of-the-art libraries •automatic support for old browsers •fast loading times on production •fast build times •instant onboarding of new team devs
  • 11. 11
  • 12. 12 Webpack is a module bundler and not a “build” tool.
  • 13. 13 THEY ALL TRUST WEBPACK. BECAUSE IT’S SO GREAT.
  • 14. 14 •initial setup = no brainer •Javascript files are the root of truth 
 •webpack takes care of •JS transpilation (via babel / tsc) •browser compatibility & polyfilling •SCSS compilation & extraction •asset copying / concatenation •naming & versioning webpack at the core import Vue from 'vue/dist/vue.esm.js'; require('bootstrap.scss'); const img = require('images/elephpant.png'); <img src={img} />
  • 15. 15 •babel integration •write modern javascript •sourcemaps •enables framework syntaxes like •JSX / Vue single file components
 •Typescript transpilation
 •style inlining / css components •versioning •long term caching •tree shaking •~ dead code removal •chunk splitting •common chunks •entrypoint asset collections •developer experience •file watching •dev-server (reload on build) •HMR (inject changes) •code metrics webpack++
  • 16. 16 FINALLY WE CAN WRITE NICE JAVASCRIPT Demo
  • 17. 17 const path = require("path"); const webpack = require("webpack"); const CleanWebpackPlugin = require("clean-webpack-plugin"); const ManifestPlugin = require("webpack-manifest-plugin"); const provide = new webpack.ProvidePlugin({ $: "cash-dom", jQuery: "cash-dom" }); module.exports = { entry: { index: "./assets/js/index.js" }, output: { filename: "[name].[hash].js", publicPath: "/dist/", path: path.resolve(__dirname, "public/dist") }, plugins: [ new CleanWebpackPlugin(["public/dist"]), new ManifestPlugin({ writeToFileEmit: true }), provide ], module: { rules: [ { test: /.(sa|sc|c)ss$/, use: [ "style-loader", "css-loader", { loader: "postcss-loader", options: { ident: "postcss", plugins: [require("autoprefixer")()] } }, "sass-loader" ] }, { test: /.js$/, exclude: /(node_modules|bower_components)/, const merge = require("webpack-merge"); const common = require("./webpack.common.js"); const webpack = require("webpack"); module.exports = merge(common, { mode: "development", devtool: "cheap-module-eval-source-map", //inline-source-map, output: { publicPath: "http://localhost:8080/dist/" }, devServer: { host: "localhost", publicPath: "/dist/", https: false, contentBase: "./public/dist", hot: true, inline: true, headers: { "Access-Control-Allow-Origin": "*" } }, plugins: [ new webpack.NamedModulesPlugin(), new webpack.HotModuleReplacementPlugin() ] }); const merge = require("webpack-merge"); const common = require("./webpack.common.js"); const UglifyJsPlugin = require("uglifyjs-webpack-plugin") const OptimizeCssAssetsPlugin = require("optimize-css-ass const MiniCssExtractPlugin = require("mini-css-extract-pl module.exports = merge(common, { mode: "production", //devtool: "source-map", plugins: [ new MiniCssExtractPlugin({ filename: "[name].[hash].css", chunkFilename: "[id].[hash].css" }) ], optimization: { minimizer: [ new UglifyJsPlugin({ cache: true, parallel: true, sourceMap: false // set to true if you want JS so }), new OptimizeCssAssetsPlugin({}) ], runtimeChunk: "single", splitChunks: { cacheGroups: { vendor: { test: /[/]node_modules[/]/, name: "vendors", chunks: "all" } } } }, module: { rules: [ { test: /.(sa|sc|c)ss$/, use: [ MiniCssExtractPlugin.loader, //"style-loader", "css-loader", //'postcss-loader', "sass-loader" ] } ] } }); FINALLY WE CAN WRITE NICE JAVASCRIPT?
  • 18. encore is a webpack configuration generator
  • 20. npm i -D @symfony/webpack-encore or
  • 21. 21 const path = require("path"); const webpack = require("webpack"); const CleanWebpackPlugin = require("clean-webpack-plugin"); const ManifestPlugin = require("webpack-manifest-plugin"); const provide = new webpack.ProvidePlugin({ $: "cash-dom", jQuery: "cash-dom" }); module.exports = { entry: { index: "./assets/js/index.js" }, output: { filename: "[name].[hash].js", publicPath: "/dist/", path: path.resolve(__dirname, "public/dist") }, plugins: [ new CleanWebpackPlugin(["public/dist"]), new ManifestPlugin({ writeToFileEmit: true }), provide ], module: { rules: [ { test: /.(sa|sc|c)ss$/, use: [ "style-loader", "css-loader", { loader: "postcss-loader", options: { ident: "postcss", plugins: [require("autoprefixer")()] } }, "sass-loader" ] }, { test: /.js$/, exclude: /(node_modules|bower_components)/, const merge = require("webpack-merge"); const common = require("./webpack.common.js"); const webpack = require("webpack"); module.exports = merge(common, { mode: "development", devtool: "cheap-module-eval-source-map", //inline-source-map, output: { publicPath: "http://localhost:8080/dist/" }, devServer: { host: "localhost", publicPath: "/dist/", https: false, contentBase: "./public/dist", hot: true, inline: true, headers: { "Access-Control-Allow-Origin": "*" } }, plugins: [ new webpack.NamedModulesPlugin(), new webpack.HotModuleReplacementPlugin() ] }); const merge = require("webpack-merge"); const common = require("./webpack.common.js"); const UglifyJsPlugin = require("uglifyjs-webpack-plugin") const OptimizeCssAssetsPlugin = require("optimize-css-ass const MiniCssExtractPlugin = require("mini-css-extract-pl module.exports = merge(common, { mode: "production", //devtool: "source-map", plugins: [ new MiniCssExtractPlugin({ filename: "[name].[hash].css", chunkFilename: "[id].[hash].css" }) ], optimization: { minimizer: [ new UglifyJsPlugin({ cache: true, parallel: true, sourceMap: false // set to true if you want JS so }), new OptimizeCssAssetsPlugin({}) ], runtimeChunk: "single", splitChunks: { cacheGroups: { vendor: { test: /[/]node_modules[/]/, name: "vendors", chunks: "all" } } } }, module: { rules: [ { test: /.(sa|sc|c)ss$/, use: [ MiniCssExtractPlugin.loader, //"style-loader", "css-loader", //'postcss-loader', "sass-loader" ] } ] } }); FINALLY WE CAN WRITE NICE JAVASCRIPT?
  • 22. const path = require("path"); const webpack = require("webpack"); const CleanWebpackPlugin = require("clean-webpack-plugin"); const ManifestPlugin = require("webpack-manifest-plugin"); const provide = new webpack.ProvidePlugin({ $: "cash-dom", jQuery: "cash-dom" }); module.exports = { entry: { index: "./assets/js/index.js" }, output: { filename: "[name].[hash].js", publicPath: "/dist/", path: path.resolve(__dirname, "public/dist") }, plugins: [ new CleanWebpackPlugin(["public/dist"]), new ManifestPlugin({ writeToFileEmit: true }), provide ], module: { rules: [ { test: /.(sa|sc|c)ss$/, use: [ "style-loader", "css-loader", { loader: "postcss-loader", options: { ident: "postcss", plugins: [require("autoprefixer")()] } }, "sass-loader" ] }, { test: /.js$/, exclude: /(node_modules|bower_components)/, const merge = require("webpack-merge"); const common = require("./webpack.common.js"); const webpack = require("webpack"); module.exports = merge(common, { mode: "development", devtool: "cheap-module-eval-source-map", //inline-source-map, output: { publicPath: "http://localhost:8080/dist/" }, devServer: { host: "localhost", publicPath: "/dist/", https: false, contentBase: "./public/dist", hot: true, inline: true, headers: { "Access-Control-Allow-Origin": "*" } }, plugins: [ new webpack.NamedModulesPlugin(), new webpack.HotModuleReplacementPlugin() ] }); const merge = require("webpack-merge"); const common = require("./webpack.common.js"); const UglifyJsPlugin = require("uglifyjs-webpack-plugin") const OptimizeCssAssetsPlugin = require("optimize-css-ass const MiniCssExtractPlugin = require("mini-css-extract-pl module.exports = merge(common, { mode: "production", //devtool: "source-map", plugins: [ new MiniCssExtractPlugin({ filename: "[name].[hash].css", chunkFilename: "[id].[hash].css" }) ], optimization: { minimizer: [ new UglifyJsPlugin({ cache: true, parallel: true, sourceMap: false // set to true if you want JS so }), new OptimizeCssAssetsPlugin({}) ], runtimeChunk: "single", splitChunks: { cacheGroups: { vendor: { test: /[/]node_modules[/]/, name: "vendors", chunks: "all" } } } }, module: { rules: [ { test: /.(sa|sc|c)ss$/, use: [ MiniCssExtractPlugin.loader, //"style-loader", "css-loader", //'postcss-loader', "sass-loader" ] } ] } }); 22 the same thing in encore. multiple entries css loading & transformation dev tools & mode check global variable shimming chunking / splitting all dev tools included automatic manifests / entrypoints
  • 23. 23 asset versioning old webpack.common/prod.js old manifest.json (generated) enables infinite cache times for things that never change
  • 24. 24 entrypoints asset helper product-list.twig entrypoints.json (generated) every page loads only assets it needs!
  • 25. 25 tree shaking only used modules are exported!
  • 26. 26 tree shaking only used modules are exported!
  • 27. Demo
  • 28. 28
  • 30. .enableVueLoader() npm install vue vue-loader@^15.0.11 vue-template-compiler --save-dev
  • 31. using .vue template / components out of the box! encore
  • 32. using .vue components (vtw!) out of the box!
  • 33. bonus: lazy load / defer imports load modules only when you really need them!
  • 35. 35 •enables modern frontend coding •by being super opinionated
 •integrates webpack killer features into Symfony applications •tree-shaking, chunking, versioning, manifests, entrypoints •is a perfect tool to start migrating •not so great to start a SPA/PWA/AMP project (use vue/cli or c-r-app instead)
 •just generates configuration •you can always add your own config •simple to “down”grade to plain webpack (aka “ejecting”)
 •can absolutely be used outside a Symfony context wrap up encore…
  • 36. Turbine Kreuzberg GmbH Ohlauer Straße 43 10999 Berlin ASSET MANAGEMENT FOR THE REST OF US. @stadolf #turbinejetzt hello@turbinekreuzberg.com https://github.com/elmariachi111/encore-demo