Blog

Using prismjs for code syntax highlighting with browserify and npm


We use prismjs to generate fancy code snippets like this:

Object.assign = require( 'object-assign' );           // Polyfill for IE8
const classie = require( 'classie' );                 // DOM class manipulations
const config = {
  enable: {
    menubar: true,
    menubutton: true,
  }
}

Prismjs seems to be a popular choice right now. It's light (2kb gzipped), follows the HTML5 spec, and modular so that you only load the languages you're going to use and there's plugins for things like displaying line numbers.

You can use their website to create a custom build. But that's a bit cumbersome if your language needs are going to change. As with all our external javascript we just downloaded the npm package. The prismjs docs suggest using babel-plugin-prismjs to enable the language modules, which requires configuring the language modules in .babelrc (or the babel section of package.json). Configuring actual application code, we're not talking about tooling here, inside the transpiler configuration is a big yuck for us. This should really be done at point of use, which is more logical and flexible. Also babel-plugin-prismjs requires (no pun intended) prismjs to be included via an ES6 import, and we use babelify's require because ES6 import adds nothing except one more step (it's transpiled to require). There is a loadLanguages() function, but this only works in node.

So... we decided to import the language modules with a big long list of require statements.

const prism = require('prismjs');

require('prismjs/components/prism-apacheconf.js');
require('prismjs/components/prism-bash.js');
require('prismjs/components/prism-clike.js');
require('prismjs/components/prism-css.js');
require('prismjs/components/prism-git.js');
require('prismjs/components/prism-ini.js');
require('prismjs/components/prism-javascript.js');
require('prismjs/components/prism-json.js');
require('prismjs/components/prism-jsx.js');
require('prismjs/components/prism-makefile.js');
require('prismjs/components/prism-markup.js');
require('prismjs/components/prism-nginx.js');
require('prismjs/components/prism-php.js');
require('prismjs/components/prism-python.js');
require('prismjs/components/prism-sass.js');
require('prismjs/components/prism-scss.js');
require('prismjs/components/prism-sql.js');

prism.highlightAll();

Our first, naive attempt resulted in this error:

TypeError: Cannot read property 'tokenizePlaceholders' of undefined
  
  - prism-php.js:121 

Turns out that language modules have dependencies, and prism-php.js depends on prism-markup-templating.js which was missing from our list. This is the problem which babel-plugin-prism and loadLanguages solve. Fortunately, all languages together with their dependencies are listed in prismjs/components.js.

Other than that minor hiccup, prismjs is working well and has a nice collection of themes.


By Spritely Design