1 of 64

Angular+Webpack<3

ng-conf 2016

2 of 64

About Me

3 of 64

UX Developer @ Mutual of Omaha

4 of 64

Home of the Notoriously controversial license plate DRAFT.

5 of 64

Where most people think Nebraska is...

6 of 64

Where Nebraska really is...

THATS WHERE LINCOLN, NE IS!!

7 of 64

Background

Former Tech Support Rep. gone rogue turned Software Engineer / Web Developer who got tired of never being able to really help the customer he served.

Written in...

Languages: Ruby, Objective-C, Swift, Javascript.

Also…

Woodworker, chicken farmer, IoT.

8 of 64

@TheLarkInn

“OMG! Just watched @TheLarkInn talk about #Webpack and #Angular2 at @ngconf. Going to #Webpack all things Angular!! <insert selfie with me here>”

9 of 64

JavaScript Modules

10 of 64

Qualities of JavaScript Modules:

Don’t pollute global scope

Reusable

Encapsulated

Organized

Convenient

11 of 64

JavaScript Modules...

How to use them?

Script Tag

Global Variable

Namespace (require/import)

12 of 64

JavaScript Modules...

What they look like...

13 of 64

CommonJS

//loading module

var _ = require(‘lodash’);

//declaring module

module.exports = someValue;

14 of 64

AMD

define(‘myAwesomeLib’, [‘lodash’, ‘someDep’],

function (_, someDep) {

return { … }

}

);

15 of 64

AMD + CommonJS

define( function(require, exports, module) {

var _ = require(‘lodash’);

//..do things

module.exports = someLib;

});

16 of 64

ES2015/TypeScript

import {Component} fromangular2/core

@Component({

selector:’info’

})

export class InfoComponent{}

17 of 64

So let’s talk about web application bundling...

18 of 64

Every library is different...

And has their own loading requirements...

19 of 64

Wouldn’t it be nice...

20 of 64

WEBPACK

21 of 64

Webpack is a module bundler and not a task runner.

Analyzes dependencies among your modules (not only JS but also CSS, HTML, etc) and generates assets.

Understands multiple standards for how to define dependencies and export values: AMD, CommonJS, ES6 modules, ...

22 of 64

But how?

23 of 64

Webpack - How to use it?

webpack.config.js

Yes, its a module too!!!

module.exports = {

entry: {

vendor: './src/vendors.ts',

main: './src/main.browser.ts'

},

output: {

path: 'dist/',

filename: '[name].bundle.js',

sourceMapFilename: '[name].map',

chunkFilename: '[id].chunk.js'

},

resolve: {

extensions: ['', '.ts', '.js'],

root: root('src'),

modulesDirectories: ['node_modules']

},

module: {

preLoaders: [

{

test: /\.js$/,

loader: 'source-map-loader',

exclude: [

// these packages have problems with their sourcemaps

root('node_modules/rxjs')

]

}

],

loaders: [

{

test: /\.ts$/,

loader: 'awesome-typescript-loader',

exclude: [/\.(spec|e2e)\.ts$/]

},

{

test: /\.json$/,

loader: 'json-loader'

},

{

test: /\.css$/,

loader: 'raw-loader'

},

{

test: /\.html$/,

loader: 'raw-loader',

exclude: [root('src/index.html')]

}

]

},

24 of 64

Webpack - How to use it?

Webpack CLI

$> webpack <entry.js> <result.js> --colors --progress

$> webpack-dev-server --port=9000

25 of 64

Webpack - How to use it?

Node API

var webpack = require("webpack");�� // returns a Compiler instance� webpack({� // configuration object here!� }, function(err, stats) {� // …

// compilerCallback

console.error(err);� });

26 of 64

The Core Concepts

27 of 64

Entry

28 of 64

some.component.js

bootstrap.js

app.component.ts

external.lib.js

some.component.ts

external.lib.dep.js

external.lib.dep.css

some.component.sass

The “contextual root” of your application.

The first javascript file to load to “kick-off” your app in the browser.

The Core Concepts: Entry

