Skip to content

Commit

Permalink
feat: Code Splitting (#3860)
Browse files Browse the repository at this point in the history
* feat: configure webpack to allow splitting chunks
* feat: `JsDirectoryCompiler` and expose js assets URL
* chore: support es2020 dynamic importing
* feat: control which URL to fetch chunks from
* feat: allow showing async modals & split 'LogInModal'
* feat: split `SignUpModal`
* feat: allow rendering async pages & split `UserSecurityPage`
* fix: module might not be listed in chunk
* feat: lazy load user pages
* feat: track the chunk containing each module
* chore: lightly warn
* chore: split `Composer`
* feat: add common frontend (for split common chunks)
* fix: jsDoc typing imports should be ignored
* feat: split `PostStream` `ForgotPasswordModal` and `EditUserModal`
* fix: multiple inline async imports not picked up
* chore: new `common` frontend assets only needs a jsdir compiler
* feat: add revision hash to chunk import URL
* fix: nothing to split for `admin` frontend yet
* chore: cleanup registry API
* chore: throw an error in debug mode if attempting to import a non-loaded module
* feat: defer `extend` & `override` until after module registration
* fix: plugin not picking up on all module sources
* fix: must override default chunk loader function from webpack plugin
* feat: split tags `TagDiscussionModal` and `TagSelectionModal`
* fix: wrong export name
* feat: import chunked modules from external packages
* feat: extensions compatibility
* feat: Router frontend extender async component
* chore: clean JS output path (removes stale chunks)
* fix: common chunks also need flushing
* chore: flush backend stale chunks
* Apply fixes from StyleCI
* feat: loading alert when async page component is loading
* chore: `yarn format`
* chore: typings
* chore: remove exception
* Apply fixes from StyleCI
* chore(infra): bundlewatch
* chore(infra): bundlewatch split chunks
* feat: split text editor
* chore: tag typings
* chore: bundlewatch
* fix: windows paths
* fix: wrong planned ext import format
  • Loading branch information
SychO9 authored Aug 2, 2023
1 parent 2ffbc44 commit 229a7af
Show file tree
Hide file tree
Showing 87 changed files with 1,217 additions and 304 deletions.
8 changes: 8 additions & 0 deletions .bundlewatch.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,17 @@
"path": "./framework/core/js/dist/*.js",
"maxSize": "150KB"
},
{
"path": "./framework/core/js/dist/*/**/*.js",
"maxSize": "30KB"
},
{
"path": "./extensions/*/js/dist/*.js",
"maxSize": "30KB"
},
{
"path": "./extensions/*/js/dist/*/**/*.js",
"maxSize": "30KB"
}
],
"defaultCompression": "gzip",
Expand Down
8 changes: 3 additions & 5 deletions extensions/embed/js/src/forum/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,14 @@ import { override, extend } from 'flarum/common/extend';
import app from 'flarum/forum/app';
import Stream from 'flarum/common/utils/Stream';
import ForumApplication from 'flarum/forum/ForumApplication';
import Composer from 'flarum/forum/components/Composer';
import PostStream from 'flarum/forum/components/PostStream';
import ModalManager from 'flarum/common/components/ModalManager';
import PostMeta from 'flarum/forum/components/PostMeta';

import DiscussionPage from 'flarum/forum/components/DiscussionPage';

