Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable Webpack ESM output and move assets to /assets/ without subdirectories #25940

Closed
wants to merge 28 commits into from
Closed
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
925a3f3
Enable Webpack ESM output and move to /static/ asset directory
silverwind Jul 17, 2023
564361e
fix WEBPACK_DEST
silverwind Jul 17, 2023
098a72c
fix WEBPACK_DEST_ENTRIES
silverwind Jul 17, 2023
e42d45a
move import
silverwind Jul 17, 2023
67a46fd
Update web_src/js/bootstrap.js
silverwind Jul 18, 2023
6c9bf21
Merge branch 'main' into static
silverwind Jul 18, 2023
f4b9927
devtest fixes
silverwind Jul 18, 2023
6ab4848
output assets directly to /assets/
silverwind Jul 20, 2023
167c0d0
remove WEBPACK_DEST_ENTRIES
silverwind Jul 20, 2023
1fa9115
add back webpack asset cleaning in clean-all
silverwind Jul 20, 2023
010607c
use eval for performance
silverwind Jul 20, 2023
9d6097a
load bootstrap in devtest as well
silverwind Jul 20, 2023
8aefb87
Merge branch 'main' into static
silverwind Jul 20, 2023
5ccb1d4
Merge branch 'main' into static
silverwind Jul 29, 2023
174342b
use Proxy
silverwind Jul 29, 2023
06c1bf3
Merge branch 'main' into static
silverwind Jul 29, 2023
4566d00
update comment
silverwind Jul 29, 2023
47fb741
fix typo
silverwind Jul 29, 2023
c9ef48a
return true from proxy handler
silverwind Jul 29, 2023
bd0bf1d
improve proxy
silverwind Jul 29, 2023
c3fde7e
remove duplicate imports, modal error unresolved
silverwind Jul 29, 2023
b6d4af7
remove separate devtest chunk
silverwind Jul 29, 2023
d58fd74
avoid flicker in devtest
silverwind Jul 29, 2023
449d640
fix lint
silverwind Jul 29, 2023
178538c
load webcomponents as non-module
silverwind Jul 29, 2023
ee3484d
add comment
silverwind Jul 29, 2023
0ede200
update comment
silverwind Jul 29, 2023
48ca34c
use separate chunk for devtest css
silverwind Jul 29, 2023
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
6 changes: 2 additions & 4 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,8 @@ cpu.out
/yarn.lock
/yarn-error.log
/npm-debug.log*
/public/assets/js
/public/assets/css
/public/assets/fonts
/public/assets/img/webpack
/public/assets/*
!/public/assets/img
/vendor
/web_src/fomantic/node_modules
/web_src/fomantic/build/*
Expand Down
6 changes: 2 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,8 @@ cpu.out
/yarn.lock
/yarn-error.log
/npm-debug.log*
/public/assets/js
/public/assets/css
/public/assets/fonts
/public/assets/img/webpack
/public/assets/*
!/public/assets/img
/vendor
/web_src/fomantic/node_modules
/web_src/fomantic/build/*
Expand Down
10 changes: 4 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,7 @@ FOMANTIC_WORK_DIR := web_src/fomantic

WEBPACK_SOURCES := $(shell find web_src/js web_src/css -type f)
WEBPACK_CONFIGS := webpack.config.js
WEBPACK_DEST := public/assets/js/index.js public/assets/css/index.css
WEBPACK_DEST_ENTRIES := public/assets/js public/assets/css public/assets/fonts public/assets/img/webpack
WEBPACK_DEST := public/assets/index.js public/assets/index.css

BINDATA_DEST := modules/public/bindata.go modules/options/bindata.go modules/templates/bindata.go
BINDATA_HASH := $(addsuffix .hash,$(BINDATA_DEST))
Expand Down Expand Up @@ -271,8 +270,9 @@ node-check:
fi

.PHONY: clean-all
clean-all: clean
rm -rf $(WEBPACK_DEST_ENTRIES) node_modules
clean-all:
$(eval WEBPACK_ASSETS := $(filter-out public/assets/img, $(wildcard public/assets/*)))
@rm -rf $(WEBPACK_ASSETS) node_modules

.PHONY: clean
clean:
Expand Down Expand Up @@ -433,7 +433,6 @@ watch:

.PHONY: watch-frontend
watch-frontend: node-check node_modules
@rm -rf $(WEBPACK_DEST_ENTRIES)
NODE_ENV=development npx webpack --watch --progress

.PHONY: watch-backend
Expand Down Expand Up @@ -950,7 +949,6 @@ webpack: $(WEBPACK_DEST)

$(WEBPACK_DEST): $(WEBPACK_SOURCES) $(WEBPACK_CONFIGS) package-lock.json
@$(MAKE) -s node-check node_modules
rm -rf $(WEBPACK_DEST_ENTRIES)
npx webpack
@touch $(WEBPACK_DEST)

Expand Down
12 changes: 0 additions & 12 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
"escape-goat": "4.0.0",
"fast-glob": "3.3.0",
"jquery": "3.7.0",
"jquery.are-you-sure": "1.9.0",
"katex": "0.16.8",
"license-checker-webpack-plugin": "0.2.1",
"lightningcss-loader": "2.1.0",
Expand Down
2 changes: 1 addition & 1 deletion templates/base/footer.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<script src='https://challenges.cloudflare.com/turnstile/v0/api.js'></script>
{{end}}
{{end}}
<script src="{{AssetUrlPrefix}}/js/index.js?v={{AssetVersion}}" onerror="alert('Failed to load asset files from ' + this.src + '. Please make sure the asset files can be accessed.')"></script>
<script type="module" src="{{AssetUrlPrefix}}/index.js?v={{AssetVersion}}" onerror="alert('Failed to load asset files from ' + this.src + '. Please make sure the asset files can be accessed.')"></script>
{{template "custom/footer" .}}
</body>
</html>
2 changes: 1 addition & 1 deletion templates/base/footer_content.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
{{end}}
</div>
</div>
<a href="{{AssetUrlPrefix}}/js/licenses.txt">{{.locale.Tr "licenses"}}</a>
<a href="{{AssetUrlPrefix}}/licenses.txt">{{.locale.Tr "licenses"}}</a>
{{if .EnableSwagger}}<a href="{{AppSubUrl}}/api/swagger">API</a>{{end}}
{{template "custom/extra_links_footer" .}}
</div>
Expand Down
7 changes: 5 additions & 2 deletions templates/base/head_script.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ If you are customizing Gitea, please do not change this file.
If you introduce mistakes in it, Gitea JavaScript code wouldn't run correctly.
*/}}
<script>
window.addEventListener('error', function(e) {window._globalHandlerErrors=window._globalHandlerErrors||[]; window._globalHandlerErrors.push(e);});
window._globalHandlerErrors = [];
window.addEventListener('error', function(e) {
window._globalHandlerErrors.push(e);
});
window.config = {
appUrl: '{{AppUrl}}',
appSubUrl: '{{AppSubUrl}}',
Expand Down Expand Up @@ -44,4 +47,4 @@ If you introduce mistakes in it, Gitea JavaScript code wouldn't run correctly.
{{/* in case some pages don't render the pageData, we make sure it is an object to prevent null access */}}
window.config.pageData = window.config.pageData || {};
</script>
<script src="{{AssetUrlPrefix}}/js/webcomponents.js?v={{AssetVersion}}"></script>
<script type="module" src="{{AssetUrlPrefix}}/webcomponents.js?v={{AssetVersion}}"></script>
silverwind marked this conversation as resolved.
Show resolved Hide resolved
6 changes: 3 additions & 3 deletions templates/base/head_style.tmpl
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<link rel="stylesheet" href="{{AssetUrlPrefix}}/css/index.css?v={{AssetVersion}}">
<link rel="stylesheet" href="{{AssetUrlPrefix}}/index.css?v={{AssetVersion}}">
{{if .IsSigned}}
{{if ne .SignedUser.Theme "gitea"}}
<link rel="stylesheet" href="{{AssetUrlPrefix}}/css/theme-{{.SignedUser.Theme | PathEscape}}.css?v={{AssetVersion}}">
<link rel="stylesheet" href="{{AssetUrlPrefix}}/theme-{{.SignedUser.Theme | PathEscape}}.css?v={{AssetVersion}}">
{{end}}
{{else if ne DefaultTheme "gitea"}}
<link rel="stylesheet" href="{{AssetUrlPrefix}}/css/theme-{{DefaultTheme | PathEscape}}.css?v={{AssetVersion}}">
<link rel="stylesheet" href="{{AssetUrlPrefix}}/theme-{{DefaultTheme | PathEscape}}.css?v={{AssetVersion}}">
{{end}}
13 changes: 2 additions & 11 deletions templates/devtest/fomantic-modal.tmpl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{{template "base/head" .}}
<link rel="stylesheet" href="{{AssetUrlPrefix}}/devtest.css?v={{AssetVersion}}">
<div class="page-content devtest ui container">
{{template "base/alert" .}}

Expand Down Expand Up @@ -47,16 +48,6 @@
</div>

<div class="modal-buttons"></div>
<script type="module">
for (const el of $('.ui.modal')) {
const $btn = $('<button>').text(`Show ${el.id}`).on('click', () => {
$(el).modal({onApprove() {alert('confirmed')}}).modal('show');
});
$('.modal-buttons').append($btn);
}
</script>
<style>
.modal-buttons button { margin: 5px; }
</style>
<script src="{{AssetUrlPrefix}}/devtest.js?v={{AssetVersion}}"></script>
silverwind marked this conversation as resolved.
Show resolved Hide resolved
</div>
{{template "base/footer" .}}
13 changes: 2 additions & 11 deletions templates/devtest/gitea-ui.tmpl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{{template "base/head" .}}
<link rel="stylesheet" href="{{AssetUrlPrefix}}/css/devtest.css?v={{AssetVersion}}">
<link rel="stylesheet" href="{{AssetUrlPrefix}}/devtest.css?v={{AssetVersion}}">
<div class="page-content devtest ui container">
<div>
<h1>Button</h1>
Expand Down Expand Up @@ -67,15 +67,6 @@
</div>
</li>
</ul>
<script type="module">
const $buttons = $('#devtest-button-samples').find('button.ui');

const $buttonStyles = $('input[name*="button-style"]');
$buttonStyles.on('click', () => $buttonStyles.map((_ ,el) => $buttons.toggleClass(el.value, el.checked)));

const $buttonStates = $('input[name*="button-state"]');
$buttonStates.on('click', () => $buttonStates.map((_ ,el) => $buttons.prop(el.value, el.checked)));
</script>
</div>
</div>

Expand Down Expand Up @@ -252,6 +243,6 @@
<div>ps: no JS code attached, so just a layout</div>
{{template "shared/combomarkdowneditor" .}}
</div>
<script src="{{AssetUrlPrefix}}/js/devtest.js?v={{AssetVersion}}"></script>
<script src="{{AssetUrlPrefix}}/devtest.js?v={{AssetVersion}}"></script>
</div>
{{template "base/footer" .}}
4 changes: 2 additions & 2 deletions templates/swagger/ui.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
<html lang="en">
<head>
<title>Gitea API</title>
<link href="{{AssetUrlPrefix}}/css/swagger.css?v={{AssetVersion}}" rel="stylesheet">
<link href="{{AssetUrlPrefix}}/swagger.css?v={{AssetVersion}}" rel="stylesheet">
</head>
<body>
<a class="swagger-back-link" href="{{AppSubUrl}}/">{{svg "octicon-reply"}}{{.locale.Tr "return_to_gitea"}}</a>
<div id="swagger-ui" data-source="{{AppSubUrl}}/swagger.{{.APIJSONVersion}}.json"></div>
<script src="{{AssetUrlPrefix}}/js/swagger.js?v={{AssetVersion}}"></script>
<script type="module" src="{{AssetUrlPrefix}}/swagger.js?v={{AssetVersion}}"></script>
</body>
</html>
3 changes: 3 additions & 0 deletions web_src/css/index.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
@import "../fomantic/build/semantic.css";
@import "easymde/dist/easymde.min.css";
silverwind marked this conversation as resolved.
Show resolved Hide resolved

@import "./modules/normalize.css";
@import "./modules/animations.css";
@import "./modules/button.css";
Expand Down
4 changes: 4 additions & 0 deletions web_src/css/standalone/devtest.css
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@ h1, h2 {
margin: 0;
padding: 10px 0;
}

.modal-buttons button {
margin: 5px;
}
32 changes: 16 additions & 16 deletions web_src/js/bootstrap.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import {joinPaths} from './utils.js';

// DO NOT IMPORT window.config HERE!
// to make sure the error handler always works, we should never import `window.config`, because some user's custom template breaks it.

// This sets up the URL prefix used in webpack's chunk loading.
// This file must be imported before any lazy-loading is being attempted.
__webpack_public_path__ = joinPaths(window?.config?.assetUrlPrefix ?? '/', '/');
__webpack_public_path__ = `${window.config?.assetUrlPrefix ?? '/assets'}/`;

export function showGlobalErrorMessage(msg) {
const pageContent = document.querySelector('.page-content');
Expand All @@ -29,18 +27,20 @@ function processWindowErrorEvent(e) {
showGlobalErrorMessage(`JavaScript error: ${e.message} (${e.filename} @ ${e.lineno}:${e.colno}). Open browser console to see more details.`);
}

function initGlobalErrorHandler() {
if (!window.config) {
showGlobalErrorMessage(`Gitea JavaScript code couldn't run correctly, please check your custom templates`);
}
// we added an event handler for window error at the very beginning of <script> of page head
// the handler calls `_globalHandlerErrors.push` (array method) to record all errors occur before this init
// then in this init, we can collect all error events and show them
for (const e of window._globalHandlerErrors || []) {
processWindowErrorEvent(e);
}
// then, change _globalHandlerErrors to an object with push method, to process further error events directly
window._globalHandlerErrors = {'push': (e) => processWindowErrorEvent(e)};
if (!window.config) {
showGlobalErrorMessage(`Gitea JavaScript code couldn't run correctly, please check your custom templates`);
}

initGlobalErrorHandler();
// we added an event handler for window error at the very beginning of <script> of page head
// the handler calls `_globalHandlerErrors.push` (array method) to record all errors occur,
// now we display any errors that had occured
for (const e of window._globalHandlerErrors) {
processWindowErrorEvent(e);
}

// watch for further mutations on the array
window._globalHandlerErrors = new Proxy(window._globalHandlerErrors, {
set: (_target, _property, value) => {
processWindowErrorEvent(value);
}
});
2 changes: 1 addition & 1 deletion web_src/js/features/common-global.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import $ from 'jquery';
import 'jquery.are-you-sure';
import '../vendor/ays.js';
import {createDropzone} from './dropzone.js';
import {initCompColorPicker} from './comp/ColorPicker.js';
import {showGlobalErrorMessage} from '../bootstrap.js';
Expand Down
2 changes: 1 addition & 1 deletion web_src/js/features/notification.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export function initNotificationCount() {

if (notificationSettings.EventSourceUpdateTime > 0 && window.EventSource && window.SharedWorker) {
// Try to connect to the event source via the shared worker first
const worker = new SharedWorker(`${__webpack_public_path__}js/eventsource.sharedworker.js?v=${assetVersionEncoded}`, 'notification-worker');
const worker = new SharedWorker(`${__webpack_public_path__}eventsource.sharedworker.js?v=${assetVersionEncoded}`, 'notification-worker');
worker.addEventListener('error', (event) => {
console.error('worker error', event);
});
Expand Down
2 changes: 1 addition & 1 deletion web_src/js/features/stopwatch.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export function initStopwatch() {
// if the browser supports EventSource and SharedWorker, use it instead of the periodic poller
if (notificationSettings.EventSourceUpdateTime > 0 && window.EventSource && window.SharedWorker) {
// Try to connect to the event source via the shared worker first
const worker = new SharedWorker(`${__webpack_public_path__}js/eventsource.sharedworker.js?v=${assetVersionEncoded}`, 'notification-worker');
const worker = new SharedWorker(`${__webpack_public_path__}eventsource.sharedworker.js?v=${assetVersionEncoded}`, 'notification-worker');
worker.addEventListener('error', (event) => {
console.error('worker error', event);
});
Expand Down
2 changes: 2 additions & 0 deletions web_src/js/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// bootstrap module must be the first one to be imported, it handles webpack lazy-loading and global errors
import './bootstrap.js';
import './jquery.js';
import '../fomantic/build/semantic.js';

import {initRepoActivityTopAuthorsChart} from './components/RepoActivityTopAuthors.vue';
import {initScopedAccessTokenCategories} from './components/ScopedAccessTokenSelector.vue';
Expand Down
25 changes: 22 additions & 3 deletions web_src/js/standalone/devtest.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,30 @@
import '../bootstrap.js';
import '../jquery.js';
import '../../fomantic/build/semantic.js';
import $ from 'jquery';
silverwind marked this conversation as resolved.
Show resolved Hide resolved
import {showInfoToast, showWarningToast, showErrorToast} from '../modules/toast.js';

document.getElementById('info-toast').addEventListener('click', () => {
document.getElementById('info-toast')?.addEventListener('click', () => {
showInfoToast('success 😀');
});
document.getElementById('warning-toast').addEventListener('click', () => {
document.getElementById('warning-toast')?.addEventListener('click', () => {
showWarningToast('warning 😐');
});
document.getElementById('error-toast').addEventListener('click', () => {
document.getElementById('error-toast')?.addEventListener('click', () => {
showErrorToast('error 🙁');
});

const $buttons = $('#devtest-button-samples').find('button.ui');

const $buttonStyles = $('input[name*="button-style"]');
$buttonStyles.on('click', () => $buttonStyles.map((_, el) => $buttons.toggleClass(el.value, el.checked)));

const $buttonStates = $('input[name*="button-state"]');
$buttonStates.on('click', () => $buttonStates.map((_, el) => $buttons.prop(el.value, el.checked)));

for (const el of $('.ui.modal')) {
const $btn = $('<button>').text(`Show ${el.id}`).on('click', () => {
$(el).modal({onApprove() {alert('confirmed')}}).modal('show');
});
$('.modal-buttons').append($btn);
}
10 changes: 0 additions & 10 deletions web_src/js/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,6 @@ export function extname(path = '') {
return ext || '';
}

// join a list of path segments with slashes, ensuring no double slashes
export function joinPaths(...parts) {
let str = '';
for (const part of parts) {
if (!part) continue;
str = !str ? part : `${str.replace(/\/$/, '')}/${part.replace(/^\//, '')}`;
}
return str;
}

// test whether a variable is an object
export function isObject(obj) {
return Object.prototype.toString.call(obj) === '[object Object]';
Expand Down
Loading
Loading