6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

webpackでhighlight.jsをビルドする際にハマった

Last updated at Posted at 2015-09-03

概要

highlight.jswebpackとあまり相性が良くない。
本系からダウンロードしてきたのをそのままwebpackでビルドするとエラーになる。
単純にscriptタグでインクルードすれば使えるけど、
せっかくなのでwebpackの知識も深めるという意味でなんとか対応してみた話。

現象

フォルダ構成

folder

htmlはこんな感じ

<!DOCTYPE html>
<html lang="jp">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>testing highlight with webpack</title>
    <link rel="stylesheet" href="./github.css">
</head>
<body>
    <div>
        <pre><code>
angular.module('myApp').service('AwesomeService', ['$http',
    function($http) {
        var i = 1;

        this.yo = function() {
            return 'AwesomeService:' + new Date().getTime();
        };

        this.name = 'AwesomeService';
        this.ts = new Date().getTime();

        this.up = function() {
            i = i + 1;
        };
    }
]);
        </code></pre>
    </div>

    <script src="../lib/js/jquery.min.js"></script>
    <script src="http://localhost:3010/assets/hl.bundle.js"></script>
</body>
</html>

普通にrequireする

/* globals jQuery: true */

(function( undefined ) {

    var $, hljs;
    $ = require( 'jquery' );

    // autoreload for html
    require( 'raw!./hl.html' );

    hljs = require( './highlight.pack' );

    $(function() {

        $( document ).ready(function() {

            $( 'pre code' ).each(function( i, block ) {

                hljs.highlightBlock( block );
            });
        });
    });
})();

これだけだとhljsが見つからないとのこと、もちろんハイライトもされない

error

ダウンロードしてきたhighlight.pack.jsを整形して見てみると
モジュール化したあとで言語を登録している模様。

highlight.js

この状態ではglobalで普通にインクルードする時はこれで動くが
webpackでビルドするとhighlight.pack.jsが読み込まれた時点でhljsが存在しないから当然エラーになる。

解決策

モジュールと言語登録処理を分割し、言語登録処理でモジュールをインクルードしてそれを返せば良い。
使うときはモジュールファイルではなく言語登録ファイルをインクルードする。
こうすれば両方のファイルをインクルードする必要もなくなる。

手順

  1. highlight.jsカスタムパッケージ無しの状態でダウンロードする。
  2. ダウンロードしてきたピュアなhighlight.pack.jsのファイル名をhighlight.min.jshljs.jsと略称)に変更。
  3. それから空の新たなhighlight.pack.jspack.jsと略称)を用意。
  4. このpack.jsが実際にインクルードされるライブラリーとなる。

pack.jsの中にhljs.jsをインクルードし言語登録をしてあげる

fixed

13行目のようにファクトリーを実行する際にhljs.jsを依存モジュールとしてインクルードして渡す。
scriptタグのインクルードされる際はwindowhljsを渡す。

CommonJSモジュールの考え方

CommonJS形式でrequireする際、依存先のモジュールの関数を呼出して値をセットすることはできるが、依存先モジュールをそのまま返すことはできない。
CommonJSexportsにメンバーを追加することでそれがrequire先で使えるようになる(理解が正しいかわからん)。

ということはpack.jsの中でhljs.jsreturnで返しても何も受け取れない。
使い方が少し変わってしまうがこれを解決するために27行目のようにexportsオブジェクトにhljsプロパティとしてモジュールをセットしてあげる。

require先では下記のようにプロパティから取得すればOK。

hljs = require( './highlight.pack' ).hljs;

これでも新たな言語を追加したい場合はpack.jsに登録処理を追加して上げる必要があるという問題が残る。

結果

これでちゃんとハイライトされ、エラーも出ずに全てが丸く収まる

success

言語登録コマンド

highlight.jsは様々な言語を対応しており、それぞれのハイライト定義ファイルが別に用意されている。
対象言語だけをビルドするコマンドnodeとブラウザー用に言語登録の用意されている。
それで試して見てもがやはりうまくいかないので上記の対策をせざるの得なかった。

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?