Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Does Not Work Well With Webpack Applications #28

Open
therealpaulgg opened this issue Jul 28, 2019 · 6 comments
Open

Does Not Work Well With Webpack Applications #28

therealpaulgg opened this issue Jul 28, 2019 · 6 comments

Comments

@therealpaulgg
Copy link

This plugin does not work on webpack applications. After doing some testing and looking into the source code of this project, Prism themselves say that this is because you should not call loadLanguages() in a webpack application, and that a babel plugin should be used instead. That plugin seems to be integral to this plugin, and so I was getting the same errors using this plugin that I was when I was simply using Prism without the plugin, but attempting to use loadLanguages().

I am using this plugin on a node.js express application, and it renders server-side with no issues (no webpack). However, when I am building my vue.js app and need to add preview functionality, it does not work, probably because I am using webpack.

If there would be any way to fix it so others could avoid the trouble of having to manually add prism to markdown, that would be great.

I am including source code below that I am using that is based off of the official markdown-it docs using highlight-js here https://markdown-it.github.io/markdown-it/, but instead using Prismjs. I hope this helps anyone who is trying to accomplish what I was. This is the code I'll be using for now.

import markdownit from "markdown-it"; 

let md = markdownit({
  highlight: (str, lang) => {
   if (lang) {
        let langObject = Prism.languages[lang]
      try {
        return (
            `<pre class="language-${lang}"><code>` + 
            Prism.highlight(str, langObject, lang) + 
            '</code></pre>'
        ) 
      } catch (__) {}
    }
    return `<pre class="language-${lang}><code>` + md.utils.escapeHtml(str) + "</code></pre>"
  }
});
@jGleitz
Copy link
Owner

jGleitz commented Aug 27, 2019

Hi! I just realized that I never answered your issue. Sorry!

First of all: thank you for reporting this.

After you opened the issued I did some digging. However, I found no straightforward solution to the problem. I attempted to make this plugin compatible to babel-plugin-prismjs, but with no success.

How do you make sure that the languages are included in the Webpack result when you use your code snippet?

@therealpaulgg
Copy link
Author

therealpaulgg commented Aug 27, 2019

The workaround solution that I used is definitely not ideal and it is NOT by any means an elegant solution, but it works and I am currently not sure on how to load the languages automatically without calling that PrismJS function (But it breaks in webpack :/).

To load languages I had to import each language from prismjs individually. Many languages in prismJS have dependencies too, so the order of the import statements actually matters. For instance, JavaScript, C, and Java require the clike language to be loaded beforehand otherwise the application will throw an error.

I'll include some sample code that I used below (it is very long).

Main downside from this from a performance standpoint is that it increases the overall bundle size of the application by a significant amount.

