当前位置: 首页 > 软件库 > Web应用开发 > >

jekyll-minibundle

A minimalistic asset bundling plugin for Jekyll
授权协议 MIT License
开发语言 JavaScript
所属分类 Web应用开发
软件类型 开源软件
地区 不详
投 递 者 蒋航
操作系统 未知
开源组织
适用人群 未知
 软件概览

Jekyll Minibundle plugin

CI

A straightforward asset bundling plugin for Jekyll, utilizing externalminification tool of your choice. It provides asset concatenation forbundling and asset fingerprinting with MD5 digest for cache busting.

There are no runtime dependencies, except for the minification tool usedfor bundling (fingerprinting has no dependencies).

The plugin requires Jekyll version 3 or 4. It is tested with Ruby MRI2.5 and later.

The plugin works with Jekyll's watch mode (auto-regeneration, Jekylloption --watch), but not with incremental feature enabled (Jekylloption --incremental).

Features

There are two features: fingerprinting with MD5 digest over thecontents of the asset file (any type of file will do), and assetbundling combined with the first feature.

Asset bundling consists of concatenation and minification. The pluginimplements concatenation and leaves choosing the minification tool up toyou. UglifyJS is a good and fast minifier, for example. Theplugin connects to the minifier with standard unix pipe, feeding assetfile contents to it in desired order via standard input, and reads theresult from standard output.

Why is this good? A fingerprint in asset's path is the recommendedway to handle caching of static resources,because you can allow browsers and intermediate proxies to cache theasset for a very long time. Calculating MD5 digest over the contents ofthe file is fast and the resulting digest is reasonably unique to begenerated automatically.

Asset bundling is good for reducing the number of requests to thebackend upon page load. The minification of stylesheets and JavaScriptsources makes asset sizes smaller and thus faster to load over network.

Usage

The plugin ships as a RubyGem. To install:

  1. Add the following line to the Gemfile of your site:

    gem 'jekyll-minibundle'
  2. Run bundle install.

  3. Instruct Jekyll to load the gem by adding this line to theconfiguration file of your site (_config.yml):

    plugins:
      - jekyll/minibundle

    (Use the gems key instead of plugins for Jekyll older than v3.5.0.)

An alternative to using the plugins configuration option is to add the_plugins/minibundle.rb file to your site project with this line:

require 'jekyll/minibundle'

You must allow Jekyll to use custom plugins. That is, do not enableJekyll's safe configuration option.

Asset fingerprinting

If you just want to have an MD5 fingerprint in your asset's path, usethe ministamp Liquid tag in a Liquid template file. For example,fingerprinting CSS styles:

<link rel="stylesheet" href="{{ site.baseurl }}/{% ministamp _assets/site.css assets/site.css %}" media="screen, projection">

When it's time to render the ministamp tag, the plugin copies thesource file (_assets/site.css, the first tag argument) to thespecified destination path (assets/site.css, the second tag argument)in Jekyll's site destination directory. The filename will contain afingerprint.

The tag outputs the asset destination path, encoded for HTML, intoLiquid's template rendering outcome. For example, when site.baseurl isempty:

<link rel="stylesheet" href="/assets/site-390be921ee0eff063817bb5ef2954300.css" media="screen, projection">

Another example, this time fingerprinting an image and using theabsolute_url Liquid filter of Jekyll to renderthe absolute URL of the image in the src attribute:

<img src="{{ "/" | absolute_url }}{% ministamp _assets/dog.jpg assets/dog.jpg %}" alt="My dog smiling to the camera" title="A photo of my dog" width="195" height="258" />

