没有html模块,html-plugin-webpack无模板实践

本文是html-plugin-webpack在使用时不配置template选项, 所有html模板内容采用js代码生成.

使用html-plugin-webpack时一般都会设置template属性配置html模板, 但这有一些缺点: 在管理多个项目中, 对某个项目的模板进行优化后, 无法快速其他项目中生效. 为了解决这个问题, 可以将模板封装在基础的构建工具中, 但模板为html文件,比较限制模板的封装和扩展能力. 如果采用模板内容都通过js代码生成, 获取js的完全编码能力, 既可以封装团队中项目通用模板内容, 有保证较高的定制能力.

本文中使用的是html-plugin-webpack的v3版本, 对应npm上的官方文档, github上文档对应的是v4版本.

下文就html模板中常用的内容, 改用为js代码怎么配置.

标题

如果不配置html-webpacl-plugin的template选项, 配置title选项时, 生成的html文件中将会有标题:

module.exports = {

entry: './src/index.js',

output: {

filename: 'bundle.js',

path: path.resolve(__dirname, 'dist')

},

plugins: [

new HtmlWebpackPlugin({

title: '测试',

}),

],

};

生成的文件中:

测试

图标

设置favicon选项, html-plugin-webpack会自动将图片文件复制到output目录下, 然后使用, 会自动添加上publicPath.

module.exports = {

entry: './src/index.js',

output: {

filename: 'bundle.js',

publicPath: 'https://www.wangzhan.com/path/static',

path: path.resolve(__dirname, 'dist')

},

plugins: [

new HtmlWebpackPlugin({

favicon: './build/favicon.ico',

}),

],

};

生成的html代码中:

设置meta信息

html文件中通常需要设置许多meta信息, 通过html-webpack-html的meta选项, 可以生成这些meta信息, 如:

meta: {

author: 'xxx前端团队',

},

如果需要配置http-equiv相关, 需要以下语法:

meta: {

pragma: { 'http-equiv': 'pragma', 'content': 'no-cache' },

},

如果需要对同一个http-equiv属性设置多次值, 需要为:

cacheControl1: { 'http-equiv': 'cache-control', content: 'no-cache' },

cacheControl2: { 'http-equiv': 'cache-control', content: 'no-siteapp' },

cacheControl3: { 'http-equiv': 'cache-control', content: 'no-transform' },

一个完整的配置:

const path = require('path');

const HtmlWebpackPlugin = require('html-webpack-plugin');

const WebpackConcatPlugin = require('webpack-concat-plugin');

const HtmlCodePlugin = require('./build/webpack-plugin-html-code');

module.exports = {

entry: './src/index.js',

output: {

filename: 'bundle.js',

publicPath: 'https://www.wangzhan.com/path/static',

path: path.resolve(__dirname, 'dist')

},

plugins: [

new HtmlWebpackPlugin({

meta: {

author: 'xxx前端团队',

cacheControl1: { 'http-equiv': 'cache-control', content: 'no-cache' },

cacheControl2: { 'http-equiv': 'cache-control', content: 'no-siteapp' },

cacheControl3: { 'http-equiv': 'cache-control', content: 'no-transform' },

expires: { 'http-equiv': 'expires', content: '0' },

compatible: { 'http-equiv': 'X-UA-Compatible', content: 'IE=edge,chrome=1' },

},

}),

],

};

生成的html代码:

额外的资源

html中通常需要一些额外的资源, 如一些库(jquery, vue)全局提供, 一些polyfill等. 这里推荐使用html-webpack-tags-plugin.

html-webpack-tags-plugin可以添加一些额外的资源标签, 注意, 只是添加标签, 不会对目标资源文件做任何其他操作. 所以如果使用html-webpack-tags-plugin, 需要配合copy-webpack-plugin使用, 把额外的资源文件(可能在node_modules中)复制到复制到output目录下.

这里以导入的谷歌分析文件为例, 假如在项目根目录下有谷歌分析单页面应用插件autotrack:

|--assets

|--autotrack.min.js

|--autotrack.min.js.map

配置:

module.exports = {

entry: './src/index.js',

output: {

filename: 'bundle.js',

publicPath: '/',

path: path.resolve(__dirname, 'dist')

},

plugins: [

new HtmlWebpackPlugin({

title: '测试',

}),

new CopyWebpackPlugin([{

from: './assets',

to: './',

toType: 'dir',

}]),

new HtmlWebpackTagsPlugin({

tags: [{

path: 'autotrack/autotrack.js',

attributes: {

async: 'true',

},

}],

scripts: [{

path: 'https://www.google-analytics.com/analytics.js',

attributes: {

type: 'text/javascript',

async: 'true',

},

append: false,

}],

}),

],

};

