Utiliser Webpack dans une application Symfony

Post on 21-Apr-2017

788 views 5 download

Transcript of Utiliser Webpack dans une application Symfony

IntegrateWebpackinaSymfonyapp

Howto?

1 . 1

Me?

LeadDeveloperSensioLabs@al0neh

AlainHippolyte

1 . 2

AsseticTransformassetsviafiltersNotinSymfonyStandardEditionanymore

2 . 1

2 . 2

AsseticdrawbacksNotthebestDXNotcontentawareNotfrontenddevfriendlyPoorlymaintained

2 . 3

3 . 1

Modulebundler

3 . 2

Moduleonesinglefunctionalunit

https://addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript3 . 3

BundlertakesmoduleswithdependenciesandemitsstaticassetsrepresentingthosemodulesliketheServiceContainerinSymfony

3 . 4

3 . 5

FeaturesLoadssourcefilesTransformsassetsProducesassetbundlesGeneratesartifacts(hashes,srcmaps)GreatDX

3 . 6

Howdoesitwork?

3 . 7

3 . 8

The4CoreConceptsEntries-Wheretostart?Output-Wheretooutput?Loaders-Howtotransform?Plugins-Howtobundle?

4 . 1

webpack.config.js

module.exports={entry:{...},output:{...},module:{rules:[...]},plugins:[...]};

4 . 2

Entries//shortandsyntaxconstconfig={entry:'./src/app.js'};

//Objectsyntaxconstconfig={entry:{app:'./src/app.js',vendor:'./src/vendor.js'}};

Wheretostart?

4 . 3

Output

module.exports={output:{path:'./web/builds',filename:'bundle.js',publicPath:'/builds/'}};

Wheretooutput?

4 . 4

Loaders

module.exports={module:{rules:[{test:/\.js$/,use:'babel-loader'}]}};

Howtotransform?

4 . 5

Commonloaders

Transpiler:babel-loader,ts-loaderStyles:css-loader,style-loaderFiles:url-loader,file-loaderLinting:jslint-loader

https://webpack.js.org/loaders/4 . 6

Plugins

module.exports={plugins:[newwebpack.optimize.UglifyJsPlugin()]};

https://webpack.js.org/plugins/

bundle-wideprocessing

4 . 7

GettingStarted

5 . 1

AgendaEntryConfigureWebpackwithSCSSfilesImportfonts

5 . 2

InstallWebpack1/Makeapackage.jsonfile

{"name":"sf-live-2017-symfony-webpack","version":"1.0.0","devDependencies":{"babel-core":"^6.24.0","babel-loader":"^6.4.1","webpack":"^2.2.1"}}

$npminstall$./node_modules/.bin/webpack

5 . 3

Myfirstwebpackentry

//app/Resources/assets/js/main.js

console.log('SymfonyLiveParis2017');

