umberto 10.7.1 → 10.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,13 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ ## [10.7.2](https://github.com/cksource/umberto/compare/v10.7.1...v10.7.2) (July 16, 2026)
5
+
6
+ ### Other changes
7
+
8
+ * Replaced webpack with Rolldown for building theme scripts. The theme bundles are now built as ES modules with code splitting and loaded via `<script type="module">`, keeping dynamically imported dependencies (such as the shiki grammars in the Gloria theme) in separate, lazily loaded chunks. The output targets ES2022 instead of the Babel-transpiled ES5, and `webpack`, `babel-loader`, `@babel/core`, and `@babel/preset-env` are no longer dependencies of the package.
9
+
10
+
4
11
  ## [10.7.1](https://github.com/cksource/umberto/compare/v10.7.0...v10.7.1) (July 15, 2026)
5
12
 
6
13
  ### Bug fixes
@@ -50,13 +57,6 @@ Changelog
50
57
 
51
58
  * Updated the GTM integration to use the new server-side setup in both Gloria and legacy Umberto themes.
52
59
 
53
-
54
- ## [10.5.1](https://github.com/cksource/umberto/compare/v10.5.0...v10.5.1) (May 14, 2026)
55
-
56
- ### Bug fixes
57
-
58
- * Changed the call for feedback title from `<h3>` to `<div>` to prevent it from appearing in the table of contents.
59
-
60
60
  ---
61
61
 
62
62
  To see all releases, visit the [release page](https://github.com/cksource/umberto/releases).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "umberto",
3
- "version": "10.7.1",
3
+ "version": "10.7.2",
4
4
  "description": "CKSource Documentation builder",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -15,11 +15,8 @@
15
15
  "CHANGELOG.md"
16
16
  ],
17
17
  "dependencies": {
18
- "@babel/core": "^7.29.7",
19
- "@babel/preset-env": "^7.29.7",
20
18
  "@minify-html/node": "^0.17.1",
21
19
  "@vscode/markdown-it-katex": "^1.1.2",
22
- "babel-loader": "^10.0.0",
23
20
  "chokidar": "^4.0.3",
24
21
  "css-select": "^6.0.0",
25
22
  "dom-serializer": "^2.0.0",
@@ -55,6 +52,7 @@
55
52
  "minimatch": "^10.0.1",
56
53
  "moment": "^2.29.4",
57
54
  "pug": "^3.0.2",
55
+ "rolldown": "^1.1.5",
58
56
  "sass": "^1.54.0",
59
57
  "shiki": "^3.4.0",
60
58
  "sitemap": "^8.0.0",
@@ -62,8 +60,7 @@
62
60
  "tinypool": "^2.0.0",
63
61
  "tippy.js": "^6.3.7",
64
62
  "tree-model": "^1.0.7",
65
- "upath": "^2.0.1",
66
- "webpack": "^5.94.0"
63
+ "upath": "^2.0.1"
67
64
  },
68
65
  "engines": {
69
66
  "node": ">=24.11.0"
@@ -76,6 +73,6 @@
76
73
  ]
77
74
  },
78
75
  "hexo": {
79
- "version": "8.1.1"
76
+ "version": "8.1.2"
80
77
  }
81
78
  }
package/src/index.js CHANGED
@@ -6,7 +6,7 @@
6
6
  import { styleText } from 'node:util';
7
7
  import upath from 'upath';
8
8
  import { compileSass } from './tasks/compile-sass.js';
9
- import { runWebpack } from './tasks/run-webpack.js';
9
+ import { prepareLayoutScripts } from './tasks/prepare-layout-scripts.js';
10
10
  import { copyAssets } from './tasks/copy-assets.js';
11
11
  import { getMainConfig } from './tasks/get-main-config.js';
12
12
  import { createSymLinks } from './tasks/create-sym-links.js';
