Improve bundle size, dynamic imports & remove parse5 (#10865)

* Remove unused import

* Lazy load tar-js and pako for rageshakes

* Update cheerio imports

* Replace parse5 with DOMParser

* Remove stale comment
This commit is contained in:
Michael Telatynski 2023-05-12 12:13:08 +01:00 committed by GitHub
parent 9611cbf6c4
commit 15ed660975
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 20 additions and 29 deletions

View file

@ -15,7 +15,7 @@ limitations under the License.
*/ */
const EventEmitter = require("events"); const EventEmitter = require("events");
const { LngLat, NavigationControl, LngLatBounds, AttributionControl } = require("maplibre-gl"); const { LngLat, NavigationControl, LngLatBounds } = require("maplibre-gl");
class MockMap extends EventEmitter { class MockMap extends EventEmitter {
addControl = jest.fn(); addControl = jest.fn();

View file

@ -102,7 +102,6 @@
"minimist": "^1.2.5", "minimist": "^1.2.5",
"opus-recorder": "^8.0.3", "opus-recorder": "^8.0.3",
"pako": "^2.0.3", "pako": "^2.0.3",
"parse5": "^6.0.1",
"png-chunks-extract": "^1.0.0", "png-chunks-extract": "^1.0.0",
"posthog-js": "1.53.2", "posthog-js": "1.53.2",
"proposal-temporal": "^0.9.0", "proposal-temporal": "^0.9.0",
@ -164,7 +163,6 @@
"@types/node": "^16", "@types/node": "^16",
"@types/node-fetch": "^2.6.2", "@types/node-fetch": "^2.6.2",
"@types/pako": "^2.0.0", "@types/pako": "^2.0.0",
"@types/parse5": "^6.0.0",
"@types/qrcode": "^1.3.5", "@types/qrcode": "^1.3.5",
"@types/react": "17.0.58", "@types/react": "17.0.58",
"@types/react-beautiful-dnd": "^13.0.0", "@types/react-beautiful-dnd": "^13.0.0",

View file

@ -19,7 +19,7 @@ limitations under the License.
import React, { LegacyRef, ReactElement, ReactNode } from "react"; import React, { LegacyRef, ReactElement, ReactNode } from "react";
import sanitizeHtml from "sanitize-html"; import sanitizeHtml from "sanitize-html";
import cheerio from "cheerio"; import { load as cheerio } from "cheerio";
import classNames from "classnames"; import classNames from "classnames";
import EMOJIBASE_REGEX from "emojibase-regex"; import EMOJIBASE_REGEX from "emojibase-regex";
import { merge, split } from "lodash"; import { merge, split } from "lodash";
@ -549,7 +549,7 @@ export function bodyToHtml(content: IContent, highlights: Optional<string[]>, op
} }
safeBody = sanitizeHtml(formattedBody!, sanitizeParams); safeBody = sanitizeHtml(formattedBody!, sanitizeParams);
const phtml = cheerio.load(safeBody, { const phtml = cheerio(safeBody, {
// @ts-ignore: The `_useHtmlParser2` internal option is the // @ts-ignore: The `_useHtmlParser2` internal option is the
// simplest way to both parse and render using `htmlparser2`. // simplest way to both parse and render using `htmlparser2`.
_useHtmlParser2: true, _useHtmlParser2: true,

View file

@ -22,7 +22,6 @@ import { User } from "matrix-js-sdk/src/models/user";
import { Direction } from "matrix-js-sdk/src/models/event-timeline"; import { Direction } from "matrix-js-sdk/src/models/event-timeline";
import { EventType } from "matrix-js-sdk/src/@types/event"; import { EventType } from "matrix-js-sdk/src/@types/event";
import * as ContentHelpers from "matrix-js-sdk/src/content-helpers"; import * as ContentHelpers from "matrix-js-sdk/src/content-helpers";
import { Element as ChildElement, parseFragment as parseHtml } from "parse5";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
import { IContent } from "matrix-js-sdk/src/models/event"; import { IContent } from "matrix-js-sdk/src/models/event";
import { MRoomTopicEventContent } from "matrix-js-sdk/src/@types/topic"; import { MRoomTopicEventContent } from "matrix-js-sdk/src/@types/topic";
@ -1003,16 +1002,15 @@ export const Commands = [
// Try and parse out a widget URL from iframes // Try and parse out a widget URL from iframes
if (widgetUrl.toLowerCase().startsWith("<iframe ")) { if (widgetUrl.toLowerCase().startsWith("<iframe ")) {
// We use parse5, which doesn't render/create a DOM node. It instead runs const embed = new DOMParser().parseFromString(widgetUrl, "text/html").body;
// some superfast regex over the text so we don't have to.
const embed = parseHtml(widgetUrl);
if (embed?.childNodes?.length === 1) { if (embed?.childNodes?.length === 1) {
const iframe = embed.childNodes[0] as ChildElement; const iframe = embed.firstElementChild;
if (iframe.tagName.toLowerCase() === "iframe" && iframe.attrs) { if (iframe.tagName.toLowerCase() === "iframe") {
const srcAttr = iframe.attrs.find((a) => a.name === "src");
logger.log("Pulling URL out of iframe (embed code)"); logger.log("Pulling URL out of iframe (embed code)");
if (!srcAttr) return reject(new UserFriendlyError("iframe has no src attribute")); if (!iframe.hasAttribute("src")) {
widgetUrl = srcAttr.value; return reject(new UserFriendlyError("iframe has no src attribute"));
}
widgetUrl = iframe.getAttribute("src");
} }
} }
} }

View file

@ -16,7 +16,7 @@ limitations under the License.
*/ */
import { encode } from "html-entities"; import { encode } from "html-entities";
import cheerio from "cheerio"; import { load as cheerio } from "cheerio";
import escapeHtml from "escape-html"; import escapeHtml from "escape-html";
import Markdown from "../Markdown"; import Markdown from "../Markdown";
@ -143,7 +143,7 @@ export function htmlSerializeFromMdIfNeeded(md: string, { forceHTML = false } =
const parser = new Markdown(md); const parser = new Markdown(md);
if (!parser.isPlainText() || forceHTML) { if (!parser.isPlainText() || forceHTML) {
// feed Markdown output to HTML parser // feed Markdown output to HTML parser
const phtml = cheerio.load(parser.toHTML(), { const phtml = cheerio(parser.toHTML(), {
// @ts-ignore: The `_useHtmlParser2` internal option is the // @ts-ignore: The `_useHtmlParser2` internal option is the
// simplest way to both parse and render using `htmlparser2`. // simplest way to both parse and render using `htmlparser2`.
_useHtmlParser2: true, _useHtmlParser2: true,
@ -153,7 +153,7 @@ export function htmlSerializeFromMdIfNeeded(md: string, { forceHTML = false } =
if (SettingsStore.getValue("feature_latex_maths")) { if (SettingsStore.getValue("feature_latex_maths")) {
// original Markdown without LaTeX replacements // original Markdown without LaTeX replacements
const parserOrig = new Markdown(orig); const parserOrig = new Markdown(orig);
const phtmlOrig = cheerio.load(parserOrig.toHTML(), { const phtmlOrig = cheerio(parserOrig.toHTML(), {
// @ts-ignore: The `_useHtmlParser2` internal option is the // @ts-ignore: The `_useHtmlParser2` internal option is the
// simplest way to both parse and render using `htmlparser2`. // simplest way to both parse and render using `htmlparser2`.
_useHtmlParser2: true, _useHtmlParser2: true,

View file

@ -16,10 +16,9 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import pako from "pako";
import Tar from "tar-js";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
import type * as Pako from "pako";
import { MatrixClientPeg } from "../MatrixClientPeg"; import { MatrixClientPeg } from "../MatrixClientPeg";
import PlatformPeg from "../PlatformPeg"; import PlatformPeg from "../PlatformPeg";
import { _t } from "../languageHandler"; import { _t } from "../languageHandler";
@ -177,6 +176,11 @@ async function collectBugReport(opts: IOpts = {}, gzipLogs = true): Promise<Form
body.append("mx_local_settings", localStorage.getItem("mx_local_settings")!); body.append("mx_local_settings", localStorage.getItem("mx_local_settings")!);
if (opts.sendLogs) { if (opts.sendLogs) {
let pako: typeof Pako | undefined;
if (gzipLogs) {
pako = await import("pako");
}
progressCallback(_t("Collecting logs")); progressCallback(_t("Collecting logs"));
const logs = await rageshake.getLogsForReport(); const logs = await rageshake.getLogsForReport();
for (const entry of logs) { for (const entry of logs) {
@ -237,6 +241,7 @@ export default async function sendBugReport(bugReportEndpoint?: string, opts: IO
* @return {Promise} Resolved when the bug report is downloaded (or started). * @return {Promise} Resolved when the bug report is downloaded (or started).
*/ */
export async function downloadBugReport(opts: IOpts = {}): Promise<void> { export async function downloadBugReport(opts: IOpts = {}): Promise<void> {
const Tar = (await import("tar-js")).default;
const progressCallback = opts.progressCallback || ((): void => {}); const progressCallback = opts.progressCallback || ((): void => {});
const body = await collectBugReport(opts, false); const body = await collectBugReport(opts, false);

View file

@ -2293,11 +2293,6 @@
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==
"@types/parse5@^6.0.0":
version "6.0.3"
resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-6.0.3.tgz#705bb349e789efa06f43f128cef51240753424cb"
integrity sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==
"@types/pbf@*", "@types/pbf@^3.0.2": "@types/pbf@*", "@types/pbf@^3.0.2":
version "3.0.2" version "3.0.2"
resolved "https://registry.yarnpkg.com/@types/pbf/-/pbf-3.0.2.tgz#8d291ad68b4b8c533e96c174a2e3e6399a59ed61" resolved "https://registry.yarnpkg.com/@types/pbf/-/pbf-3.0.2.tgz#8d291ad68b4b8c533e96c174a2e3e6399a59ed61"
@ -6990,11 +6985,6 @@ parse5-htmlparser2-tree-adapter@^7.0.0:
domhandler "^5.0.2" domhandler "^5.0.2"
parse5 "^7.0.0" parse5 "^7.0.0"
parse5@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b"
integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==
parse5@^7.0.0, parse5@^7.1.1: parse5@^7.0.0, parse5@^7.1.1:
version "7.1.2" version "7.1.2"
resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.1.2.tgz#0736bebbfd77793823240a23b7fc5e010b7f8e32" resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.1.2.tgz#0736bebbfd77793823240a23b7fc5e010b7f8e32"