Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
293 changes: 293 additions & 0 deletions invenio_assets/assets/build/rspack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,293 @@
/*
* This file is part of Invenio.
* Copyright (C) 2017-2018 CERN.
* Copyright (C) 2022-2023 Graz University of Technology.
* Copyright (C) 2023 TU Wien.
*
* Invenio is free software; you can redistribute it and/or modify it
* under the terms of the MIT License; see LICENSE file for more details.
*/
// https://birtles.blog/2024/08/14/lessons-learned-switching-to-rspack/

const BundleTracker = require("webpack-bundle-tracker");
const config = require("./config");
const path = require("path");

// Use rspack
const rspack = require("@rspack/core");

// Load aliases from config and resolve their full path
let aliases = {};
if (config.aliases) {
aliases = Object.fromEntries(
Object.entries(config.aliases).map(([alias, alias_path]) => [
alias,
path.resolve(config.build.context, alias_path),
]),
);
}

// Create copy patterns from config
let copyPatterns = [
{
from: path.resolve(
__dirname,
"../node_modules/tinymce/skins/content/default/content.css",
),
to: path.resolve(config.build.assetsPath, "js/skins/content/default"),
},
{
from: path.resolve(
__dirname,
"../node_modules/tinymce/skins/ui/oxide/skin.min.css",
),
to: path.resolve(config.build.assetsPath, "js/skins/ui/oxide"),
},
{
from: path.resolve(
__dirname,
"../node_modules/tinymce/skins/ui/oxide/content.min.css",
),
to: path.resolve(config.build.assetsPath, "js/skins/ui/oxide"),
},
];
if (config.copy) {
for (copy of config.copy) {
const copyPattern = {
from: path.resolve(__dirname, copy.from),
to: path.resolve(__dirname, copy.to),
};

copyPatterns.push(copyPattern);
}
}

const prod = process.env.NODE_ENV === "production";

var webpackConfig = {
mode: process.env.NODE_ENV,
entry: config.entry,
context: config.build.context,
stats: {
//preset: 'verbose',
// warnings: true,
// errors: true,
// errorsCount: true,
// errorStack: true,
// errorDetails: true,
// children: true,
},
resolve: {
extensions: ["*", ".js", ".jsx"],
symlinks: false,
alias: aliases,
fallback: {
zlib: require.resolve("browserify-zlib"),
stream: require.resolve("stream-browserify"),
https: require.resolve("https-browserify"),
http: require.resolve("stream-http"),
url: false,
assert: false,
},
},
output: {
clean: true, // replaces CleanWebpackPlugin
path: config.build.assetsPath,
filename: "js/[name].[chunkhash].js",
chunkFilename: "js/[id].[chunkhash].js",
publicPath: config.build.assetsURL,
},
optimization: {
minimizer: [
new rspack.SwcJsMinimizerRspackPlugin({
compress: {
ecma: 5,
// warnings: false,
// Disabled because of an issue with Uglify breaking seemingly valid code:
// https://github.com/facebook/create-react-app/issues/2376
// Pending further investigation:
// https://github.com/mishoo/UglifyJS2/issues/2011
comparisons: false,
// Disabled because of an issue with Terser breaking valid code:
// https://github.com/facebook/create-react-app/issues/5250
// Pending further investigation:
// https://github.com/terser-js/terser/issues/120
inline: 2,
},
mangle: {
safari10: true,
},
// output: {
// ecma: 5,
// comments: false,
// // Turned on because emoji and regex is not minified properly using default
// // https://github.com/facebook/create-react-app/issues/2488
// ascii_only: true,
// },
}),

// would be nice, but not workable at the moment, no idea why
new rspack.LightningCssMinimizerRspackPlugin({
minimizerOptions: {
targets: [
"last 2 Chrome versions",
"Firefox ESR",
"last 2 Safari versions",
],
},
}),
],
splitChunks: {
chunks: "all",
},
// Extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated.
runtimeChunk: {
name: "manifest",
},
},
module: {
rules: [
{
test: require.resolve("jquery"),
use: [
{
loader: "expose-loader",
options: {
exposes: ["$", "jQuery"],
},
},
],
},
{
test: /\.(js|jsx)$/,
exclude: [/node_modules/, /@babel(?:\/|\\{1,2})runtime/],
loader: "builtin:swc-loader",
options: {
jsc: {
parser: {
syntax: "ecmascript",
jsx: true,
},
externalHelpers: true,
transform: {
react: {
development: !prod,
useBuiltins: true,
// runtime: 'automatic',
// throwIfNamespace: true,
},
},
},
env: {
targets: "Chrome >= 48",
},
},
},

{
test: /\.(scss|css)$/,
use: [
rspack.CssExtractRspackPlugin.loader,
"css-loader",
"sass-loader",
],
},
{
test: /\.(less)$/,
use: [
rspack.CssExtractRspackPlugin.loader,
"css-loader",
"less-loader",
],
},

// Rspack
// Inline images smaller than 10k
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
type: "asset/resource",
},
// no mimetype for ".cur" in mimetype database, specify it with `generator`
{
test: /\.(cur)(\?.*)?$/,
type: "asset/inline",
generator: {
dataUrl: {
encoding: "base64",
mimetype: "image/x-icon",
},
},
},
// Inline webfonts smaller than 10k
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
type: "asset/resource",
generator: {
filename: "fonts/[name].[contenthash:7].[ext]",
},
},
],
},
devtool:
process.env.NODE_ENV === "production" ? "source-map" : "inline-source-map",
plugins: [
// RSpack compat
// new ESLintPlugin({
// emitWarning: true,
// quiet: true,
// formatter: require("eslint-friendly-formatter"),
// eslintPath: require.resolve("eslint"),
// }),
// Pragmas
new rspack.DefinePlugin({
"process.env": process.env.NODE_ENV,
}),
new rspack.CssExtractRspackPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: "css/[name].[contenthash].css",
chunkFilename: "css/[name].[contenthash].css",
}),

