manlili blog

webpack之模板和图片例子

下面来讲解个例子,将component组件里面的js,css,html打包进模板index.html,源码地址https://github.com/manlili/webpack_learn里面的lesson10

第一步

在空白的文件夹正确的安装webpack,这一步webpack入门指南已经讲过了。
然后创建源文件夹src,在src下面创建app.js和components文件夹,组件components,下面放layer文件夹,里面分别创建layer的相关js,css,html,然后创建个目标文件夹dist,用来盛放打包生成的文件.
先来看看整个项目目录:
图
下面来分别看下各个文件的内容
layer.css

1
2
3
4
5
.layer {
background-color: red;
height: 100%;
font-size: 100px;
}

layer.html

1
2
3
<div class="layer">
我是layer文件内容
</div>

layer.js

1
2
3
4
5
6
7
8
9
10
import layerCss from "./layer.css";
import template from "./layer.html";
function layer () {
return {
name: 'layer',
layerCss: layerCss,
template: template
}
}
export default layer

上面代码需要关注的是我们用的ES6的import语法将这个组件的css和html载入js,然后将访问的接口通过export default给出去,方便app.js访问我们这个组件

app.js

1
2
3
4
5
6
7
8
import Layer from './components/layer/layer.js';
const App = function () {
let dom = document.getElementById('app');
let layer = new Layer();
dom.innerHTML = layer.template;
}
new App();

上面的代码我们通过ES6的import语法将layer.js暴露的layer函数引入,然后用过new Layer()实例化这个函数,我们就可以访问layer内部的变量了,这里是找到id为app的标签,然后将定义的组件html插入id为app的标签里面

模板index.html

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>webapp</title>
</head>
<body>
<div id="app"></div>
</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
33
34
35
36
37
38
39
40
41
42
43
//使用html-loader
var path = require("path"); //webpack升级到2.0以后,路径需要引用这个模块
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
app: './src/app.js',
},
output: {
path: path.resolve(__dirname, './dist'),
filename: 'js/[name].bundle.js' //区分文件有[name], [hash], [chunkhash]
},
module: {
rules: [{
test: /\.js$/, //用正则匹配找到所有的js文件
include: path.resolve(__dirname, 'src'), //指定babel-loaders寻找的文件路径,注意需是绝对路径
exclude: path.resolve(__dirname, 'node_modules'), //排除node_modules文件下js,注意需是绝对路径
use: {loader: 'babel-loader'}
},
{
test: /\.css$/,
include: path.resolve(__dirname, 'src'), //指定babel-loaders寻找的文件路径,注意需是绝对路径
exclude: path.resolve(__dirname, 'node_modules'), //排除node_modules文件下js,注意需是绝对路径
use: [
{loader: 'style-loader'}, //注意先后顺序,一般都要先用css-loader处理完然后用style-loader生成style标签,但webpack读取的顺序是从右到左
{loader: 'css-loader'}
]
},
{
test: /\.html$/,
use: {loader: 'html-loader'}
}
]
},
plugins: [
new htmlWebpackPlugin({
filename: 'index.html', //生成的文件名字
template: 'index.html', //生成文件的 模板
inject: 'body', //打包生成的js,css和其他东西插入的位置
title: 'i am girl',
inject: 'body'
})
]
}

注意上面使用了html-loader,这个是将.html文件转为字符串模板,处理模板文件的做法:
(1)webpack将模板文件当做一个字符串进行处理。(本次使用这种方法讲解)
(2)webpack将模板文件当成已经编译好的的模板的处理函数。
使用html-loader就要先安装:

1
npm i -D html-loader --save-dev

第二步

在根目录下打开命名行输入

1
webpack

打包后发现dist/js下面生成的app.bundle.js(打包后代码很乱,无需关注),这个时候我们来看下生成的index.html在浏览器里面的展示:
图
达到我们的预期了,layer.css和layer.html都插入到了index.html里面

第三步

在我们的实际项目中,我们的模板会用到模板语法,比如EJS模板,就需要用ejs-loader进行处理,紧接着来讲解下EJS模板
源码地址https://github.com/manlili/webpack_learn里面的lesson11
这是我们在layer.html写入ejs语法:

1
2
3
4
5
6
<div class="layer">
<%= name %>
<% for (var i = 0; i < arr.length ; i++) { %>
<%= arr[i] %>
<% } %>
</div>

将app.js引用html时传入参数:

1
2
3
4
5
6
7
8
9
10
11
import Layer from './components/layer/layer.js';
const App = function () {
let dom = document.getElementById('app');
let layer = new Layer();
dom.innerHTML = layer.template({
name: 'ejs模板',
arr: ['1', '2', '3']
});
}
new App();

注意上面引入的layer.template不再是字符串,而是一个用ejs-loader生成的函数,这个时候可以传参

