Webpack 学习示例

介绍

Webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 Webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle

本章节主要介绍Webpack的核心概念的Demo使用示例,建议读者查看之前请阅读Webpack的官方文档也可以查看中文地址文档

Webpack版本: 3.9.0

代码GitHub地址https://github.com/gulijian/webpack-learning-example

How to use

Install webpack

1
$ npm i -g webpack

Clone the repo.

1
$ git clone https://github.com/gulijian/webpack-learning-example.git

Install the dependencies

1
2
# 进入每个章节根目录,执行 npm install 
$ npm install

Open the each chapter index.html

Index

Style-loader

Style-loader/url

Css-loader And Css-Module

Js Tree-shaking

Url-loader

ProvidePlugin

Clean-webpack-plugin

chapter4-1 (source)

style-loader use

处理css,以 style 标签形式引入css

app.js
1
import './css/app.css'
app.css
1
2
3
html {
background: #00bcd4b5;
}
index.html
1
2
3
4
5
6
<!DOCTYPE html>
<html lang="en">
<body>
<script src="./dist/app.bundle.js"></script>
</body>
</html>
webpack.config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
var path = require('path')

module.exports = {
entry: {
'app': './src/app.js'
},

output: {
path: path.resolve(__dirname,'./dist/'),
filename: '[name].bundle.js'
},

module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader'
}
]
}
]
}
}

chapter4-2 (source)

style-loader/url use

处理css,以标签形式引入css

app.js
1
import './css/app.css'
app.css
1
2
3
4
5
6
7
8
9
html {
background: #00bcd4b5;
}

#styleLoaderUrl {
font-size: 30px;
color: white;
text-align: center;
}

index.html

1
2
3
4
5
6
7
<!DOCTYPE html>
<html lang="en">
<body>
<span id="styleLoaderUrl"> hello style-loader/url</span>
<script src="./dist/app.bundle.js"></script>
</body>
</html>
webpak.config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var path = require('path')

module.exports = {
entry: {
'app': './src/app.js'
},

output: {
path: path.resolve(__dirname,'./dist/'),
publicPath: './dist/',
filename: '[name].bundle.js'
},

module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: 'style-loader/url'
},
{
loader: 'file-loader'
}
]
}
]
}
}

chapter4-3 (source)

css-loader and css-module use

处理css,支持 css-module 形式

app.js
1
2
3
4
5
6
7
8
import app1 from './css/app1.css'

import app2 from './css/app2.css'

var app = document.getElementById('app');

// 使用样式
app.innerHTML = '<div class = "'+app1.box+'"></div>'
app1.css
1
2
3
4
5
6
7
8
.box {
composes: borderBox from './app2.css';
height: 200px;
width: 200px;
border-radius: 4px;
background: #76d4e0ab;
margin: 0 auto;
}
app2.css
1
2
3
.borderBox {
border: 4px solid #e87ff5;
}
index.html
1
2
3
4
5
6
7
<!DOCTYPE html>
<html lang="en">
<body>
<div id="app"></div>
<script src="./dist/app.bundle.js"></script>
</body>
</html>
webpack.config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
var path = require('path')

module.exports = {
entry: {
'app': './src/app.js'
},

output: {
path: path.resolve(__dirname,'./dist/'),
filename: '[name].bundle.js'
},

module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
minimize: true, // 启用压缩
modules: true // 启用 css module
}
}
]
}
]
}
}

chapter5-1 (source)

UglifyJsPlugin use

使用 UglifyJsPlugin 插件; 不打包没有使用的 js

util.js
1
2
3
4
5
6
7
8
9
10
11
export function a (){
return 'this is a';
}

export function b (){
return 'this is b';
}

export function c (){
return 'this is c';
}
app.js
1
2
3
import { a } from './common/util.js'

console.log(a())
index.html
1
2
3
4
5
6
<!DOCTYPE html>
<html lang="en">
<body>
<script src="./dist/app.bundle.js"></script>
</body>
</html>
webpack.config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var webpack = require('webpack')
var path = require('path')