ENTRY_FILE.js

29 of 64

app.js

ng2-material.lib.js

some.component.js

ng-core.class.js

browser.main.ts

app.component.ts

external.lib.js

some.component.ts

external.lib.dep.js

external.lib.dep.css

some.component.sass

The Core Concepts: Entry

//webpack.config.js

module.exports = {

entry: ‘./browser.main.ts’,

//...

}

//browser.main.ts

import {

Component

} from ‘@angular/core’;

import {

App

} from ‘./app.component’;

bootstrap(App,[]);

//app.component.ts

@Component({...})

export class App {};

30 of 64

app.js

ng2-material.lib.js

some.component.js

ng-core.class.js

browser.main.ts

app.component.ts

external.lib.js

some.component.ts

external.lib.dep.js

external.lib.dep.css

some.component.sass

The Core Concepts: Entry

//webpack.config.js

module.exports = {

entry: ‘./browser.main.ts’,

//...

}

//browser.main.ts

import {

Component

} from ‘@angular/core’;

import {

App

} from ‘./app.component’;

bootstrap(App,[]);

//app.component.ts

@Component({...})

export class App {};

31 of 64

app.js

ng2-material.lib.js

some.component.js

ng-core.class.js

browser.main.ts

app.component.ts

external.lib.js

some.component.ts

external.lib.dep.js

external.lib.dep.css

some.component.sass

The Core Concepts: Entry

//webpack.config.js

module.exports = {

entry: ‘./browser.main.ts’,

//...

}

//browser.main.ts

import {

Component

} from ‘@angular/core’;

import {

App

} from ‘./app.component’;

bootstrap(App,[]);

//app.component.ts

@Component({...})

export class App {};

32 of 64

app.js

ng2-material.lib.js

some.component.js

ng-core.class.js

browser.main.ts

app.component.ts

external.lib.js

some.component.ts

external.lib.dep.js

external.lib.dep.css

some.component.sass

The Core Concepts: Entry

//webpack.config.js

//Entry Array Syntax

module.exports = {

entry: [

‘./browser.main.ts’,

‘./vendors.ts’,

‘./polyfills.ts’

],

//...

}

vendors.ts

polyfills.ts

33 of 64

app.js

ng2-material.lib.js

some.component.js

ng-core.class.js

desktop.main.ts

app.component.ts

external.lib.js

some.component.ts

external.lib.dep.js

external.lib.dep.css

some.component.sass

The Core Concepts: Entry

//webpack.config.js

//Entry Object Syntax

module.exports = {

entry: {

web: ‘./web.main.ts’,

mobile: ‘./mobile.main.ts’,

desktop: ‘./desktop.main.ts’

},

//...three non connected entrys

}

web.main.ts

mobile.main.ts

@angular/platform-browser

@angular/platform-browser-dynamic

34 of 64

The Core Concepts: Entry

//webpack.config.js

//Entry Object Syntax

module.exports = {

entry: {

browser: ‘./web.main.ts’,

Vendors: ‘./src/vendors.ts’

}

}

Take a moment to talk with a partner about what this entry definition does

Discuss the purpose of the entry file

35 of 64

The Core Concepts

Entry

Tells webpack WHAT (files) to load for the browser; Compliments the Output property.

36 of 64

Output

37 of 64

browser.main.ts

app.component.ts

external.lib.js

some.component.ts

external.lib.dep.js

external.lib.dep.css

some.component.sass

The Core Concepts: Output

//webpack.config.js

module.exports = {

entry: ‘./browser.main.ts’,

output: {

path: ‘./dist’,

filename: ‘./bundle.js’,

},

//...

}

//Generates bundle.js

./dist/

bundle.js

38 of 64

desktop.main.ts

app.component.ts

external.lib.js

some.component.ts

external.lib.dep.js

external.lib.dep.css

some.component.sass

The Core Concepts: Output

//webpack.config.js

//[name] === entry.nameOfKey

