packing it all with webpack

115
Webpack Packing it all

Upload: derek-willian-stavis

Post on 15-Apr-2017

104 views

Category:

Technology


0 download

TRANSCRIPT

WebpackPacking it all

$ whois

Derek Stavis github.com/derekstavis Software Engineer @ pagar.me

Node, React & Webpack Advocate

–See no evil monkey

“Webpack is just a module bundler.”

🙈

Why do we need a module bundler?

Why we need module bundling

early web

<html> <head> <script src="header.js"></script> <script src="menu.js"></script> <script src="sidebar.js"></script> <script src="fancy-button.js"></script> <script src="carousel.js"></script> </head> <body> </body> </html>

2003

JSMin

The JavaScript Minifier

Douglas Crockfordwww.crockford.com

2003-12-04

JSMin is a filter which removes comments and unnecessary whitespace from JavaScript files. It typically reduces filesize by half, resultingin faster downloads. It also encourages a more expressive programming style because it eliminates the download cost of clean, literateself-documentation.

What JSMin DoesJSMin is a filter that omits or modifies some characters. This does not change the behavior of the program that it is minifying. The resultmay be harder to debug. It will definitely be harder to read.

JSMin first replaces carriage returns ('\r') with linefeeds ('\n'). It replaces all other control characters (including tab) with spaces. Itreplaces comments in the // form with linefeeds. It replaces comments in the /* */ form with spaces. All runs of spaces are replaced witha single space. All runs of linefeeds are replaced with a single linefeed.

It omits spaces except when a space is preceded and followed by a non-ASCII character or by an ASCII letter or digit, or by one of thesecharacters:

\ $ _

It is more conservative in omitting linefeeds, because linefeeds are sometimes treated as semicolons. A linefeed is not omitted if itprecedes a non-ASCII character or an ASCII letter or digit or one of these characters:

\ $ _ { [ ( + -

and if it follows a non-ASCII character or an ASCII letter or digit or one of these characters:

\ $ _ } ] ) + - " '

No other characters are omitted or modified.

JSMin knows to not modify quoted strings and regular expression literals.

JSMin does not obfuscate, but it does uglify.

Before:

// is.js

// (c) 2001 Douglas Crockford// 2001 June 3

// is

// The -is- object is used to identify the browser. Every browser edition// identifies itself, but there is no standard way of doing it, and some of// the identification is deceptive. This is because the authors of web// browsers are liars. For example, Microsoft's IE browsers claim to be// Mozilla 4. Netscape 6 claims to be version 5.

var is = { ie: navigator.appName == 'Microsoft Internet Explorer', java: navigator.javaEnabled(), ns: navigator.appName == 'Netscape', ua: navigator.userAgent.toLowerCase(), version: parseFloat(navigator.appVersion.substr(21)) || parseFloat(navigator.appVersion), win: navigator.platform == 'Win32'}is.mac = is.ua.indexOf('mac') >= 0;if (is.ua.indexOf('opera') >= 0) { is.ie = is.ns = false; is.opera = true;}if (is.ua.indexOf('gecko') >= 0) { is.ie = is.ns = false; is.gecko = true;}

After:

var is={ie:navigator.appName=='Microsoft Internet Explorer',java:navigator.javaEnabled(),ns:navigator.appName=='Netscape',ua:navigator.userAgent.toLowerCase(),version:parseFloat(navigator.appVersion.substr(21))||parseFloat(navigator.appVersion),win:navigator.platform=='Win32'}is.mac=is.ua.indexOf('mac')>=0;if(is.ua.indexOf('opera')>=0){is.ie=is.ns=false;is.opera=true;}if(is.ua.indexOf('gecko')>=0){is.ie=is.ns=false;is.gecko=true;}

Character SetJSMin requires, but does not verify, that the character set encoding of the input program is either ASCII or UTF-8. It might not workcorrectly with other encodings.