This feature can be combined with asset generation tools external toJekyll. For example, you can configure Sass to take input files from_assets/styles/*.scss and to produce output to _tmp/site.css. Then,you use the ministamp tag to copy the file with a fingerprint toJekyll's site destination directory:

<link rel="stylesheet" href="{{ site.baseurl }}/{% ministamp _tmp/site.css assets/site.css %}">

ministamp call syntax

The argument for the ministamp tag must be in YAML syntax, andparsing the argument as YAML must result either in a String or aHash. What you saw previously was the argument being parsed as a String;it's effectively a shorthand version of passing the argument as a Hashwith certain keys. That is, in the following call:

{% ministamp _tmp/site.css assets/site.css %}

the argument is a String: "_tmp/site.css assets/site.css". The call isequivalent to the following call with a Hash argument:

{% ministamp { source_path: _tmp/site.css, destination_path: assets/site.css } %}

The Hash argument allows expressing more options and quotingsource_path and destination_path values, if needed.

The supported keys for the Hash argument are:

Key Required? Value type Value example Default value Description
source_path yes string '_tmp/site.css' - The source path of the asset file, relative to the site directory.
destination_path yes string 'assets/site.css' - The destination path of the asset file, relative to Jekyll's site destination directory. If the value begins with / and render_basename_only is false, ministamp's output will begin with /.
render_basename_only no boolean true false If true, ministamp's rendered URL will be the basename of the asset destination path. See Separating asset destination path from generated URL for more.

With a Hash argument, the plugin processes source_path anddestination_path values through a tiny template engine. This allowsyou to use Liquid's variables as input to ministamp tag. An examplewith Liquid's assign tag:

{% assign asset_dir = 'assets' %}
<link rel="stylesheet" href="{% ministamp { source_path: _tmp/site.css, destination_path: '{{ asset_dir }}/site.css' } %}">

The above would use assets/site.css as the destination path.

Note that you must quote destination_path's value, otherwise YAML doesnot recognize it as a proper string.

To refer to Jekyll's configuration options (_config.yml)in the template, prefix the variable name with site.. For example, torefer to baseurl option, use syntax {{ site.baseurl }} in thetemplate.

See Variable templating for details about thetemplate syntax.

Asset bundling

This is a straightforward way to bundle assets with any minificationtool that supports reading input from stdin and writing the output tostdout. You write the configuration for input sources directly into thecontent file where you want the markup tag for the bundle file toappear. The markup tag contains the path to the bundle file, and theJekyll's site destination directory will have the bundle file at thatpath. The path will contain an MD5 fingerprint.

Place the minibundle Liquid block into the Liquid template filewhere you want the block's generated markup to appear. Write bundlingconfiguration inside the block in YAML syntax. For example, to bundlea set of JavaScript sources:

{% minibundle js %}
source_dir: _assets/scripts
destination_path: assets/site
baseurl: '{{ site.baseurl }}/'
assets:
  - dependency
  - app
attributes:
  id: my-scripts
  async:
{% endminibundle %}

Then, specify the command for launching your favorite minifier in_config.yml:

baseurl: ''

minibundle:
  minifier_commands:
    js: node_modules/.bin/uglifyjs

When it's time to render the minibundle block, the plugin launches theminifier and connects to it with a Unix pipe. The plugin feeds thecontents of the asset files in source_dir directory as input to theminifier (stdin). The feeding order is the order of the files in theassets key in the block configuration. The plugin expects the minifierto produce output (stdout) and writes it to the file atdestination_path in Jekyll's site destination directory. The filenamewill contain a fingerprint.

The block outputs <link> (for css type) or <script> (for jstype) HTML element into Liquid's template rendering outcome. Continuingthe example above, the block's output will be:

<script src="/assets/site-8e764372a0dbd296033cb2a416f064b5.js" type="text/javascript" id="my-scripts" async></script>

You can pass custom attributes, like id="my-scripts" and asyncabove, to the generated markup with attributes map inside theminibundle block.

As shown above for the baseurl key, you can use Liquid template syntaxinside the contents of the block. Liquid renders block contents beforethe minibundle block gets the turn to render itself. Just ensure thatblock contents will result in valid YAML.

For bundling CSS assets, use css as the argument to the minibundleblock:

{% minibundle css %}
source_dir: _assets/styles
destination_path: assets/site
baseurl: '{{ site.baseurl }}/'
assets:
  - reset
  - common
attributes:
  media: screen
{% endminibundle %}

And then specify the minifier command in _config.yml:

minibundle:
  minifier_commands:
    css: _bin/remove_whitespace
    js: node_modules/.bin/uglifyjs

minibundle call syntax

Use css or js as the argument to the opening tag, for example {% minibundle css %}.

The block contents must be in YAML syntax. The supported keys are:

Key Value type Value example Default value Description
source_dir string - '_assets' The source directory of assets, relative to the site directory. You can use period (.) to select the site directory itself.
assets array of strings ['deps/one', 'deps/two', 'app'] [] Array of assets relative to source_dir directory, without type extension. These are the asset files to be bundled, in order, into one bundle destination file.
destination_path string - 'assets/site' The destination path of the bundle file, without type extension, relative to Jekyll's site destination directory. If the value begins with / and baseurl is empty, baseurl will be set to '/' implicitly.
baseurl string '{{ site.baseurl }}/' '' If nonempty, the bundle destination URL inside minibundle's rendered HTML element will be this value prepended to the destination path of the bundle file. Ignored if destination_baseurl is nonempty.
destination_baseurl string '{{ site.cdn_baseurl }}/' '' If nonempty, the bundle destination URL inside minibundle's rendered HTML element will be this value prepended to the basename of the bundle destination path. See Separating asset destination path from generated URL for more.
attributes map of keys to string values {id: my-link, media: screen} {} Custom HTML element attributes to be added to minibundle's rendered HTML element.
minifier_cmd string 'node_modules/.bin/uglifyjs' - Minifier command specific to this bundle. See Minifier command specification for more.

Minifier command specification

You can specify minifier commands in three places:

  1. In _config.yml (as shown earlier):

    minibundle:
      minifier_commands:
        css: _bin/remove_whitespace
        js: node_modules/.bin/uglifyjs
  2. As environment variables:

    export JEKYLL_MINIBUNDLE_CMD_CSS=_bin/remove_whitespace
    export JEKYLL_MINIBUNDLE_CMD_JS="node_modules/.bin/uglifyjs"
  3. Inside the minibundle block with minifier_cmd option, allowingblocks to have different commands from each other:

    {% minibundle js %}
    source_dir: _assets/scripts
    destination_path: assets/site
    minifier_cmd: node_modules/.bin/uglifyjs
    assets:
      - dependency
      - app
    attributes:
      id: my-scripts
    {% endminibundle %}
    

These ways of specification are listed in increasing order ofspecificity. Should multiple commands apply to a block, the mostspecific one wins. For example, the minifier_cmd option inside the {% minibundle js }% block overrides the setting in the$JEKYLL_MINIBUNDLE_CMD_JS environment variable.

Recommended directory layout

It's recommended that you exclude the files you use as asset sourcesfrom Jekyll itself. Otherwise, you end up with duplicate files in thesite destination directory.

For example, in the following snippet we're using assets/src.css asasset source to ministamp tag:

<!-- BAD: unless assets dir is excluded, both src.css and dest.css will be copied to site destination directory -->
<link rel="stylesheet" href="{{ site.baseurl }}/{% ministamp assets/src.css assets/dest.css %}" media="screen, projection">

By default, Jekyll includes this file to the site destinationdirectory. As a result, there will be both src.css anddest-<md5>.css files in _site/assets/ directory, which you probablydo not want.

In order to avoid this, exclude the asset source file from Jekyll.Because Jekyll's site generation excludes underscore directories (thatis, directories whose name begins with underscore character), considerusing the following directory layout:

  • _assets/ for JavaScript and CSS assets handled by the plugin thatare in version control
  • _tmp/ for temporary JavaScript and CSS assets handled by the pluginthat are not in version control (for example, Sass output files)
  • assets/ for images and other assets handled by Jekyll directly

However, Jekyll's watch mode (auto-regeneration) does monitor filesinside underscore directories. If such a file is modified, the watchmode triggers site generation. For Minibundle's functionality, this isbeneficial: it allows the plugin to check if assets need to be updatedto the site destination directory.

The exclude Jekyll configuration option affects Jekyll'swatch mode. Given the recommended directory layout above, if you set thefollowing in _config.yml:

exclude:
  - _assets
  - _tmp

Then Jekyll won't see if files inside those directories have changed andthe plugin won't get the chance to update assets to the site destinationdirectory. So, don't explicitly exclude the _assets and _tmpdirectories.

See Jekyll configuration for more about excluding filesand directories.

Development mode

If you set the $JEKYLL_MINIBUNDLE_MODE environment variable todevelopment, then the plugin will copy asset files as is to Jekyll'ssite destination directory and omit fingerprinting.

The development mode changes minibundle block's destination_pathoption to be the base directory for files mentioned in the assetsoption. This is useful in development workflow, where you need thefilenames and line numbers of the original asset sources.

$ JEKYLL_MINIBUNDLE_MODE=development jekyll serve --watch

Alternatively, you can enable development mode from _config.yml:

minibundle:
  mode: development

Should both be defined, the setting from the environment variable wins.

Variable templating

The template engine used by ministamp tag's Hash argument has syntaxresembling the ones of Liquid and Mustache, with {{ and }} tagssurrounding the variable to be substituted into the output string. Forexample, given Liquid variable var = 'foo', the template begin{{ var }}end results in beginfooend.

The engine supports variable substitution only. It does not supportother expressions. If you need to, you can write complex expressions inLiquid, store the result to a variable, and use the variable in thetemplate.

If you need literal { or } characters in the template, you canescape them with backslash. For example, \{ results in { in theoutput. To output backslash character itself, write it twice: \\results in \ in the output.

Inside variable subsitution (between {{ and }}), anything before theclosing }} tag is interpreted as part of the variable name, exceptthat the engine removes any leading and trailing whitespace from thename. For example, in the template {{ var } }}, var } is treated asthe name of the variable.

A reference to undefined variable results in empty string. For example,begin{{ nosuch }}end will output beginend if there's no variablenamed nosuch.

Separating asset destination path from generated URL

Use the render_basename_only: true option of the ministamp tag andthe destination_baseurl option of the minibundle block to separatethe destination path of the asset file from the generated URL of theasset. This allows you to serve the asset from a separate domain, forexample.

Example usage, with the following content in _config.yml:

cdn_baseurl: 'https://cdn.example.com'

For the ministamp tag:

<link rel="stylesheet" href="{{ site.cdn_baseurl }}/css/{% ministamp { source_path: '_tmp/site.css', destination_path: assets/site.css, render_basename_only: true } %}">

The asset file will be in Jekyll's site destination directory with pathassets/site-ff9c63f843b11f9c3666fe46caaddea8.css, and Liquid'srendering will result in:

<link rel="stylesheet" href="https://cdn.example.com/css/site-ff9c63f843b11f9c3666fe46caaddea8.css">

For the minibundle block:

{% minibundle js %}
source_dir: _assets/scripts
destination_path: assets/site
destination_baseurl: '{{ site.cdn_baseurl }}/js/'
assets:
  - dependency
  - app
{% endminibundle %}

The bundle file will be in Jekyll's site destination directory with pathassets/site-4782a1f67803038d4f8351051e67deb8.js, and Liquid'srendering will result in:

<script type="text/javascript" src="https://cdn.example.com/js/site-4782a1f67803038d4f8351051e67deb8.js"></script>

Capturing Liquid output

Use Liquid's capture block to store outputrendered inside the block to a variable, as a string. Then you canprocess the string as you like.

For example:

{% capture site_css %}{% ministamp _assets/site.css assets/site.css %}{% endcapture %}
<link rel="stylesheet" href="{{ site_css | remove_first: "assets/" }}">

Liquid's rendering outcome:

<link rel="stylesheet" href="site-390be921ee0eff063817bb5ef2954300.css">

Example site

See the sources of an example site.

Known caveats

The plugin does not work with Jekyll's incremental rebuild feature(Jekyll option --incremental).

License

MIT. See LICENSE.txt.

 相关资料
  • Jekyll 是一个简单的免费的Blog生成工具,类似WordPress。但是和WordPress又有很大的不同,原因是jekyll只是一个生成静态网页的工具,不需要数据库支持。但是可以配合第三方服务,例如discuz。最关键的是jekyll可以免费部署在Github上,而且可以绑定自己的域名。 快速安装指令: gem install jekylljekyll new my-awesome-sit

  • 中文网站 jekyllcn 快速开始 ~ $ gem install jekyll bundler ~ $ jekyll new my-awesome-site ~ $ cd my-awesome-site ~/my-awesome-site $ bundle install ~/my-awesome-site $ bundle exec jekyll serve # => 打开浏览器 http

  • jekyll-admin 是一个 jekyll 插件,为用户提供了传统 CMS(内容管理系统)风格的图形化界面来创作内容和管理 jekyll 网站。 该项目分为两部分。基于 Ruby 的 HTTP API 处理 jekyll 和文件系统的操作部分,以及在这个 API 基础上的基于 JavaScript 的前端部分。 安装: 就像安装其他插件一样,请参阅 jekyll 文档的插件安装部分安装 jek

  • Jekyll的增强版,使用Markdown来写日志。 Jekyll采用静态文件方式管理,不需要数据库即可支持一个独立博客站点,在github-pages平台上被普遍采用。Jekyll-Bootstrap在Jekyll基础上,集成了twitter-bootstrap界面风格和一些实用的插件,并且易于扩展。

  • Jekyll Docker Jekyll Docker is a software image that has Jekyll and many of its dependencies ready to use for you in an encapsulated format. It includes a default set of gems, different image types wi

  • jekyll-katex This is a Jekyll plugin for performing compile-time math rendering via the KaTeX library.KaTeX is a library for rending math on the web using LaTeX, similar to MathJax. KaTeX differs from

  • �� Jekyll Spaceship �� Jekyll plugin for Astronauts. Install | Config | Usage | Credits | License Built with ❤︎ by jeffreytse and contributors Spaceship is a minimalistic, powerful and extremely custo

  • reveal-jekyll Transforms Markdown files into presentation slides using reveal.js and Jekyll. The theme is based on Solarized Colors (by Ethan Schoonover) containing a light and a dark theme. reveal-je

相关阅读

相关文章

相关问答

相关文档