// Copying relevant CSS files as TinyMCE tries to import css files from the dist/js folder of static files
new rspack.CopyRspackPlugin({
patterns: copyPatterns,
}),
// Automatically inject jquery
new rspack.ProvidePlugin({
jQuery: "jquery",
$: "jquery",
jquery: "jquery",
"window.jQuery": "jquery",
}),
// Write manifest file which Python will read.
new BundleTracker({
path: config.build.assetsPath,
filename: path.join(config.build.assetsPath, "manifest.json"),
publicPath: config.build.assetsURL,
}),
],
performance: { hints: false },
// snapshot: {
// managedPaths: [],
// },
watchOptions: {
followSymlinks: true,
},
experiments: {
css: false,
},
devServer: {
hot: true, // Enable Hot Module Replacement (HMR)
liveReload: true, // Enable live reload
},
};

if (process.env.npm_config_report) {
var BundleAnalyzerPlugin =
require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
webpackConfig.plugins.push(new BundleAnalyzerPlugin());
}

module.exports = webpackConfig;
36 changes: 11 additions & 25 deletions invenio_assets/assets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,68 +5,54 @@
"author": "CERN <[email protected]>",
"private": true,
"scripts": {
"start": "NODE_PRESERVE_SYMLINKS=1 NODE_ENV=development webpack --watch --progress --config ./build/webpack.config.js",
"build": "NODE_PRESERVE_SYMLINKS=1 NODE_ENV=production webpack --config ./build/webpack.config.js",
"postinstall": "patch-package"
},
"dependencies": {
"tinymce": "^6.7.2"
},
"devDependencies": {
"browserify-zlib": "^0.2.0",
"https-browserify": "^1.0.0",
"stream-browserify": "^3.0.0",
"stream-http": "^3.2.0",
"patch-package": "^6.5.0",
"@babel/core": "^7.18.0",
"ajv": "^8.12.0",
"@babel/eslint-parser": "^7.18.0",
"@babel/plugin-proposal-class-properties": "^7.18.0",
"@babel/plugin-proposal-private-property-in-object": "^7.21.0",
"@babel/plugin-transform-runtime": "^7.18.0",
"@babel/preset-env": "^7.18.0",
"@babel/preset-react": "^7.18.0",
"@babel/register": "^7.18.0",
"@babel/runtime": "^7.18.0",
"@inveniosoftware/eslint-config-invenio": "^2.0.0",
"@swc/core": "^1.6.13",
"@swc/helpers": "^0.5.11",
"ajv": "^8.12.0",
"autoprefixer": "^10.4.0",
"babel-loader": "^9.0.0",
"browserify-zlib": "^0.2.0",
"chalk": "^5.0.0",
"clean-webpack-plugin": "^4.0.0",
"css-loader": "^6.0.0",
"css-minimizer-webpack-plugin": "^4.2.0",
"eslint-config-react-app": "^7.0.1",
"eslint-friendly-formatter": "^4.0.1",
"eslint-webpack-plugin": "^2.5.0",
"eventsource-polyfill": "^0.9.0",
"expose-loader": "^4.0.0",
"file-loader": "^6.0.0",
"function-bind": "^1.1.0",
"https-browserify": "^1.0.0",
"less": "^4.0.0",
"less-loader": "^11.0.0",
"mini-css-extract-plugin": "^2.0.0",
"ora": "^6.0.0",
"patch-package": "^6.5.0",
"postcss-flexbugs-fixes": "^5.0.0",
"postcss-loader": "^7.0.0",
"postcss-preset-env": "^8.0.0",
"postcss-safe-parser": "^6.0.0",
"prettier": "^2.7.0",
"rimraf": "^4.0.0",
"sass": "^1.50.0",
"sass-loader": "^13.0.0",
"sass-loader": "^16.0.0",
"stream-browserify": "^3.0.0",
"stream-http": "^3.2.0",
"style-loader": "^3.0.0",
"terser-webpack-plugin": "^5.0.0",
"url-loader": "^4.1.0",
"webpack": "^5.0.0",
"webpack-bundle-analyzer": "^4.0.0",
"webpack-bundle-tracker": "^1.0.0",
"webpack-cli": "^5.0.0",
"webpack-dev-middleware": "^6.0.0",
"webpack-hot-middleware": "^2.24.0",
"webpack-livereload-plugin": "^3.0.0",
"webpack-merge": "^5.1.0",
"webpack-yam-plugin": "^1.0.0",
"copy-webpack-plugin": "^11.0.0"
"swc-loader": "^0.2.6",
"url-loader": "^4.1.0"
},
"engines": {
"node": ">=18",
Expand Down
Loading