下面来看下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
33
34
35
36
37
38
39
40
41
42
43
//使用ejs-loader
var path = require("path"); //webpack升级到2.0以后,路径需要引用这个模块
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
app: './src/app.js',
},
output: {
path: path.resolve(__dirname, './dist'),
filename: 'js/[name].bundle.js' //区分文件有[name], [hash], [chunkhash]
},
module: {
rules: [{
test: /\.js$/, //用正则匹配找到所有的js文件
include: path.resolve(__dirname, 'src'), //指定babel-loaders寻找的文件路径,注意需是绝对路径
exclude: path.resolve(__dirname, 'node_modules'), //排除node_modules文件下js,注意需是绝对路径
use: {loader: 'babel-loader'}
},
{
test: /\.css$/,
include: path.resolve(__dirname, 'src'), //指定babel-loaders寻找的文件路径,注意需是绝对路径
exclude: path.resolve(__dirname, 'node_modules'), //排除node_modules文件下js,注意需是绝对路径
use: [
{loader: 'style-loader'}, //注意先后顺序,一般都要先用css-loader处理完然后用style-loader生成style标签,但webpack读取的顺序是从右到左
{loader: 'css-loader'}
]
},
{
test: /\.html$/,
use: {loader: 'ejs-loader'}
}
]
},
plugins: [
new htmlWebpackPlugin({
filename: 'index.html', //生成的文件名字
template: 'index.html', //生成文件的 模板
inject: 'body', //打包生成的js,css和其他东西插入的位置
title: 'i am girl',
inject: 'body'
})
]
}

从上面我们看出对html用ejs-loader处理,注意使用前需要先安装,安装语法如下:

1
npm install ejs-loader --save-dev

在根目录下打开命名行输入

1
webpack

打包后发现dist/js下面生成的app.bundle.js(打包后代码很乱,无需关注),这个时候我们来看下生成的index.html在浏览器里面的展示:
图
达到我们的预期了,layer.html里面的ejs语法都转义后插入到了index.html里面。

第四步

假设我们的项目里面需要用到图片,这个时候需要注意图片引入的地址
源码地址https://github.com/manlili/webpack_learn里面的lesson12
我们在src文件下建立一个assets文件夹,放入一个smell.jpg,然后在我们的layer.css引入作为背景

1
2
3
4
5
6
.layer {
background-color: red;
height: 100%;
font-size: 100px;
background: url(../../assets/smell.jpg);
}

这个时候需要修改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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
//使用file-loader
var path = require("path"); //webpack升级到2.0以后,路径需要引用这个模块
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
app: './src/app.js',
},
output: {
path: path.resolve(__dirname, './dist'),
filename: 'js/[name].bundle.js' //区分文件有[name], [hash], [chunkhash]
},
module: {
rules: [{
test: /\.js$/, //用正则匹配找到所有的js文件
include: path.resolve(__dirname, 'src'), //指定babel-loaders寻找的文件路径,注意需是绝对路径
exclude: path.resolve(__dirname, 'node_modules'), //排除node_modules文件下js,注意需是绝对路径
use: {loader: 'babel-loader'}
},
{
test: /\.css$/,
include: path.resolve(__dirname, 'src'), //指定babel-loaders寻找的文件路径,注意需是绝对路径
exclude: path.resolve(__dirname, 'node_modules'), //排除node_modules文件下js,注意需是绝对路径
use: [
{loader: 'style-loader'}, //注意先后顺序,一般都要先用css-loader处理完然后用style-loader生成style标签,但webpack读取的顺序是从右到左
{loader: 'css-loader'}
]
},
{
test: /\.html$/,
use: {loader: 'ejs-loader'}
},
{
test: /\.(jpg|png|gif|svg)$/,
use: {
loader: 'file-loader?name=asset/[hash].[ext]'
}
}
]
},
plugins: [
new htmlWebpackPlugin({
filename: 'index.html', //生成的文件名字
template: 'index.html', //生成文件的 模板
inject: 'body', //打包生成的js,css和其他东西插入的位置
title: 'i am girl',
inject: 'body'
})
]
}

注意上面我们使用了file-loader处理图片,使用之前需要先安装

1
npm install --save-dev file-loader

在根目录下打开命名行输入

1
webpack

打包后发现dist/js下面生成一系列文件,这个时候我们来看下生成的index.html在浏览器里面的展示:
图
达到我们的预期了,背景图加载出来了,并且css也插入到了index.html里面。

如果我们在layer.html里面引入图片

1
2
3
4
5
6
7
<div class="layer">
<%= name %>
<% for (var i = 0; i < arr.length ; i++) { %>
<%= arr[i] %>
<% } %>
<img src="${require('../../assets/smell.jpg')}"/> <!--注意这里使用es6模板语法和require-->
</div>

