As you might have already seen: Webpack 4 beta is out
This beta release is pretty much stable and will be released as such in a month.
As promised, we will wait a month from today before releasing webpack 4 stable
The new release offers a lot simpler configuration and better compression. This should reduce the amount of code in encore and yield better results in production.
This should reduce the amount of code in encore
That would be the case if we drop Webpack 2 and 3 compatibility... which is probably ok for new projects but would prevent existing projects from updating Encore easily.
Making it work with both Webpack 2, 3 and 4 may not be easy though based on some of the changes listed on this page: https://github.com/webpack/webpack/issues/6357
It is released today
https://medium.com/webpack/webpack-4-released-today-6cdb994702d4
waiting for the update :fireworks:
Yep! We just need someone to create a PR :). Also, some libs we depend on may not yet be compat with 4, but we鈥檒l find out with a PR. Volunteers? It鈥檒l get done faster that way ;)
@weaverryan What do you need in that PR? I started upgrading Webpack version and resolving module dependencies errors, ran yarn test (no errors in the output), but what can I do more to help on this?
Really looking forward to use Encore with Webpack 4 馃憤
Same question here @weaverryan - what do you expect in the PR? As I've tested only extract-text-plugin breaks 4.0 support.
@andrewtch For the moment, I fixed extract-text-plugin breaking by fixing its version to "extract-text-webpack-plugin": "4.0.0-beta.0".
Hi @enguerranws,
I'd say that if you have something that works with Webpack 4 you can already create a PR for it.
That'll help to see if something more is needed :)
I'm really interested to see how you handled some of the other things that changed in this version (such as the new mode option and the removal of CommonsChunkPlugin and UglifyJsPlugin).
Does your version still works with Webpack 3 by the way ? (even though I'm not sure we should keep supporting it, WDYT @weaverryan ?)
Well, the new mode option maps directly to our concept of Encore.isProduction(), so this is probably the easiest part of the migration.
I would be totally fine with requiring webpack 4 for a new version of Encore, assuming it is a semver major (which would be the case anyway as we are pre-1.0). Maintaining both support for version 3 and 4 in parallel would probably be a nightmare, especially given that the npm ecosystem does not resolve a common versions of deps (so we might end up having webpack 4 installed as a dependency of Encore and webpack 3 installed as a dependency of something else, or the opposite...). It might create more issues than what it solves. People needing to stay on Webpack 3 would have to do some special things anyway to force their whole no_modules to stay on v3 once Encore supports v4. It might be much simpler to tell them to stay on the previous version of Encore, and to upgrade when their other plugins are compatible with webpack 4.
for the CSS, we should migrate to https://github.com/webpack-contrib/mini-css-extract-plugin for Webpack 4
Well, the new mode option maps directly to our concept of Encore.isProduction()
@stof From my understanding it is used to enable some loaders/plugins presets (source maps, minification, etc...). It could make some things from the Encore API a bit awkward since we also have methods that directly control these kind of things (especially enableSourceMaps).
That's why I was wondering if it wouldn't be better to use mode: "none" and keep handling everything ourselves.
Initially, I think Stof has a good point about creating a new version of Encore that only supports Webpack 4. Most users don鈥檛 care about the underlying version anyways.
At this point, we just need to create a PR and start hacking on it. It鈥檚 been on my list (probably you to @Lyrkan), just haven鈥檛 gotten to it yet.
But I would love to do this soon and be progressive :).
Well, the goal of Encore is to make webpack easier to use. If webpack 4 gives us sensible defaults for the dev and prod modes, we may want to deprecate our own APIs enabling the sourcemaps for instance, and relying on the webpack decision (that even means less code to maintain for us).
Webpack 4 introduced modes to make their configuration easier, which is also what we want to achieve in Encore. It totally makes sense to have some of our APIs becoming obsolete thanks to the underlying work.
Initially, I think Stof has a good point about creating a new version of Encore that only supports Webpack 4. Most users don鈥檛 care about the underlying version anyways.
I totally agree on that. Since @Lyrkan pointed that up, I'm thinking of cases and projects that would need a Webpack 4 "Webpack 3 compatible". Didn't find it out.
I was thinking of cases and projects that would need a Webpack 4 "Webpack 3 compatible". Didn't find it out.
It could be needed if someone wants to use Encore with a Webpack plugin (for instance by using Encore.addPlugin()) that doesn't support Webpack 3 yet.
@Lyrkan for such case, they could use an older release of Encore. It would be much more easier than fighting with npm or yarn to make them use older versions of the Encore deps.
and yes, such resolution is much harder to achieve in the JS world than with composer, because of the fact that composer resolves a single version of each package (so you can influence them from the root), while npm/yarn are able to use different versions of the same package in different places in the tree (thanks to the fact that nothing is global in JS modules, unlike in PHP where class definitions are global)
Any update on that issue? Really looking forward to use Encore again (I temporary switched to a pure - not Encore - Webpack 4 build).
Note that while starting to use webpack in my project (still a WIP for now), I actually decided to use Webpack 4 instead of using Encore. And I found it quite easy to use (their new mode handles most things automatically for me). The most complex part of my config is related to a need that Encore not solve for me anyway.
@stof I'm curious - did you dod anything special in your setup related to having a "common chunk" (the plugin is gone of course, which is why I'm asking). That's one of the big changes that I haven't looked into yet.
No work has been done on this yet - need to find some time :)
@stof same here, using a pure Webpack 4 build is quite easy, the only thing I'm missing is the Webpack HRM that I'm not able to enable.
@weaverryan Webpack 4 defines splitting cache groups (the new system used by the SplitChunksPlugin replacing CommonsChunkPlugin) automatically for node_modules. By default, it does it only for dynamic chunks (places where you use import() for code splitting), as webpack controls this code to be able to import multiple chunks. This is the code needed to use the builtin splitting also for the main entry points (for which you have to take care of loading the JS files in your HTML):
module.exports = {
entry: {
'js/app': './assets/js/app.js'
},
output: {
filename: '[name].js',
path: 'public/build/',
publicPath: '/build/'
},
plugins: [
// TODO add a ManifestPlugin
],
optimization: {
runtimeChunk: 'single', // Extract the runtime to its own chunk
splitChunks: {
chunks: 'all' // Split all chunks, not only dynamic ones
}
}
}
This will create the following files in public/js:
runtime.js: equivalent of Encore's manifest.js fileapp.js: your own codevendors~app.js: vendor files for the app entry point, if there are enough (webpack has a min size condition to extract it). Note that the ~ delimiter is configurable if you prefer something else.this is of course missing the loaders rules in case you want to customize them
Actually, runtimeChunk should be manifest if you want to match the name used in Encore. When using single, it will create a file named runtime.js, not manifest.js (which is a better name btw, as this is not about a manifest but about the webpack runtime)
Thanks for the details! What I鈥檓 trying to determine is the best strategy going forward. Currently, we allow people to create their single commons entry and put whatever they choose into it explicitly. But, that seems contrary to the Webpack 4 way, where it uses sensible rules to figure things out.
Part of the problem is that if we want to split all chunks, then the user will need some extra tool on the server side to know what script tags are needed dynamically. Or, we could only do async out of the box. Or we could use the new system to re-create our old setup (where you explicitly choose one shared/commons entry). As usual, backend devs have a slightly different use case (multi entry apps commonly, inability to use the HtmlWebpackPlugin), so the best path isn鈥檛 clear.
In progress - #324 :)
@weaverryan What we could have is a plugin dumping a JSON file mapping an entrypoint to the list of chunks it includes (i.e. storing the info that Webpack has about whether the vendors chunk was created). This would allow to have a small Symfony bundle getting this list.
Note that building the old behavior is also possible by configuring some cacheGroups for the splitChunks plugin (and probably disabling the builtin ones).
I'm excited to see webpack 4 being supported. I really like the idea around encore and hope to see it supporting webpack 4 really soon. :grin:
@stof this sounds great. BTW this is exactly what I did recently using the webpack-manifest-plugin generate hook (not in a symfony project though).
@iwyg is your code public ?
@stof sadly no, but I could provide the generator hook if you're interested. This will produce a manifest.json like
{
"app.js": {
"path": "/app/dist/app.0bd544445e6ba035f61d.js",
"dependencies": [
{
"name": "runtime~app",
"files": {
"js": [
"/app/dist/runtime~app.d41d8cd98f00b204e980.js"
]
}
},
{
"name": "vendors~app",
"files": {
"js": [
"/app/dist/vendors~app.32c57c5163ee99487c3d.js"
]
}
},
{
"name": "app",
"files": {
"js": [
"/app/dist/app.0bd544445e6ba035f61d.js"
],
"css": [
"/app/dist/app.0bd544445e6ba035f61d.css"
]
}
}
]
}
}
You can check the linked PR. Currently, I鈥檓 dumping a new entrypoints.json file. It鈥檚 a bit simpler, so I鈥檇 appreciate it if you see any shortcoming.
I couldn't see it in the comments here, but we should look into the issues in webpack 4 with uglify-es. It has a couple of big issues, and seems to unsupported. One of my colleagues pointed me on the fact that the way uglify-es works:
When using React, for example, it create a new Component class at each render which will force React to unmount and remount your component.
Since linked PR merged - this one could be closed?
When will this be tagged/released? @seyfer : I guess they'll close this issue when it'll be done
Hi @weaverryan, thank you for all the work on this. I see #324 has been merged and the only thing preventing this from being released is the doc which needs to be updated
Document use of browserslist + update Encore recipe
How can we help on that ?
Any updates?
Version 0.21.0 has been released :)
Nice, thank you for that, we're all eager to try it out.
Since the changelog mentions a few [BC BREAK], shouldn't the major version have changed (i.e. 1.0.0) ?
@MrMitch This shouldn't be an issue for now (= before 1.0.0 is tagged) since, for instance, having ^0.20.0 in your package.json file won't allow 0.21.0 to be installed. This behavior is explained on this page:
Caret Ranges ^1.2.3 ^0.2.5 ^0.0.4
Allows changes that do not modify the left-most non-zero digit in the [major, minor, patch] tuple.
@Lyrkan great news, thanks a lot!
Most helpful comment
Well, the goal of Encore is to make webpack easier to use. If webpack 4 gives us sensible defaults for the dev and prod modes, we may want to deprecate our own APIs enabling the sourcemaps for instance, and relying on the webpack decision (that even means less code to maintain for us).
Webpack 4 introduced modes to make their configuration easier, which is also what we want to achieve in Encore. It totally makes sense to have some of our APIs becoming obsolete thanks to the underlying work.