123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- const path = require('path');
- // 缓存已读取过的数据
- let cache = {};
- const createHtml = require('./createHtml');
- const getTemplate = require('./getTemplate');
- class CreateHtmlPlugin {
- constructor({templateMap, beforeAppendCss, beforeAppendJs}) {
- // 存储静态文件相关信息, 包含css和js信息
- this.assetsMap = {};
- // 存储已经更新过的文件路径,并且标记是否需要更新
- this.updated = {};
- // 入口对应的html文件绝对路径
- this.templateMap = getTemplate(templateMap);
- // 在插入css前需要处理的函数
- this.beforeAppendCss = beforeAppendCss;
- // 在插入js前需要处理的函数
- this.beforeAppendJs = beforeAppendJs;
- this.apply = this.apply.bind(this);
- }
- apply(compiler) {
- const {output} = compiler.options;
- compiler.hooks.done.tapAsync('CreateHtmlPlugin', (stat, callback) => {
- // 取到生成的静态文件路径
- let assetsList = Object.keys(stat.compilation.assets);
- assetsList.map((item) => {
- // 解析路径信息成一个对象
- let fileInfo = path.parse(item);
- // 只对css和js文件进行处理
- if (fileInfo.ext === '.js' || fileInfo.ext === '.css') {
- if (!this.assetsMap[fileInfo.dir]) {
- this.assetsMap[fileInfo.dir] = {};
- }
- let currentFile = this.assetsMap[fileInfo.dir];
- // 当assetsMap没有存储过当前文件信息,或者当前存储的文件名字改变了
- // 就说明有更新,需要重新进行编译
- // 文件名字改变针对的是文件名带有hash值
- if (
- !this.assetsMap[fileInfo.dir][fileInfo.ext] ||
- this.assetsMap[fileInfo.dir][fileInfo.ext].name !== fileInfo.name
- ) {
- // 将需要更新标记置为true
- this.updated[fileInfo.dir] = true;
- // 并且将存储的信息更新成当前信息
- currentFile[fileInfo.ext] = fileInfo;
- }
- // 判断是否需要更新html
- if (this.updated[fileInfo.dir]) {
- // 更新前提是js和css都要有
- if (
- this.assetsMap[fileInfo.dir]['.css'] &&
- this.assetsMap[fileInfo.dir]['.js']
- ) {
- // 更新过的文件需要将标记置否
- this.updated[fileInfo.dir] = false;
- // 拿到默认的模版内容
- let content = this.templateMap['default'].content;
- // 拿到默认模版的文件名
- let templateName = path.basename(this.templateMap['default'].templatePath);
- // 将静态文件路径和模版一一对应起来,缓存起来
- // 如果有缓存,直接读取缓存
- if (cache[item]) {
- content = cache[item]
- } else {
- for (let key in this.templateMap) {
- // 如果静态文件路径和模版定义的入口路径匹配,则取匹配模版
- if (item.indexOf(key) >= 0) {
- // 缓存模版
- cache[item] = this.templateMap[key];
- // 取出对应模版内容
- content = this.templateMap[key].content;
- // 取出对应模版名字
- templateName = path.basename(this.templateMap[key].templatePath);
- break;
- } else {
- // 没有对应模版的入口文件,则取默认模版
- cache[item] = this.templateMap['default'].content;
- }
- }
- }
- /**
- * 适配移动端模板
- * 判断是否html模板中含有configjs或configcss
- * 没有就不能添加,否则会出现移动端引用uap文件报错
- */
- let hasAppendJs = /<%= configjs %>/.test(content);
- let hasAppendCss = /<%= configcss %>/.test(content);
- content = content.replace(/(<%= configjs %>|<%= configcss %>)/g, '');
- // 生成html文件
- createHtml(this.assetsMap[fileInfo.dir], content, templateName, output.publicPath, output.path, hasAppendCss && this.beforeAppendCss, hasAppendJs && this.beforeAppendJs);
- }
- }
- }
- });
- callback();
- })
- }
- }
- module.exports = CreateHtmlPlugin;
|