extend(ForumApplication.prototype, 'mount', function () {
if (m.route.param('hideFirstPost')) {
extend(PostStream.prototype, 'view', (vdom) => {
extend('flarum/forum/components/PostStream', 'view', (vdom) => {
if (vdom.children[0].attrs['data-number'] === 1) {
vdom.children.splice(0, 1);
}
Expand Down Expand Up @@ -42,15 +40,15 @@ const reposition = function () {
};

extend(ModalManager.prototype, 'show', reposition);
extend(Composer.prototype, 'show', reposition);
extend('flarum/forum/components/Composer', 'show', reposition);

window.iFrameResizer = {
readyCallback: function () {
window.parentIFrame.getPageInfo(app.pageInfo);
},
};

extend(PostStream.prototype, 'goToNumber', function (promise, number) {
extend('flarum/forum/components/PostStream', 'goToNumber', function (promise, number) {
if (number === 'reply' && 'parentIFrame' in window && app.composer.isFullScreen()) {
const itemTop = this.$('.PostStream-item:last').offset().top;
window.parentIFrame.scrollToOffset(0, itemTop);
Expand Down
3 changes: 2 additions & 1 deletion extensions/emoji/extend.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
return [
(new Extend\Frontend('forum'))
->js(__DIR__.'/js/dist/forum.js')
->css(__DIR__.'/less/forum.less'),
->css(__DIR__.'/less/forum.less')
->jsDirectory(__DIR__.'/js/dist/forum'),

(new Extend\Formatter)
->configure(function (Configurator $config) {
Expand Down
17 changes: 10 additions & 7 deletions extensions/emoji/js/src/forum/addComposerAutocomplete.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import emojiMap from 'simple-emoji-map';

import { extend } from 'flarum/common/extend';
import TextEditor from 'flarum/common/components/TextEditor';
import TextEditorButton from 'flarum/common/components/TextEditorButton';
import KeyboardNavigatable from 'flarum/common/utils/KeyboardNavigatable';

Expand All @@ -10,11 +7,15 @@ import getEmojiIconCode from './helpers/getEmojiIconCode';
import cdn from './cdn';

export default function addComposerAutocomplete() {
const emojiKeys = Object.keys(emojiMap);
const $container = $('<div class="ComposerBody-emojiDropdownContainer"></div>');
const dropdown = new AutocompleteDropdown();
let emojiMap = null;

extend('flarum/common/components/TextEditor', 'oninit', function () {
this._loaders.push(async () => await import('./emojiMap').then((m) => (emojiMap = m.default)));
});

extend(TextEditor.prototype, 'oncreate', function () {
extend('flarum/common/components/TextEditor', 'onbuild', function () {
const $editor = this.$('.TextEditor-editor').wrap('<div class="ComposerBody-emojiWrapper"></div>');

this.navigator = new KeyboardNavigatable();
Expand All @@ -29,7 +30,9 @@ export default function addComposerAutocomplete() {
$editor.after($container);
});

extend(TextEditor.prototype, 'buildEditorParams', function (params) {
extend('flarum/common/components/TextEditor', 'buildEditorParams', function (params) {
const emojiKeys = Object.keys(emojiMap);

let relEmojiStart;
let absEmojiStart;
let typed;
Expand Down Expand Up @@ -166,7 +169,7 @@ export default function addComposerAutocomplete() {
});
});

extend(TextEditor.prototype, 'toolbarItems', function (items) {
extend('flarum/common/components/TextEditor', 'toolbarItems', function (items) {
items.add(
'emoji',
<TextEditorButton onclick={() => this.attrs.composer.editor.insertAtCursor(' :')} icon="far fa-smile">
Expand Down
3 changes: 3 additions & 0 deletions extensions/emoji/js/src/forum/emojiMap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import emojiMap from 'simple-emoji-map';

export default emojiMap;
3 changes: 1 addition & 2 deletions extensions/likes/js/src/forum/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { extend } from 'flarum/common/extend';
import app from 'flarum/forum/app';
import NotificationGrid from 'flarum/forum/components/NotificationGrid';

import addLikeAction from './addLikeAction';
import addLikesList from './addLikesList';
Expand All @@ -16,7 +15,7 @@ app.initializers.add('flarum-likes', () => {
addLikesList();
addLikesTabToUserProfile();

extend(NotificationGrid.prototype, 'notificationTypes', function (items) {
extend('flarum/forum/components/NotificationGrid', 'notificationTypes', function (items) {
items.add('postLiked', {
name: 'postLiked',
icon: 'far fa-thumbs-up',
Expand Down
3 changes: 1 addition & 2 deletions extensions/lock/js/src/forum/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { extend } from 'flarum/common/extend';
import app from 'flarum/forum/app';
import NotificationGrid from 'flarum/forum/components/NotificationGrid';

import DiscussionLockedNotification from './components/DiscussionLockedNotification';
import addLockBadge from './addLockBadge';
Expand All @@ -14,7 +13,7 @@ app.initializers.add('flarum-lock', () => {
addLockBadge();
addLockControl();

extend(NotificationGrid.prototype, 'notificationTypes', function (items) {
extend('flarum/forum/components/NotificationGrid', 'notificationTypes', function (items) {
items.add('discussionLocked', {
name: 'discussionLocked',
icon: 'fas fa-lock',
Expand Down
9 changes: 2 additions & 7 deletions extensions/markdown/js/src/common/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

import app from 'flarum/common/app';
import { extend, override } from 'flarum/common/extend';
import TextEditor from 'flarum/common/components/TextEditor';
import BasicEditorDriver from 'flarum/common/utils/BasicEditorDriver';
import styleSelectedText from 'flarum/common/utils/styleSelectedText';

Expand Down Expand Up @@ -89,13 +88,9 @@ export function initialize(app) {
items.add('italic', makeShortcut('italic', 'i', this));
});

if (TextEditor.prototype.markdownToolbarItems) {
override(TextEditor.prototype, 'markdownToolbarItems', markdownToolbarItems);
} else {
TextEditor.prototype.markdownToolbarItems = markdownToolbarItems;
}
override('flarum/common/components/TextEditor', 'markdownToolbarItems', markdownToolbarItems);

extend(TextEditor.prototype, 'toolbarItems', function (items) {
extend('flarum/common/components/TextEditor', 'toolbarItems', function (items) {
items.add(
'markdown',
<MarkdownToolbar for={this.textareaId} setShortcutHandler={(handler) => (shortcutHandler = handler)}>
Expand Down
15 changes: 15 additions & 0 deletions extensions/markdown/js/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
// Use Flarum's tsconfig as a starting point
"extends": "flarum-tsconfig",
// This will match all .ts, .tsx, .d.ts, .js, .jsx files in your `src` folder
// and also tells your Typescript server to read core's global typings for
// access to `dayjs` and `$` in the global namespace.
"include": ["src/**/*", "../../../framework/core/js/dist-typings/@types/**/*", "@types/**/*"],
"compilerOptions": {
// This will output typings to `dist-typings`
"declarationDir": "./dist-typings",
"paths": {
"flarum/*": ["../../../framework/core/js/dist-typings/*"]
}
}
}
7 changes: 3 additions & 4 deletions extensions/mentions/js/src/forum/addComposerAutocomplete.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import app from 'flarum/forum/app';
import { extend } from 'flarum/common/extend';
import TextEditor from 'flarum/common/components/TextEditor';
import TextEditorButton from 'flarum/common/components/TextEditorButton';
import KeyboardNavigatable from 'flarum/common/utils/KeyboardNavigatable';

Expand All @@ -11,7 +10,7 @@ export default function addComposerAutocomplete() {
const $container = $('<div class="ComposerBody-mentionsDropdownContainer"></div>');
const dropdown = new AutocompleteDropdown();

extend(TextEditor.prototype, 'oncreate', function () {
extend('flarum/common/components/TextEditor', 'onbuild', function () {
const $editor = this.$('.TextEditor-editor').wrap('<div class="ComposerBody-mentionsWrapper"></div>');

this.navigator = new KeyboardNavigatable();
Expand All @@ -26,7 +25,7 @@ export default function addComposerAutocomplete() {
$editor.after($container);
});

extend(TextEditor.prototype, 'buildEditorParams', function (params) {
extend('flarum/common/components/TextEditor', 'buildEditorParams', function (params) {
let relMentionStart;
let absMentionStart;
let matchTyped;
Expand Down Expand Up @@ -128,7 +127,7 @@ export default function addComposerAutocomplete() {
params.inputListeners.push(suggestionsInputListener);
});

extend(TextEditor.prototype, 'toolbarItems', function (items) {
extend('flarum/common/components/TextEditor', 'toolbarItems', function (items) {
items.add(
'mention',
<TextEditorButton onclick={() => this.attrs.composer.editor.insertAtCursor(' @')} icon="fas fa-at">
Expand Down
3 changes: 1 addition & 2 deletions extensions/mentions/js/src/forum/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { extend } from 'flarum/common/extend';
import app from 'flarum/forum/app';
import NotificationGrid from 'flarum/forum/components/NotificationGrid';
import { getPlainContent } from 'flarum/common/utils/string';
import textContrastClass from 'flarum/common/helpers/textContrastClass';
import Post from 'flarum/forum/components/Post';
Expand Down Expand Up @@ -46,7 +45,7 @@ app.initializers.add('flarum-mentions', function () {
app.notificationComponents.groupMentioned = GroupMentionedNotification;

// Add notification preferences.
extend(NotificationGrid.prototype, 'notificationTypes', function (items) {
extend('flarum/forum/components/NotificationGrid', 'notificationTypes', function (items) {
items.add('postMentioned', {
name: 'postMentioned',
icon: 'fas fa-reply',
Expand Down
7 changes: 4 additions & 3 deletions extensions/mentions/js/src/forum/mentionables/PostMention.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import usernameHelper from 'flarum/common/helpers/username';
import avatar from 'flarum/common/helpers/avatar';
import highlight from 'flarum/common/helpers/highlight';
import { truncate } from 'flarum/common/utils/string';
import ReplyComposer from 'flarum/forum/components/ReplyComposer';
import EditPostComposer from 'flarum/forum/components/EditPostComposer';
import getCleanDisplayName from '../utils/getCleanDisplayName';
import type AtMentionFormat from './formats/AtMentionFormat';

Expand All @@ -23,7 +21,10 @@ export default class PostMention extends MentionableModel<Post, AtMentionFormat>
* match any username characters that have been typed.
*/
initialResults(): Post[] {
if (!app.composer.bodyMatches(ReplyComposer) && !app.composer.bodyMatches(EditPostComposer)) {
const EditPostComposer = flarum.reg.checkModule('core', 'forum/components/EditPostComposer');
const ReplyComposer = flarum.reg.checkModule('core', 'forum/components/ReplyComposer');

if ((!ReplyComposer || !app.composer.bodyMatches(ReplyComposer)) && (!EditPostComposer || !app.composer.bodyMatches(EditPostComposer))) {
return [];
}

Expand Down
5 changes: 3 additions & 2 deletions extensions/mentions/js/src/forum/utils/reply.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import app from 'flarum/forum/app';
import DiscussionControls from 'flarum/forum/utils/DiscussionControls';
import EditPostComposer from 'flarum/forum/components/EditPostComposer';

export function insertMention(post, composer, quote) {
return new Promise((resolve) => {
Expand All @@ -27,7 +26,9 @@ export function insertMention(post, composer, quote) {
}

export default function reply(post, quote) {
if (app.composer.bodyMatches(EditPostComposer) && app.composer.body.attrs.post.discussion() === post.discussion()) {
const EditPostComposer = flarum.reg.checkModule('core', 'forum/components/EditPostComposer');

if (EditPostComposer && app.composer.bodyMatches(EditPostComposer) && app.composer.body.attrs.post.discussion() === post.discussion()) {
// If we're already editing a post in the discussion of post we're quoting,
// insert the mention directly.
return insertMention(post, app.composer, quote);
Expand Down
19 changes: 8 additions & 11 deletions extensions/nicknames/js/src/forum/index.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import app from 'flarum/forum/app';
import { extend } from 'flarum/common/extend';
import Button from 'flarum/common/components/Button';
import EditUserModal from 'flarum/common/components/EditUserModal';
import SignUpModal from 'flarum/forum/components/SignUpModal';
import SettingsPage from 'flarum/forum/components/SettingsPage';
import extractText from 'flarum/common/utils/extractText';
import Stream from 'flarum/common/utils/Stream';
import NickNameModal from './components/NicknameModal';

export { default as extend } from './extend';

app.initializers.add('flarum/nicknames', () => {
extend(SettingsPage.prototype, 'accountItems', function (items) {
extend('flarum/forum/components/SettingsPage', 'accountItems', function (items) {
if (app.forum.attribute('displayNameDriver') !== 'nickname') return;

if (this.user.canEditNickname()) {
Expand All @@ -24,11 +21,11 @@ app.initializers.add('flarum/nicknames', () => {
}
});

extend(EditUserModal.prototype, 'oninit', function () {
extend('flarum/common/components/EditUserModal', 'oninit', function () {
this.nickname = Stream(this.attrs.user.displayName());
});

extend(EditUserModal.prototype, 'fields', function (items) {
extend('flarum/common/components/EditUserModal', 'fields', function (items) {
if (app.forum.attribute('displayNameDriver') !== 'nickname') return;

if (!this.attrs.user.canEditNickname()) return;
Expand All @@ -47,7 +44,7 @@ app.initializers.add('flarum/nicknames', () => {
);
});

extend(EditUserModal.prototype, 'data', function (data) {
extend('flarum/common/components/EditUserModal', 'data', function (data) {
if (app.forum.attribute('displayNameDriver') !== 'nickname') return;

if (!this.attrs.user.canEditNickname()) return;
Expand All @@ -57,21 +54,21 @@ app.initializers.add('flarum/nicknames', () => {
}
});

extend(SignUpModal.prototype, 'oninit', function () {
extend('flarum/forum/components/SignUpModal', 'oninit', function () {
if (app.forum.attribute('displayNameDriver') !== 'nickname') return;

this.nickname = Stream(this.attrs.username || '');
});

extend(SignUpModal.prototype, 'onready', function () {
extend('flarum/forum/components/SignUpModal', 'onready', function () {
if (app.forum.attribute('displayNameDriver') !== 'nickname') return;

if (app.forum.attribute('setNicknameOnRegistration') && app.forum.attribute('randomizeUsernameOnRegistration')) {
this.$('[name=nickname]').select();
}
});

extend(SignUpModal.prototype, 'fields', function (items) {
extend('flarum/forum/components/SignUpModal', 'fields', function (items) {
if (app.forum.attribute('displayNameDriver') !== 'nickname') return;

if (app.forum.attribute('setNicknameOnRegistration')) {
Expand All @@ -97,7 +94,7 @@ app.initializers.add('flarum/nicknames', () => {
}
});

extend(SignUpModal.prototype, 'submitData', function (data) {
extend('flarum/forum/components/SignUpModal', 'submitData', function (data) {
if (app.forum.attribute('displayNameDriver') !== 'nickname') return;

if (app.forum.attribute('setNicknameOnRegistration')) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import app from 'flarum/forum/app';
import { extend } from 'flarum/common/extend';
import SettingsPage from 'flarum/forum/components/SettingsPage';
import type SettingsPage from 'flarum/forum/components/SettingsPage';
import Switch from 'flarum/common/components/Switch';

export default function () {
extend(SettingsPage.prototype, 'notificationsItems', function (this: SettingsPage, items) {
extend('flarum/forum/components/SettingsPage', 'notificationsItems', function (this: SettingsPage, items) {
items.add(
'followAfterReply',
<Switch
Expand Down
5 changes: 1 addition & 4 deletions extensions/subscriptions/js/src/forum/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import { extend } from 'flarum/common/extend';
import app from 'flarum/forum/app';
import Model from 'flarum/common/Model';
import Discussion from 'flarum/common/models/Discussion';
import NotificationGrid from 'flarum/forum/components/NotificationGrid';

import addSubscriptionBadge from './addSubscriptionBadge';
import addSubscriptionControls from './addSubscriptionControls';
Expand All @@ -21,7 +18,7 @@ app.initializers.add('subscriptions', function () {
addSubscriptionFilter();
addSubscriptionSettings();

extend(NotificationGrid.prototype, 'notificationTypes', function (items) {
extend('flarum/forum/components/NotificationGrid', 'notificationTypes', function (items) {
items.add('newPost', {
name: 'newPost',
icon: 'fas fa-star',
Expand Down
2 changes: 1 addition & 1 deletion extensions/subscriptions/js/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"declarationDir": "./dist-typings",
"baseUrl": ".",
"paths": {
"flarum/*": ["../vendor/flarum/core/js/dist-typings/*"]
"flarum/*": ["../../../framework/core/js/dist-typings/*"]
}
}
}
Loading

0 comments on commit 229a7af

Please sign in to comment.