Solvedprism Using non-default Prism languages with Webpack

I'm trying to use Prism with Webpack. I've installed Prism with NPM, and I am importing Prism in my entry.js like so: import 'prismjs'. This works fine for highlighting the default languages like JavaScript, however, I have some Scala snippets that I need to highlight, but I cannot figure out how to include the Scala component. I've tried the following in my entry.js:

import 'prismjs';
import 'prismjs/components/prism-scala.js';

However this leaves me with the following error in the browser console: prism.js:79 Uncaught TypeError: Cannot set property 'keyword' of undefined. How can I import these other languages so that they can be included with the client-side Prism instance I'm using with Webpack?'

For reference, I'm just importing the resulting Webpack bundle into my page and then using the language-scala class on my snippets.

webpack.conf.js:

{
  entry: {
    home: './lib/client/js/pages/home.js',
    projects: './lib/client/js/pages/projects.js',
    post: './lib/client/js/pages/post.js'
  },
  output: {
    filename: '[name].js',
    publicPath: '/webpack/'
  },
  devtool: 'source-map',
  module: {
    loaders: [
      { test: /\.css$/, loader: 'style!css?sourceMap' },
      { test: /\.scss$/, loaders: ['style', 'css?sourceMap', 'sass'] },
      { test: /\.(eot|svg|ttf|woff(2)?)(\?v=\d+\.\d+\.\d+)?/, loader: 'url' },
      {
        test: /\.js$/,
        exclude: /(node_modules)/,
        loader: 'babel',
        query: {
          presets: ['es2015', 'stage-2']
        }
      }
    ]
  },
  sassLoader: {
    sourceMap: true
  },
  plugins: [
    new commons('commons.js', ['home', 'projects', 'post'])
  ]
}
12 Answers

✔️Accepted Answer

I figured it out by using this:

import Prism from 'prismjs/components/prism-core'
import 'prismjs/components/prism-clike'
import 'prismjs/components/prism-java'
import 'prismjs/themes/prism.css'

Prism is pretty stupid on resolving dynamic dependencies. First prism-core set Prism object to global.Prism, then it's used in language definition files. The definition files have dependencies with each other. In this case, "scale" depends on "java" which depends on "clike".

My webpack.config.js is very standard:

const path = require('path');

module.exports = {
    entry: './src/index.js',
    // devtool: 'sourcemap',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    module: {
        rules: [{
            test: /\.js$/,
            exclude: /(node_modules|bower_components)/,
            use: {
                loader: 'babel-loader',
                options: {
                    presets: ['@babel/preset-env']
                }
            }
        }, {
            test: /\.css$/,
            use: ['style-loader', 'css-loader']
        }]
    }
};

Related Issues:

88
prism TypeError: Cannot read property 'tokenizePlaceholders' of undefined
For anyone who comes here and is not using node or Webpack Hello When I use version 1.14.0 in node.j...
23
prism Using non-default Prism languages with Webpack
I figured it out by using this: Prism is pretty stupid on resolving dynamic dependencies First prism...