3.x 에서 4.x 으로 업그레이드

Jekyll 4 에서 변경된 점이 몇 가지 있습니다.

시작하기에 앞서, 최소 2.4.0 이상 버전의 루비가 설치되어 있어야 합니다.

다음 명령어를 실행해 확인해보세요

ruby -v
ruby 2.6.3p62 (2019-04-16 revision 67580)

사용중인 루비 버전이 2.4.0 이상이라면, Jekyll 최신 버전 다운로드를 진행하세요:

gem update jekyll
post_url 태그와 Baseurl


이제 post_url 태그 자체에 relative_url 필터가 포함되어 있기 때문에 포스트의 url 값의 앞부분에 사이트의 baseurl 를 자동으로 추가합니다.

코드 post_url 이 사용된 모든 부분을 다음과 같이 변경하기 바랍니다:

- {{ site.baseurl }}/{% post_url 2018-03-20-hello-world.markdown %}
+ {% post_url 2018-03-20-hello-world.markdown %}

템플릿 렌더링

전체적인 빌드 시간을 향상시키기 위해 Jekyll 이 템플릿을 분석하고 렌더링하는 방식을 약간 변경했습니다. 이제 Jekyll 은 템플릿을 한 번만 분석하고, 내부적으로 캐시한 뒤 분석된 템플릿을 페이지와 문서에서 필요로 하는 만큼 여러번 렌더링합니다.

이 방식의 단점은 커뮤니티에서 제작된 몇몇 플러그인들이 기존처럼 작동하지 않을 수도 있다는 점입니다.

렌더링되지 않은 컬렉션의 정적 파일

posts 를 제외한 컬렉션에는 마크다운 파일과 함께 정적 파일들이 존재할 수 있습니다. 하지만 컬렉션의 메타 데이터에 output: true 가 설정되어 있지 않으면, 해당 컬렉션의 문서 들과 정적 파일 모두 목적지 디렉토리에 생성되지 않습니다.

For plugin authors

  • If your plugin depends on the following code: site.liquid_renderer.file(path).parse(content), note that the return value (template, an instance of Liquid::Template), from that line will always be the same object for a given path.
    The template instance is then rendered as previously, with respect to the payload passed to it. You’ll therefore have to ensure that payload is not memoized or cached in your plugin instance.

  • If its a requirement that template you get from the above step be different at all times, you can invoke Liquid::Template directly:

    - template = site.liquid_renderer.file(path).parse(content)
    + template = Liquid::Template.parse(content)

Exclusion changes

We’ve enhanced our default exclusion array. It now looks like the following:

# default excludes
- .sass-cache/
- .jekyll-cache/
- gemfiles/
- Gemfile
- Gemfile.lock
- node_modules/
- vendor/bundle/
- vendor/cache/
- vendor/gems/
- vendor/ruby/

What’s new is that this array does not get overridden by the exclude array in the user’s config file anymore. The user’s exclude entries simply get added to the above default array (if the entry isn’t already excluded).

To forcibly “process” directories or files that have been excluded, list them in the include array instead:

# overrides your excluded items configuration and the default include array ([".htaccess"])
  - .htaccess
  - node_modules/uglifier/index.js

The above configuration directs Jekyll to handle only node_modules/uglifier/index.js while ignoring every other file in the node_modules directory since that directory is “excluded” by default.

Note that the default include array still gets overridden by the include array in your config file. So, be sure to add .htaccess to the list if you need that file to be present in the generated site.

Kramdown v2

Jekyll has dropped support for kramdown-1.x entirely.

From v2.0 onwards kramdown requires specific extensions to be additionally installed to use certain features are desired outside of kramdown’s core functionality.

Out of all the extensions listed in the report linked above, gem kramdown-parser-gfm is automatically installed along with Jekyll 4.0. The remaining extensions will have to be manually installed by the user depending on desired funtionality, by listing the extension’s gem-name in their Gemfile.


  • kramdown-converter-pdf will be ignored by Jekyll Core. To have Jekyll convert Markdown to PDF you’ll have to depend on a plugin that subclasses Jekyll::Converter with the required methods.

    For example:

    module Jekyll
      External.require_with_graceful_fail "kramdown-converter-pdf"
      class Markdown2PDF < Converter
        safe true
        priority :low
        def matches(ext)
          # match only files that have an extension exactly ".markdown"
          ext =~ /^\.markdown$/
        def convert(content)
        def output_ext
  • Vendors that provide a versioned Jekyll Environment Image (e.g. Docker Image, GitHub Pages, etc) will have to manually whitelist kramdown’s extension gems in their distributions for Jekyll 4.0.

Deprecated Configuration Options

Jekyll 4.0 has dropped support for all legacy configuration options that were deprecated over multiple releases in the previous series.

To that end, we shall no longer output a deprecation warning when we encounter a legacy config key nor shall we gracefully assign their values to the newer counterparts. Depending on the key, it shall either be ignored or raise an InvalidConfigurationError error if the key is still valid but the associated value is not of the valid type.