Imports for all Prism languages
import markdownit from "markdown-it"
import Prism from "prismjs/components/prism-core"
import "prismjs/components/prism-abap"
import "prismjs/components/prism-abnf"
import "prismjs/components/prism-clike"
import "prismjs/components/prism-javascript"
import "prismjs/components/prism-actionscript"
import "prismjs/components/prism-ada"
import "prismjs/components/prism-apacheconf"
import "prismjs/components/prism-apl"
import "prismjs/components/prism-applescript"
import "prismjs/components/prism-c"
import "prismjs/components/prism-cpp"
import "prismjs/components/prism-arduino"
import "prismjs/components/prism-arff"
import "prismjs/components/prism-asciidoc"
import "prismjs/components/prism-asm6502"
import "prismjs/components/prism-csharp"
import "prismjs/components/prism-markup"
import "prismjs/components/prism-aspnet"
import "prismjs/components/prism-autohotkey"
import "prismjs/components/prism-autoit"
import "prismjs/components/prism-bash"
import "prismjs/components/prism-basic"
import "prismjs/components/prism-batch"
import "prismjs/components/prism-bison"
import "prismjs/components/prism-bnf"
import "prismjs/components/prism-brainfuck"
import "prismjs/components/prism-bro"
import "prismjs/components/prism-cil"
import "prismjs/components/prism-clojure"
import "prismjs/components/prism-cmake"
import "prismjs/components/prism-coffeescript"
import "prismjs/components/prism-core"
import "prismjs/components/prism-ruby"
import "prismjs/components/prism-crystal"
import "prismjs/components/prism-csp"
import "prismjs/components/prism-css"
import "prismjs/components/prism-d"
import "prismjs/components/prism-dart"
import "prismjs/components/prism-diff"
import "prismjs/components/prism-dns-zone-file"
import "prismjs/components/prism-docker"
import "prismjs/components/prism-ebnf"
import "prismjs/components/prism-eiffel"
import "prismjs/components/prism-ejs"
import "prismjs/components/prism-elixir"
import "prismjs/components/prism-elm"
import "prismjs/components/prism-erb"
import "prismjs/components/prism-erlang"
import "prismjs/components/prism-flow"
import "prismjs/components/prism-fortran"
import "prismjs/components/prism-fsharp"
import "prismjs/components/prism-gcode"
import "prismjs/components/prism-gedcom"
import "prismjs/components/prism-gherkin"
import "prismjs/components/prism-git"
import "prismjs/components/prism-glsl"
import "prismjs/components/prism-gml"
import "prismjs/components/prism-go"
import "prismjs/components/prism-graphql"
import "prismjs/components/prism-groovy"
import "prismjs/components/prism-haml"
import "prismjs/components/prism-handlebars"
import "prismjs/components/prism-haskell"
import "prismjs/components/prism-haxe"
import "prismjs/components/prism-hcl"
import "prismjs/components/prism-hpkp"
import "prismjs/components/prism-hsts"
import "prismjs/components/prism-http"
import "prismjs/components/prism-ichigojam"
import "prismjs/components/prism-icon"
import "prismjs/components/prism-inform7"
import "prismjs/components/prism-ini"
import "prismjs/components/prism-io"
import "prismjs/components/prism-j"
import "prismjs/components/prism-java"
import "prismjs/components/prism-javadoclike"
import "prismjs/components/prism-javadoc"
import "prismjs/components/prism-javastacktrace"
import "prismjs/components/prism-jolie"
import "prismjs/components/prism-jq"
import "prismjs/components/prism-js-extras"
import "prismjs/components/prism-js-templates"
import "prismjs/components/prism-jsdoc"
import "prismjs/components/prism-json"
import "prismjs/components/prism-json5"
import "prismjs/components/prism-jsonp"
import "prismjs/components/prism-jsx"
import "prismjs/components/prism-julia"
import "prismjs/components/prism-keyman"
import "prismjs/components/prism-kotlin"
import "prismjs/components/prism-latex"
import "prismjs/components/prism-less"
import "prismjs/components/prism-lilypond"
import "prismjs/components/prism-liquid"
import "prismjs/components/prism-lisp"
import "prismjs/components/prism-livescript"
import "prismjs/components/prism-lolcode"
import "prismjs/components/prism-lua"
import "prismjs/components/prism-makefile"
import "prismjs/components/prism-markdown"
import "prismjs/components/prism-markup-templating"
import "prismjs/components/prism-django"
import "prismjs/components/prism-matlab"
import "prismjs/components/prism-mel"
import "prismjs/components/prism-mizar"
import "prismjs/components/prism-monkey"
import "prismjs/components/prism-n1ql"
import "prismjs/components/prism-n4js"
import "prismjs/components/prism-nand2tetris-hdl"
import "prismjs/components/prism-nasm"
import "prismjs/components/prism-nginx"
import "prismjs/components/prism-nim"
import "prismjs/components/prism-nix"
import "prismjs/components/prism-nsis"
import "prismjs/components/prism-objectivec"
import "prismjs/components/prism-ocaml"
import "prismjs/components/prism-opencl"
import "prismjs/components/prism-oz"
import "prismjs/components/prism-parigp"
import "prismjs/components/prism-parser"
import "prismjs/components/prism-pascal"
import "prismjs/components/prism-pascaligo"
import "prismjs/components/prism-pcaxis"
import "prismjs/components/prism-perl"
import "prismjs/components/prism-php-extras"
import "prismjs/components/prism-php"
import "prismjs/components/prism-phpdoc"
import "prismjs/components/prism-sql"
import "prismjs/components/prism-plsql"
import "prismjs/components/prism-powershell"
import "prismjs/components/prism-processing"
import "prismjs/components/prism-prolog"
import "prismjs/components/prism-properties"
import "prismjs/components/prism-protobuf"
import "prismjs/components/prism-pug"
import "prismjs/components/prism-puppet"
import "prismjs/components/prism-pure"
import "prismjs/components/prism-python"
import "prismjs/components/prism-q"
import "prismjs/components/prism-qore"
import "prismjs/components/prism-r"
import "prismjs/components/prism-reason"
import "prismjs/components/prism-regex"
import "prismjs/components/prism-renpy"
import "prismjs/components/prism-rest"
import "prismjs/components/prism-rip"
import "prismjs/components/prism-roboconf"
import "prismjs/components/prism-rust"
import "prismjs/components/prism-sas"
import "prismjs/components/prism-sass"
import "prismjs/components/prism-scala"
import "prismjs/components/prism-scheme"
import "prismjs/components/prism-scss"
import "prismjs/components/prism-shell-session"
import "prismjs/components/prism-smalltalk"
import "prismjs/components/prism-smarty"
import "prismjs/components/prism-soy"
import "prismjs/components/prism-splunk-spl"
import "prismjs/components/prism-stylus"
import "prismjs/components/prism-swift"
import "prismjs/components/prism-t4-templating"
import "prismjs/components/prism-t4-cs"
import "prismjs/components/prism-t4-vb"
import "prismjs/components/prism-tap"
import "prismjs/components/prism-tcl"
import "prismjs/components/prism-textile"
import "prismjs/components/prism-toml"
import "prismjs/components/prism-tsx"
import "prismjs/components/prism-tt2"
import "prismjs/components/prism-twig"
import "prismjs/components/prism-typescript"
import "prismjs/components/prism-vala"
import "prismjs/components/prism-vbnet"
import "prismjs/components/prism-velocity"
import "prismjs/components/prism-verilog"
import "prismjs/components/prism-vhdl"
import "prismjs/components/prism-vim"
import "prismjs/components/prism-visual-basic"
import "prismjs/components/prism-wasm"
import "prismjs/components/prism-wiki"
import "prismjs/components/prism-xeora"
import "prismjs/components/prism-xojo"
import "prismjs/components/prism-xquery"
import "prismjs/components/prism-yaml"

