webpack多页运用架构系列(十二):应用webpack天生HTML一般网页&页面模板

本文首发于
Array_Huang的手艺博客——
有用至上,非经作者赞同,请勿转载。

原文地点:
https://segmentfault.com/a/1190000007126268

假如您对本系列文章感兴趣,迎接关注定阅这里:
https://segmentfault.com/blog/array_huang

为何要用webpack来天生HTML页面

根据我们前面的十一篇的内容来看,本身写一个HTML页面,然后在上面加载webpack打包的js或别的范例的资本,觉得不也用得好好的么?

是的没错,不必webpack用requireJs实在也能够啊,以至于,传统那种人工治理模块依靠的做法也没有什么问题嘛。

但既然你都已看到这一篇了,想必早已和我一样,追求着以下这几点吧:

  • 更懒,能自动化的事变绝不做第二遍。
  • 更宁神,调通的代码比人靠谱,更不轻易失足。
  • 代码洁癖,什么东西该放哪,一点都不能暧昧,混在一同我就要死了。

那末,空话不多说,下面就来讲说运用webpack天生HTML页面有哪些优点吧。

对多个页面共有的部份完成复用

在现实项目的开辟历程当中,我们会发明,虽然一个项目里会有很多个页面,但这些页面总有那末几个部份是相同或类似的,尤其是页头页尾,基本上是完全一致的。那我们要怎样处置惩罚这些共有的部份呢?

复制粘贴流

不就是复制粘贴的事嘛?写好一份完全的HTML页面,做下个页面的时刻,直接copy一份文件,然后直接在copy的文件上举行修正不就好了吗?

谁是这么想这么做的,放学留下来,我保证不打死你!我曾接受过这么一套体系,顶部栏菜单想加点东西,就要每一个页面都改一遍,可维护性烂到爆啊。

Iframe流

Iframe流常见于治理背景类项目,可维护性OK,就是缺点比较多,比方说:

  • 点击某个菜单,页面是加载出来了然则浏览器地点栏上的URL没变,革新的话又回到首页了。
  • 搜索引擎收录垮台,前台项目平常不能用Iframe来规划。
  • 没有逼格,Low爆了,这是最主要的一点(大误)。

SPA流

近来这几年,跟着挪动互联网的鼓起,SPA也变得异常常见了。不过SPA的局限性也异常大,比方搜索引擎没法收录,但我个人最在乎的,是它太庞杂了,尤其是一些原本营业逻辑就多的体系,很轻易懵圈。

后端模板衬着

这倒真是一个要领,只是,须要后端的合营,运用后端代码把页面的各个部份给拼合在一同,所以这要领对前端起身的程序员照样有点门坎的。

运用前端模板引擎天生HTML页面

所谓“用webpack天生HTML页面”,实在也并非webpack起的核心作用,现实上靠的照样前端的模板引擎将页面的各个部份给拼合在一同来到达大众地区的复用。webpack更多的是构造兼顾全部天生HTML页面的历程,并供应更大的掌握力。终究,webpack天生的究竟是完全的页面,照样供后端衬着的模板,就全看你本身把控了,异常天真,外人以至发觉不出来这究竟是你本身写的照样代码一致天生的。

处置惩罚资本的动态途径

假如你想用在文件名上加hash的要领作为缓存计划的话,那末用webpack天生HTML页面就成为你唯一的挑选了,因为跟着文件的更改,它的hash也会变化,那末全部文件名都邑转变,你总不能在每次编译后都手动修正加载途径吧?照样宁神交给webpack吧。

自动加载webpack天生的css、less

假如你运用webpack来天生HTML页面,那末,你能够设置好每一个页面加载的chunk(webpack打包后天生的js文件),天生出来的页面会自动用<script>来加载这些chunk,途径什么的你都不必管了哈(固然条件是你设置好了output.publicPath)。别的,用extract-text-webpack-plugin打包好的css文件,webpack也会帮你自动添加到<link>里,相称轻易。

完全星散源文件目次和天生文件目次

运用webpack天生出来的HTML页面能够很安心肠跟webpack打包好的别的资本放到一同,相关于另起一个目次特地寄存HTML页面文件来讲,全部文件目次构造越发合理:

build
  - index
    - index
      - entry.js
      - page.html
    - login
      - entry.js
      - page.html
      - styles.css

怎样运用webpack天生HTML页面

webpack天生HTML页面主如果经由过程html-webpack-plugin来完成的,下面来引见怎样完成。

html-webpack-plugin的设置项

每一个html-webpack-plugin的对象实例都只针对/天生一个页面,因而,我们做多页运用的话,就要设置多个html-webpack-plugin的对象实例:

pageArr.forEach((page) => {
  const htmlPlugin = new HtmlWebpackPlugin({
    filename: `${page}/page.html`,
    template: path.resolve(dirVars.pagesDir, `./${page}/html.js`),
    chunks: [page, 'commons'],
    hash: true, // 为静态资本天生hash值
    minify: true,
    xhtml: true,
  });
  configPlugins.push(htmlPlugin);
});

pageArr现实上是各个chunk的name,因为我在output.filename设置的是'[name]/entry.js',因而也起到构建文件目次构造的结果(详细请看这里),附上pageArr的定义:

module.exports = [
  'index/login',
  'index/index',
  'alert/index',
  'user/edit-password', 'user/modify-info',
];

html-webpack-plugin的设置项真不少,这里仅列出多页运用经常使用到的设置:

  • filename,天生的网页HTML文件的文件名,注重能够运用/来掌握文件目次构造的,其终究天生的途径,是基于webpack设置中的output.path的。
  • template,指定一个基于某种模板引擎语法的模板文件,html-webpack-plugin默许支撑ejs花样的模板文件,假如你想运用别的花样的模板文件,那末须要在webpack设置里设置好响应的loader,比方handlebars-loaderhtml-loader啊之类的。假如不指定这个参数,html-webpack-plugin会运用一份默许的ejs模板举行衬着。假如你做的是简朴的SPA运用,那末这个参数不指定也行,但关于多页运用来讲,我们就依靠模板引擎给我们拼装页面了,所以这个参数异常主要。
  • inject,指导把加载js文件用的<script>插进去到哪里,默许是插到<body>的末端,假如设置为’head’,则把<script>插进去到<head>里。
  • minify,天生紧缩后的HTML代码。
  • hash,在html-webpack-plugin担任加载的js/css文件的网址末端加个URL参数,此URL参数的值是代表本次编译的一个hash值,每次编译后该hash值都邑变化,属于缓存处理计划。
  • chunks,以数组的情势指定由html-webpack-plugin担任加载的chunk文件(打包后天生的js文件),不指定的话就会加载一切的chunk。

天生一个简朴的页面

下面供应一份供天生简朴页面(之所以说简朴,是因为不指定页面模板,仅用默许模板)的设置:

var HtmlWebpackPlugin = require('html-webpack-plugin');
var webpackConfig = {
  entry: 'index.js',
  output: {
    path: 'dist',
    filename: 'index_bundle.js'
  },
  plugins: [new HtmlWebpackPlugin({
    title: '简朴页面',
    filename: 'index.html',
  })],
};

运用这份设置编译后,会在dist目次下天生一个index.html,内容以下所示:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>简朴页面</title>
  </head>
  <body>
    <script src="index_bundle.js"></script>
  </body>
</html>

因为没有指定模板文件,因而天生出来的HTML文件唯一最基本的HTML构造,并不带本质内容。能够看出,这更适合React这类把HTML藏js里的计划。

运用模板引擎猎取更大的掌握力

接下来,我们演示怎样经由过程制订模板文件来天生HTML的内容,因为html-webpack-plugin原生支撑ejs模板,因而这里也以ejs作为演示对象:

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
    <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1" /> 
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body>
    <h1>这是一个用<b>html-webpack-plugin</b>天生的HTML页面</h1>
    <p>人人细致瞧好了</p>
  </body>
</html>

‘html-webpack-plugin’的设置里也要指定template参数:

var HtmlWebpackPlugin = require('html-webpack-plugin');
var webpackConfig = {
  entry: 'index.js',
  output: {
    path: 'dist',
    filename: 'index_bundle.js'
  },
  plugins: [new HtmlWebpackPlugin({
    title: '根据ejs模板天生出来的页面',
    filename: 'index.html',
    template: 'index.ejs',
  })],
};

那末,末了天生出来的HTML文件会是如许的:

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
    <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1" /> 
    <title>根据ejs模板天生出来的页面</title>
  </head>
  <body>
    <h1>这是一个用<b>html-webpack-plugin</b>天生的HTML页面</h1>
    <p>人人细致瞧好了</p>
    <script src="index_bundle.js"></script>
  </body>
</html>

到这里,我们已能够掌握全部HTML文件的内容了,那末天生后端衬着所需的模板也就不是什么难事了,以PHP的模板引擎smarty为例:

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
    <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1" /> 
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body>
    <h1>这是一个用<b>html-webpack-plugin</b>天生的HTML页面</h1>
    <p>人人细致瞧好了</p>
    <p>这是用smarty天生的内容:<b>{$articleContent}</b></p>
  </body>
</html>

处置惩罚资本的动态途径

接下来在上面例子的基础上,我们演示怎样处置惩罚资本的动态途径:

var HtmlWebpackPlugin = require('html-webpack-plugin');
var webpackConfig = {
  entry: 'index.js',
  output: {
    path: 'dist',
    filename: 'index_bundle.[chunkhash].js'
  },
  plugins: [new HtmlWebpackPlugin({
    title: '根据ejs模板天生出来的页面',
    filename: 'index.html',
    template: 'index.ejs',
  })],
  module: {
    loaders: {
      // 图片加载器,相同file-loader,更适合图片,能够将较小的图片转成base64,削减http要求
      // 以下设置,将小于8192byte的图片转成base64码
      test: /\.(png|jpg|gif)$/,
      loader: 'url?limit=8192&name=./static/img/[hash].[ext]',
    },
  },
};
<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
    <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1" /> 
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body>
    <h1>这是一个用<b>html-webpack-plugin</b>天生的HTML页面</h1>
    <p>人人细致瞧好了</p>
    <img src="<%= require('./imgs/login-bg.jpg')  %>" />
  </body>
</html>

我们改动了什么呢?

  1. 参数output.filename里,我们添了个变量[chunkhash],这个变量的值会随chunk内容的变化而变化,那末,这个chunk文件终究的途径就会是一个动态途径了。
  2. 我们在页面上添加了一个<img>,它的src是require一张图片,响应地,我们设置了针对图片的loader设置,假如图片比较小,require()就会返回DataUrl,而假如图片比较大,则会拷贝到dist/static/img/目次下,并返回新图片的途径。

下面来看看,究竟html-webpack-plugin能不能处置惩罚好这些动态的途径。

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
    <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1" /> 
    <title>根据ejs模板天生出来的页面</title>
  </head>
  <body>
    <h1>这是一个用<b>html-webpack-plugin</b>天生的HTML页面</h1>
    <p>人人细致瞧好了</p>
    <img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAAaAFADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD29Y4fJkm1BxJLCkYuHZHSHdH8+9EYkDls5BJ4ALEpxxjfETw1c3McU9tdSaW0ssZubq0MkZkbuHZiQu1nBXbnDgfKBg7niC3uJfCmqyQQ3dvLLBKsiTT+YwVTIwKqC6/MTjAwdjAZBRVHiFxNZnwFZxgxPfR6jIQox5iRsiZPqFJAz67e5FcVfEShPTok/W7tY4sViJ0pJQ03/D7j6J+0XEtzHDCsSr5SyyysHZeWGFTgK2QJOd2V+QlSGrB1LxFqh1+40/SvD76ibDY8ki34gAZ1OAQR8wwenPODjIFafhvY2jWUnlwCQ2duA6Nlnj2Aru44+Yvgcjvnkgc9c+HbaefW9ZbxTqFtEJXeYafKEEOxcEPt3FiAoOOCM9ATXVU3tH+rHqYZxtzVFbRd+vprsdHpd9dyqovNKubW7mbfPF53mxwghgp3khSD5YyqZILgkDcWqyLpbHTZrnUJFght/MZ5JDgLGpOGJ3N/CAck5PUgHgYvhLU7m80m8kupWvb2zlktmaNgvniNm2sFJCqWyRnjOOTxxz/jXWLifxLYaXPoGtahoCIt3K2nWhmS6lzlI2OQuwYDEZOTtzgZzrSjGrJW7X+RNWEoSaa2f9f0zY8G+Im8T6PqGpW9ggubW8ure2+0M6F1LB1DFgzRg5QEDIG3gYAUa2u6/p3hTTGurx5GBcssKuGlfc43bQzDIG7OM4A4HYVwvwl1xDDr9odC1GwRL+4uiBat5MQ+UeSuACXX+4FBwBx2q/8AGJHbwvaMqkqt4NxA6fI1XjoqhN8q7foPCU1WrKE31aNnQ/iDo2u6p/ZsaXVrdlQyR3UYUvldwxgn+Eg84yCMZrS/tJdOura1nH2ayjs7mWSW7l3MqwtGodnLH5SrFiWOcYzg5FeTQXlvd/EXwuYLiKbbbWqMUbOGCjI+ozyO1eo6syzeIYrZHTzv7OuIgjXLW5Z5SpjVXX5gSIJTlASoQn0zjGTcbef5G+IoQpzVuqv6GrfwXs0Z+xXv2eTy3X5ow4JI+VuehBx6jBYEHII8lvPBXizVoE0660iwikF2ZH1OIwxq64xyiAMecnJGeegr1Pw3LJP4X0iaaRpJZLKFndzlmJQEknua06xqUI1XeX9df6sebiKCq+7J2tfYpW+mRW8Onp5k5NlGI4yszKrfLt+ZQdrcdNwODyMVhaj4FtL/AFS6vItS1LTlugpmj0+4MQlcE5Z+oORgYwO+c7q6SSztpYriKS3heO5BE6MgIlyoU7h/F8oA57DFTV0SjzJSl5m9NujpDQzdNtLfRLOHS7aAhUSR4lhiYLtDDgsSRu+YdWBY7iBgHFmeGNpoy9u84kZQ2WBSPZl1cqxwPmwMqCclewyLNYXhj/iZ+BNG+3/6X9q0yDz/AD/n83dEN27P3s5Oc9c1UYX1+X5icmSWGgafo0N6Astwl7qBvXWVBJtmZ1IIAXgKwUgn7uMk8ZqDxfp+sX+gzQ6NND9oLhmhuIo3SVAOUw6kdcHnv3Aq5qsskeo6IqSOqyXrK4VsBh9nmOD6jIB+oFalZzbqaSY6dTknzJapnlmg+DtbuvFWm6tqOlwaTDZRR7o43iPmuoOSFj+Vcnk/XjNdlDCqeL727S3YyQaTbokCLHuIMkx2gnofkAxuC+vQEdDRUqCW39XNqmJlUfvLpY//2Q==" />
    <script src="index_bundle.c3a064486c8318e5e11a.js"></script>
  </body>
</html>

明显,html-webpack-plugin成功地将chunk加载了,又处置惩罚好了转化为DataUrl花样的图片,这一切,都是我们手工难以完成的事变。

还未完毕

至此,我们完成了运用webpack天生HTML页面并尝到了它所带来的甜头,但我们还没有完成“对多个页面共有的部份完成复用”,下一篇《webpack多页运用架构系列(十三):构建一个简朴的模板规划体系》我们就来引见这部份的内容。

示例代码

诸位看本系列文章,搭配我在Github上的脚手架项目食用更佳哦(笑):Array-Huang/webpack-seedhttps://github.com/Array-Huang/webpack-seed)。

附系列文章目次(同步更新)

本文首发于
Array_Huang的手艺博客——
有用至上,非经作者赞同,请勿转载。

原文地点:
https://segmentfault.com/a/1190000007126268

假如您对本系列文章感兴趣,迎接关注定阅这里:
https://segmentfault.com/blog/array_huang

    原文作者:array_huang
    原文地址: https://segmentfault.com/a/1190000007126268
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