{#app/Resources/views/base.html.twig#}

<scriptsrc="{{asset('builds/bundle.js')}}"></script>

5 . 4

webpack.config.jsmodule.exports={entry:{app:'./app/Resources/assets/js/app.js',},output:{path:'./web/builds',filename:'bundle.js',publicPath:'/builds/'},module:{rules:[{test:/\.js$/,exclude:/(node_modules)/,use:'babel-loader'}]}};

5 . 5

./node_modules/.bin/webpack

5 . 6

Addoursassloader

//app/Resources/assets/scss/app.scss

$icon-font-path:"~bootstrap-sass/assets/fonts/bootstrap/";

@import"variables";@import"~bootstrap-sass/assets/stylesheets/bootstrap";@import"bootstrap-theme";

//app/Resources/assets/js/app.js

import'../scss/app.scss';

6 . 1

Installsassdependencies

module:{rules:[//...+{+test:/\.scss$/,+use:[+{loader:"style-loader"},+{loader:"css-loader"},+{loader:"sass-loader"}+]+}]};

./node_modules/.bin/webpack

$npminstall--save-devstyle-loadercss-loadernode-sasssass-loader

6 . 2

Houstonwehaveaproblem

6 . 3

//app/Resources/assets/scss/bootstrap.scss

@font-face{font-family:'GlyphiconsHalflings';src:url(#{$icon-font-path}glyphicons-halflings-regular.eot'));//...}

6 . 4

Let'sfixthat!

module.exports={module:{rules:[//...+{+test:/\.woff2?$|\.ttf$|\.eot$|\.svg$/,+use:"file-loader"+}]}};

Installfile-loaderdependency

6 . 5

//app/Resources/assets/saas/main.scss

//...

@import"../css/font-awesome-4.6.3.min.css";@import"../css/font-lato.css";@import"../css/bootstrap-datetimepicker.min.css";@import"../css/highlight-solarized-light.css";@import"../css/main.css";

Importotherstyles

6 . 6

12 3 4 5

6

1. GoogleFontLatoimport2. Bootstrap3. font-lato.css4. bootstrap-datetimepicker.min.css5. highlight-solarized-light.css6. main.css

6 . 7

Summary

ImportabootstrapthemeUseWebpacktotransformSCSSfilesUseWebpacktoworkwithfonts

7

Now,JS

8 . 1

//app/Resources/assets/js/app.js

import"../scss/app.scss";

import"./jquery-2.1.4.min";import"./bootstrap-3.3.4.min";//...

CommonproblemwithWebpack

JqueryInlineJS

8 . 2

Let'sgetfixthem

8 . 3

JqueryconstjqueryPath='app/Resources/assets/js/jquery-2.1.4.min.js';module.exports={plugins:[newwebpack.ProvidePlugin({$:"jquery",jQuery:"jquery","window.jQuery":"jquery",}),],resolve:{alias:{jquery:path.resolve(__dirname,jqueryPath)}},};

8 . 4

//login.html.twig{%blockjavascripts%}{#...#}<script>$(document).ready(function(){varusernameEl=$('#username');varpasswordEl=$('#password');

if(!usernameEl.val()&&!passwordEl.val()){usernameEl.val('anna_admin');passwordEl.val('kitten');}});</script>{%endblock%}

8 . 5

$npminstall--save-devexpose-loader

rules:[+{+test:/jquery/,+use:[+{+loader:'expose-loader',+options:'$'+},+{+loader:'expose-loader',+options:'jQuery'+}+]+}]

8 . 6

Everythingisgood!

8 . 7

WebpackDevServer

9 . 1

$npminstall--save-devwebpack-dev-server

module.exports={plugins:[newwebpack.HotModuleReplacementPlugin()],devServer:{hot:true,contentBase:'./web/'},devtool:'inline-source-map',};

9 . 2

//app/AppKernel.phpclassAppKernelextendsKernel{publicfunctionregisterContainerConfiguration(LoaderInterface$loader){//...$loader->load(function($container){if($container->getParameter('use_webpack_dev_server')){$container->loadFromExtension('framework',['assets'=>['base_url'=>'http://localhost:8080/']]);}});}}

RyanWeaver

./node_modules/.bin/webpack-dev-server

9 . 3

Prepareforproduction

10 . 1

10 . 2

module.exports={module:{rules:[{test:/\.scss$/,+use:ExtractTextPlugin.extract({+fallback:'style-loader',+use:['css-loader','sass-loader']+})}]},plugins:[+newExtractTextPlugin('app.css')]};

{#app/Resources/views/base.html.twig#}+{%blockstylesheets%}+<linkrel="stylesheet"href="{{asset('builds/app.css')}}">+{%endblock%}

Extractcssintoaseparatedfile

10 . 3

SplitvendorswithCommonChunksPluginmodule.exports={entry:{vendor:['jquery','bootstrap-sass']},output:{filename:'[name].js'},plugins:[newwebpack.optimize.CommonsChunkPlugin({name:'vendor'})]};

{#app/Resources/views/base.html.twig#}{%blockjavascripts%}+<scriptsrc="{{asset('builds/vendor.js')}}"></script><scriptsrc="{{asset('builds/app.js')}}"></script>{%endblock%}

10 . 4

MinifywithUglifyJs

SupportedbyWebpackoutof

thebox!

module.exports={plugins:[+newwebpack.optimize.UglifyJsPlugin({+beautify:false,+compress:{+screw_ie8:true,+warnings:false+},+mangle:{+screw_ie8:true,+keep_fnames:true+},+comments:false+})]};

10 . 5

Minifyourstyles{test:/\.scss$/,use:ExtractTextPlugin.extract({fallback:'style-loader',use:[{loader:'css-loader',options:{//CSSNanoconfigurationminimize:{discardComments:{removeAll:true},core:true,minifyFontValues:true}}},'sass-loader']})}

10 . 6

Longtermcaching

10 . 7

constWebpackManifestPlugin=require('webpack-manifest-plugin');

module.exports={output:{filename:'[name].[chunkhash].js'},plugins:[newWebpackManifestPlugin({fileName:'manifest.json'})]};

$npminstall--save-devwebpack-manifest-plugin

InstallWebpackManifestplugin

10 . 8

https://github.com/symfony/symfony/pull/22046

Symfony3.3

10 . 9

//app/config/config_prod.yml

framework:assets:json_manifest_path:'%kernel.root_dir%/../web/builds/manifest.json'

10 . 10

Tips

11 . 1

Treeshaking

onlyincludecodeinyourbundlethatisbeingused

https://blog.engineyard.com/2016/tree-shaking

11 . 2

EnvvarsEnvironmentPlugin:referenceenvvarsthroughprocess.envDefinePlugin:globalconstants

11 . 3

OptimizeJsPlugin

optimizeaJavaScriptfileforfasterinitialexecutionandparsing

https://github.com/vigneshshanmugam/optimize-js-plugin11 . 4

DedupePlugin

Deduplicatecommonfiles

https://medium.com/@rajaraodv/two-quick-ways-to-reduce-react-apps-size-in-production-82226605771a

11 . 5

Thankyou!

https://joind.in/talk/94c36

https://github.com/alOneh/sf-live-2017-symfony-webpack

12

Questions?

13