@@ -102,12 +102,12 @@ async function buildThemes( outputDir, options ) {
102
102
  const layoutThemes = [ 'umberto', 'gloria' ];
103
103
 
104
104
  for ( const theme of layoutThemes ) {
105
- await runWebpack(
105
+ await prepareLayoutScripts(
106
106
  upath.join( sourceDir, theme, 'js/app.js' ),
107
107
  upath.join( outputAssetsPath, theme, 'scripts' ),
108
108
  {
109
+ theme,
109
110
  minify: !options.dev,
110
- umbertoDir: themesDir,
111
111
  version
112
112
  }
113
113
  );
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @license Copyright (c) 2017-2026, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md.
4
+ */
5
+
6
+ import upath from 'upath';
7
+ import { build } from 'rolldown';
8
+
9
+ export const prepareLayoutScripts = async ( sourceFile, destinationDirectory, {
10
+ theme,
11
+ minify = true,
12
+ outputFileName = 'app.js',
13
+ version,
14
+ basePath = '/docs'
15
+ } = {} ) => {
16
+ console.log( `Preparing layout scripts ("${ outputFileName }") for the "${ theme }" theme...` );
17
+
18
+ await build( {
19
+ input: upath.resolve( sourceFile ),
20
+ transform: {
21
+ target: 'es2022',
22
+ define: {
23
+ VERSION: JSON.stringify( version ),
24
+ BASE_PATH: JSON.stringify( basePath )
25
+ }
26
+ },
27
+ output: {
28
+ dir: upath.resolve( destinationDirectory ),
29
+ // The bundles are loaded via `<script type="module">`, so dynamically imported dependencies
30
+ // (e.g. the shiki grammars) are emitted as separate chunks loaded on demand instead of being
31
+ // inlined into the entry bundle.
32
+ format: 'es',
33
+ entryFileNames: outputFileName,
34
+ chunkFileNames: 'app.[hash].js',
35
+ minify,
36
+ sourcemap: !minify
37
+ }
38
+ } );
39
+ };
@@ -28,4 +28,4 @@ html(lang='en')
28
28
  .l-layout__main
29
29
  +not-found
30
30
 
31
- script(src=`/docs/assets/${umbertoVersion}/gloria/scripts/app.js`)
31
+ script(type='module', src=`/docs/assets/${umbertoVersion}/gloria/scripts/app.js`)
@@ -12,7 +12,7 @@ mixin head-preloads()
12
12
  { type: 'font', path: 'fonts/Mulish/Mulish-Italic-VariableFont_wght.woff2' },
13
13
 
14
14
  // Scripts
15
- { type: 'script', path: 'scripts/app.js' }
15
+ { type: 'module', path: 'scripts/app.js' }
16
16
  ];
17
17
 
18
18
  //- Preconnect to CDN
@@ -24,6 +24,8 @@ mixin head-preloads()
24
24
 
25
25
  if resource.type === 'font'
26
26
  link(rel='preload', href=url, as=resource.type, crossorigin='anonymous')
27
+ else if resource.type === 'module'
28
+ link(rel='modulepreload', href=url)
27
29
  else
28
30
  link(rel='preload', href=url, as=resource.type)
29
31
 
@@ -56,7 +56,16 @@ if kapa
56
56
  if sentry
57
57
  +load-sentry-script(sentry)
58
58
 
59
- script(src=relative_url(page.path, pathJoin( 'assets', umbertoVersion, 'gloria/scripts/app.js')))
59
+ //- `app.js` is a module script, so it executes only after the document is parsed. This bootstrap queue lets
60
+ //- classic scripts that run during parsing register `window.umberto.afterReady()` callbacks anyway. The full
61
+ //- public API (`src/gloria/js/public-api.js`) merges into this object once the module executes.
62
+ script.
63
+ window.umberto = {
64
+ afterReady( callback ) {
65
+ ( this._afterReadyCallbacks = this._afterReadyCallbacks || [] ).push( callback );
66
+ }
67
+ };
68
+ script(type='module', src=relative_url(page.path, pathJoin( 'assets', umbertoVersion, 'gloria/scripts/app.js')))
60
69
 
61
70
  if page.BASE_PATH
62
71
  //- When a project does not define its own assets, let's use the default ones (from a theme).
@@ -32,7 +32,7 @@ html( lang='en' )
32
32
  include _partial/footer
33
33
  include _partial/docsearch
34
34
 
35
- script( src = relative_url( page.path, pathJoin( 'assets', umbertoVersion, 'umberto/scripts/app.js' ) ) )
35
+ script( type = 'module', src = relative_url( page.path, pathJoin( 'assets', umbertoVersion, 'umberto/scripts/app.js' ) ) )
36
36
 
37
37
  if page.isSnippetPage
38
38
  //UMBERTO: SNIPPET: JS
@@ -19,8 +19,11 @@ import { injectStylesheet } from './helpers/inject-stylesheet.js';
19
19
  import { injectResourcePreload } from './helpers/inject-resource-preload.js';
20
20
  import { onDropdownSelection, selectDropdownItem } from './components/dropdown.js';
21
21
 
22
- window.umberto = {
23
- // The `VERSION` value will be replaced by the `DefinePlugin` webpack plugin.
22
+ // The `window.umberto` object may already exist: a bootstrap script in the page `<head>` creates it so that
23
+ // classic scripts executed while the document is still being parsed (before this module runs) can queue
24
+ // `afterReady()` callbacks. Merge into that object to preserve the queued callbacks.
25
+ window.umberto = Object.assign( window.umberto || {}, {
26
+ // The `VERSION` value will be replaced at build time.
24
27
  version: VERSION, // eslint-disable-line no-undef
25
28
 
26
29
  // Tooltips public API
@@ -72,4 +75,4 @@ window.umberto = {
72
75
 
73
76
  this._afterReadyCallbacks.push( callback );
74
77
  }
75
- };
78
+ } );
@@ -31,7 +31,7 @@ if ( localStorage.getItem( 'theme' ) === 'theme-dark' ) {
31
31
 
32
32
  // Set up the global variable.
33
33
  window.umberto = {
34
- // The `VERSION` value will be replaced by the `DefinePlugin` webpack plugin.
34
+ // The `VERSION` value will be replaced at build time.
35
35
  version: VERSION, // eslint-disable-line no-undef
36
36
  showWarningBanner,
37
37
  createTooltip
@@ -1,88 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2017-2026, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md.
4
- */
5
-
6
- import upath from 'upath';
7
- import { createRequire } from 'node:module';
8
- import webpack from 'webpack';
9
-
10
- const require = createRequire( import.meta.url );
11
-
12
- export const runWebpack = ( sourceFile, destinationFile, {
13
- minify = true,
14
- outputFileName = 'app.js',
15
- umbertoDir,
16
- version,
17
- basePath = '/docs'
18
- } = {} ) => {
19
- const webpackConfig = {
20
- context: umbertoDir,
21
-
22
- mode: minify ? 'production' : 'development',
23
-
24
- entry: upath.resolve( sourceFile ),
25
-
26
- output: {
27
- filename: outputFileName,
28
- path: upath.resolve( destinationFile )
29
- },
30
-
31
- target: 'web',
32
-
33
- optimization: {
34
- minimize: minify
35
- },
36
-
37
- // Increased the size of the allowed assets two times to hide the warning in the console.
38
- performance: {
39
- hints: false,
40
- maxEntrypointSize: 500000,
41
- maxAssetSize: 500000
42
- },
43
-
44
- plugins: [
45
- new webpack.DefinePlugin( {
46
- VERSION: `"${ version }"`,
47
- BASE_PATH: JSON.stringify( basePath )
48
- } )
49
- ],
50
-
51
- module: {
52
- rules: [
53
- {
54
- test: /\.js$/,
55
- use: {
56
- loader: 'babel-loader',
57
- options: {
58
- presets: [
59
- require.resolve( '@babel/preset-env' )
60
- ]
61
-
62
- }
63
- }
64
- }
65
- ]
66
- }
67
- };
68
-
69
- if ( !minify ) {
70
- webpackConfig.devtool = 'source-map';
71
- }
72
-
73
- return new Promise( ( resolve, reject ) => {
74
- console.log( `Running webpack for "${ outputFileName }"...` );
75
-
76
- webpack( webpackConfig, ( err, stats ) => {
77
- if ( err ) {
78
- reject( err );
79
- } else if ( stats.hasErrors() ) {
80
- reject( new Error( stats.toString() ) );
81
- } else {
82
- console.log( '[Webpack]', stats.toString( 'minimal' ) );
83
-
84
- resolve();
85
- }
86
- } );
87
- } );
88
- };