module.exports = {

entry: {

web: ‘./web.main.ts’,

mobile: ‘./mobile.main.ts’,

desktop: ‘./desktop.main.ts’

},

output: {

path: ‘.dist/’,

filename: ‘[name].js’,

}

//...three separate entries

//...three bundles (output)

}

web.main.ts

mobile.main.ts

@angular/platform-browser

@angular/platform-browser-dynamic

./dist/

web.js

mobile.js

desktop.js

39 of 64

desktop.main.ts

app.component.ts

external.lib.js

some.component.ts

external.lib.dep.js

external.lib.dep.css

some.component.sass

The Core Concepts: Output

//webpack.config.js

//You can target modules types!

module.exports = {

entry: {

web: ‘./web.main.ts’,

mobile: ‘./mobile.main.ts’,

desktop: ‘./desktop.main.ts’

},

output: {

path: ‘.dist/’,

filename: ‘[name].umd.js’,

library: ‘[name]’,

libraryTarget: ‘umd’

}

//...three separate entries

//...three bundles (output)

}

web.main.ts

mobile.main.ts

@angular/platform-browser

@angular/platform-browser-dynamic

./dist/

web.umd.js

mobile.umd.js

desktop.umd.js

40 of 64

The Core Concepts: Output

module.exports = {

entry: {

browser: ‘./web.main.ts’,

Vendors: ‘./src/vendors.ts’

},

output: {

path: ‘.dist/’,

library: ‘[name]’,

libraryTarget: ‘umd’

}

//...three separate entries

//...three bundles (output)

}

Real Example!!!!!

Find a new friend, use what you learned about Entry and now Output to talk about what the result of this would look like.

Talk about how Output can interact with Entry definitions.

Talk about why Output is important.

Why would you want to use UMD?

41 of 64

The Core Concepts

Entry

Output

Tells Webpack WHERE and HOW to distribute bundles (compilations). Works with Entry.

42 of 64

Loaders

43 of 64

module: {

loaders: [

{test: /\.ts$/, loader: ‘ts’},

{test: /\.js$/, loader: ‘babel’},

{test: /\.css$/, loader: ‘css’}

],

}

app.component.ts

Tells webpack how to load files in your content base.

Loaders are also javascript modules (function) that takes the source file, and returns it in a ‘loaded’ [modified] state.

The Core Concepts: Loaders

entry.js

external.lib.js

external.es6.dep.js

external.lib.dep.css

44 of 64

module: {

preLoaders:[], //lint

loaders: [

{

test: regex,

loader: string,

loaders: Array<string>,

include: Array<regex>,

exclude: Array<regex>,

},

],

postLoaders:[] //coverage, docs, etc.

}

The Core Concepts: Loaders

test

A regular expression that instructs the compiler which files to run the loader against.

loader

A string of the loader names you want to run.

loaders

An array of strings representing the modules you want to run. If using ‘loader’,

provide a string of multiple loaders separated by ‘!’.

IE: ‘style!css!less`

45 of 64

module: {

preLoaders:[], //lint

loaders: [

{

test: /\.ts$/,

loader: string,

loaders: [

‘awesome-typescript-loader’,

‘ng2-asset-loader`

],

include: /some_dir_name/,

exclude: [/\.(spec|e2e)\.ts$/],

},

],

postLoaders:[] //coverage, docs, etc.

}

The Core Concepts: Loaders

include

An array of regular expression that instruct the compiler which folders/files to include. Will only search paths provided with the include.

exclude

An array of regular expression that instructs the compiler which folders/files to ignore.

46 of 64

inlineStyleInBrowser.js

*.js

style.css

style.less

The Core Concepts: Loaders

Chaining Loaders

less-loader

css-loader

style-loader

loaders: [

{ test: /\.less$/, loader:’style!css!less’ },

{ test: /\.less$/,

loaders:[‘style’, ‘css’, less’]}

]

47 of 64

loaders: [� {� test: /\.ts$/,� loaders:[

'awesome-typescript-loader',

'ng2-asset-loader'

],� exclude: [/\.(spec|e2e)\.ts$/]� },� {� test: /\.json$/, loader: 'json-loader'� },� {� test: /\.css$/, loader: 'raw-loader'� },� {� test: /\.html$/,� loader: 'raw-loader',� exclude: [/index\.html$/]� }�]

