Hexo is a Nodejs-powered static site generator. It offers powerful API to integrate existing npm packages for web development and programmatically inserts certain content into articles.
This is our biggest release to date with tons of new features, performance improvements and bugfixes. According to our benchmark (which we run in every pull request to detect regression), Hexo 5 processed 500 posts in 16 seconds, whereas 4.2.0 processed 300 posts at the same time. Hexo now requires Nodejs 10+, Nodejs has dropped support of version 8 since 31 Dec 2019; although Nodejs 10.x is still supported, but since it’s going to be deprecated in less than a year (April 2021), we recommend using Nodejs 12+.
Refer to our installation guide to install Hexo.
To upgrade to Hexo v5, change the following line in your package.json,
- "hexo": "^4.2.1", |
Breaking change
refactor(external_link): migrate config during load_config @SukkaW #4414 #4371
- See Writing section for new options (introduced back in v4)
_config.yml # Deprecated
external_link: true|false
# New option
external_link:
enable: true|false
# Deprecated
use_date_for_updated: true
# New option
# https://hexo.io/docs/configuration#Date-Time-format
updated_option: date- If you check
external_link
for truthy value, since it’s now automatically converted to object, it will always be truthy:
<% if (config.external_link) { %>
- If you wish to maintain backward compatibility with past versions:
<% if ((typeof config.external_link === 'boolean' && config.external_link === true) || (typeof config.external_link === 'object' && config.external_link.enable === true)) { %>
feat: bring up config.updated_option @SukkaW #4278
- This can be useful for a theme that prefers to display
Updated:
only when it’s set in the article’s front-matter.
- This can be useful for a theme that prefers to display
feat(open_graph): drop ‘keywords’ option from front-matter @curbengh #4174
- Search engines no longer support
keywords
.
- Search engines no longer support
fix: override site’s permalink using an article’s front-matter @SukkaW #4359
- User config:
_config.yml permalink: :year/:month/:day/:title/
- Front-matter
source/foo-bar.md
title: foo bar
permalink: breaking-news/- That post will be available on
http://yourhexo.com/breaking-news/
- A reminder that permalink must have a trailing
.html
or/
permalink: :year/:month/:day/:title/ # default
# or
permalink: :year/:month/:day/:title.htmlRemove lodash from global variable @SukkaW #4266
- Lodash
_
is no longer available in Hexo API.
// Dropped
<% const arrayB = _.uniq(arrayA) %>- We encourage the use of native JS API over Lodash, we find this guide to be helpful.
- If you prefer to use Lodash, you can always install it and make it available via
Helper
API
- Lodash
chore/ci: drop Node.js 8 and add Node.js 14 @SukkaW #4255
- Node 8 has reached EOL on 31 Dec 2019.
refactor: remove site config from theme config @SukkaW #4145
- Previously
hexo.theme.config
is merged intohexo.config
, they are now separated to avoid possible conflict in configuration.
- Previously
New feature
feat(tag): show source of the error & beautify @SukkaW #4420
feat(post_link): better error message when a post could not be located #4426
- The error message is now clearer when there is an incorrect filename.
skip assets of unpublished posts and delete them if exist @DaemondShu #3489
- When there is an unpublished post:
title: Still a draft....
published: false- That post including its assets will not be generated into the
public/
folder.
feat(extend/injector): bring up new extend Injector @SukkaW #4049
- Refer to the API documentation for usage.
feat: add prism highlight support @SukkaW #4119
- Refer to the documentation for usage.
feat(tagcloud): new option class & level @stevenjoezhang #4370
- Ability to add class name for CSS styling.
feat(config): validate config before processing posts @SukkaW #4381
feat(post_permalink): add
:second
attribute option for post permalink @kkocdko #4185- Example:
permalink: :year/:month/:day/:hour/:minute/:second/:title.html
- Refer to Permalinks for available attributes.
feat(youtube_tag): add cookie option @curbengh #4155
- When disabled, cookie is not set/sent in the youtube video embed.
feat(youtube_tag): support playlist @SukkaW #4139
- Ability to embed a playlist.
feat(load_theme_config): support alternate theme config @SukkaW #4120
- Theme can be configured in a file
_config.[name].yml
, e.g._config.landscape.yml
for hexo-theme-landscape. - Placed the file in the root folder, same as the current
_config.yml
. - Refer to the documentation for configuration priority.
- Theme can be configured in a file
feat(feed_tag): support parsing config.feed @curbengh #4029
- Better integration with hexo-generator-feed.
feat(tag): add unregister() method @SukkaW #4046
- This means you can now unregister existing tag plugins and replace it with your own with the same name.
feat(load_config): support theme_dir in node_modules @SukkaW #4112
fix(list_tags): custom class for each element @noraj #4059
- Customize the class name for each element
<ul>
,<li>
,<a>
,<span>
for list_tags plugin.
- Customize the class name for each element
Performance
- perf(tag): rendering optimization @SukkaW #4418
- perf(external_link): faster regexp & condition shorthand @SukkaW #4436
- perf(external_link): optimize regex @SukkaW #4008
- perf(filter): shorthand syntax @SukkaW #4377
- perf(backtick_code): shorthand @SukkaW #4369
- perf: avoid running irrelevant plugins in ‘clean’ command @curbengh #4386
- To maintain compatibility with third-party console plugins, this only applies to
hexo clean
, nothexo c
alias.
- To maintain compatibility with third-party console plugins, this only applies to
- perf(titlecase): lazy require @SukkaW #4417
- perf(tag/code): performance improvements @SukkaW #4416
- perf(post): simplify codeblock escape @SukkaW #4254
- perf(meta_generator): avoid unnecessary check @SukkaW #4208
- perf(external_link): cache config @SukkaW #4134
- perf(open_graph): avoid using htmlTag() and enhance cache @SukkaW #4125
- refactor(list_archives): reduce calls to date.format() @dailyrandomphoto #4011
- fix(moment.locale): avoid lookup repeatedly with the wrong names @dailyrandomphoto #4007
Fix
- fix(box): ignore .git and node modules in the theme folder @jiangtj #4306
- fix: allow empty title @stevenjoezhang #4344
- fix(#4236): don’t create “/index” directories when post_asset_folder is true @jiangtj #4258
- fix(#4317): non-greedy regexp for tag escape @SukkaW #4358
- fix(post): use non-greedy regular expressions @stevenjoezhang #4161
- fix(post): properly escape swig tag inside post @SukkaW #4352
- swig tag inside a single backtick is now interpreted as code embed.
`{% foo %}{{ bar }}{% endfoo %}`
- fix(logging): log database only in relevant commands @curbengh #4387
Writing database to ${dbPath}/db.json
message shouldn’t show up inhexo clean
andhexo version
.
- fix(server-cache): must match exact alias @curbengh #4388
- Improve compatibility with 3rd-party console plugins that may have a name that starts with an ‘s’.
- fix(tag-code): parse ‘wrap’ option @curbengh #4391
highlight.wrap
option in user config is now properly passed to thecodeblock
tag plugin
- fix: remove unused type check @Himself65 #4398
- fix: access error code from error object directly @SukkaW #4280
- Improve compatibility with native JS API
- fix: load_plugin with extra line EOF @SukkaW #4256
- fix: parsing code error in backticks @seaoak #4229
- fix(toc_helper): escape class name and handle null id @curbengh #4009
- fix(meta_generator): match existing
<meta>
with different order @SukkaW #4017 - fix(excerpt): stricter regex @curbengh #4443
- Now only the following variants of excerpt tag are valid.
<!--more-->
<!-- more-->
<!--more -->
<!-- more -->
Refactor
- refactor(meta_generator): no longer ignore empty @SukkaW #4442
- refactor(external_link): migrate config during load_config @SukkaW #4414
- Reduce array#reduce @segayuu #4299
- Correct using createSha1Hash() with pipe() @seaoak #4323
- refactor(post): reduce promise @SukkaW #4337
- refactor: simplify code @2997ms #4408
- refactor(external_link): filter regexp @segayuu #4412
- refactor(hexo): merge theme_config before generation @SukkaW #4360
- refactor(nunjucks): dedicated nunjucks renderer @SukkaW #4356
- refactor: drop hexo-util#HashStream @SukkaW #4279
- refactor(toc): avoid using htmlTag @SukkaW #4183
- refactor(hexo_index): remove unused parameter @curbengh #4153
- Refactor(class): Replace prototype to class syntax @segayuu #4151
- refactor: copy object with spread operator @SukkaW #4140
- refactor: simplify code @Himself65 #4138
- refactor: utilize Object.entries @SukkaW #4118
- refactor: utilize hexo-util pr-169 @SukkaW #4045
- refactor(hexo/index): use Set @SukkaW #4013
- refactor: Class syntax @SukkaW #4100
- refactor(helper): minor changes @SukkaW #4061
- style: space for asyncArrow @SukkaW #4102
- Reduce stream @segayuu #4333
Misc
- refactor: port shell script to javascript @Himself65 #4405
- refactor(console/generate): class & destructure assign @SukkaW #4338
- Fix not to pass callback to hexo-fs @segayuu #4339
- style: es6 string extensions & destructure @SukkaW #4357
- Migrate Travis and Appveyor tp GitHub Actions
- ci(appveyor): drop appveyor @SukkaW #4402
- chore: add release release-drafter (#3858) @YoshinoriN #4165
- ci: add GitHub Actions to run linter @Himself65 #4143
- ci(travis): remove Windows @curbengh #4076
- ci(github_actions): Create tester job @segayuu #4169
- Move coveralls from travis to github actions @segayuu #4326
- ci(benchmark): generate flamegraph @SukkaW #4000
- ci(flamegraph): fix 0x @SukkaW #4116
- Fix issues found by lgtm.com
- refactor(benchmark): minor changes @SukkaW #4411
- github(issue_template): add special notice @SukkaW #4348
- add mandarin issue template
Refer to the release note for a complete changelog.