Introducing Webpack Encore for Asset Management
June 13, 2017 • Published by Ryan Weaver
If you write front end code, this might sound familiar:
Ryan is excited to write a killer front end (maybe with React or Vue.js!). But first, he needs to install Webpack... and configure loaders. And Ryan definitely wants to use SASS, so he should configure
sass-loader
and setupExtractTextWebpackPlugin
to output CSS files. Oh, and don't forget to output source maps! And is everything being minified in production? Wow, that's a lot of setup!
For everyone that has hit this barrier, I'm very excited to show you something we've been working on for the last few months: Webpack Encore.
Encore gives you powerful CSS and JavaScript processing, combination, minification and a lot more, wrapped up in a simple API that's built on an industry-standard tool (Webpack). Write some expressive JavaScript, then let Webpack do the rest:
// webpack.config.js var Encore = require('@symfony/webpack-encore'); Encore .setOutputPath('web/build/') .setPublicPath('/build') // read main.js -> output as web/build/app.js .addEntry('app', './assets/js/main.js') // read global.scss -> output as web/build/global.css .addStyleEntry('global', './assets/css/global.scss') // enable features! .enableSassLoader() .autoProvidejQuery() .enableReactPreset() .enableSourceMaps(!Encore.isProduction()) .enableVersioning() // hashed filenames (e.g. main.abc123.js) ; module.exports = Encore.getWebpackConfig();
Encore is inspired by Webpacker and Mix, but stays in the spirit of Webpack: using its features, concepts and naming conventions for a familiar feel. It aims to solve the most common Webpack use cases. It works great with Symfony, but can be used in any app, in any language.
You can already use Encore today: Webpack Encore Docs! It does not (yet) have a stable 1.0 release, but the CHANGELOG will be updated for each new version. See a feature that's missing or find a bug? Help move this community project forward on GitHub symfony/webpack-encore.
Why Webpack Encore?
When you use Symfony, we want to make it simple to leverage the best tools from beginning to end. That's why, for assets, Symfony 2.0 came with Assetic: a pure PHP library. In 2011, this made sense. In 2017, life is much different.
Now, the best-practice tools for processing assets are written in Node.js. And Webpack is a clear leader. Since we want to recommend the highest quality tools, we recommend Webpack.
There's just one problem: configuring Webpack is not simple. So, Encore was born:
as a thin tool that help make the best library (Webpack) accessible to everyone.
Encore generates the standard webpack.config.js
file, uses native Webpack features
and stays consistent with its language and concepts. Instead of creating "yet another library",
we embrace Webpack.
Try it out and help us make front-end setup powerful, but accessible to everyone.
Thanks to community members stof, javiereguiluz, tucksaun, lyrixx and others who helped review and bootstrap the original version of Encore.
Encore inside Symfony
While Encore will work great in any project, it works especially well in Symfony, thanks to the JSON manifest strategy that's new in Symfony 3.3. By adding one new line to config.yml, you can add versioning and configure a CDN in Encore without changing anything else in your app.
Help the Symfony project!
As with any Open-Source project, contributing code or documentation is the most common way to help, but we also have a wide range of sponsoring opportunities.
Comments are closed.
To ensure that comments stay relevant, they are closed for old posts.
But, really, there is still room to grow.
What I mean by this is that is that I just started integrating this into a test project, but I have some js files from third party bundles which have functions available in global variables, but after those js files are included with Webpack, those global variables are no longer available since the file was included as a 'module' and there is no way for me to edit the js files and export the variables so I can use them in my app.
How should someone do this?I am a back end developer and I have never use front end tools before and I use CDNs for the most used libraries (bootstrap, jquery etc) and do not need the scss and other functionality, just combining and minfying of assets.I haved used Assetic before and with that the logic of my application remained the same and I kind of hoped this will do the same...
1) This is Webpack: https://github.com/alOneh/sf-live-2017-symfony-webpack/blob/master/webpack.config.js
2) This is Webpack Encore: https://github.com/symfony/symfony-demo/blob/master/webpack.config.js
@Daniel Can you open an issue (https://github.com/symfony/webpack-encore) and tell me more about this? I'm not sure auto-discovering JS from different bundles is a good idea... but I also don't know what you want to accomplish ;)
> You need to define full file paths of all your bundles assets explicitly configured through Encore to get what you had out of the box before (with Assetic)? I don't see what the upgrade here is
@Michael There *is* a discussion about the bundle paths topic: https://github.com/symfony/webpack-encore/issues/5. But, there IS a big advantage to webpack/Encore: module loading. Once you require a .js file (for example, a main.js that lives in a bundle), *that* file can require whatever other files it needs. For the first time, your JS files can require their dependencies. This is different from Assetic: if you added a new .js file that was needed by another .js file, you needed to remember to go include the new .js file in your Assetic javascripts tag. When you try the new approach, it will feel much more powerful :). You can even include CSS dependencies from a JS file.
> What about a way to combine and minify multiple css/js files into one but not use Webpack modules? ... I have some js files from third party bundles which have functions available in global variables, but after those js files are included with Webpack, those global variables are no longer available since the file was included as a 'module' ...
@Rareș This *is* one of the real-world complications: legacy code (i.e. code not written to support being loaded as a module) takes some work to integrate. First, from experience, I can tell you that this is happening less and less. Over time, more and more libraries are being written correctly. But, it does still happen. To fix this, you have a few options, many are described here: https://webpack.js.org/guides/shimming/. You can access the ProvidePlugin in Encore via autoProvideVariables() (http://symfony.com/doc/current/frontend/encore/legacy-apps.html).
I'd love for you to open an issue (https://github.com/symfony/webpack-encore) with more info - I'm sure we can improve the docs to help people.
I basically have the same concern as the participants of the dicussion in issue #5, so no need to open a new one :-)
Thank you so much for this.
I see there is already an open issue for Vue support, cool :)
Thanks!
But this is a big change for those used to Assetic and a blog post or documentation page that would compare the differences in philosophy working with assetic and with webpack would be great.
With uses cases for instance in a multi-bundle environment, because, while Symfony 4 will remove bundles, old projects will still have them for a while, not easy to remove in some cases.
Thanks for the work !
Building additional bulk to proxy existing tools because they are "so hard".
So Symfony is going to maintain additional sub project for which there are already clear standards.
I really don't like the idea at all, there tons of existing projects which work fine out of the box.
Then there is the fact that if you where going to use the best of the best a simple yeoman generator would have been the best choice for many reasons.
What I really don't understand is that not to long ago there was announcement to drop HHVM. While reading the post as of why I could semi understand, but now Symfony is going to add new sub project in hole differed language.
Thank you for the feedback.If anyone else has this problem, it can be resolved by using the "script-loader" and the "expose-loader" on files contain configuration variables and the "imports-loader" on files which should use those variables.
@Stéphane That's a great idea. I'm going to see if I can add an article to the docs :)
> This feels exactly the same as the Symfony installer. Building additional bulk to proxy existing tools because they are "so hard".
@Doni Alejandro Ramirez Soto
That's a fair opinion, but using webpack for the first time is *quite* complex. It would have saved me many hours if it had existed before.
> Then there is the fact that if you where going to use the best of the best a simple yeoman generator would have been the best choice for many reasons
@Doni Alejandro Ramirez Soto
Definitely another valid opinion :). We didn't want to add "yet another solution", but, in practice, doing nothing is very unhelpful for users (most of the feedback so far has been "Finally, what took you so long?"). That's why we created something that works really well... but is also as thin as possible. Basically, we want to re-use as much as possible out there... and just "tie it together" so that it works and makes sense to Symfony users. If we can use more stuff that's standard and make Encore thinner and thinner, awesome :).
> What I really don't understand is that not to long ago there was announcement to drop HHVM ... but now Symfony is going to add new sub project in whole differed language.
@Doni Alejandro Ramirez Soto
I can see your point, but these are 2 different situations. Fabien decided to remove HHVM support because he asked the community, and very few people were using it. Everything we support has a cost, and we need to weight that against the benefit. Encore has a much bigger benefit than HHVM. Dropping HHVM and adding Encore is a big net win.
Cheers!
@Ryan Weaver
That is why I feel that choosing yeoman would been best choice, We could easily enjoy all other generators that are already made by the community and would allow for better customization while still maintain the standards. Which help people allot since they can use all tutorials and information already available.
> Encore has a much bigger benefit than HHVM. Dropping HHVM and adding Encore is a big net win.
@Ryan Weaver
Valid point I totally understand the reason why Symfony dropped HHVM. Let met explain my point bit better. Javascript is a highly volatile platform and seeing how it is moving I would say your taking more on than you probably want.
I made a small test project with encore to test out the points where I know this type of generators break down most of the time. On windows the the example given in documentation does not work due path problems. Then I tried using a differed css framework and had problems understanding where to add customization arguments for sass for example include paths which are required if you want to use Foundation.
Thank you for the respons!
> That is why I feel that choosing yeoman would been best choice
We'll just have to agree to disagree on this conclusion - but I think your arguments are valid :). Obviously, anyone can still use something like Yeoman. For people that aren't well-versed in the Node.js world, Encore will still be easier.
> I tried using a differed css framework and had problems understanding where to add customization arguments for sass for example
I would love if you could open an issue about explain your situation: https://github.com/symfony/webpack-encore. There are almost definitely some ways we can improve the docs (which is a collective win for everyone) and parts of Encore were purposefully not made extensible out-of-the box (again, the idea is to be small/thin, and grow cautiously - at some point, if you want to do really crazy things, you can/should use Webpack directly). What you're trying to do sounds very reasonable, so we should make sure it's possible and documented :).
> Thank you for the response!
Thank you!
My interpretation is probably incorrect, but to me it appears as if the primary reason for this change was because "Webpack is the latest fad". It would be very helpful if you could somewhere explain the benefits of Webpack Encore over Assetic, so that we can assess whether it makes financial sense to adopt the change. Assetic still works, and works very well, so why spend time and money to change? In what ways are Webpack so far superior to Assetic?
"Encore is inspired by Webpacker and Mix, but stays in the spirit of Webpack: using its features, concepts and naming conventions for a familiar feel. It aims to solve the most common Webpack use cases."
Just to note, there are solutions integrating webpack tighter with symfony, so that you wouldn't need to configure each and every entrypoint inside separate config file, also adds additional features. For example [MabaWebpackBundle](https://github.com/mariusbalcytis/webpack-bundle), which supports Symfony 2.7 and above.
https://github.com/gardenhq/o
https://greenhouse.gardenhq.io/o/ (docs)
Does bundling, transpiling, minifying all in-browser with no node installation required (and therefore no webpack or multitude of dependencies, plugins and configuration). All you need is a javascript enabled browser.
Also works using unpkg.com so no npm needed either (you can still use npm/yarn if that floats your boat also).
As well as being able to bundle and minify `require` based js, you can also use yaml files to plumb your javascript together using symfony-like dependency injection.
webpack was unfortunately built on top of some OSX specific libraries. Example:
webpack dev ⊋ webpack-dev-server ⊋ chokidar ⊋ fsevents
chokidar was intended primarily for OSX, and fsevents is Exclusively OSX.
This makes for some complications when installing/running on anything other OS.
Also, it could be great to insert a (thin) word about Encore in asset best practices page : https://symfony.com/doc/current/best_practices/web-assets.html