The Core Concepts: Loaders

Real Example!!!!!

Take a moment to read this

Discuss with the person next to you what these loaders do.

Being comfortable with reading the loader syntax will make you more comfortable using it!

48 of 64

The Core Concepts: Loaders

Loaders can be chained. They are applied in a pipeline to the resource. The final loader is expected to return JavaScript, the others can return arbitrary format (which is passed to the next loader)

�Loaders can be synchronous and asynchronous.

�Loaders run in node.js and can do everything that’s possible there.

�Loaders accept query parameters. This can be used to pass configuration to the loader.

Loaders can be bound to extension / RegExps in the configuration.

�Loaders can be published / installed through npm.

�Normal modules can export a loader in addition to the normal main via package.json loader.

�Loaders can access the configuration.

�Loaders can emit additional arbitrary files.

https://webpack.github.io/docs/list-of-loaders.html

49 of 64

The Core Concepts

Entry

Output

Loaders

Tells Webpack HOW to interpret and translate files. They return compilations.

50 of 64

Plugins

51 of 64

The Core Concepts: Plugins

ES5 Classes

Apply functionality at the compilation level.

A compilation is a bundle of files processed by the webpack compiler. (Processed via loaders).

Webpack has a variety of built in plugins.

52 of 64

function BellOnBundlerErrorPlugin () { }��BellOnBundlerErrorPlugin.prototype.apply = function(compiler) {� if (typeof(process) !== 'undefined') {�

// Compiler events that are emitted and handled

compiler.plugin('done', function(stats) {

if (stats.hasErrors()) {

process.stderr.write('\x07');

}

});�

compiler.plugin('failed', function(err) {

process.stderr.write('\x07');

});�

}�}��module.exports = BellOnBundlerErrorPlugin;

The Core Concepts: Plugins

Basic Plugin Example

A plugin is an ES5 ‘class’ which implements an apply function.

The compiler uses it to emit events.

53 of 64

The Core Concepts: Plugins

// require() from node_modules or webpack or local file

var BellOnBundlerErrorPlugin = require(‘bell-on-error’);

var webpack = require(‘webpack’);

module.exports = {

//...

plugins: [

new BellOnBundlerErrorPlugin(),

// Just a few of the built in plugins

new webpack.optimize.CommonsChunkPlugin(‘vendors’),

new webpack.optimize.UglifyJsPlugin()

]

//...

}

How to use Plugins

require() plugin from node_modules into config.

add new instance of plugin to plugins key in config object.

provide additional info for arguments

54 of 64

The Core Concepts: Plugins

// require() from node_modules or webpack or local file

var BellOnBundlerErrorPlugin = require(‘bell-on-error’);

var webpack = require(‘webpack’);

module.exports = {

//...

plugins: [

new BellOnBundlerErrorPlugin(),

// Just a few of the built in plugins

new webpack.optimize.CommonsChunkPlugin(‘vendors’),

new webpack.optimize.UglifyJsPlugin()

]

//...

}

Real Example!!!!!

Find 2 people!!! Goto the list of Plugins seen below. Then take a moment to find one thats relevant to your dev stack and discuss how you would add it to your configuration.

Talk about what Plugins do!!!

55 of 64

The Core Concepts

Entry

Output

Loaders

Plugins

Adds additional functionality to Compilations(file globs). More powerful w/ more access to CompilerAPI.

56 of 64

Comparing the features...

57 of 64

58 of 64

The Future of Webpack?

59 of 64

Webpack 2

Native ES2015 Module Support

Tree Shaking

Faster Compilation

More Optimizations Built In

A bunch more

60 of 64

Wait, there’s more!

61 of 64

WEBPACK

ANGULAR2

+

62 of 64

Angular2 and Webpack Works

Lets look at some repositories.

63 of 64

angular2-webpack-lite

64 of 64

Awesome Examples