markdownから1ファイルなhtmlを生成するmd-standaloneというツールを作ってみました。これは内部でwebpackを使っていて、その中でも汎用的に使えそうなtipsをここで紹介します。
読み込んで欲しいモジュールをaliasでどうにかする
md-standaloneではレンダラを自作のものに置き換えられます(以下参照)。こいつはテキトーなところに置ける仕様になっています。(デフォルトはmd-standalone/defaultRenderer.js at master · ukyo/md-standalone)
var html = require('mdHelper').getHtml();
var options = require('options');
var tocHelper = require('tocHelper');
module.exports = function() {
document.body.innerHTML = '<div id="md">' +html + '</div>';
document.title = '(^ω^ ≡ ^ω^)おっおっおっ';
};
ただテキトーなところに置きながらも、オプション(↑だとmdHelper
, options
, tocHelper
)等々を読みこんでもらいたいときもあります。そういうときはaliasを使うことができます。webpackConfig.resolve.alias
で対象のパスを絶対パスとかにすればrequire('options')
とかで読み込むことができます。
var webpackConfig = {
...
resolve: {
alias: {
options: path.resolve(__dirname, './options.js')
...
}
}
};
入力ファイルのパス解決もaliasでどうにかする
このツールだと、markdown、スタイル(css, scss, less)、自作レンダラ(js)にあたります。これもaliasを使います。以下例ならjsからrequire('mdPath')
で読み込めます。
var webpackConfig = {
...
resolve: {
alias: {
mdPath: path.resolve(process.cwd(), mdPath) // mdPathは 'path/to/foo.md' とか
...
}
}
};
自作ローダー
npmから持ってきたhoge-loader
でかゆいところに手が届かないような場合、自作ローダーを作ります。
基本
require('./foo!./bar!./baz!mdPath')
みたいなかんじでrequireしたとき、mdPathのファイルを読み込んでbazしてbarしてfooした結果が最終的に受け取れます。例えばrequire('./foo?a=aaa&b=bbb!mdPath')
のように読み込むローダーは以下のように作れます
var loaderUtils = require("loader-utils"); // npm installしてね
module.exports = function(content) {
var query = loaderUtils.parseQuery(this.query);
...
return result;
}
基本的には文字列を返す必要がありますが、以下のようにすればオブジェクトを返すこともできます。
module.exports = function() {
...
return 'module.exports = ' JSON.stringify(obj);
};
webpackConfigからオプションをぶっこ抜く
webpackConfigにオプションを生やしておいて
var webpackConfig = {
...
fooOptions: {...}
};
ローダーからぶっこ抜き
module.exports = function() {
return 'module.exports = ' + JSON.stringify(this.options.fooOptions);
};
最終的にこうします(require('options')
はつまりこういうこと)。
module.exports = require('./optionsLoader!./hogehoge'); // hogehogeは存在すればなんでも良い
なんというか、ローダーは工夫次第でもっと色々できそうですね。
まとめ
ツール内部でwebpackをつかうときのtipsを紹介しました。1つのファイルにまとめる系のツールを作りたい場合はwebpackベースで作るのもありだと思います。