When I first started with Aurelia, I created applications using a combination of the Skeleton Navigation project, and JSPM. I found that JSPM was a convenient way to get started, because for a simple project at DEV time I could get by without needing much build tooling. More recently I switched to requireJS. This was primarily because it has great performance, and I found that in combination with the aurelia-cli I didn’t really need to think about the build tooling, as the cli does most of the heavy lifting for you. Adding third party projects using this tool chain has also been fairly simple for the most part, as you can generally follow the same pattern, and the au install cli command makes this even easier.
My question is, with webpack now also supported by the CLI, I’m interested to hear from people as to which build toolchain they are using and whether there are pros and cons of a particular setup, other whether it’s down to personal preference for the most part. The main benefits touted for webpack appear to be related to hot module reloading, and the fact that requireJS is “outdated”.
I often see people picking between SystemJS/JSPM or Webpack, not RequireJS. Between those, Webpack has a reputatation of having a lot of ‘hip’ features (like hot module reloading, although IIRC there’s ways to do that with SystemJS as well), while SystemJS moves slowly. Particularly the breaking changes in SystemJS 0.19 -> 0.20 didn’t work in its favour.
But with the loader spec finally starting to get implemented, perhaps in the not so distant future we’ll have the browsers doing the loading directly. I’m guessing SystemJS builds will be in a better position to be taking advantage of this than Webpack, though I can’t speak from experience.
I’m currently working on projects where we set up the JSPM build during the Aurelia beta, when Webpack wasn’t supported yet. I’ve never seen any convoncing reason to switch over.
I’m currently working on projects using the aurelia-cli and requirejs, I’ve found it has the fewest hurdles and the most flexibility. With webpack I ran into issues with loaders or certain configuration, I couldn’t get my head around the way it’s setup or how to easily add to it.
I used to think JSPM is a better choice mainly because it’s spec driven. But the truth is, with JSPM you sacrifice performance (mobile especially). Plus, it’s being reworked (again) at the moment. And it’s a one man show… Who knows what will come out of this. WebPack might be harder to configure initially but it’s a set-and-forget thing. Gist - use vanilla webpack, no CLI.
I can definitely see the advantages of working this way, though I do really like the simplicity of working with the CLI, particularly since it generates a pretty bare-bones type project out of the box.
Depending on your environment… If VS2017, I would run dotnet new aurelia. If plain web project, I would start with plain webpack config and install npm modules myself. Or maybe grab webpack config files from aforementioned template.
We have tried almost all the work flows mentioned here, I want to share our experience:
cli (require, system, webpack)
Clearly this is the flow with the smallest learning curve. So it’s easy to start with, but haves a few caveats, mainly watching is a very slow process (as by default it rebuilds all your bundles, and because it uses amodo trace for tracing module dependencies that needs to reparse all your modules every time), in big projects it can be unusable. Also as its an abstraction of all three supported bundlers, you cannot leverage easily advanced functionalities of each. And finally is hard to customize while keeping up to date with cli version changes.
Webpack and NPM
This is at the moment the most performant of all three, however you have to be careful, specially use separated webpack runs and DllPlugin to keep your watch fast, and keep in mind it static nature, so you have to help it when doing dynamic loading, and sometimes (as in our case) is not possible to give it enough information at build time to make webpack aware of the loading pattern. We found in large projects that hot reloading is unstable, and crashes frequently, slowing down you while debugging
Systemjs and NPM
This is our current approach, we use aurelia builder to help with bundling, and we crafted our bundle configs separating those that do not change from our main bundle, watching is done with gulp, and it’s fast if you take the time to polish it. However as said here, systemjs can be somewhat slow in mobiles, even with deps maps created and switching systemjs to production build on release. However it supports nicely all module formats around the web, with almost no weird configuration, and does dynamic loading as easy as it can be. We have also some special cases where we have multiple instances of systemjs isolating some user created script loading in our app, that would almost impossible with webpack (it could be done with require and contexts).
We tried also not bundling at all, but we found HTTP/2 features needed, like parallel loading and push state, not consistent enough between browsers and server implementations, and some implementations missing some important characteristics. We also did not see a big enough improvement in loading speeds to make the switch in production. We would love to see this maturing and spreading enough to be our main approach, there is no faster way to develop than having no bundling and bloated build process and tools.
@ielcoro That’s a great overview of the different processes, I’m currently working on 2 products that use jspm and would be interested in comparing the performance of webpack especially as both you and @MaximBalaganskiy mentioned jspm can lack performance on mobile. Did you switch build processes for a project? If so was it easy?
@AquilaSands yes we switched multiple ongoing projects and it totally depends on how complex your project is, how tied it is to the previous loader features and what dependecies you have.
For example, if you are leveraging systemjs dynamic loading capabilities you have to be carefoul and see if you can go back to static load or have a structure that can help webpack detect the dynamic load at build time, like context replacement: https://webpack.js.org/plugins/context-replacement-plugin/
You should be careful and tske your time to analize your dependencies, specially as jspm has been magically hiding, module formats, and exports and imports from you, with webpack you will need to configure them.
From there you could face some minor import issues, like plugin syntax order (text!url vs url!text) and loader configuration.
Finally try to not change module names as much as possible to make your current imports compatible.
In our migrations, a small project has taken 1 day of work, while a big project with lot of dependencies and dynamic loading 2-3 weeks. Middle sized projects should be done in a week or so.
I’m a bit curious about this since I don’t have the same experience; only relevant modules are re-traced and only changed bundles are updated. While my current project isn’t that big (about 1500 files), it’s not small either, and it’s typically rebuilt within a couple of seconds when I’m --watching it. How recent are these experiences of yours?
@jwx maybe, the last version I tried was 0.30.1, from June 28.
As for the bundling I’m sure that it does watch and create only needed bundles when using the cli with Systemjs, however when using it with require or webpack my experience is the cli creates all of them on watch.
@ielcoro I’m using requirejs and I can assure you and everybody else that only the relevant files are retraced and the relevant bundles recreated when I’m --watching. I would not have a build time of 1-3 seconds if it wasn’t.
We have about 6 applications (both large and small) within our company using aurelia. Most are using either the jspm/systemjs or the original CLI. With my most recent greenfield app, I opted for webpack since that seems to be the favored method now days. I can say for sure it was a very good move on my part. It has completely diminished the maintenance and dealing with extra json files to manage client-side packages. It has also made it more flexible with all available webpack plugins and loaders. I can customize the heck out of it to make it lean and clean, including code splitting for our larger apps. I’d highly recommend looking into using webpack if your in the market to change out the build functionality.
In regards to aurelia, We could not be more happy with our decision to go with this framework for all our enterprise apps. I wish we could say that we use aurelia but alas, as with many enterprise companies, we cannot. We have many “generalist” developers who’s skills usually hover around .net MVC and jQuery. It was a breeze for ALL of them to jump right into aurelia with it’s “convention over configuration”. Love it!!!
I started with the aurelia CLI and created a webpack version. I ended up just using webpack’s cmd line rather than aurelia cli (au run) so that I would only need to manage one config (webpack.config) and eliminate aurelia.json. Not saying that is the way to go but it worked well for us and was just easier to customize.