preboot / angular-webpack

A complete, yet simple, starter for Angular v2+ using webpack
MIT License
1.29k stars 556 forks source link

App works without all angular and rxjs vendor dependencies #287

Closed mii9000 closed 7 years ago

mii9000 commented 7 years ago

Seems to work without Angular and Rxjs deps: https://github.com/preboot/angular2-webpack/blob/master/src/vendor.ts#L2-L10

Why and how is that?

Foxandxss commented 7 years ago

The vendor.ts file doesn't say "Hey, those are the dependencies available on this application, list them here to make them work". That is solely the work of the package.json file.

The idea behind the vendor.ts is different. When you build your application, you get 3 bundles:

app.js - Your entire application code, but without any third vendor library (AKA vendors) vendor.js - Only third party code, say angular, rxjs, bootstrap, jquery, lodash... polyfills.js - Angular polyfills like zone.js, reflect-metadata, es6-shim... (needed to a different file like this because Angular needs its polyfills to run as soon as possible).

So the idea is that you have one file with application data and one file with vendor data. If you change your application code and deploy, only the app.js file will change so all your users will need to download the app.js again and not the vendor.js because that didn't change at all.

So the idea is to split your application into parts (app code - vendor) so if only one changes, you forces the user to download only part of it. You don't want your users to download a big big vendor.js because you updated a header color.

Now, how does this work? In simple lines, what webpack does is: Every imported library that appears both in your app bundle and vendor bundle will be removed.

So if in your app bundle (AKA any code in YOUR application) you do:

import { Component } from '@angular/core';

And then in your vendor you do:

import '@angular/core'

Webpack is going to say: Aha, so @angular/core is being used in both bundles, then we are going to delete it from the app one and leave it on the vendor one.

If you do in app bundle:

import { AppComponent } from './app.component';

Webpack will say, ok, this bundle is loading something from 'app.component' but I don't see the user importing anything from that file in vendor.ts. That means that it is not a vendor so I won't remove that from the app bundle.

So in short, vendor.ts works like a registry. Every import you list in there is to say to webpack: Everything you see in here? I don't want you to add them to the app bundle.

So by default, your app.js bundle won't contain any angular 2 nor rxjs code. If you delete all those lines, your app bundle will contain everything in it (which is fine as well, just a different technique).

akrueger commented 7 years ago

Great explanation!