Advertisement
Advertisement

More Related Content

Advertisement

Utiliser Webpack dans une application Symfony

  1. Integrate Webpack in a Symfony app How to ? 1 . 1
  2. Me ? Lead Developer SensioLabs @al0neh Alain Hippolyte 1 . 2
  3. Assetic Transform assets via filters Not in Symfony Standard Edition anymore 2 . 1
  4. 2 . 2
  5. Assetic drawbacks Not the best DX Not content aware Not frontend dev friendly Poorly maintained 2 . 3
  6. 3 . 1
  7. Module bundler 3 . 2
  8. Module one single functional unit https://addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript 3 . 3
  9. Bundler takes modules with dependencies and emits static assets representing those modules like the Service Container in Symfony 3 . 4
  10. ≠ 3 . 5
  11. Features Loads source files Transforms assets Produces asset bundles Generates artifacts (hashes, srcmaps) Great DX 3 . 6
  12. How does it work ? 3 . 7
  13. 3 . 8
  14. The 4 Core Concepts Entries - Where to start ? Output - Where to output ? Loaders - How to transform ? Plugins - How to bundle ? 4 . 1
  15. webpack.config.js module.exports = { entry: { ... }, output: { ... }, module: { rules: [ ... ] }, plugins: [ ... ] }; 4 . 2
  16. Entries // shortand syntax const config = { entry: './src/app.js' }; // Object syntax const config = { entry: { app: './src/app.js', vendor: './src/vendor.js' } }; Where to start? 4 . 3
  17. Output module.exports = { output: { path: './web/builds', filename: 'bundle.js', publicPath: '/builds/' } }; Where to output ? 4 . 4
  18. Loaders module.exports = { module: { rules: [ { test: /.js$/, use: 'babel-loader' } ] } }; How to transform ? 4 . 5
  19. Common loaders Transpiler : babel-loader, ts-loader Styles : css-loader, style-loader Files : url-loader, file-loader Linting : jslint-loader https://webpack.js.org/loaders/ 4 . 6
  20. Plugins module.exports = { plugins: [ new webpack.optimize.UglifyJsPlugin() ] }; https://webpack.js.org/plugins/ bundle-wide processing 4 . 7
  21. Getting Started 5 . 1
  22. Agenda Entry Configure Webpack with SCSS files Import fonts 5 . 2
  23. Install Webpack 1/ Make a package.json file { "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" } } $ npm install $ ./node_modules/.bin/webpack 5 . 3
  24. My first webpack entry // app/Resources/assets/js/main.js console.log('Symfony Live Paris 2017'); {# app/Resources/views/base.html.twig #} <script src="{{ asset('builds/bundle.js') }}"></script> 5 . 4
  25. webpack.config.js module.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
  26. ./node_modules/.bin/webpack 5 . 6
  27. Add our sass loader // 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
  28. Install sass dependencies module: { rules: [ // ... + { + test: /.scss$/, + use: [ + { loader: "style-loader" }, + { loader: "css-loader" }, + { loader: "sass-loader" } + ] + } ] }; ./node_modules/.bin/webpack $ npm install --save-dev style-loader css-loader node-sass sass-loader 6 . 2
  29. Houston we have a problem 6 . 3
  30. // app/Resources/assets/scss/bootstrap.scss @font-face { font-family: 'Glyphicons Halflings'; src: url(#{$icon-font-path}glyphicons-halflings-regular.eot')); // ... } 6 . 4
  31. Let's fix that ! module.exports = { module: { rules: [ // ... + { + test: /.woff2?$|.ttf$|.eot$|.svg$/, + use: "file-loader" + } ] } }; Install file-loader dependency 6 . 5
  32. // 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"; Import other styles 6 . 6
  33. 12 3 4 5 6 1. Google Font Lato import 2. Bootstrap 3. font-lato.css 4. bootstrap-datetimepicker.min.css 5. highlight-solarized-light.css 6. main.css 6 . 7
  34. Summary Import a bootstrap theme Use Webpack to transform SCSS files Use Webpack to work with fonts 7
  35. Now, JS 8 . 1
  36. // app/Resources/assets/js/app.js import "../scss/app.scss"; import "./jquery-2.1.4.min"; import "./bootstrap-3.3.4.min"; // ... Common problem with Webpack Jquery Inline JS 8 . 2
  37. Let's get fix them 8 . 3
  38. Jquery const jqueryPath = 'app/Resources/assets/js/jquery-2.1.4.min.js'; module.exports = { plugins: [ new webpack.ProvidePlugin({ $: "jquery", jQuery: "jquery", "window.jQuery": "jquery", }), ], resolve: { alias: { jquery: path.resolve(__dirname, jqueryPath) } }, }; 8 . 4
  39. // login.html.twig {% block javascripts %} {# ... #} <script> $(document).ready(function() { var usernameEl = $('#username'); var passwordEl = $('#password'); if (!usernameEl.val() && !passwordEl.val()) { usernameEl.val('anna_admin'); passwordEl.val('kitten'); } }); </script> {% endblock %} 8 . 5
  40. $ npm install --save-dev expose-loader rules: [ + { + test: /jquery/, + use: [ + { + loader: 'expose-loader', + options: '$' + }, + { + loader: 'expose-loader', + options: 'jQuery' + } + ] + } ] 8 . 6
  41. Everything is good ! 8 . 7
  42. Webpack Dev Server 9 . 1
  43. $ npm install --save-dev webpack-dev-server module.exports = { plugins: [ new webpack.HotModuleReplacementPlugin() ], devServer: { hot: true, contentBase: './web/' }, devtool: 'inline-source-map', }; 9 . 2
  44. // app/AppKernel.php class AppKernel extends Kernel { public function registerContainerConfiguration(LoaderInterface $loader) { //... $loader->load(function($container) { if ($container->getParameter('use_webpack_dev_server')) { $container->loadFromExtension('framework', [ 'assets' => [ 'base_url' => 'http://localhost:8080/' ] ]); } }); } } Ryan Weaver ./node_modules/.bin/webpack-dev-server 9 . 3
  45. Prepare for production 10 . 1
  46. 10 . 2
  47. module.exports = { module: { rules: [{ test: /.scss$/, + use: ExtractTextPlugin.extract({ + fallback: 'style-loader', + use: ['css-loader', 'sass-loader'] + }) }] }, plugins: [ + new ExtractTextPlugin('app.css') ] }; {# app/Resources/views/base.html.twig #} +{% block stylesheets %} + <link rel="stylesheet" href="{{ asset('builds/app.css') }}"> +{% endblock %} Extract css into a separated file 10 . 3
  48. Split vendors with CommonChunksPlugin module.exports = { entry: { vendor: [ 'jquery', 'bootstrap-sass' ] }, output: { filename: '[name].js' }, plugins: [ new webpack.optimize.CommonsChunkPlugin({ name: 'vendor' }) ] }; {# app/Resources/views/base.html.twig #} {% block javascripts %} + <script src="{{ asset('builds/vendor.js') }}"></script> <script src="{{ asset('builds/app.js') }}"></script> {% endblock %} 10 . 4
  49. Minify with UglifyJs Supported by Webpack out of the box ! module.exports = { plugins: [ + new webpack.optimize.UglifyJsPlugin({ + beautify: false, + compress: { + screw_ie8: true, + warnings: false + }, + mangle: { + screw_ie8: true, + keep_fnames: true + }, + comments: false + }) ] }; 10 . 5
  50. Minify our styles { test: /.scss$/, use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: [ { loader: 'css-loader', options: { // CSS Nano configuration minimize: { discardComments: { removeAll: true }, core: true, minifyFontValues: true } } }, 'sass-loader' ] }) } 10 . 6
  51. Long term caching 10 . 7
  52. const WebpackManifestPlugin = require('webpack-manifest-plugin'); module.exports = { output: { filename: '[name].[chunkhash].js' }, plugins: [ new WebpackManifestPlugin({ fileName: 'manifest.json' }) ] }; $ npm install --save-dev webpack-manifest-plugin Install Webpack Manifest plugin 10 . 8
  53. https://github.com/symfony/symfony/pull/22046 Symfony 3.3 10 . 9
  54. // app/config/config_prod.yml framework: assets: json_manifest_path: '%kernel.root_dir%/../web/builds/manifest.json' 10 . 10
  55. Tips 11 . 1
  56. Tree shaking only include code in your bundle that is being used https://blog.engineyard.com/2016/tree-shaking 11 . 2
  57. Env vars EnvironmentPlugin : reference env vars through process.env DefinePlugin : global constants 11 . 3
  58. OptimizeJs Plugin optimize a JavaScript file for faster initial execution and parsing https://github.com/vigneshshanmugam/optimize-js-plugin 11 . 4
  59. DedupePlugin Deduplicate common files https://medium.com/@rajaraodv/two-quick-ways-to- reduce-react-apps-size-in-production-82226605771a 11 . 5
  60. Thank you ! https://joind.in/talk/94c36 https://github.com/alOneh/sf-live-2017-symfony-webpack 12
  61. Questions ? 13
Advertisement