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

Webpack Encore - Asset Management for the rest of us

  • 1.
  • 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.
  • 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 2017Kapitel5 monolithic assets, the naïve way Your code Libraries
  • 6.
  • 7.
    Projekttitel             30. Juni 2017Kapitel7 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 inmonolithic 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 expectfrom 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.
    12 Webpack is amodule bundler and not a “build” tool.
  • 13.
    13 THEY ALL TRUSTWEBPACK. 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 modernjavascript •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 CANWRITE 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 webpackconfiguration generator
  • 19.
  • 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 oldwebpack.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 usedmodules are exported!
  • 26.
    26 tree shaking only usedmodules are exported!
  • 27.
  • 28.
  • 29.
  • 30.
    .enableVueLoader() npm install vuevue-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!
  • 34.
  • 35.
    35 •enables modern frontendcoding •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 OhlauerStraße 43 10999 Berlin ASSET MANAGEMENT FOR THE REST OF US. @stadolf #turbinejetzt hello@turbinekreuzberg.com https://github.com/elmariachi111/encore-demo