mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-17 09:36:08 +08:00
ui: use esbuild-loader & chunk-splitting
This commit is contained in:
1 parent
db9def7917
commit
e67c1c333a
9 files changed
+104
-54
No files matched your search
@@ -1,10 +1,12 @@
|
||||
/* eslint-disable global-require */
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
import { dirname } from 'path';
|
||||
import webpack from 'webpack';
|
||||
import { CleanWebpackPlugin } from 'clean-webpack-plugin';
|
||||
import { ESBuildMinifyPlugin } from 'esbuild-loader';
|
||||
import ExtractCssPlugin from 'mini-css-extract-plugin';
|
||||
import MonacoWebpackPlugin from 'monaco-editor-webpack-plugin';
|
||||
import FriendlyErrorsPlugin from 'friendly-errors-webpack-plugin';
|
||||
import OptimizeCssAssetsPlugin from 'optimize-css-assets-webpack-plugin';
|
||||
import CopyWebpackPlugin from 'copy-webpack-plugin';
|
||||
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
|
||||
import SpeedMeasurePlugin from 'speed-measure-webpack-plugin';
|
||||
@@ -20,22 +22,13 @@ const beautifyOutputUrl = mapWebpackUrlPrefix([
|
||||
const smp = new SpeedMeasurePlugin();
|
||||
|
||||
export default function (env = {}) {
|
||||
function babelLoader() {
|
||||
return {
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
...require(root('babel.config.js')), // eslint-disable-line
|
||||
cacheDirectory: true,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function esbuildLoader() {
|
||||
return {
|
||||
loader: 'esbuild-loader',
|
||||
options: {
|
||||
loader: 'tsx',
|
||||
target: 'es2015',
|
||||
sourcemap: true,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -113,13 +106,7 @@ export default function (env = {}) {
|
||||
use: [fileLoader()],
|
||||
},
|
||||
{
|
||||
test: /\.jsx?$/,
|
||||
exclude: /node_modules[/\\]/,
|
||||
use: [babelLoader()],
|
||||
},
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
exclude: /node_modules[/\\]/,
|
||||
test: /\.[jt]sx?$/,
|
||||
use: [esbuildLoader()],
|
||||
},
|
||||
{
|
||||
@@ -139,14 +126,55 @@ export default function (env = {}) {
|
||||
},
|
||||
optimization: {
|
||||
splitChunks: {
|
||||
minSize: 80000,
|
||||
maxAsyncRequests: 15,
|
||||
maxInitialRequests: 10,
|
||||
minSize: 256000,
|
||||
maxAsyncRequests: 5,
|
||||
maxInitialRequests: 3,
|
||||
automaticNameDelimiter: '-',
|
||||
cacheGroups: {
|
||||
blockly: {
|
||||
test: /[\\/]@?blockly[\\/]/,
|
||||
priority: 10,
|
||||
name: 'blockly',
|
||||
},
|
||||
monaco: {
|
||||
test: /[\\/]monaco-editor[\\/]/,
|
||||
priority: 9,
|
||||
name: `monaco-${require('monaco-editor/package.json').version}`,
|
||||
},
|
||||
vditor: {
|
||||
test: /[\\/]vditor[\\/]/,
|
||||
priority: 8,
|
||||
name: `vditor-${require('vditor/package.json').version}`,
|
||||
},
|
||||
vendors: {
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
priority: -10,
|
||||
name: 'vendors',
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
default: {
|
||||
priority: -20,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
minimizer: [new ESBuildMinifyPlugin({
|
||||
css: true,
|
||||
minify: true,
|
||||
minifySyntax: true,
|
||||
minifyWhitespace: true,
|
||||
minifyIdentifiers: true,
|
||||
treeShaking: true,
|
||||
target: [
|
||||
'chrome60',
|
||||
],
|
||||
exclude: [/mathmaps/, /\.min\.js$/],
|
||||
})],
|
||||
moduleIds: env.production ? 'size' : 'named',
|
||||
chunkIds: env.production ? 'size' : 'named',
|
||||
},
|
||||
plugins: [
|
||||
new CleanWebpackPlugin(),
|
||||
new WebpackBar(),
|
||||
new webpack.ProvidePlugin({
|
||||
$: 'jquery',
|
||||
@@ -183,12 +211,6 @@ export default function (env = {}) {
|
||||
NODE_ENV: env.production ? '"production"' : '"debug"',
|
||||
},
|
||||
}),
|
||||
...(env.production || env.measure)
|
||||
? [
|
||||
new OptimizeCssAssetsPlugin(),
|
||||
new webpack.LoaderOptionsPlugin({ minimize: true }),
|
||||
]
|
||||
: [],
|
||||
new webpack.LoaderOptionsPlugin({
|
||||
options: {
|
||||
context: root(),
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
import _ from 'lodash';
|
||||
import { escapeRegExp } from 'lodash';
|
||||
|
||||
export default function mapWebpackUrlPrefix(mapList) {
|
||||
const rules = mapList.map((mappingRule) => {
|
||||
const regex = mappingRule.prefix.split('/').map((s) => _.escapeRegExp(s)).join('[\\/\\\\]');
|
||||
const regex = mappingRule.prefix.split('/').map((s) => escapeRegExp(s)).join('[\\/\\\\]');
|
||||
return {
|
||||
from: new RegExp(`^${regex}`, mappingRule.flag),
|
||||
to: mappingRule.replace,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import _ from 'lodash';
|
||||
import { assign } from 'lodash';
|
||||
import tpl from 'vj/utils/tpl';
|
||||
import request from 'vj/utils/request';
|
||||
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
|
||||
@@ -40,5 +40,5 @@ export default class DomainSelectAutoComplete extends AutoComplete {
|
||||
}
|
||||
}
|
||||
|
||||
_.assign(DomainSelectAutoComplete, DOMAttachedObject);
|
||||
assign(DomainSelectAutoComplete, DOMAttachedObject);
|
||||
window.Hydro.components.DomainSelectAutoComplete = DomainSelectAutoComplete;
|
||||
@@ -1,4 +1,4 @@
|
||||
import _ from 'lodash';
|
||||
import { assign } from 'lodash';
|
||||
import tpl from 'vj/utils/tpl';
|
||||
import request from 'vj/utils/request';
|
||||
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
|
||||
@@ -37,5 +37,5 @@ export default class ProblemSelectAutoComplete extends AutoComplete {
|
||||
}
|
||||
}
|
||||
|
||||
_.assign(ProblemSelectAutoComplete, DOMAttachedObject);
|
||||
assign(ProblemSelectAutoComplete, DOMAttachedObject);
|
||||
window.Hydro.components.ProblemSelectAutoComplete = ProblemSelectAutoComplete;
|
||||
@@ -1,5 +1,5 @@
|
||||
import Drop from 'tether-drop';
|
||||
import _ from 'lodash';
|
||||
import { assign } from 'lodash';
|
||||
import 'jquery-scroll-lock';
|
||||
|
||||
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
|
||||
@@ -194,5 +194,5 @@ export default class AutoComplete extends DOMAttachedObject {
|
||||
}
|
||||
}
|
||||
|
||||
_.assign(AutoComplete, DOMAttachedObject);
|
||||
assign(AutoComplete, DOMAttachedObject);
|
||||
window.Hydro.components.autocomplete = AutoComplete;
|
||||
@@ -1,23 +1,28 @@
|
||||
/*
|
||||
|
||||
To add a new language to highlight:
|
||||
1. Add language in babel in package.json
|
||||
2. Add new import statement in `components/cmeditor/vjcmeditor.js`
|
||||
3. Add new import statement in `components/scratchpad/ScratchpadEditorContainer.js`
|
||||
4. Add new meta data in `components/highlighter/meta.js`
|
||||
|
||||
*/
|
||||
|
||||
import Prism from 'prismjs';
|
||||
|
||||
import components from 'prismjs/components';
|
||||
import getLoader from 'prismjs/dependencies';
|
||||
import 'prismjs/plugins/toolbar/prism-toolbar';
|
||||
import 'prismjs/plugins/toolbar/prism-toolbar.css';
|
||||
import 'prismjs/plugins/line-numbers/prism-line-numbers';
|
||||
import 'prismjs/plugins/line-numbers/prism-line-numbers.css';
|
||||
import Clipboard from 'clipboard';
|
||||
import Notification from 'vj/components/notification/index';
|
||||
import i18n from 'vj/utils/i18n';
|
||||
|
||||
import languageMeta from './meta';
|
||||
|
||||
const languageExtMap = {};
|
||||
const files = require.context('prismjs/components/', true, /prism-[a-z0-9-]+\.js/);
|
||||
const loadedLanguages = new Set();
|
||||
function loadLanguages() {
|
||||
const languages = Object.keys(components.languages).filter((l) => l !== 'meta');
|
||||
const loaded = [...loadedLanguages, ...Object.keys(Prism.languages)];
|
||||
getLoader(components, languages, loaded).load((lang) => {
|
||||
files(`./prism-${lang}.js`);
|
||||
loadedLanguages.add(lang);
|
||||
});
|
||||
}
|
||||
|
||||
const languageExtMap = {};
|
||||
loadLanguages();
|
||||
// Map possible language names to Prism language name
|
||||
languageMeta.forEach((meta) => {
|
||||
for (let i = 0; i < meta.ext.length; ++i) {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import React from 'react';
|
||||
import _ from 'lodash';
|
||||
import { connect } from 'react-redux';
|
||||
import TimeAgo from 'timeago-react';
|
||||
import moment from 'dayjs';
|
||||
@@ -55,7 +54,7 @@ export default connect(mapStateToProps)(class MessagePadDialogueContentContainer
|
||||
|
||||
renderInner() {
|
||||
if (this.props.activeId === null) return [];
|
||||
return _.map(this.props.item.messages, (msg) => (
|
||||
return this.props.item.messages.map((msg) => (
|
||||
<Message
|
||||
key={msg._id}
|
||||
isSelf={msg.from === UserContext._id}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import load from 'vj/components/wastyle/index';
|
||||
import monaco from 'vj/components/monaco/index';
|
||||
import Notification from 'vj/components/notification';
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
value: state.editor.code,
|
||||
@@ -29,7 +31,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(class MonacoEditor e
|
||||
const { language, theme } = this.props;
|
||||
if (this.props.language === 'blockly') {
|
||||
if (!this.blockly) {
|
||||
import('./blockly.jsx').then(({ default: Blockly }) => {
|
||||
import('./blockly').then(({ default: Blockly }) => {
|
||||
if (!this.blockly) return;
|
||||
Blockly.inject(this.containerElement, {
|
||||
});
|
||||
@@ -51,6 +53,29 @@ export default connect(mapStateToProps, mapDispatchToProps)(class MonacoEditor e
|
||||
const fontSize = localStorage.getItem('scratchpad.editor.fontSize');
|
||||
if (fontSize && !Number.isNaN(+fontSize)) config.fontSize = +fontSize;
|
||||
this.editor = monaco.editor.create(this.containerElement, config);
|
||||
this.editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyMod.Shift | monaco.KeyCode.KEY_P, () => {
|
||||
this.editor.getAction('editor.action.quickCommand').run();
|
||||
});
|
||||
load().then(([loaded, format]) => {
|
||||
if (!loaded) return;
|
||||
const formatAction = {
|
||||
id: 'hydro.format',
|
||||
label: 'Format Code',
|
||||
contextMenuOrder: 0,
|
||||
contextMenuGroupId: 'operation',
|
||||
keybindings: [monaco.KeyMod.Alt | monaco.KeyMod.Shift | monaco.KeyCode.KEY_F],
|
||||
run: () => {
|
||||
if (!['cpp', 'c'].includes(this.model._languageIdentifier.language)) return;
|
||||
const [success, result] = format(this.editor.getValue(), `${UserContext.astyleOptions.trim()} mode=c`);
|
||||
if (success) this.editor.setValue(result);
|
||||
else Notification.warn(result);
|
||||
},
|
||||
};
|
||||
this.editor.addAction(formatAction);
|
||||
this.editor.addCommand(monaco.KeyMod.Alt | monaco.KeyMod.Shift | monaco.KeyCode.KEY_F, () => {
|
||||
this.editor.getAction('hydro.format').run();
|
||||
});
|
||||
});
|
||||
this.disposable.push(
|
||||
this.editor.onDidChangeModelContent((event) => {
|
||||
if (!this.__prevent_trigger_change_event) {
|
||||
@@ -69,7 +94,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(class MonacoEditor e
|
||||
if (this.props.language === 'blockly') {
|
||||
if (!this.blockly) {
|
||||
this.editor.dispose();
|
||||
import('./blockly.jsx').then(({ default: Blockly, toolbox }) => {
|
||||
import('./blockly').then(({ default: Blockly, toolbox }) => {
|
||||
if (!this.blockly) return;
|
||||
Blockly.inject(this.containerElement, {
|
||||
toolbox,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hydrooj/ui-default",
|
||||
"version": "4.15.2",
|
||||
"version": "4.16.0",
|
||||
"author": "undefined <i@undefined.moe>",
|
||||
"license": "AGPL-3.0",
|
||||
"main": "hydro.js",
|
||||
@@ -75,7 +75,6 @@
|
||||
"nanoid": "^3.1.23",
|
||||
"normalize.css": "^8.0.1",
|
||||
"nprogress": "^0.2.0",
|
||||
"optimize-css-assets-webpack-plugin": "^5.0.8",
|
||||
"pickadate": "^3.6.4",
|
||||
"plugin-error": "^1.0.1",
|
||||
"postcss-loader": "^3.0.0",
|
||||
|
||||
Reference in new issue
Block a user