part 2
a constituent part; element; ingredient.
being or serving as an element (in something larger)
<page>
<group>
<picture></picture>
<picture></picture>
</group>
<picture></picture>
</page>
.block {}
.block__element {}
.block__element--modifier {}
block == component*
* well, not always!
// utility.js
function generateRandom() {
return Math.random();
}
function sum(a, b) {
return a + b;
}
export { generateRandom, sum }
// component.js
import { generateRandom, sum } from 'utility';
console.log(generateRandom()); //logs a random number
console.log(sum(1, 2)); //3
// utility.js
var utils = {
generateRandom: function() {
return Math.random();
},
sum: function(a, b) {
return a + b;
}
};
export default utils;
// component.js
import utils from 'utility';
console.log(utils.generateRandom()); //logs a random number
console.log(utils.sum(1, 2)); //3
// utility.js
var utils = {
generateRandom: function() {
return Math.random();
},
sum: function(a, b) {
return a + b;
}
};
module.exports utils;
// component.js
var utils = require('utility');
console.log(utils.generateRandom()); //logs a random number
console.log(utils.sum(1, 2)); //3
Not just Javascript can become a module. You can require HTML, CSS and even Images.
require('myComponent.js')
require('myStyles.css')
All assets are split into smaller parts that can be loaded asynchronously
Similar to tasks, loaders allow you to preprocess files as you require() or “load” them.
Loaders can transform files from a different language like, CoffeeScript to JavaScript, or inline images as data URLs.
Loaders even allow you to do things like require() css files right in your JavaScript!
{
module: {
loaders: [
{ test: /\.coffee$/, loader: "coffee-loader" }
],
preLoaders: [
{ test: /\.coffee$/, loader: "coffee-hint-loader" }
]
}
};
module: {
loaders: [
{ test: /\.coffee$/, loader: 'coffee-loader' },
{
test: /\.js$/,
loader: 'babel-loader',
query: {
presets: ['es2015', 'react']
}
}
]
}
query – Configuration object for loader
module: {
loaders: [
// use ! to chain loaders
{ test: /\.less$/, loader: 'style-loader!css-loader!less-loader' },
{ test: /\.css$/, loader: 'style-loader!css-loader' },
// inline base64 URLs for <=8k images, direct URLs for the rest
{ test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192' }
]
}
The data flows from right to left. In the above example:
1. Less-loader – transforms .less files into .css files
2. Css-loader – injects css code inside the .js file
3. Style-loader – injects the css code from .js file into the page inside <style></style> tags.
// webpack.config.js
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
}
};
$ webpack // for building once for development
$ webpack -p // for building once for production (minification)
$ webpack --watch // for continuous incremental build in development (fast!)
$ webpack -d // to include source maps
// webpack.config.js
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
module: {
loaders: [
{ test: /\.coffee$/, loader: 'coffee-loader' },
{
test: /\.js$/,
loader: 'babel-loader',
query: {
presets: ['es2015', 'react']
}
}
]
},
resolve: {
// you can now require('file') instead of require('file.coffee')
extensions: ['', '.js', '.json', '.coffee']
}
};
// webpack.config.js
module.exports = {
entry: {
Profile: './profile.js',
Feed: './feed.js'
},
output: {
path: 'build',
filename: '[name].js' // Template based on keys in entry above
}
};
This will generate 2 bundles:
Profile.js and Feed.js
Webpack has two types of dependencies in its dependency tree: sync and async.
Async dependencies act as split points and form a new chunk. After the chunk tree is optimized, a file is emitted for each chunk.
// cats.js
var cats = ['dave', 'henry', 'martha'];
module.exports = cats;
// app.js
var cats = require('./cats.js');
console.log(cats); // ['dave', 'henry', 'martha']
// or asynchronously
require.ensure(['cats.js'], function (require) {
var cats = require('cats.js');
});
// example.js
var a = require("a");
var b = require("b");
require.ensure(["c"], function(require) {
require("b").xyz();
var d = require("d");
});
// output.js
webpack module loading code
module a
module b
webpack async module require
// 1.js
webpackJsonp([1],[
module c
module d
]);
if (window.location.pathname === '/feed') {
showLoadingState();
// this syntax is weird but it works
require.ensure([], function() {
hideLoadingState();
// when this function is called,
// the module is guaranteed to be synchronously available.
require('./feed').show();
});
} else if (window.location.pathname === '/profile') {
showLoadingState();
require.ensure([], function() {
hideLoadingState();
require('./profile').show();
});
}
// webpack.config.js
module.exports = {
entry: './main.js',
output: {
// This is where images AND js will go
path: './build',
// This is used to generate URLs to e.g. images
publicPath: 'http://mycdn.com/',
filename: 'bundle.js'
},
module: {
loaders: [
{ test: /\.less$/, loader: 'style-loader!css-loader!less-loader' },
{ test: /\.css$/, loader: 'style-loader!css-loader' },
// inline base64 URLs for <=8kB images, direct URLs for the rest
{ test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192' }
]
}
};
require('./bootstrap.css');
require('./myapp.less');
// picture.png is larger than 8kB
var img = document.createElement('img');
img.src = require('./picture.png');
// logo.png is smaller than 8kB
var logo = document.createElement('img');
logo.src = require('./logo.png');
Both bootstrap.css and myapp.less (as css) will be injected into the page inside <style></style> tags.
picture.png – url will equal "http://mycdn.com/picture.png"
logo.png – will be injected as base64 encoded image
HOT HOT HOT!
Add, remove and modify modules „on the fly” without refreshing the page.
This means the state is preserved. For example, if you fill a form it won’t get lost.
Can swap javascript, css, images, templates.
HOT HOT HOT!
Like vue-loader for Vue.js, which gives you the possibility to have JavaScript, HTML and CSS (with preprocessors for all of them) inside a .vue component file!
With from Monterail
Damian Dulisz
Register at: monterail.com/pwr