Let's learn what is webpack and the basic of it.
- Install webpack global
npm i webpack -g
- create a package json file
npm init -y
- create index.js & index.html
<!-- index.html -->
<html>
<head>
<title>webpack 2 demo</title>
<script src="https://unpkg.com/lodash@4.16.6"></script>
</head>
<body>
<script src="app/index.js"></script>
</body>
</html>
// index.js
function component () {
var element = document.createElement('div');
/* lodash is required for the next line to work */
element.innerHTML = _.join(['Hello','webpack'], ' ');
return element;
}
document.body.appendChild(component());
- install lodash library using this command
npm i lodash --save
- add the contents below into the file
// index.js
// import & export is ES6 that doesn't work in the browser
// but webpack would replace them with compatible wrapper code
+ import _ from 'lodash';
- <script src="https://unpkg.com/lodash@4.16.6"></script>
- <script src="app/index.js"></script>
+ <script src="dist/bundle.js"></script>
- run this command below and start the index.html. You will see this result on the web page.
webpack app/index.js dist/bundle.js
- Let's add config file for more complex configuration
// webpack.config.js
// `webpack` command will pick up this config setup by default
var path = require('path');
module.exports = {
entry: './app/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
- As for CSS files, use
css-loader
for default setting. The extra optionExtractTextWebpackPlugin
is available for better performance
npm i css-loader style-loader --save-dev
npm i extract-text-webpack-plugin --save-dev
- Create a new
package.json
npm init -y
- Install the necessary loaders and plugins using the commands above
- Add index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS & Libraries Code Splitting</title>
</head>
<body>
<header>
<h3>CSS Code Splitting</h3>
</header>
<div>
<p>
This text should be colored with blue after injecting CSS bundle
</p>
</div>
<script src="dist/bundle.js"></script>
</body>
</html>
- Add
base.css
p {
color : blue;
}
- Add
app/index.js
import '../base.css';
- Add
webpack.config.js
var path = require('path');
module.exports = {
entry: './app/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}]
},
}
- Add ExtractPlugin to exract the bundled css filename
// webpack.config.js
// ...
var ExtractTextPlugin = require('extract-text-webpack-plugin');
// ...
{
// ...
module: {
rules: [{
test: /\.css$/,
// Comment this out to load ExtractTextPlugin
// use: ['style-loader', 'css-loader']
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
}]
},
plugins: [
new ExtractTextPlugin('styles.css')
]
}
- When using a couple of libraries, should you import them at the very beginning of bundling all files to avoid repetitively use them in every build.
npm install webpack --save-dev
npm install moment lodash --save
npm i webpack-manifest-plugin --save-dev
- Create a new
package.json
npm init -y
- Install the necessary loaders and plugins using the commands above
- Add
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Libraries Code Splitting</title>
</head>
<body>
<header>
<h3>Libraries Code Splitting</h3>
</header>
<div>
<label for="p1"><strong>Moment JS : </strong></label>
<p class="p1">
not yet loaded
</p>
<label for="p2"><strong>Lodash JS : </strong></label>
<p class="p2">
not yet loaded
</p>
</div>
<script src="dist/vendor.js"></script>
<script src="dist/main.js"></script>
</body>
</html>
- Add
app/index.js
var moment = require('moment');
var _ = require('lodash');
var ele = document.querySelectorAll('p');
document.addEventListener("DOMContentLoaded", function(event) {
ele[0].innerText = moment().format();
ele[1].innerText = _.drop([1, 2, 3], 0);
});
- Add
webpack.config.js
var webpack = require('webpack');
var path = require('path');
module.exports = {
entry: {
main: './app/index.js',
vendor: [
'moment',
'lodash'
]
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist')
}
}
optional
// 1
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor' // Specify the common bundle's name.
}),
]
// 2
plugins: [
new webpack.optimize.CommonsChunkPlugin({
names: ['vendor', 'manifest'] // Extract the webpack bootstrap logic into manifest.js
}),
]
// 3
new ManifestPlugin({
fileName: 'manifest.json',
basePath: './dist/'
})
- Besides loader, plugins offer a wide variety of different features that Loaders don't provide
- Create a new
package.json
and install plugins below
npm init -y
npm install webpack & jquery --save-dev
- Add
index.html
<html>
<head>
<title>Webpack Plugins</title>
</head>
<body>
<script src="dist/bundle.js"></script>
</body>
</html>
- Add
app/index.js
var $ = require('jquery');
console.log("loaded jQuery version is " + $.fn.jquery);
- Add
webpack.config.js
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: './app/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
- run
webpack
- uncomments
#2
and#3
to see how Resolve alias & Provide Plugin works
// #2 - Using alias
// index.js
import $ from 'Vendor/jquery-2.2.4.min.js';
console.log("loaded jQuery version is " + $.fn.jquery);
// webpack.config.js
resolve: {
alias: {
Vendor: path.resolve(__dirname, './app/vendor/')
}
}
// #3 - Using Provide Plugin
// index.js
console.log("loaded jQuery version is " + $.fn.jquery);
// webpack.config.js
plugins: [
new webpack.ProvidePlugin({
$: 'jquery'
})
]
- Initial development setting to make the build process easier
npm install webpack webpack-dev-server --save-dev
webpack-dev-server --open
- or add this option to
package.json
to launch the dev server
"scripts": { "start": "webpack-dev-server" }
- Create a new
package.json
and type the commands above - Add
index.html
<html>
<head>
<title>Webpack Dev Server</title>
</head>
<body>
<div class="container">
hello
</div>
<script src="/dist/bundle.js"></script>
</body>
</html>
- Add
app/index.js
var ele = document.getElementsByClassName('container')[0];
ele.innerText = "Webpack loaded!!";
- Add
webpack.config.js
var path = require('path');
module.exports = {
entry: './app/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath: 'dist'
},
devtool: "cheap-eval-source-map",
devServer: {
publicPath: "/dist/",
port: 9000
},
};
- Run
npm start
to launch the Webpack Dev Server
Please keep in mind that the webpack devserver compiles in memory not emits bundled file in output.path
- Have a full control over already installed Node.js by installing the commands below
npm install webpack --save
npm install express webpack-dev-middleware --save-dev
- Create a new
package.json
and type the commands above - Add
index.html
<html>
<head>
<title>Webpack Dev Middleware</title>
</head>
<body>
<div class="container">
hello
</div>
<script src="/dist/bundle.js"></script>
</body>
</html>
- Create a new
server.js
file and add Express & EJS in it
var express = require('express');
var app = express();
var path = require('path');
app.use(express.static(__dirname));
// view engine setup
// __dirname : root folder
app.set('views', path.join(__dirname));
app.set('view engine', 'ejs');
app.engine('html', require('ejs').renderFile);
app.get('/', function (req, res) {
res.send('index');
});
app.listen(3000);
console.log("Server running on port 3000");
- Run
server.js
and make sure it doens't cause any errors - Add
app/index.js
var ele = document.getElementsByClassName('container')[0];
ele.innerText = "Webpack loaded!!";
- Add
webpack.config.js
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: './app/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath: 'http://localhost:3000/dist'
},
};
- Add the codes below to
server.js
var webpackDevMiddleware = require("webpack-dev-middleware");
var webpack = require("webpack");
var webpackConfig = require("./webpack.config");
var compiler = webpack(webpackConfig);
app.use(webpackDevMiddleware(compiler, {
publicPath: webpackConfig.output.publicPath,
stats: {colors: true}
}));
Copyright © 2017 Captain Pangyo
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 4.0 Unported License.