CautionBe sure to retain your original source file. JSMin is a one-way trip: Once done, it cannot be undone.

Do not put raw control characters inside a quoted string. That is an extremely bad practice. Use \xhh notation instead. JSMin will replacecontrol characters with spaces or linefeeds.

Use parens with confusing sequences of + or -. For example, minification changes

a + ++b

into

a+++b

which is interpreted as

a++ + b

which is wrong. You can avoid this by using parens:

a + (++b)

JSLint checks for all of these problems. It is suggested that JSLint be used before using JSMin.

Command Line OptionsOptional parameters will be listed at the beginning of the output as comments. This is a convenient way of replacing copyright messagesand other documentation.

Example:

jsmin <fulljslint.js >jslint.js "(c)2002 Douglas Crockford"

ErrorsJSMin can produce three error messages to stderr:

Unterminated comment.

Unterminated string constant.

Unterminated regular expression.

It ignores all other errors that may be present in your source program.

Get MinifiedYou can get a zip file containing an MS-DOS.exe file, or you can get the C source code and build it yourself.

Copyright 2001 Douglas Crockford. All Rights Reserved Wrrrldwide.

<html> <head> <script src="header.min.js"></script> <script src="menu.min.js"></script> <script src="sidebar.min.js"></script> <script src="fancy-button.min.js"></script> <script src="carousel.min.js"></script> </head> <body> </body> </html>

still too many files

use all browser connections

add request overhead

hard to invalidate cache

let’s concatenate files

wrap every file with an IIFE

;(function () { var counter = 0 ... })(); ;(function () { var xpto = 0 ... })();

to isolate file scope

each file is now a module

concatenate all files

now you have the bundle

<html> <head> <script src="app.min.js"></script> </head> <body> </body> </html>

2006

Support jQuery!

Amount: $ 5.00

Donate

jQueryNew Wave Javascript

jQuery is a new type of Javascript library. It is not a huge, bloated, frameworkpromising the best in AJAX - nor is just a set of needlessly complexenhancements - jQuery is designed to change the way that you writeJavascript.

New: The jQuery Mailing List is now up - join and discuss!New: The jQuery Blog has just been opened - subscribe now!

What is jQuery?jQuery is a Javascript library that takes this motto to heart: Writing Javascriptcode should be fun. jQuery acheives this goal by taking common, repetitive,tasks, stripping out all the unnecessary markup, and leaving them short, smartand understandable.

What does jQuery code look like? The quick and dirty:

The above code snippet looks for all paragraphs that have a class of 'surprise',adds the class 'ohmy' to them, then slowly reveals them. Click the 'Run' buttonto see it in action!

Quick Facts:

jQuery supports CSS 1-3 and basic XPath.jQuery is about 10kb in size.jQuery works in Internet Explorer, Firefox, Safari, and Opera.

Getting Started:» Download jQuery (compressed) or Configure Your Download

If you're new to jQuery, we recommend that you check out the tutorial, look atsome of the demos, then move on over to the documentation and start coding!

If you'd like to keep up-to-date with jQuery (and see some more code examples,then you should read the jQuery blog.

Advanced:If you're feeling adventurous, you may take a peek at the full source code, ortry your hand at writing a plugin.

About:jQuery was written by John Resig. The maintenance, andhosting, of jQuery is a service of Juniper Bay.

jQuery was heavily inspired by the previous work ofSimon Willison, Ben Nolan, Sam Stephenson, ValerioProietti, Dean Edwards, and Devo.

$("p.surprise").addClass("ohmy").show("slow");

Congratulations! You just ran a snippet of jQuery code - wasn't thateasy? There's lots of example code throughout the documentation, onthis site - be sure to give all the code a test run, to see what happens.

jQuery popularized AJAX

lots of community plugins

some problems too

<html> <head> <script src="jquery.min.js"></script>

... <script src="jquery.soundy.min.js"></script> <script src="jquery.fancy.min.js"></script> <script src="jquery.blinky.min.js"></script> <script src="photo-gallery.min.js"></script>

</head> <body> </body> </html>

<html> <head> <script src="jquery.min.js"></script>

... <script src="jquery.soundy.min.js"></script> <script src="jquery.fancy.min.js"></script> <script src="jquery.blinky.min.js"></script> <script src="about-us.min.js"></script>

</head> <body> </body> </html>

<html> <head> <script src="jquery.min.js"></script>

... <script src="jquery.soundy.min.js"></script> <script src="jquery.fancy.min.js"></script> <script src=“jquery.blinky.min.js"></script> <script src="contact-us.min.js"></script>

</head> <body> </body> </html>

manual dependency order

script tag ordering hell

2007

and it included…

a real browser!

to mimic real apps

web apps had to be light

they had to be smooth

we already had async http

let’s do more single page

<html> <head> <script src="jquery.min.js"></script> ...

<script src="jquery.soundy.min.js"></script> <script src="jquery.fancy.min.js"></script> <script src="jquery.blinky.min.js"></script> <script src="app.min.js"></script> </head> <body> </body> </html>

in this new approach

full app was downloaded

even unneeded code

we needed lazy load

dependency ordering

2009

commonjs is born

r.js is born

hello async modules

<html> <head> <script src="r.js"></script> <script> require(["app.js"]) </script> </head> <body> </body> </html>

index.html

app.js

require(["jquery.fancy", "jquery.soundy"], function () { $(".target").fancy() })

now single page apps

could load app code

progressively

but with dependencies

comes managing

we used to

download and drop .min.js in the project

version control was hard

2010

JavaScript outside browser

module based from day 0

set us free from browser

brought sane packages

a package manager

with the power of node

lots of tools were created

solving pains from the past

also in the same year

suddenly we were writing

not just web pages

but entire applications

2012

after lots of nasty scripts

a boom of task managers

we created extensive

gruntfiles

gulpfiles

2014

React became popular

Webpack had its glory

since then

we have been doing nice

lots of overhead is over

2017

const path = require('path')

module.exports = { entry: './index.js', output: { path: path.join(__dirname, 'dist'), filename: "bundle.js", }, module: { rules: [ { test: /\.js$/, use: ['babel-loader'], }, { test: /\.css$/, use: ['style-loader', 'css-loader'], }, { test: /\.(svg|otf|woff|woff2|ttf|otf|png|jpg|gif)$/, use: ['file-loader'], } ] } }

module

bundler

builds a dependency tree

by walking though imports

every single dependency of your system is a module

loaders are the key point

have standard interface

take an input

output transformed content

J S X J S ( E S 5 )babel-loader

S C S S C S Spostcss-loader

P N G B A S E 6 4url-loader

B U N D L E . J S

outputs can be chunks or files

chunks are text modules

concatenated in bundle

files are emitted in output directory

a handful of loaders

url-loader file-loader json-loader json5-loader script-loader babel-loader coffee-loader html-loader

pug-loader jade-loader style-loader css-loader sass-loader less-loader postcss-loader eslint-loader

loaders can be piped

const path = require('path')

module.exports = { entry: './index.js', output: { path: path.join(__dirname, 'dist'), filename: "bundle.js", }, module: { rules: [ { test: /\.js$/, use: ['babel-loader'], }, { test: /\.css$/, use: ['style-loader', 'css-loader'], }, { test: /\.(svg|otf|woff|woff2|ttf|otf|png|jpg|gif)$/, use: ['file-loader'], } ] } }

lazy module loading

split bundles

incremental builds

hot module replacement

what all this means?

demo time

https://web-beta.archive.org/web/20060201000000*/http://jquery.com

http://www.crockford.com/javascript/jsmin.html

http://gizmodo.com/5072967/iphone-secret-web-apps-can-mimic-real-apps

https://web.archive.org/web/20071011085815/http://developer.yahoo.com/common/json.html