From 70870a7734bd985eacc0fb57b3a04b9f8dc42023 Mon Sep 17 00:00:00 2001 From: Jim O'Donnell Date: Sat, 6 Jan 2024 10:40:43 +0000 Subject: [PATCH] Replace rehype with rehype-dom in the browser Use `rehype-dom` 5.0 (36k) as the Rehype parser in browsers, where Rehype can use DOM APIs to parse HTML. In Node, require in the full `rehype` processor, which is ~240k. This should give smaller, faster bundles for Markdown parsing in browsers. --- package-lock.json | 101 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + src/lib/utils.js | 9 ++++- 3 files changed, 109 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index b220154..3da3c99 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "markdown-it-table-of-contents": "~0.6.0", "markdown-it-video": "~0.6.3", "rehype": "~11.0.0", + "rehype-dom": "~5.0.0", "rehype-react": "~6.2.1" }, "devDependencies": { @@ -4777,6 +4778,19 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-from-dom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-from-dom/-/hast-util-from-dom-3.0.0.tgz", + "integrity": "sha512-4vQuGiD5Y/wlD7fZiY4mZML/6oh0GOnH38UNyeDFcSTE4AHF0zjKHZfbd+ekVwPvsZXRl8choc99INHUwSPJlg==", + "dependencies": { + "hastscript": "^6.0.0", + "web-namespaces": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-from-parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-6.0.1.tgz", @@ -4812,6 +4826,19 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-to-dom": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/hast-util-to-dom/-/hast-util-to-dom-2.0.6.tgz", + "integrity": "sha512-rQ5Bu71whciB9imQUO6V6O25VR3I1H0Ah5ztwicWCQ6JBn7RjytcfIouEgUShXLxmjxkhErNHBwMAHSoScwqlg==", + "dependencies": { + "property-information": "^5.1.0", + "web-namespaces": "^1.1.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-to-html": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-7.1.3.tgz", @@ -6859,6 +6886,34 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/rehype-dom": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/rehype-dom/-/rehype-dom-5.0.0.tgz", + "integrity": "sha512-SGGlT1purj4vkPK3cr95zLlIYNktchg75+m/jMVW4MwFD3deAbFCmVzhcP1TE6DGmwUwBe5JHwrtEiZK8vxpWQ==", + "dependencies": { + "rehype-dom-parse": "^3.0.0", + "rehype-dom-stringify": "^2.0.1", + "unified": "^9.0.0" + } + }, + "node_modules/rehype-dom-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/rehype-dom-parse/-/rehype-dom-parse-3.0.0.tgz", + "integrity": "sha512-FXJF0y3COYBm/vI6/kNVxrZr15rCuFtusL9qXTWlPkimDACCymoeX87fWOxc6jumjpOH3FfBU+EjJHW6oh4ghw==", + "dependencies": { + "hast-util-from-dom": "^3.0.0" + } + }, + "node_modules/rehype-dom-stringify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/rehype-dom-stringify/-/rehype-dom-stringify-2.0.1.tgz", + "integrity": "sha512-MiABypOaG6JCd8l4COOa8l7485FXSWrvdbTcEBCItgJ0Y8c7zRVJutM+Q+wnHZmUEKjdQm9ZXU7a03FFNKwwTw==", + "dependencies": { + "hast-util-to-dom": "^2.0.1", + "web-namespaces": "^1.0.0", + "xtend": "^4.0.1" + } + }, "node_modules/rehype-parse": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-7.0.1.tgz", @@ -11512,6 +11567,15 @@ "web-namespaces": "^1.0.0" } }, + "hast-util-from-dom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-from-dom/-/hast-util-from-dom-3.0.0.tgz", + "integrity": "sha512-4vQuGiD5Y/wlD7fZiY4mZML/6oh0GOnH38UNyeDFcSTE4AHF0zjKHZfbd+ekVwPvsZXRl8choc99INHUwSPJlg==", + "requires": { + "hastscript": "^6.0.0", + "web-namespaces": "^1.0.0" + } + }, "hast-util-from-parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-6.0.1.tgz", @@ -11535,6 +11599,15 @@ "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==" }, + "hast-util-to-dom": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/hast-util-to-dom/-/hast-util-to-dom-2.0.6.tgz", + "integrity": "sha512-rQ5Bu71whciB9imQUO6V6O25VR3I1H0Ah5ztwicWCQ6JBn7RjytcfIouEgUShXLxmjxkhErNHBwMAHSoScwqlg==", + "requires": { + "property-information": "^5.1.0", + "web-namespaces": "^1.1.3" + } + }, "hast-util-to-html": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-7.1.3.tgz", @@ -13048,6 +13121,34 @@ "unified": "^9.0.0" } }, + "rehype-dom": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/rehype-dom/-/rehype-dom-5.0.0.tgz", + "integrity": "sha512-SGGlT1purj4vkPK3cr95zLlIYNktchg75+m/jMVW4MwFD3deAbFCmVzhcP1TE6DGmwUwBe5JHwrtEiZK8vxpWQ==", + "requires": { + "rehype-dom-parse": "^3.0.0", + "rehype-dom-stringify": "^2.0.1", + "unified": "^9.0.0" + } + }, + "rehype-dom-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/rehype-dom-parse/-/rehype-dom-parse-3.0.0.tgz", + "integrity": "sha512-FXJF0y3COYBm/vI6/kNVxrZr15rCuFtusL9qXTWlPkimDACCymoeX87fWOxc6jumjpOH3FfBU+EjJHW6oh4ghw==", + "requires": { + "hast-util-from-dom": "^3.0.0" + } + }, + "rehype-dom-stringify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/rehype-dom-stringify/-/rehype-dom-stringify-2.0.1.tgz", + "integrity": "sha512-MiABypOaG6JCd8l4COOa8l7485FXSWrvdbTcEBCItgJ0Y8c7zRVJutM+Q+wnHZmUEKjdQm9ZXU7a03FFNKwwTw==", + "requires": { + "hast-util-to-dom": "^2.0.1", + "web-namespaces": "^1.0.0", + "xtend": "^4.0.1" + } + }, "rehype-parse": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-7.0.1.tgz", diff --git a/package.json b/package.json index 768451a..520d8f8 100644 --- a/package.json +++ b/package.json @@ -75,6 +75,7 @@ "markdown-it-table-of-contents": "~0.6.0", "markdown-it-video": "~0.6.3", "rehype": "~11.0.0", + "rehype-dom": "~5.0.0", "rehype-react": "~6.2.1" }, "overrides": { diff --git a/src/lib/utils.js b/src/lib/utils.js index 6e3535d..599221e 100644 --- a/src/lib/utils.js +++ b/src/lib/utils.js @@ -13,7 +13,7 @@ import twemoji from '@twemoji/api'; import { sanitize } from 'isomorphic-dompurify'; import { Fragment, createElement } from 'react'; -import rehype from 'rehype'; +import rehypeDom from 'rehype-dom'; import rehype2react from 'rehype-react'; import markdownNewTab from './links-in-new-tabs'; @@ -21,6 +21,11 @@ import relNofollow from './links-rel-nofollow'; import replaceSymbols from './default-transformer'; let counter = 0; +let rehypeParser = rehypeDom; + +if (typeof window === 'undefined') { + rehypeParser = require('rehype'); +} export function emojify(input) { return twemoji.parse(input); @@ -107,7 +112,7 @@ export function getComponentTree({ html, settings, components }) { let parsedHTML = null; try { - parsedHTML = rehype() + parsedHTML = rehypeParser() .data('settings', rehypeSettings) .use(rehype2react, { Fragment,