module.exports = {
entry: {
'app': './src/app.js',

},

output: {
path: path.resolve(__dirname,'./dist/'),
filename: '[name].bundle.js'
},

plugins: [
new webpack.optimize.UglifyJsPlugin()
]
}

app.js 中只使用了 util.js 中的 a 函数 打包的时候只会打包 a 函数;因为 b 和 c 函数没有使用到,则不会被打包

chapter6-1 (source)

url-loader use

图片文件处理

app.js
1
2
3
4
5
var img1 = document.getElementById('img1')
var img2 = document.getElementById('img2')

img1.src = require('./assets/img1.jpg')
img2.src = require('./assets/img2.png')
index.html
1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html lang="en">
<body>
<!-- size < 30kb -->
<img id="img1"/>
<!-- size > 30kb -->
<img id="img2">
<script src="./dist/app.bundle.js"></script>
</body>
</html>
webpack.config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var path = require('path')

module.exports = {

entry: {
'app': './src/app.js',
},

output: {
path: path.resolve(__dirname,'./dist/'),
filename: '[name].bundle.js'
},

module: {
rules: [
{
test: /\.(png|jpg|jpeg|gif)$/,
use: [
{
loader:'url-loader',
options: {
limit: 30000
}
}
]
}
]
}
}

图片 小于 30kb 会变成base64编码,大于 30kb 会生成图片地址

1
2
<img id="img1" src="6443347e97d394b23b05746b2fe41cd1.jpg">
<img id="img2" src="data:image/png;base64,iVBORw0KGgoAXBIWXMAAC4jAAAuIwF4pT92AAAKTWlD"/>

chapter7-1 (source)

ProvidePlugin use

处理第三方 JS 库,方式一:( jquery 作为npm的一个module)

app.js
1
$('#app').append('hello jquery')
index.html
1
2
3
4
5
6
7
<!DOCTYPE html>
<html lang="en">
<body>
<div id="app"></div>
<script src="./dist/app.bundle.js"></script>
</body>
</html>
webpack.config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var path = require('path')
var webpack = require('webpack')

module.exports = {
entry: {
'app': './src/app.js',
},

output: {
path: path.resolve(__dirname,'./dist/'),
filename: '[name].bundle.js'
},

plugins: [
new webpack.ProvidePlugin({
$: 'jquery'
})
]
}

chapter7-2 (source)

处理第三方 JS 库,方式二:(引入本地的 jquery 库)

app.js
1
$('#app').append('hello jquery')
index.html
1
2
3
4
5
6
7
<!DOCTYPE html>
<html lang="en">
<body>
<div id="app"></div>
<script src="./dist/app.bundle.js"></script>
</body>
</html>
webpack.config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var path = require('path')
var webpack = require('webpack')

module.exports = {
entry: {
'app': './src/app.js',
},

output: {
path: path.resolve(__dirname,'./dist/'),
filename: '[name].bundle.js'
},

// 注意 jquery$ 的名字 要和 ProvidePlugin 插件中配置的名称(jquery)保持一致
resolve: {
alias: {
jquery$: path.resolve(__dirname,'src/libs/jquery.min.js')
}
},

plugins: [
new webpack.ProvidePlugin({
$: 'jquery'
})
]
}

如果 jquery 在CDN上,直接引入即可

chapter8-1 (source)

clean-webpack-plugin use

每次打包清除原先的打包目录

app.js
1
2
3
var app = document.getElementById('app')

app.innerHTML = '<h1>使用 clean-webpack-plugin 插件,可以每次打包清除原先的打包目录</h1>'
index.html
1
2
3
4
5
6
7
<!DOCTYPE html>
<html lang="en">
<body>
<span id="app"></span>
<script src="./dist/app.bundle.js"></script>
</body>
</html>
webpack.config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var path = require('path')
var CleanWebpackPlugin = require('clean-webpack-plugin')

module.exports = {
entry: {
'app': './src/app.js',
},

output: {
path: path.resolve(__dirname,'./dist/'),
filename: '[name].bundle.js'
},

plugins: [
new CleanWebpackPlugin([
'dist'
])
]
}