注意上面引入图片的写法。

在根目录下打开命名行输入

1
webpack

打包后发现dist/js下面生成一系列文件,这个时候我们来看下生成的index.html在浏览器里面的展示:
图
达到我们的预期了,背景图加载出来了,并且css也插入到了index.html里面,在img里面也引入了对应的图片。

第五步

有时间图片太小,我们可以直接将图片用base64形式,减少向服务器的请求,这个时候可以借助url-loader里面limit参数进行处理。
这个时候需要修改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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
//使用url-loader
var path = require("path"); //webpack升级到2.0以后,路径需要引用这个模块
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
app: './src/app.js',
},
output: {
path: path.resolve(__dirname, './dist'),
filename: 'js/[name].bundle.js' //区分文件有[name], [hash], [chunkhash]
},
module: {
rules: [{
test: /\.js$/, //用正则匹配找到所有的js文件
include: path.resolve(__dirname, 'src'), //指定babel-loaders寻找的文件路径,注意需是绝对路径
exclude: path.resolve(__dirname, 'node_modules'), //排除node_modules文件下js,注意需是绝对路径
use: {loader: 'babel-loader'}
},
{
test: /\.css$/,
include: path.resolve(__dirname, 'src'), //指定babel-loaders寻找的文件路径,注意需是绝对路径
exclude: path.resolve(__dirname, 'node_modules'), //排除node_modules文件下js,注意需是绝对路径
use: [
{loader: 'style-loader'}, //注意先后顺序,一般都要先用css-loader处理完然后用style-loader生成style标签,但webpack读取的顺序是从右到左
{loader: 'css-loader'}
]
},
{
test: /\.html$/,
use: {loader: 'ejs-loader'}
},
{
test: /\.(jpg|png|gif|svg)$/,
use: {
loader: 'url-loader?limit=30000!name=asset/[hash].[ext]'
}
}
]
},
plugins: [
new htmlWebpackPlugin({
filename: 'index.html', //生成的文件名字
template: 'index.html', //生成文件的 模板
inject: 'body', //打包生成的js,css和其他东西插入的位置
title: 'i am girl',
inject: 'body'
})
]
}

注意使用之前需要安装url-loader:

1
npm install --save-dev url-loader

在根目录下打开命名行输入

1
webpack

打包后发现dist/js下面生成一系列文件,这个时候我们来看下生成的index.html在浏览器里面的展示:
图
达到我们的预期了,背景图是用base64加载出来了,在img里面也是引用的base64图片。

第六步

如果我们的图片太大,需要压缩一下,这个时候需要img-loader
这个时候需要修改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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
var path = require("path"); //webpack升级到2.0以后,路径需要引用这个模块
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
app: './src/app.js',
},
output: {
path: path.resolve(__dirname, './dist'),
filename: 'js/[name].bundle.js' //区分文件有[name], [hash], [chunkhash]
},
module: {
rules: [{
test: /\.js$/, //用正则匹配找到所有的js文件
include: path.resolve(__dirname, 'src'), //指定babel-loaders寻找的文件路径,注意需是绝对路径
exclude: path.resolve(__dirname, 'node_modules'), //排除node_modules文件下js,注意需是绝对路径
use: {loader: 'babel-loader'}
},
{
test: /\.css$/,
include: path.resolve(__dirname, 'src'), //指定babel-loaders寻找的文件路径,注意需是绝对路径
exclude: path.resolve(__dirname, 'node_modules'), //排除node_modules文件下js,注意需是绝对路径
use: [
{loader: 'style-loader'}, //注意先后顺序,一般都要先用css-loader处理完然后用style-loader生成style标签,但webpack读取的顺序是从右到左
{loader: 'css-loader'}
]
},
{
test: /\.html$/,
use: {loader: 'ejs-loader'}
},
{
test: /\.(jpg|png|gif|svg)$/,
use: [
{loader: 'file-loader?name=asset/[hash].[ext]'},
{loader: 'img-loader'}
]
}
]
},
plugins: [
new htmlWebpackPlugin({
filename: 'index.html', //生成的文件名字
template: 'index.html', //生成文件的 模板
inject: 'body', //打包生成的js,css和其他东西插入的位置
title: 'i am girl',
inject: 'body'
})
]
}

注意使用img-loader之前需要先安装:

1
npm install img-loader --save-dev

在根目录下打开命名行输入

1
webpack

打包后发现dist/js下面生成一系列文件,这个时候我们来看下dist/asset/a36939881292c3d8606448723481f194.jpg,原始大小是22.2k,经过压缩后是7.33k,生成的index.html在浏览器里面的展示也是正确的,这样我们就达到了压缩图片功能。

请我喝杯果汁吧!