Added cm6 strategy for splitting and dyn. loading langs

Split out legacy modes to their own dynamically imported bundle to
reduce main code bundle size.
This commit is contained in:
Dan Brown 2023-04-14 18:08:57 +01:00
parent 257a703878
commit 9874a53206
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
8 changed files with 144 additions and 114 deletions

View File

@ -12,6 +12,7 @@ const isProd = process.argv[2] === 'production';
const entryPoints = { const entryPoints = {
app: path.join(__dirname, '../../resources/js/app.js'), app: path.join(__dirname, '../../resources/js/app.js'),
code: path.join(__dirname, '../../resources/js/code/index.mjs'), code: path.join(__dirname, '../../resources/js/code/index.mjs'),
'legacy-modes': path.join(__dirname, '../../resources/js/code/legacy-modes.mjs'),
}; };
// Locate our output directory // Locate our output directory

33
package-lock.json generated
View File

@ -6,6 +6,9 @@
"": { "": {
"dependencies": { "dependencies": {
"@codemirror/commands": "^6.0.1", "@codemirror/commands": "^6.0.1",
"@codemirror/lang-css": "^6.1.1",
"@codemirror/lang-javascript": "^6.1.6",
"@codemirror/lang-json": "^6.0.1",
"@codemirror/lang-markdown": "^6.0.1", "@codemirror/lang-markdown": "^6.0.1",
"@codemirror/lang-php": "^6.0.0", "@codemirror/lang-php": "^6.0.0",
"@codemirror/language": "^6.2.1", "@codemirror/language": "^6.2.1",
@ -61,9 +64,9 @@
} }
}, },
"node_modules/@codemirror/lang-css": { "node_modules/@codemirror/lang-css": {
"version": "6.0.2", "version": "6.1.1",
"resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.0.2.tgz", "resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.1.1.tgz",
"integrity": "sha512-4V4zmUOl2Glx0GWw0HiO1oGD4zvMlIQ3zx5hXOE6ipCjhohig2bhWRAasrZylH9pRNTcl1VMa59Lsl8lZWlTzw==", "integrity": "sha512-P6jdNEHyRcqqDgbvHYyC9Wxkek0rnG3a9aVSRi4a7WrjPbQtBTaOmvYpXmm13zZMAatO4Oqpac+0QZs7sy+LnQ==",
"dependencies": { "dependencies": {
"@codemirror/autocomplete": "^6.0.0", "@codemirror/autocomplete": "^6.0.0",
"@codemirror/language": "^6.0.0", "@codemirror/language": "^6.0.0",
@ -88,9 +91,9 @@
} }
}, },
"node_modules/@codemirror/lang-javascript": { "node_modules/@codemirror/lang-javascript": {
"version": "6.1.4", "version": "6.1.6",
"resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.1.4.tgz", "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.1.6.tgz",
"integrity": "sha512-OxLf7OfOZBTMRMi6BO/F72MNGmgOd9B0vetOLvHsDACFXayBzW8fm8aWnDM0yuy68wTK03MBf4HbjSBNRG5q7A==", "integrity": "sha512-TTK28z+vJQY9GAefLTDDptI2LMqMfAiuTpt8s9SsNwocjVQ1v9yTzfReMf1hYhspQCdhfa7fdKnQJ78mKe/bHQ==",
"dependencies": { "dependencies": {
"@codemirror/autocomplete": "^6.0.0", "@codemirror/autocomplete": "^6.0.0",
"@codemirror/language": "^6.6.0", "@codemirror/language": "^6.6.0",
@ -101,6 +104,15 @@
"@lezer/javascript": "^1.0.0" "@lezer/javascript": "^1.0.0"
} }
}, },
"node_modules/@codemirror/lang-json": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@codemirror/lang-json/-/lang-json-6.0.1.tgz",
"integrity": "sha512-+T1flHdgpqDDlJZ2Lkil/rLiRy684WMLc74xUnjJH48GQdfJo/pudlTRreZmKwzP8/tGdKf83wlbAdOCzlJOGQ==",
"dependencies": {
"@codemirror/language": "^6.0.0",
"@lezer/json": "^1.0.0"
}
},
"node_modules/@codemirror/lang-markdown": { "node_modules/@codemirror/lang-markdown": {
"version": "6.1.0", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/@codemirror/lang-markdown/-/lang-markdown-6.1.0.tgz", "resolved": "https://registry.npmjs.org/@codemirror/lang-markdown/-/lang-markdown-6.1.0.tgz",
@ -599,6 +611,15 @@
"@lezer/lr": "^1.3.0" "@lezer/lr": "^1.3.0"
} }
}, },
"node_modules/@lezer/json": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@lezer/json/-/json-1.0.0.tgz",
"integrity": "sha512-zbAuUY09RBzCoCA3lJ1+ypKw5WSNvLqGMtasdW6HvVOqZoCpPr8eWrsGnOVWGKGn8Rh21FnrKRVlJXrGAVUqRw==",
"dependencies": {
"@lezer/highlight": "^1.0.0",
"@lezer/lr": "^1.0.0"
}
},
"node_modules/@lezer/lr": { "node_modules/@lezer/lr": {
"version": "1.3.3", "version": "1.3.3",
"resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.3.3.tgz", "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.3.3.tgz",

View File

@ -25,6 +25,9 @@
}, },
"dependencies": { "dependencies": {
"@codemirror/commands": "^6.0.1", "@codemirror/commands": "^6.0.1",
"@codemirror/lang-css": "^6.1.1",
"@codemirror/lang-javascript": "^6.1.6",
"@codemirror/lang-json": "^6.0.1",
"@codemirror/lang-markdown": "^6.0.1", "@codemirror/lang-markdown": "^6.0.1",
"@codemirror/lang-php": "^6.0.0", "@codemirror/lang-php": "^6.0.0",
"@codemirror/language": "^6.2.1", "@codemirror/language": "^6.2.1",

View File

@ -200,6 +200,7 @@ export function markdownEditor(elem, onChange, domEventHandlers, keyBindings) {
// Create editor view, hide original input // Create editor view, hide original input
const ev = createView(config); const ev = createView(config);
setMode(ev, 'markdown', '');
elem.style.display = 'none'; elem.style.display = 'none';
return ev; return ev;

View File

@ -1,119 +1,97 @@
import {StreamLanguage} from "@codemirror/language" import {StreamLanguage} from "@codemirror/language"
import {css} from '@codemirror/legacy-modes/mode/css'; import {css} from '@codemirror/lang-css';
import {c, cpp, csharp, java, kotlin, scala, dart} from '@codemirror/legacy-modes/mode/clike'; import {json} from '@codemirror/lang-json';
import {diff} from '@codemirror/legacy-modes/mode/diff'; import {javascript} from '@codemirror/lang-javascript';
import {fortran} from '@codemirror/legacy-modes/mode/fortran';
import {go} from '@codemirror/legacy-modes/mode/go';
import {haskell} from '@codemirror/legacy-modes/mode/haskell';
import {javascript, json, typescript} from '@codemirror/legacy-modes/mode/javascript';
import {julia} from '@codemirror/legacy-modes/mode/julia';
import {lua} from '@codemirror/legacy-modes/mode/lua';
import {markdown} from '@codemirror/lang-markdown'; import {markdown} from '@codemirror/lang-markdown';
import {oCaml, fSharp, sml} from '@codemirror/legacy-modes/mode/mllike';
import {nginx} from '@codemirror/legacy-modes/mode/nginx';
import {octave} from '@codemirror/legacy-modes/mode/octave';
import {perl} from '@codemirror/legacy-modes/mode/perl';
import {pascal} from '@codemirror/legacy-modes/mode/pascal';
import {php} from '@codemirror/lang-php'; import {php} from '@codemirror/lang-php';
import {powerShell} from '@codemirror/legacy-modes/mode/powershell'; export {twig} from "@ssddanbrown/codemirror-lang-twig";
import {properties} from '@codemirror/legacy-modes/mode/properties';
import {python} from '@codemirror/legacy-modes/mode/python'; const legacyLoad = async (mode) => {
import {ruby} from '@codemirror/legacy-modes/mode/ruby'; const modes = await window.importVersioned('legacy-modes');
import {rust} from '@codemirror/legacy-modes/mode/rust'; return StreamLanguage.define(modes[mode]);
import {scheme} from '@codemirror/legacy-modes/mode/scheme'; };
import {shell} from '@codemirror/legacy-modes/mode/shell';
import {smarty} from "@ssddanbrown/codemirror-lang-smarty";
import {standardSQL, pgSQL, msSQL, mySQL, sqlite, plSQL} from '@codemirror/legacy-modes/mode/sql';
import {stex} from '@codemirror/legacy-modes/mode/stex';
import {swift} from "@codemirror/legacy-modes/mode/swift";
import {toml} from '@codemirror/legacy-modes/mode/toml';
import {twig} from "@ssddanbrown/codemirror-lang-twig";
import {vb} from '@codemirror/legacy-modes/mode/vb';
import {vbScript} from '@codemirror/legacy-modes/mode/vbscript';
import {xml, html} from '@codemirror/legacy-modes/mode/xml';
import {yaml} from '@codemirror/legacy-modes/mode/yaml';
// Mapping of possible languages or formats from user input to their codemirror modes. // Mapping of possible languages or formats from user input to their codemirror modes.
// Value can be a mode string or a function that will receive the code content & return the mode string. // Value can be a mode string or a function that will receive the code content & return the mode string.
// The function option is used in the event the exact mode could be dynamic depending on the code. // The function option is used in the event the exact mode could be dynamic depending on the code.
const modeMap = { const modeMap = {
bash: () => StreamLanguage.define(shell), bash: () => legacyLoad('shell'),
c: () => StreamLanguage.define(c), c: () => legacyLoad('c'),
css: () => StreamLanguage.define(css), css: async () => css(),
'c++': () => StreamLanguage.define(cpp), 'c++': () => legacyLoad('cpp'),
'c#': () => StreamLanguage.define(csharp), 'c#': () => legacyLoad('csharp'),
csharp: () => StreamLanguage.define(csharp), csharp: () => legacyLoad('csharp'),
dart: () => StreamLanguage.define(dart), dart: () => legacyLoad('dart'),
diff: () => StreamLanguage.define(diff), diff: () => legacyLoad('diff'),
for: () => StreamLanguage.define(fortran), for: () => legacyLoad('fortran'),
fortran: () => StreamLanguage.define(fortran), fortran: () => legacyLoad('fortran'),
'f#': () => StreamLanguage.define(fSharp), 'f#': () => legacyLoad('fSharp'),
fsharp: () => StreamLanguage.define(fSharp), fsharp: () => legacyLoad('fSharp'),
go: () => StreamLanguage.define(go), go: () => legacyLoad('go'),
haskell: () => StreamLanguage.define(haskell), haskell: () => legacyLoad('haskell'),
hs: () => StreamLanguage.define(haskell), hs: () => legacyLoad('haskell'),
html: () => StreamLanguage.define(html), html: () => legacyLoad('html'),
ini: () => StreamLanguage.define(properties), ini: () => legacyLoad('properties'),
java: () => StreamLanguage.define(java), java: () => legacyLoad('java'),
javascript: () => StreamLanguage.define(javascript), javascript: async () => javascript(),
json: () => StreamLanguage.define(json), json: async () => json(),
js: () => StreamLanguage.define(javascript), js: async () => javascript(),
jl: () => StreamLanguage.define(julia), jl: () => legacyLoad('julia'),
julia: () => StreamLanguage.define(julia), julia: () => legacyLoad('julia'),
kotlin: () => StreamLanguage.define(kotlin), kotlin: () => legacyLoad('kotlin'),
latex: () => StreamLanguage.define(stex), latex: () => legacyLoad('stex'),
lua: () => StreamLanguage.define(lua), lua: () => legacyLoad('lua'),
markdown: () => markdown(), markdown: async () => markdown(),
matlab: () => StreamLanguage.define(octave), matlab: () => legacyLoad('octave'),
md: () => markdown(), md: async () => markdown(),
mdown: () => markdown(), mdown: async () => markdown(),
ml: () => StreamLanguage.define(sml), ml: () => legacyLoad('sml'),
mssql: () => StreamLanguage.define(msSQL), mssql: () => legacyLoad('msSQL'),
mysql: () => StreamLanguage.define(mySQL), mysql: () => legacyLoad('mySQL'),
nginx: () => StreamLanguage.define(nginx), nginx: () => legacyLoad('nginx'),
octave: () => StreamLanguage.define(octave), octave: () => legacyLoad('octave'),
pas: () => StreamLanguage.define(pascal), pas: () => legacyLoad('pascal'),
pascal: () => StreamLanguage.define(pascal), pascal: () => legacyLoad('pascal'),
perl: () => StreamLanguage.define(perl), perl: () => legacyLoad('perl'),
pgsql: () => StreamLanguage.define(pgSQL), pgsql: () => legacyLoad('pgSQL'),
php: (code) => { php: async (code) => {
const hasTags = code.includes('<?php'); const hasTags = code.includes('<?php');
return php({plain: !hasTags}); return php({plain: !hasTags});
}, },
pl: () => StreamLanguage.define(perl), pl: () => legacyLoad('perl'),
'pl/sql': () => StreamLanguage.define(plSQL), 'pl/sql': () => legacyLoad('plSQL'),
postgresql: () => StreamLanguage.define(pgSQL), postgresql: () => legacyLoad('pgSQL'),
powershell: () => StreamLanguage.define(powerShell), powershell: () => legacyLoad('powerShell'),
properties: () => StreamLanguage.define(properties), properties: () => legacyLoad('properties'),
ocaml: () => StreamLanguage.define(oCaml), ocaml: () => legacyLoad('oCaml'),
py: () => StreamLanguage.define(python), py: () => legacyLoad('python'),
python: () => StreamLanguage.define(python), python: () => legacyLoad('python'),
rb: () => StreamLanguage.define(ruby), rb: () => legacyLoad('ruby'),
rs: () => StreamLanguage.define(rust), rs: () => legacyLoad('rust'),
ruby: () => StreamLanguage.define(ruby), ruby: () => legacyLoad('ruby'),
rust: () => StreamLanguage.define(rust), rust: () => legacyLoad('rust'),
scala: () => StreamLanguage.define(scala), scala: () => legacyLoad('scala'),
scheme: () => StreamLanguage.define(scheme), scheme: () => legacyLoad('scheme'),
shell: () => StreamLanguage.define(shell), shell: () => legacyLoad('shell'),
sh: () => StreamLanguage.define(shell), sh: () => legacyLoad('shell'),
smarty: () => StreamLanguage.define(smarty), smarty: () => legacyLoad('smarty'),
stext: () => StreamLanguage.define(stex), stext: () => legacyLoad('stex'),
swift: () => StreamLanguage.define(swift), swift: () => legacyLoad('swift'),
toml: () => StreamLanguage.define(toml), toml: () => legacyLoad('toml'),
ts: () => StreamLanguage.define(typescript), ts: async () => javascript({typescript: true}),
twig: () => twig(), twig: async () => twig(),
typescript: () => StreamLanguage.define(typescript), typescript: async () => javascript({typescript: true}),
sql: () => StreamLanguage.define(standardSQL), sql: () => legacyLoad('standardSQL'),
sqlite: () => StreamLanguage.define(sqlite), sqlite: () => legacyLoad('sqlite'),
vbs: () => StreamLanguage.define(vbScript), vbs: () => legacyLoad('vbScript'),
vbscript: () => StreamLanguage.define(vbScript), vbscript: () => legacyLoad('vbScript'),
'vb.net': () => StreamLanguage.define(vb), 'vb.net': () => legacyLoad('vb'),
vbnet: () => StreamLanguage.define(vb), vbnet: () => legacyLoad('vb'),
xml: () => StreamLanguage.define(xml), xml: () => legacyLoad('xml'),
yaml: () => StreamLanguage.define(yaml), yaml: () => legacyLoad('yaml'),
yml: () => StreamLanguage.define(yaml), yml: () => legacyLoad('yaml'),
}; };
/** /**
@ -121,7 +99,7 @@ const modeMap = {
* suggestion and content. * suggestion and content.
* @param {String} langSuggestion * @param {String} langSuggestion
* @param {String} content * @param {String} content
* @returns {StreamLanguage} * @returns {Promise<StreamLanguage|LanguageSupport>}
*/ */
export function getLanguageExtension(langSuggestion, content) { export function getLanguageExtension(langSuggestion, content) {
const suggestion = langSuggestion.trim().replace(/^\./g, '').toLowerCase(); const suggestion = langSuggestion.trim().replace(/^\./g, '').toLowerCase();

View File

@ -0,0 +1,28 @@
export {c, cpp, csharp, java, kotlin, scala, dart} from '@codemirror/legacy-modes/mode/clike';
export {diff} from '@codemirror/legacy-modes/mode/diff';
export {fortran} from '@codemirror/legacy-modes/mode/fortran';
export {go} from '@codemirror/legacy-modes/mode/go';
export {haskell} from '@codemirror/legacy-modes/mode/haskell';
export {julia} from '@codemirror/legacy-modes/mode/julia';
export {lua} from '@codemirror/legacy-modes/mode/lua';
export {oCaml, fSharp, sml} from '@codemirror/legacy-modes/mode/mllike';
export {nginx} from '@codemirror/legacy-modes/mode/nginx';
export {octave} from '@codemirror/legacy-modes/mode/octave';
export {perl} from '@codemirror/legacy-modes/mode/perl';
export {pascal} from '@codemirror/legacy-modes/mode/pascal';
export {powerShell} from '@codemirror/legacy-modes/mode/powershell';
export {properties} from '@codemirror/legacy-modes/mode/properties';
export {python} from '@codemirror/legacy-modes/mode/python';
export {ruby} from '@codemirror/legacy-modes/mode/ruby';
export {rust} from '@codemirror/legacy-modes/mode/rust';
export {scheme} from '@codemirror/legacy-modes/mode/scheme';
export {shell} from '@codemirror/legacy-modes/mode/shell';
export {standardSQL, pgSQL, msSQL, mySQL, sqlite, plSQL} from '@codemirror/legacy-modes/mode/sql';
export {stex} from '@codemirror/legacy-modes/mode/stex';
export {swift} from "@codemirror/legacy-modes/mode/swift";
export {toml} from '@codemirror/legacy-modes/mode/toml';
export {vb} from '@codemirror/legacy-modes/mode/vb';
export {vbScript} from '@codemirror/legacy-modes/mode/vbscript';
export {xml, html} from '@codemirror/legacy-modes/mode/xml';
export {yaml} from '@codemirror/legacy-modes/mode/yaml';
export {smarty} from "@ssddanbrown/codemirror-lang-smarty";

View File

@ -6,7 +6,6 @@ import {defaultKeymap, history, historyKeymap} from "@codemirror/commands"
import {EditorState} from "@codemirror/state" import {EditorState} from "@codemirror/state"
import {defaultLight} from "./themes"; import {defaultLight} from "./themes";
import {getLanguageExtension} from "./languages";
export function viewer() { export function viewer() {
return [ return [
@ -44,7 +43,6 @@ export function editor(language) {
...defaultKeymap, ...defaultKeymap,
...historyKeymap, ...historyKeymap,
]), ]),
getLanguageExtension(language, ''),
EditorView.lineWrapping, EditorView.lineWrapping,
]; ];
} }

View File

@ -47,9 +47,9 @@ function getTheme(viewParentEl) {
* @param {string} modeSuggestion * @param {string} modeSuggestion
* @param {string} content * @param {string} content
*/ */
export function updateViewLanguage(ev, modeSuggestion, content) { export async function updateViewLanguage(ev, modeSuggestion, content) {
const compartment = viewLangCompartments.get(ev); const compartment = viewLangCompartments.get(ev);
const language = getLanguageExtension(modeSuggestion, content); const language = await getLanguageExtension(modeSuggestion, content);
ev.dispatch({ ev.dispatch({
effects: compartment.reconfigure(language ? language : []) effects: compartment.reconfigure(language ? language : [])