生成的dist目录:

|--dist

|--autotrack

|--autotrack.min.js

|--autotrack.min.js.map

|--bundle.js

|--index.html

html代码内容:

测试

也可以使用html-webpack-tags-plugin的增强库html-webpack-deploy-plugin

内联js代码或者其他直接在html中引用的js代码

在html文件中, 通常还会包含一些内联的js代码或者引用的非第三方代码, 如配置谷歌分析使用的代码,这些代码跟当前业务无关, 也不想放在webpack中打包.

推荐使用webpack-concat-plugin), 它比html-webpack-tags-plugin的好处是支持对导入的js文件进行压缩.

webpack-concat-plugin对于目标js资源, 会自动复制到当前ouput目录下, 所以不需要配合copy-webpack-plugin使用.

假如google-analytics-starter.js:

;((function(){

window.ga = window.ga || function () { (ga.q = ga.q || []).push(arguments) }; ga.l = +new Date;

ga('create', 'UA-63187412-4', 'auto');

ga('require', 'eventTracker');

ga('require', 'outboundLinkTracker');

ga('require', 'urlChangeTracker');

ga('send', 'pageview');

})());

webpack配置:

module.exports = {

entry: './src/index.js',

output: {

filename: 'bundle.js',

publicPath: '/',

path: path.resolve(__dirname, 'dist')

},

plugins: [

new HtmlWebpackPlugin({

title: '测试',

}),

new WebpackConcatPlugin({

uglify: false,

sourceMap: false,

name: 'google-analytics-starter',

outputPath: 'static',

fileName: '[name].[hash:8].js',

filesToConcat: [path.resolve(__dirname, './google-analytics-starter.js')],

}),

],

};

生成的html:

测试

对于内联代码, 建议抽取为一个一个js文件, 通过webpack-concat-plugin引用外链.对于可能造成的资源请求过多, webpack-concat-plugin可以配置filesToConcat为一个目录(多个目录也行), 会整体打成一个包.

当然也可以配合其他插件或者自己实现插件, 内联js代码.

其他额外的代码

在html模板中, 通常还需要设置一些其他的内容, 比如供渲染框架挂载的dom元素.

这种框架暂时还未在市面上找到, 不过可以编写一个简单的html-plugin-webpack插件实现:

const _ = require('lodash');

function resetOptionToFn(option) {

if (_.isArray(option)) {

return (tags) => {

tags.push(...option);

};

}

if (_.isPlainObject(option)) {

if (option.before || option.after) {

return (tags) => {

tags.unshift(...[].concat(option.before || []));

tags.push(...[].concat(option.after || []));

};

}

return (tags) => {

tags.push(option);

};

}

return () => {};;

}

module.exports = class HtmlCodePlugin {

constructor({

body,

head,

} = {}) {

this.body = resetOptionToFn(body);

this.head = resetOptionToFn(head);

}

apply(_compiler) {

const compiler = _compiler;

compiler.hooks.compilation.tap(this.constructor.name, (compilation) => {

compilation.hooks.htmlWebpackPluginAlterAssetTags.tapAsync(this.constructor.name, async (data, cb) => {

try {

this.body(data.body);

this.head(data.head);

cb(null, data);

} catch (error) {

cb(error, null);

}

});

});

}

};

然后在webpack中使用:

module.exports = {

entry: './src/index.js',

output: {

filename: 'bundle.js',

publicPath: '/',

path: path.resolve(__dirname, 'dist')

},

plugins: [

new HtmlWebpackPlugin({

title: '测试',

}),

new MyPlugin({

body: {

tagName: 'div',

selfClosingTag: false,

voidTag: false,

attributes: {

id: 'app',

},

},

}),

],

};

生成的html代码:

测试

对于其他的如注释代码, HTML中IE判断语句if !IE都可以自己实现html-webpacl-plugin实现.

写在最后

上文中列举了许多html模板中的内容怎么用js去配置, 这对使用统一构建工具构建多个项目的团队非常有用. 利用js的编程能力, 可以把团队通用的模板配置内容封装在构建工具内, 并提供对项目中对模板内容定制提供api, 提供封装和扩展能力.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值