VUE学习:九.模板解析
前言
模板指的是每个 page 下的 html 模板文件,vue 创建项目时,默认使用单页应用配置,模板文件的作用主要用于 webpack 中 html-webpack-plugin
插件的配置,其会根据模板文件生产一个编译后的 html 文件并自动加入携带 hash 的脚本和样式
#1.模板配置
#1.1 单模板配置
/* webpack 配置文件 */const HtmlWebpackPlugin = require('html-webpack-plugin') // 安装并引用插件module.exports = { ... plugins: [ new HtmlWebpackPlugin({ title: 'My Page', // 生成 html 中的 title filename: 'demo.html', // 生成 html 的文件名 template: 'xxx/xxx/demo.html', // 模板路径 chunks: ['manifest', 'vendor', 'demo'], // 所要包含的模块 inject: true, // 是否注入资源 }) ] ...}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#1.2 多模板配置
抽离公共配置
/* utils.js */// 多页面输出配置// 与上面的多页面入口配置相同,读取 page 文件夹下的对应的 html 后缀文件,然后放入数组中exports.htmlPlugin = (configs) => { let entryHtml = glob.sync(PAGE_PATH + "/*/*.html") let arr = [] entryHtml.forEach((filePath) => { let filename = filePath.substring( filePath.lastIndexOf("/") + 1, filePath.lastIndexOf(".") ) let conf = { template: filePath, // 模板路径 filename: filename + ".html", // 生成 html 的文件名 chunks: ["manifest", "vendor", filename], inject: true, } // 如果有自定义配置可以进行 merge if (configs) { conf = merge(conf, configs) } // 针对生产环境配置 if (process.env.NODE_ENV === "production") { conf = merge(conf, { minify: { removeComments: true, // 删除 html 中的注释代码 collapseWhitespace: true, // 删除 html 中的空白符 // removeAttributeQuotes: true // 删除 html 元素中属性的引号 }, chunksSortMode: "manual", // 按 manual 的顺序引入 }) } arr.push(new HtmlWebpackPlugin(conf)) }) return arr}
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
以上我们仍然是使用 glob 读取所有模板文件,然后将其遍历并设置每个模板的 config,同时针对一些自定义配置和生产环境的配置进行了 merge 处理,其中自定义配置的功能我会在下节进行介绍,这里介绍一下生产环境下 minify
配置的作用:将 html-minifier 的选项作为对象来缩小输出。
html-minifier 是一款用于缩小 html 文件大小的工具,其有很多配置项功能,包括上述所列举的常用的删除注释、空白、引号等。
配置多模板配置
/* vue.config.js */const utils = require('./build/utils')module.exports = { ... configureWebpack: config => { config.entry = utils.getEntries() // 直接覆盖 entry 配置 return { plugins: [...utils.htmlPlugin()] // 使用 return 一个对象会通过 webpack-merge 进行合并,plugins 不会置空 } }, ...}
2
3
4
5
6
7
8
9
10
11
12
这时候我们运行命令 yarn build
后你会发现 dist 目录下生成了 3 个 html 文件,分别是 index.html、page1.html 和 page2.html。
#2. 模板渲染
总结
基于以上多页应用的认识,多页应用典型场景:pc 端扫码登录页面,主页面用 vue 开发,移动端 h5 页面新建一个 html 文件,用原生 js 开发;配置多页面,扫码后手机端进入项目写好的 h5 页面。
#2.1. 模板渲染
这里所说的模板渲染是在我们的 html 模板文件中使用 html-webpack-plugin 提供的 default template 语法进行模板编写,比如:
<!DOCTYPE html><html> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width,initial-scale=1.0" /> <title>模板</title> <% for (var chunk in htmlWebpackPlugin.files.css) { %> <% if(htmlWebpackPlugin.files.css[chunk]) {%> <link href="<%= htmlWebpackPlugin.files.css[chunk] %>" rel="stylesheet" /> <%}%> <% } %> </head> <body> <div id="app"></div> <!-- built files will be auto injected --> <% for (var chunk in htmlWebpackPlugin.files.js) { %> <% if(htmlWebpackPlugin.files.js[chunk]) {%> <script type="text/javascript" src="<%= htmlWebpackPlugin.files.js[chunk] %>" ></script> <%}%> <% } %> </body></html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
我们通过配置
htmlWebpackPlugin.files
可以获取打包输出的 js 及 css 文件路径,包括入口文件路径等
"htmlWebpackPlugin": { "files": { "css": [ "main.css" ], "js": [ "assets/head_bundle.js", "assets/main_bundle.js"], "chunks": { "head": { "entry": "assets/head_bundle.js", "css": [ "main.css" ] }, "main": { "entry": "assets/main_bundle.js", "css": [] }, } }}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
需要注意的是如果你在模板中编写了插入对应 js 及 css 的语法,你需要设置
inject
的值为 false 来关闭资源的自动注入:
/* utils.js */...let conf = { entry: filePath, // page 的入口 template: filePath, // 模板路径 filename: filename + '.html', // 生成 html 的文件名 chunks: ['manifest', 'vendor', filename], inject: false, // 关闭资源自动注入}...
2
3
4
5
6
7
8
9
10
#2.2. 自定义配置
如果遇到需要根据不同环境来引入不同资源,同时不同模板间的配置还可能不一样的需求情况的话,我们使用自定义配置会比较方便。比如我们需要在生产环境模板中引入第三方统计脚本
/* vue.config.js */module.exports = { ... pages: utils.setPages({ addScript() { if (process.env.NODE_ENV === 'production') { return ` <script src="https://s95.cnzz.com/z_stat.php?id=xxx&web_id=xxx" language="JavaScript"></script> ` } return '' } }), ...}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
然后在页面模板中通过 htmlWebpackPlugin.options
获取自定义配置对象并进行输出:
<% if(htmlWebpackPlugin.options.addScript){ %> <%= htmlWebpackPlugin.options.addScript() %><%}%>
2
3
同时你也可以针对个别模板进行配置,比如我想只在 Index 单页中添加统计脚本,在 Page1 单页中添加其他脚本,那么你可以给 addScript 传入标识符来进行判断输出,比如:
<% if(htmlWebpackPlugin.options.addScript){ %> <%= htmlWebpackPlugin.options.addScript('index') %><%}%>
2
3
同时为 addScript 方法添加参数 from:
addScript(from) { if (process.env.NODE_ENV === 'production') { let url = "https://xxx"; if (from === 'index') { url = "https://s95.cnzz.com/z_stat.php?id=xxx&web_id=xxx"; } return ` <script src=${url} language="JavaScript"></script> ` } return ''}
2
3
4
5
6
7
8
9
10
11
12
这样我们就完成了自定义配置中的模板渲染功能。当然根据实际项目需求你的自定义配置项可能会更加复杂和灵活。
总结
了解 vue 项目创建过程以及其目录结构,在开发中需要注意的地方,能够更好地规范前端开发