-
$ npm init -y
package.json created for npm -
$ npm install webpack webpack-cli --save-dev
intrall webpack plugins -
$ mkdir src dist
create folder src & dist -
$ touch src/index.js src/hello-world.js index.html
create file js & html -
$ touch webpack.config.js
webpack custom configuration file -
"webpack.config.js" updated code :
const path = resolve("path");
module.exports = {
entry: "./src/index.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "./dist")
},
mode: none
};
- "src/index.js" updated code ;
import helloworld from "./src/hellw-world";
helloworld();
-src/hello-world.js" updated code ;
const helloworld = () => {
console.log("Webpack project success");
};
export default helloworld;
- "index.html" updated code ;
...
<body>
<script src="bundle.js"></script>
</body>
- "package.json" added scripts
{
...
"scripts":{
"test": "echo \"Error: no test specified\" && exit 1",
+ "build": "webpack"
}
...
}
$ npm run build
start builder
-
$ npm install file-loader --save-dev
install file-loader -
$ mkdir src/images
create folder images -
$ touch src/image-add.js
create file js -
$ wget https://image.freepik.com/free-photo/kiwi-fruit-slice_44865-126.jpg -O src/images/kiwi.jpg
download images folder with change image name file -
"webpack.config.js" added code
module.exports = {
output: {
publicPath: "dist/"
},
module: {
rules: [{
test: /\.(png|jpg)$/,
use: {
loader: "file-loader"
}
}]
}
- _image-add.js update code
import kiwi from "./images/kiwi.jpg";
const addImage = () => {
const img = document.createElement("img");
img.alt = "Kivi image";
img.src = kiwi;
img.width = 300;
const body = document.querySelector("body");
body.appendChild(img);
};
export default addImage;
- "index.js" update code
import helloWorld from './hellw-world';
+ import addImage from './image-add';
helloWorld();
+ addImage();
$ npm run build
-
$ npm install style-loader css-loader
install loader css&style -
remove file "hello-world.js
-
$ mkdir src/components
create component folder -
$ touch src/components/button.js src/components/button.css
create js and css file -
"src/components/button.js" updated code
import "./button.css";
class Buttons {
render() {
const button = document.createElement("button");
button.classList.add("button");
button.innerHTML = "Add Text";
button.addEventListener("click", () => {
const text = document.createElement("p");
text.classList.add("text");
text.innerHTML = "This is Text";
document.body.appendChild(text);
});
document.body.appendChild(button);
}
}
export default Buttons;
- "src/components/button.css" updated code
.button {
background: #444;
color: #fff;
padding: 10px 30px;
display: inline-block;
border: none;
outline: none;
background-repeat: 2px;
cursor: pointer;
}
.text {
color: rgb(54, 161, 69);
font-family: Arial, Helvetica, sans-serif;
padding: 10px;
margin: 0;
}
- "src/index.js" added code
import Button from "./components/button";
const btn = new Button();
btn.render();
- "webpack.config.js" added css rules
module>rule:[
...
{
"test": /\.css$/,
"use": ["style-loader", "css-loader"]
}
...
]
$ npm run build
conrolled index.html file and clicked button
-
$ npm install sass-loader node-sass --save
install sass loader -
"src/components/button.css" rename "button.scss
-
"button.scss" update code
$btn-color: #999;
$text-color: blue;
.button {
...background: $btn-color; // added
}
.text {
...color: $text-color; // added
}
- "src/components/button.js" change import css file to scss file
import "./button.css"; // remove
import "./button.scss"; // added
- "webpack.config.js" added scss-loader rule
module.exports = {
module: {
rules: [{
test: /\.scss$/,
use: ["style-loader","css-loader","sass-loader"]
}]
}
-
$ npm install @babel/core babel-loader @babel/preset-env @babel/plugin-proposal-class-properties --save-dev
install packages babel -
"src/components/button.js" update code
class Buttons {
buttonClass = "button" // added
textClass = "text" // added
render() {
...
button.classList.add(this.buttonClass); // change
...
button.addEventListener("click", () => {
...
text.classList.add(this.textClass); // change
...
});
}
}
- "webpack.config.js" added js rule
module.exports = {
module: {
rules: [
...
{
test: /\.js$/,
use: {
loader: "babel-loader",
options: {
presets: ["@babel/env"],
plugins: ["@babel/plugin-proposal-class-properties"]
}
}
}]
}
$ npm run build
check page
-
$ npm install terser-webpack-plugin --save-dev
webpack plugin install -
"webpack.config.js" update codes
const TerserPlugin = require("terser-webpack-plugin"); // added
module.exports = {
...
plugins: [
new TerserPlugin()
]
}
$ npm run build
see "dist/bundle.js" size 17kb switch 6kb
-
$ npm install mini-css-extract-plugin --save-dev
install extract css plugin -
"webpack.config.js" updated code add plugin
const MiniCssExtractPlugin = require("mini-css-extract-plugin") // added
module.exports = {
...
plugins: [
...
new MiniCssExtractPlugin({
filename: "styles.css"
})
]
}
-
$ touch src/components/heading.js src/components/heading.scss
create new component files -
"heading.js" ;
import "./heading.scss"; // import scss file
class Heading {
render() {
const h = document.createElement("h1");
h.innerHTML = "WEBPACK awesome";
document.body.appendChild(h);
}
}
export default Heading;
- "heading.scss" ;
$colored: #f85;
h1 {
color: $colored;
}
- "index.js" imported heading.js files
import Button from "./components/button";
import Heading from "./components/heading"; // added
const hd = new Heading(); // added
const btn = new Button();
hd.render(); // added
btn.render();
$ npm run build
see all style files collected in a single file.
- "webpack.config.js" updated code
module.exports = {
output: {
filename: "bundle[contenthash].js" // change
},
plugins:{
new MiniCssExtractPlugin({
filename: "styles[contenthash].css" // change
})
}
};
$ npm run build
see dist folder. added new files md5 name
NOTE this configuration will add new files to the "dist" folder each time the "npm build run" command is executed. This will cause confusion. Clean up the dist folder before running the command
-
$ npm install clean-webpack-plugin --save-dev
-
"webpack.config.js" update code
const { CleanWebpackPlugin } = require('clean-webpack-plugin');; // added
module.exports = {
...
plugins: [
new CleanWebpack()
]
}
$ npm run build
-
$ npm install html-webpack-plugin --save
install plugin -
"webpack.config.js" update
const HtmlWebpackPlugin = require('html-webpack-plugin');; // added
module.exports = {
output:{
...
publicPath: "./" // change publicPath empty
}
...
plugins: [
new HtmlWebpackPlugin(
template: "./index.html",
)
]
}
$ npm run build
generate index.html file
NOTE publicPath file path on the server side does not work, we will address this problem in future tutorials. For now, run without a server.
-
"webpack.config.js" rename "webpack.prod.config.js
-
"webpack.dev.config.js" create new config file and "webpack.prod.config.js" inside all code copied after paste "webpack.dev.config.js
-
"webpack.prod.config.js" change mode "none" to "production"
-
"webpack.dev.config.js" change mode "none" to "development"
-
"webpack.prod.config.js" removed TerserPlugin all
-
"webpac.dev.config.js" removed all [contenthash] , TerserPlugin and MiniCssExtractPlugin (with rules loader change 'style-loader')
-
"package.json" change script properties
{
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --config=webpack.prod.config.js",
"dev": "webpack --congif=webpack.dev.js"
}
}
$ npm run build
or$ npm dev
-
$ npm install webpack-dev-server --save-dev
-
"webpack.dev.config.js" added devServer properties
module.exports = {
...
devServer: {
contentBase: path.resolve(__dirname, "./dist"),
index: "index.html",
port: 9000
},
}
NOTE change publicPath "./" to "/"
-
"package.json" change scripts in dev properties value to "webpack-dev-server --config=webpack.dev.config.js --hot"
-
$ npm run dev
live server working