Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Moving your Angular Application from SystemJS to Webpack

DZone's Guide to

Moving your Angular Application from SystemJS to Webpack

In this article, we take a blow-by-blow look at moving your Angular application from a JavaScript framework to a more framework.

· Web Dev Zone
Free Resource

Learn how to build modern digital experience apps with Crafter CMS. Download this eBook now. Brought to you in partnership with Crafter Software

In this blog post, I want to show you how you can move from an existing Angular application using SystemJS to an application with webpack.

Imagine the following application:

app
├── // modules, components and so on
├── app.component.ts
├── app.component.html
├── app.module.ts
└── main.ts
...
systemjs.config.js
tsconfig.json
tslint.json
...

Since we want to get away from SystemJS, here we will first introduce a webpack.config.js which holds your configuration and which can handle all your files.

But before we do, please install webpack and the webpack-dev-server first:

npm install webpack-dev-server webpack --save-dev

So now we can add a webpack.config.js. This is the file webpack is searching per default.

app
├── // modules, components and so on
├── app.component.ts
├── app.component.html
├── app.module.ts
└── main.ts
...
systemjs.config.js
webpack.config.js // <---
tsconfig.json
tslint.json
...

Of course, you have to modify the config so that it fits your application. A structure of this could be useful:

module.exports = {

    entry: {
        // Here all your entry points from 
        // your application are mentioned
    },

    output: {
        // Here we can specify the output
    },

    resolve: {
        extensions: // mention the extensions webpack should take care of
    },

    module: {
        rules: [
            // tell webpack HOW to react when a file is included in your application
        ]
    },

    plugins: [
// finetune the behaviour of specific plugins
    ]
}; 

You can see an example here webpack.dev.js

Adding Polyfills

To have your Angular application ready for handling polyfills, you have to introduce another file polyfills.ts where you import all the polyfills your application needs.

app
├── // modules, components and so on
├── app.component.ts
├── app.component.html
├── app.module.ts
├── polyfills.ts // <---
└── main.ts
...
systemjs.config.js
webpack.config.js
tsconfig.json
tslint.json
...

The file could look like this:

import 'ie-shim'; // Internet Explorer 9 support.

import 'core-js/es6/symbol';
import 'core-js/es6/object';
import 'core-js/es6/function';
import 'core-js/es6/parse-int';
import 'core-js/es6/parse-float';
import 'core-js/es6/number';
import 'core-js/es6/math';
import 'core-js/es6/string';
import 'core-js/es6/date';
import 'core-js/es6/array';
import 'core-js/es6/regexp';
import 'core-js/es6/map';
import 'core-js/es6/set';
import 'core-js/es6/weak-map';
import 'core-js/es6/weak-set';
import 'core-js/es6/typed';
import 'core-js/es6/reflect';
import 'core-js/es7/reflect';

import 'zone.js/dist/zone';

Notice that when you import data, you also have to install it via npm, which also should be reflected in your package.json.

Adding Third-Party Dependencies

If you have to include external libs, like jQuery or Bootstrap, you can manage them in a separate file called, vendor.ts. After installing them via npm you can consume them here:

app
├── // modules, components and so on
├── app.component.ts
├── app.component.html
├── app.module.ts
├── polyfills.ts
├── vendor.ts // <---
└── main.ts
...
systemjs.config.js
webpack.config.js
tsconfig.json
tslint.json
...

Which could look like this:

import 'jquery/dist/jquery';
import 'bootstrap/dist/js/bootstrap';

import 'bootstrap/dist/css/bootstrap.css';
import '../css/custom.css';

// import everything else here!!!

You should include all your custom files in the above code.

Delete systemjs.config.js

You can now delete the systemjs.config.js because you do not need it anymore.

app
├── // modules, components and so on
├── app.component.ts
├── app.component.html
├── app.module.ts
├── polyfills.ts
├── vendor.ts
└── main.ts
...
webpack.config.js
tsconfig.json
tslint.json
...

Entry Points

Note that you now have three entry points for your application:main.tsvendor.ts and polyfills.ts. Due to the fact that webpack is reading all your files, and going through all imports importing what is included, you have the ability to:

Give your webpack config all three entry points like this:

module.exports = {
    entry: {
        'app': './app/main.ts',
        'vendor': './app/vendor.ts',
        'polyfills': './app/polyfills.ts',
    },

Import the two files in your main.ts like:

import './polyfills';
import './vendor';

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app.module';

platformBrowserDynamic().bootstrapModule(AppModule);

Then, in your webpack.config.ts you only need one entry point:

module.exports = {
    entry: {
        'app': './app/main.ts'
    },

Asking for the Environment (dev/prod)

We will set the environment from the outside later. To consume it in your application we can simply ask for a variable like this:

var environment = (process.env.NODE_ENV || "development").trim(); if (environment === "development") { // ... } else { // ... }

With this code, you can apply multiple ways of generating your output based on the given environment asking for the variable “NODE_ENV” which we will set up later in our scripts.

You can see an example here webpack.config.js

Triggering it From the npm Scripts

Now that we introduced webpack, we can add the commands to our package.json like this:

var environment = (process.env.NODE_ENV || "development").trim();

if (environment === "development") {
    // ...
} else {
    // ...
}

Here we are setting the environment variable accordingly, and start webpack with the webpack command.

When you run npm start and have the correct configuration in your webpack and package.json, a browser should open up displaying your page while reloading if you change something.

Feel free to comment if I missed something.

Crafter is a modern CMS platform for building modern websites and content-rich digital experiences. Download this eBook now. Brought to you in partnership with Crafter Software.

Topics:
angular ,webpack ,web dev

Published at DZone with permission of Fabian Gosebrink, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}