Handles image references involved in markdown files during the webpack processing.
Highly inspired from the Webpack: A simple loader article by Michael "Z" Goddard, rewritten with some ES6 flavor, use-case documentation and unit testing.
Additions:
- the loader does not impact references to online images (eg: image path starting with
http://
,https://
or//
) - the loader handles markdown image references with a title
Install the markdown-image-loader
along other webpack development dependencies:
# via yarn
yarn add -D webpack file-loader markdown-image-loader
# via npm
npm i -D webpack file-loader markdown-image-loader
In the webpack process, this loader extracts image references of markdown documents with a regular expression, then converts them into image file requirements so that the file-loader can process them in your build chain.
This loader was originally designed to quickly setup web-based slideshows using markdown to build the content, webpack to produce the static files and webpack-dev-server to display the slideshow with live-reload, which can be interesting when editing the content while interacting with the audience.
Two full setups are given in the examples/
folder of this repository:
- RemarkJS-based slideshow: this use-case was inspired by Sébastien Castiel (thanks!). This example works with webpack 5
- RevealJS-based slideshow: this one is my initiative This example works with webpack 4 and an older version of Reveal.js (pull request to update this example are welcome)
Both slideshow examples share the same philosophy, adapted to the technical choices of each framework:
The folder structure of such projects is:
dist // folder containing the static files generated by the webpack build (and served by webpack-dev-server)
src
┣ index.html
┣ [your slideshow app name]-slideshow.js
┣ slideshow.md
┣ slides.css // your personal style additions
┣ fonts // folder containing the fonts required in the slides.css file, if any
┣ img // folder containing the images referenced in slideshow.md
┃ ┗ markdown-logo.svg, webpack-logo.svg, etc.
webpack.config.js // involves this markdown-image-loader and the file-loader
package.json // devDependencies to make the slideshow framework and webpack work together
src/index.html
:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<!-- the title header can be dynamically set by bundled-app.js -->
<title>My slideshow</title>
</head>
<body>
<!-- RemarkJS expects the markdown content to be included by the webapp this way -->
<textarea id="source" style="display: none"></textarea>
<!-- RevealJS expects the markdown content to be included by the webapp this way -->
<div class="reveal">
<div class="slides">
<!-- horizontal and vertical separators are my choices, tune them as you want -->
<section data-markdown data-separator="^---" data-separator-vertical="^--">
<textarea id="source" data-template></textarea>
</section>
</div>
</div>
<!-- the bundled webapp will be injected here by the html-webpack-plugin -->
</body>
</html>
src/[slideshow app name]-slideshow.js
:
// customize your CSS here
require('./slides.css')
// loads the markdown content with the markdown-image-loader (which processes its image references)
document.getElementById('source').innerHTML = require('./slideshow.md')
// starts the slideshow with a specific configuration object
remark.create({ ... })
// or
Reveal.initialize({ ... })
src/slideshow.md
(each slideshow engine has its specific syntax, see the slideshow.md files in the examples):
# Slide 1 with a jpg reference
![test1](img/test1.jpg)
---
# Slide 2 with an inline png reference
In line ![test2](img/test2.png) image reference.
webpack.config.js
. Loaders defined in themodule.rules
section are called from bottom to top: thefile-loader
must be called after themarkdown-image-loader
produces new file requirements: :
const path = require('path')
module.exports = {
entry: path.join(__dirname, 'src', '[slideshow app name]-slideshow.js'),
output: {
filename: 'bundled-app.js',
path: path.join(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.(svg|png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {} // produces {hash}.[ext] files by default
}
]
},
{
test: /\.(md|markdown)$/,
use: 'markdown-image-loader'
}
]
}
}
Use the file-loader options to customize the way image files must be handled (file naming, output path, url prefix, etc.).
package.json
. Use thescripts.build
to produce the static files ready to be served in production, for which you must include these mandatory dependencies in your project:webpack
,file-loader
andmarkdown-image-loader
. You can optionally include thewebpack-dev-server
to serve your slideshow with live-reload with thescripts.start
command.
{
"scripts": {
"build": "rm -rf dist && webpack",
"start": "webpack-dev-server",
"lint": "standard"
},
"devDependencies": {
"file-loader": "...",
"markdown-image-loader": "...",
"webpack": "...",
"webpack-dev-server": "..."
},
}
The outputs generated in the dist
folder will be:
- the
bundled-app.js
file, handling the markdown content as follows:
// ...
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
module.exports = [
"# Slide 1 with a jpg reference\n\n",
"![test1](" + __webpack_require__(1) + ")",
"\n\n---\n\n# Slide 2 with an inline png reference\n\nIn line ",
"![test2](" + __webpack_require__(2) + ")",
" image reference.\n"
]
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
module.exports = __webpack_require__.p + "05bf210f71dda8913b3e9ac296da171f.jpg";
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
module.exports = __webpack_require__.p + "e3989c3353cceb13f5bb1ecf343f22a6.png";
/***/ })
- the images referenced by the markdown content, processed by the
file-loader
plugin:- the
dist/05bf210f71dda8913b3e9ac296da171f.jpg
file (referenced in slide 1) - the
dist/e3989c3353cceb13f5bb1ecf343f22a6.png
file (referenced in slide 2)
- the
Unit tests can be run with the npm test
command.
Despite these efforts, should you find an issue or spot a vital feature, you are welcome to report bugs and submit code requests!
- 3.0.1: [config]
loader-utils
is a production depndency, not a dev dependency; upgraded version of eslint and mocha - 3.0.0: [config] dependencies update, for webpack 5.x
- 2.0.1: [config] dependencies update, [doc] reference to the file loader options for image file customization
- 2.0.0: [config] dependencies update, for webpack 3.x and 4.x. Webpack configurations for RemarkJS and RevealJS slideshows in the
/examples
folder have been updated for Webpack 4.x support - 1.0.5: [feature] the loader handles image references with an optional title
- 1.0.4: [doc] added sample slideshows for RemarkJS and RevealJS in the
/examples
folder - 1.0.3: [perf] made the loader outputs cacheable, [doc] added this change log section
- 1.0.2: [fix] removed the comma surrounding image requirements in the exported module content
- 1.0.1: [fix] the loader should not not require URLed-image references
- 1.0.0: initial release with unit-tests and documentation, for webpack 3.x
Pull-requests are welcome and will be processed on a best-effort basis.
Unless stated otherwise all works are licensed under the MIT license, a copy of which is included here.
Copyright (c) 2017-2024 Luc Sorel-Giffo