mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-11-24 21:52:43 +01:00
9249c810b8
* Switch code editor to Monaco This switches out CodeMirror for Monaco which is based on the same code base as VS code and should work pretty similar to it. It does add a few async chunks, totalling around 10MB to our build. It currently supports around 65 languages and in the default configuration, each language would emit one ugly [number].js chunk, so I opted to combine them all into a single file for now. CodeMirror is still being used under the hood by SimpleMDE so it can not be removed yet. * inline editorconfig, fix diff, use for markdown, remove more dead code * refactors, remove jquery usage * use tab_width * fix intellisense * rename function for clarity * misc tweaks, enable webpack progress display * only use --progress on dev build * remove useless borders in arc-green * fix typo * remove obsolete comment * small refactor * fix file creation and various refactors * unset useTabStops too when no editorconfig * small refactor * disable webpack's [big] warnings * remove useless await * fix dark theme check * rename chunk to 'monaco' * add to .gitignore and delete webpack dest before build * increase editor height * support more editorconfig properties * remove empty element filter * rename Co-authored-by: John Olheiser <john.olheiser@gmail.com>
261 lines
6.8 KiB
JavaScript
261 lines
6.8 KiB
JavaScript
const cssnano = require('cssnano');
|
|
const fastGlob = require('fast-glob');
|
|
const FixStyleOnlyEntriesPlugin = require('webpack-fix-style-only-entries');
|
|
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
|
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
|
|
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
|
|
const PostCSSPresetEnv = require('postcss-preset-env');
|
|
const PostCSSSafeParser = require('postcss-safe-parser');
|
|
const SpriteLoaderPlugin = require('svg-sprite-loader/plugin');
|
|
const TerserPlugin = require('terser-webpack-plugin');
|
|
const VueLoaderPlugin = require('vue-loader/lib/plugin');
|
|
const {statSync} = require('fs');
|
|
const {resolve, parse} = require('path');
|
|
const {SourceMapDevToolPlugin} = require('webpack');
|
|
|
|
const glob = (pattern) => fastGlob.sync(pattern, {cwd: __dirname, absolute: true});
|
|
|
|
const themes = {};
|
|
for (const path of glob('web_src/less/themes/*.less')) {
|
|
themes[parse(path).name] = [path];
|
|
}
|
|
|
|
const isProduction = process.env.NODE_ENV !== 'development';
|
|
|
|
module.exports = {
|
|
mode: isProduction ? 'production' : 'development',
|
|
entry: {
|
|
index: [
|
|
resolve(__dirname, 'web_src/js/index.js'),
|
|
resolve(__dirname, 'web_src/less/index.less'),
|
|
],
|
|
swagger: [
|
|
resolve(__dirname, 'web_src/js/standalone/swagger.js'),
|
|
],
|
|
jquery: [
|
|
resolve(__dirname, 'web_src/js/jquery.js'),
|
|
],
|
|
icons: glob('node_modules/@primer/octicons/build/svg/**/*.svg'),
|
|
...themes,
|
|
},
|
|
devtool: false,
|
|
output: {
|
|
path: resolve(__dirname, 'public'),
|
|
filename: 'js/[name].js',
|
|
chunkFilename: 'js/[name].js',
|
|
},
|
|
optimization: {
|
|
minimize: isProduction,
|
|
minimizer: [
|
|
new TerserPlugin({
|
|
sourceMap: true,
|
|
extractComments: false,
|
|
terserOptions: {
|
|
keep_fnames: /^(HTML|SVG)/, // https://github.com/fgnass/domino/issues/144
|
|
output: {
|
|
comments: false,
|
|
},
|
|
},
|
|
}),
|
|
new OptimizeCSSAssetsPlugin({
|
|
cssProcessor: cssnano,
|
|
cssProcessorOptions: {
|
|
parser: PostCSSSafeParser,
|
|
},
|
|
cssProcessorPluginOptions: {
|
|
preset: [
|
|
'default',
|
|
{
|
|
discardComments: {
|
|
removeAll: true,
|
|
},
|
|
},
|
|
],
|
|
},
|
|
}),
|
|
],
|
|
splitChunks: {
|
|
chunks: 'async',
|
|
name: (_, chunks) => chunks.map((item) => item.name).join('-'),
|
|
cacheGroups: {
|
|
// this bundles all monaco's languages into one file instead of emitting 1-65.js files
|
|
monaco: {
|
|
test: /monaco-editor/,
|
|
name: 'monaco',
|
|
chunks: 'async'
|
|
}
|
|
}
|
|
}
|
|
},
|
|
module: {
|
|
rules: [
|
|
{
|
|
test: /\.vue$/,
|
|
exclude: /node_modules/,
|
|
loader: 'vue-loader',
|
|
},
|
|
{
|
|
test: require.resolve('jquery-datetimepicker'),
|
|
use: 'imports-loader?define=>false,exports=>false',
|
|
},
|
|
{
|
|
test: /\.worker\.js$/,
|
|
exclude: /monaco/,
|
|
use: [
|
|
{
|
|
loader: 'worker-loader',
|
|
options: {
|
|
name: '[name].js',
|
|
inline: true,
|
|
fallback: false,
|
|
},
|
|
},
|
|
],
|
|
},
|
|
{
|
|
test: /\.js$/,
|
|
exclude: /node_modules/,
|
|
use: [
|
|
{
|
|
loader: 'babel-loader',
|
|
options: {
|
|
cacheDirectory: true,
|
|
cacheCompression: false,
|
|
cacheIdentifier: [
|
|
resolve(__dirname, 'package.json'),
|
|
resolve(__dirname, 'package-lock.json'),
|
|
resolve(__dirname, 'webpack.config.js'),
|
|
].map((path) => statSync(path).mtime.getTime()).join(':'),
|
|
sourceMaps: true,
|
|
presets: [
|
|
[
|
|
'@babel/preset-env',
|
|
{
|
|
useBuiltIns: 'usage',
|
|
corejs: 3,
|
|
},
|
|
],
|
|
],
|
|
plugins: [
|
|
[
|
|
'@babel/plugin-transform-runtime',
|
|
{
|
|
regenerator: true,
|
|
}
|
|
],
|
|
'@babel/plugin-proposal-object-rest-spread',
|
|
],
|
|
},
|
|
},
|
|
],
|
|
},
|
|
{
|
|
test: /\.(less|css)$/i,
|
|
use: [
|
|
{
|
|
loader: MiniCssExtractPlugin.loader,
|
|
},
|
|
{
|
|
loader: 'css-loader',
|
|
options: {
|
|
importLoaders: 2,
|
|
url: (_url, resourcePath) => {
|
|
// only resolve URLs for dependencies
|
|
return resourcePath.includes('node_modules');
|
|
},
|
|
}
|
|
},
|
|
{
|
|
loader: 'postcss-loader',
|
|
options: {
|
|
plugins: () => [
|
|
PostCSSPresetEnv(),
|
|
],
|
|
},
|
|
},
|
|
{
|
|
loader: 'less-loader',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
test: /\.svg$/,
|
|
use: [
|
|
{
|
|
loader: 'svg-sprite-loader',
|
|
options: {
|
|
extract: true,
|
|
spriteFilename: 'img/svg/icons.svg',
|
|
symbolId: (path) => {
|
|
const {name} = parse(path);
|
|
if (/@primer[/\\]octicons/.test(path)) {
|
|
return `octicon-${name}`;
|
|
}
|
|
return name;
|
|
},
|
|
},
|
|
},
|
|
{
|
|
loader: 'svgo-loader',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
test: /\.(ttf|woff2?)$/,
|
|
use: [
|
|
{
|
|
loader: 'file-loader',
|
|
options: {
|
|
name: '[name].[ext]',
|
|
outputPath: 'fonts/',
|
|
publicPath: (url) => `../fonts/${url}`, // seems required for monaco's font
|
|
},
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
plugins: [
|
|
new VueLoaderPlugin(),
|
|
// avoid generating useless js output files for css- and svg-only chunks
|
|
new FixStyleOnlyEntriesPlugin({
|
|
extensions: ['less', 'scss', 'css', 'svg'],
|
|
silent: true,
|
|
}),
|
|
new MiniCssExtractPlugin({
|
|
filename: 'css/[name].css',
|
|
chunkFilename: 'css/[name].css',
|
|
}),
|
|
new SourceMapDevToolPlugin({
|
|
filename: 'js/[name].js.map',
|
|
include: [
|
|
'js/index.js',
|
|
],
|
|
}),
|
|
new SpriteLoaderPlugin({
|
|
plainSprite: true,
|
|
}),
|
|
new MonacoWebpackPlugin({
|
|
filename: 'js/monaco-[name].worker.js',
|
|
}),
|
|
],
|
|
performance: {
|
|
hints: false,
|
|
maxEntrypointSize: Infinity,
|
|
maxAssetSize: Infinity,
|
|
},
|
|
resolve: {
|
|
symlinks: false,
|
|
alias: {
|
|
vue$: 'vue/dist/vue.esm.js', // needed because vue's default export is the runtime only
|
|
},
|
|
},
|
|
watchOptions: {
|
|
ignored: [
|
|
'node_modules/**',
|
|
],
|
|
},
|
|
stats: {
|
|
children: false,
|
|
},
|
|
};
|