@jGleitz
Copy link
Owner

jGleitz commented Sep 7, 2019

@paulgg: You can use your approach (manually listing the language dependencies) with this plugin, too:

import MarkdownIt from 'markdown-it';
import prism from 'markdown-it-prism';

import "prismjs/components/prism-abap"
import "prismjs/components/prism-abnf"
import "prismjs/components/prism-clike"
import "prismjs/components/prism-java"
import "prismjs/components/prism-javadoclike"
import "prismjs/components/prism-javadoc"
import "prismjs/components/prism-javastacktrace"

function component() {
  const md = new MarkdownIt();
  md.use(prism);
  const element = document.createElement('div');
  element.innerHTML = md.render(`
Here is some *code*:
\`\`\`java
public class Test {
  public void foo() {}
}
\`\`\`
`);

  return element;
}

document.body.appendChild(component());

after npx webpack --mode=development, the div on the webpage has this content:

<div><p>Here is some <em>code</em>:</p>
<pre class=" language-java"><code class=" language-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Test</span> <span class="token punctuation">{</span>
  <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre>
</div>

But this is not very helpful, is it? I will add a note about it in the README anyway.

@jGleitz jGleitz changed the title Does not work on Webpack applications Does Not Work Well With Webpack Applications Sep 29, 2020
@winner106
Copy link

has this problem sovled?

@jGleitz
Copy link
Owner

jGleitz commented Oct 15, 2021

@winner106 my last post still describes the state of this issue: you can use this plugin, but you will have to load the languages you need manually.

This is not something we can fix in the scope of this plugin. Prism loads the languages it needs dynamically, and it has no direct way of knowing ahead of time which languages will be needed. So you either have to preload the languages you know you need, or preemptively import all.

@kubijo
Copy link

kubijo commented Dec 13, 2024

Hey @jGleitz … somewhat related to this issue, I am getting this error from my webpack built:

WARNING in ./.yarn/cache/prismjs-npm-1.29.0-6faa5b04b8-2080db382c.zip/node_modules/prismjs/components/index.js 42:23-54
Critical dependency: the request of a dependency is an expression
 @ ./.yarn/cache/markdown-it-prism-npm-2.3.0-50dbba6264-0e29788b91.zip/node_modules/markdown-it-prism/build/index.js 10:41-71
 @ ./shared/components/format/Markdown/Markdown.tsx 15:0-40 44:7-14

Here is the answer of a prism team member regarding the core of this issue: PrismJS/prism#1477 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants