我是基于 deepseek v3 的 AI 助手
本文主要介绍了如何对Shoka主题中的JavaScript代码进行优化,以解决近200个弱警告和10余个警告的问题。文章首先提到,由于长时间未更新,作者在摸鱼时发现了这些警告,并决定进行处理。文章明确指出,优化过程中将牺牲对IE系列浏览器的支持,以换取性能和未来兼容性。 文章的核心内容包括以下几个方面: 1. **ES6语法升级**:作者首先建议升级`uglify-js`,以支持ES6语法。文章详细介绍了如何通过替换`var`为`let`或`const`来解决警告,并提供了具体的代码修改步骤。同时,作者提醒使用WebStorm的快速修复功能时需要注意代码的重新排序。 2. **处理弃用语法**:文章指出了一些已被弃用的语法,如`pageYOffset`和`webkitTransform`,并提供了替代方案。此外,作者特别提到了`execCommand`的弃用问题,并推荐使用新的`ClipboardAPI`来进行剪切板操作,详细介绍了如何替换旧代码并测试新API的使用。 3. **未来更新**:文章最后提到,优化工作仍在进行中,本文会不定期更新,以反映最新的进展。 通过这些优化,作者不仅提升了代码的性能和兼容性,还为未来的开发铺平了道路。如果你对JavaScript代码优化感兴趣,或在使用Shoka主题时遇到类似问题,这篇文章将为你提供实用的解决方案。
本篇为本站 LTS 文章,会长期更新
# 引言
最近摸了一个月鱼没有更新什么正经文章,基本都是 shoka 的改造
近期在摸鱼时发现 shoka 主题的 js 有近 200 个弱警告和 10 余个警告,就想处理一下这些警告
本文基本是兼容性换性能和未来支持,基本 IE 系列就全系不支持了
# ES6 语法
# 升级 uglifyjs
建议使用 hexo-renderer-multi-next-markdown-it , 卸载 hexo-renderer-multi-markdown-it 后安装即可
铺面而来的就是 使用了var而非let或const 这个警告,随后就直接使用了 WebStorm 的快速修复,然后 hexo g :
ERROR: Unexpected token: keyword «const» |
网上针对这个的教程都是替换为 uglify-es , 但在 npm 主页 中明确写道: support for ECMAScript is superseded by 'uglify-js' as of v3.13.0
所以直接升级 uglify-js 即可:
打开 yourblog\node_modules\hexo-renderer-multi-markdown-it\ , 随后运行 cnpm i uglify-js , 等待安装完毕。
随后打开 node_modules\hexo-renderer-multi-markdown-it\lib\filter.js , 打开第 90 行左右:
var result = UglifyJS.minify(str, options); | |
var saved = ((str.length - result.code.length) / str.length * 100).toFixed(2); | |
if (options.logger) { | |
var log = hexo.log || console.log; | |
log.log('minify the js: %s [ %s saved]', path, saved + '%'); | |
} | |
var js_result = result.code; | |
if(options.stamp) { | |
var prefix = '// build time:' + Date().toLocaleString() + "\n"; | |
var end = '\n//rebuild by hrmmi '; | |
js_result = prefix + js_result + end; | |
} | |
return js_result; |
更改为:
const uglify_v3_allow_options = ["parse", "compress", "mangle", "output", "sourceMap", "nameCache", "toplevel", "warnings"] | |
const uglify_options = {} | |
for (let key of uglify_v3_allow_options) { | |
if (options[key] !== undefined) uglify_options[key] = options[key] | |
} | |
var result = UglifyJS.minify(str, uglify_options); | |
if (!result.error) { | |
var saved = ((str.length - result.code.length) / str.length * 100).toFixed(2); | |
if (options.logger) { | |
var log = hexo.log || console.log; | |
log.log('minify the js: %s [ %s saved]', path, saved + '%'); | |
} | |
var js_result = result.code; | |
if (options.stamp) { | |
var prefix = '// build time:' + Date().toLocaleString() + "\n"; | |
var end = '\n//rebuild by kaitaku'; | |
js_result = prefix + js_result + end; | |
} | |
} else throw result.error; | |
return js_result; |
# 替换 var
建议直接使用 WebStorm 的快速修复替换,没有更快的方法了
但是需要将以下几行代码重新排序:
$.each(p + ' .md img:not(.emoji):not(.vemoji)', function (element) { | |
const $image = q(element); // 放到这个位置 | |
const imageLink = $image.attr('data-src') || $image.attr('src'); // 放到这个位置 | |
const $imageWrapLink = $image.wrap('<a class="fancybox" href="' + imageLink + '" itemscope itemtype="http://schema.org/ImageObject" itemprop="url"></a>').parent('a'); | |
let info, captionClass = 'image-info'; | |
if (!$image.is('a img')) { | |
$image.data('safe-src', imageLink) | |
if (!$image.is('.gallery img')) { | |
$imageWrapLink.attr('data-fancybox', 'default').attr('rel', 'default'); | |
} else { | |
captionClass = 'jg-caption' | |
} | |
} |
下面的代码块是错误的代码块,请手动替换下面函数内的 const 和 let , 不要使用 WebStorm 的自动替换
$.each('figure.highlight', function (element) { | |
const code_container = element.child('.code-container'); // 放到这 | |
const showBtn = code_container.child('.show-btn'); | |
const hideCode = function () { | |
code_container.style.maxHeight = "300px" | |
showBtn.removeClass('open') | |
}; |
# 处理部分弃用语法
# 杂项属性
global.js 中第 196 行的 pageYOffset 已经被标记为了弃用,可以使用 scrollY 代替,直接全局替换即可
player.js 第 470 行的 webkitTransform 已被标记为弃用,可以直接删除
# execCommand 处理
主题使用了 execCommand 进行代码块复制操作,但现在 execCommand 已经被标记为了弃用
现在已经推出了新的 ClipboardAPI 来进行剪切板操作,这个 API 有以下优点:
- 底层为异步,速度较快
- 代码复杂度低,逻辑简单
- 主流浏览器支持较好 (对于一个新兴 API 而言)
clipboardAPI 只能在安全上下文 (HTTPS) 中使用
打开 global.js 第 276 行,找到如下代码:
const clipBoard = function (str, callback) { | |
const ta = BODY.createChild('textarea', { | |
style: { | |
top: window.scrollY + 'px', // Prevent page scrolling | |
position: 'absolute', | |
opacity: '0' | |
}, | |
readOnly: true, | |
value: str | |
}); | |
const selection = document.getSelection(); | |
const selected = selection.rangeCount > 0 ? selection.getRangeAt(0) : false; | |
ta.select(); | |
ta.setSelectionRange(0, str.length); | |
ta.readOnly = false; | |
const result = document.execCommand('copy'); | |
callback && callback(result); | |
ta.blur(); // For iOS | |
if (selected) { | |
selection.removeAllRanges(); | |
selection.addRange(selected); | |
} | |
BODY.removeChild(ta); | |
} |
将其更改为如下代码:
const clipBoard = function (str, callback) { | |
if (navigator.clipboard && window.isSecureContext) { | |
console.log("使用clipboard复制") // 测试 | |
navigator.clipboard.writeText(str).then(function() { | |
callback && callback(true); | |
}, function() { | |
callback && callback(false); | |
}); | |
} else { | |
console.log("使用execCommand复制") // 测试 | |
const ta = BODY.createChild('textarea', { | |
style: { | |
top: window.scrollY + 'px', // Prevent page scrolling | |
position: 'absolute', | |
opacity: '0' | |
}, | |
readOnly: true, | |
value: str | |
}); | |
const selection = document.getSelection(); | |
const selected = selection.rangeCount > 0 ? selection.getRangeAt(0) : false; | |
ta.select(); | |
ta.setSelectionRange(0, str.length); | |
ta.readOnly = false; | |
const result = document.execCommand('copy'); | |
callback && callback(result); | |
ta.blur(); // For iOS | |
if (selected) { | |
selection.removeAllRanges(); | |
selection.addRange(selected); | |
} | |
BODY.removeChild(ta); | |
} | |
}; |
随后重新生成静态文件,打开任意界面复制代码,如果控制台输出了 使用clipboard复制 ,就可以把两行带有测试注释的代码删掉了
目前修补仍在缓慢进行中,此文章会不定期更新
