Highlight.js: HLJS compiled from website does not work with browserify

Created on 18 Jan 2015  路  14Comments  路  Source: highlightjs/highlight.js

The compiled packs tag on:

hljs.registerLanguage(....)

to the build code, for each language you ask for. However, hljs is undefined at this point if we are using browserify (commonJS) to require it. Can be fixed specifically in this case by adding var hljs = module.exports before the registerLanguage lines. Personally I'd fix by returning the hljs object from the initial function that decided where to put it, and using the returned ref when registerLanguage-ing

bug

Most helpful comment

The full npm package is quite big indeed.

In my project, I create a trimmed copy of /node_modules/highlight.js/lib/index.js. This allows me to choose a potion of all supported languages.

// This is a trimmed version of highlight.js main file
// See '/node_modules/highlight.js/lib/index.js' for all supported languages
// For more details, visit https://highlightjs.org/
var hljs = require('highlight.js/lib/highlight')
hljs.registerLanguage('xml', require('highlight.js/lib/languages/xml'))
hljs.registerLanguage('css', require('highlight.js/lib/languages/css'))
hljs.registerLanguage('javascript', require('highlight.js/lib/languages/javascript'))
module.exports = hljs

Then require this one instead of the npm package.

// var hljs = require('highlight.js')
var hljs = require('../assets/scripts/hljs.trimmed')

My production bundle file decreases for about 480KB.

All 14 comments

The way we maintain the library is that we keep the source code packaging-agnostic and then have a few specific formats in which we build the library for different targets. The website serves the browser-specific build intended to be linked by a <script> tag from a browser. If you want to package highlight.js in a different format it would make sense to either write another build pipeline in a separate packaging repo or reuse another build target that might suite you more. In particular, the package that we build for node.js does use the CommonJS convention. Also, it's very probable that someone is already doing this, though I don't know for sure.

It would be nice to have some additional highlight.js-common on NPM instead of only highlight.js, which is not suitable for browsers, because it's simply too big.

@kelunik we already provide hosted browser packages for that.

@isagalaev You mean those on highlightjs.org?
I really like organizing my dependencies with npm for browserify.

The thing is, everyone really likes organizing their workflow in their own way. We can't (and don't want to) support every combination imaginable. We encourage everyone to support third-party packages if what we provide doesn't fit the bill.

I totally agree that everybody has their own workflow here, but I think it's worth having two standard distributions for npm, one with full language support and another with common language support, so you don't have to include a common node build for browserify in every repo.

For what it's worth to anyone else bumping into this issue, you can make the web builds of hljs load via browserify by adding exports = undefined; just above the block of packed JS you downloaded from https://highlightjs.org/download/. This makes hljs register itself globally on the window object (at i.e. window.hljs, which, while not browserifyonic, works.

The full npm package is quite big indeed.

In my project, I create a trimmed copy of /node_modules/highlight.js/lib/index.js. This allows me to choose a potion of all supported languages.

// This is a trimmed version of highlight.js main file
// See '/node_modules/highlight.js/lib/index.js' for all supported languages
// For more details, visit https://highlightjs.org/
var hljs = require('highlight.js/lib/highlight')
hljs.registerLanguage('xml', require('highlight.js/lib/languages/xml'))
hljs.registerLanguage('css', require('highlight.js/lib/languages/css'))
hljs.registerLanguage('javascript', require('highlight.js/lib/languages/javascript'))
module.exports = hljs

Then require this one instead of the npm package.

// var hljs = require('highlight.js')
var hljs = require('../assets/scripts/hljs.trimmed')

My production bundle file decreases for about 480KB.

Yea i do a similar thing to just include specific languages i want. Works well

Did you guys read http://highlightjs.readthedocs.io/en/latest/building-testing.html ? You don't need to hack any files, you can just build whatever you like.

That's true. However, on the other hand my hljs.trimmed.js could also be considered as a "build config", which is eventually handled by webpack.

Or, maybe I could include this repo as submodule, then add a postinstall hook in my package.json to run the custom hljs build. I'll give it a try.

Yea, i'm just doing this along with all my other requires.

/**
 * Highlight.js
 */
var hljs = require('../node_modules/highlight.js/lib/highlight');
hljs.registerLanguage('php', require('../node_modules/highlight.js/lib/languages/php'));
hljs.initHighlightingOnLoad();

Not really hacking, just skipping the include every language file. Works well.

PS, this library is amazing...thanks for maintaining it

I'm using webpack targeting the browser and I wanted my dependencies sorted out on the server. I couldn't the website generated highlight.pack.js (rightly so b/c it's not made for webpack), and what @timacdonald suggested doesn't work for webpack as the language files aren't actually correct javascript (gets a syntax error for function without identifier). Furthermore, downloading the github repo and building it also didn't work (got an error and didn't want to debug a build pipeline) so I found a way to package it all in webpack using val-loader.

In one file put:

//Create a source file with mappings from language names to functions loaded from their
//respective JS files. Export this and run with val-loader to actually register the languages
//with hljs
var fs = require("fs");
var fullSrc = "module.exports = {";
["java", "cs", "css", "javascript", "json", "python", "xml"].forEach((lang, idx, arr)=>{
    var fp = "./vendor/highlight.js/src/languages/" + lang + ".js";
    var src = fs.readFileSync(fp);
    fullSrc += lang + ":" + src + (idx >= arr.length-1 ? "" : ",");
})
fullSrc += "}";
module.exports = fullSrc;

And then to load, you can load the above and go through each key in the exported object and register that as a language.

import hljs from "./highlight.js/src/highlight";
import langs from "val-loader!./highlightLangLoader.js";
Object.keys(langs).forEach( (lang)=>{
    hljs.registerLanguage(lang, langs[lang]) 
});

export default hljs;

Works great on my blog and all I have to do is change an array and run my build and Im good to go!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

goloroden picture goloroden  路  3Comments

kkeundotnet picture kkeundotnet  路  3Comments

alainbryden picture alainbryden  路  4Comments

Suyash2810 picture Suyash2810  路  8Comments

ghost picture ghost  路  3Comments