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

Research Webpacks DLL plugin #8398

Closed
3 of 4 tasks
jodator opened this issue Nov 2, 2020 · 7 comments
Closed
3 of 4 tasks

Research Webpacks DLL plugin #8398

jodator opened this issue Nov 2, 2020 · 7 comments
Assignees
Labels
domain:dx This issue reports a developer experience problem or possible improvement. domain:extending-builds type:task This issue reports a chore (non-production change) and other types of "todos".

Comments

@jodator
Copy link
Contributor

jodator commented Nov 2, 2020

Provide a description of the task

Research the feasibility of using Webpack's DLL plugin. in order to enable #8395.

Requirements to met:

  • Adding a plugin to a build (might be a new build type).
  • Using imports from base editor plugins (core, engine, utils <EmitterMixin>, ui).
  • Using imports from "common" plugins (widget, clipboard, ... ).
  • Potential to solve CSS double import issue #8400.
@jodator jodator added the type:task This issue reports a chore (non-production change) and other types of "todos". label Nov 2, 2020
@jodator jodator added this to the iteration 38 milestone Nov 2, 2020
@jodator jodator added domain:dx This issue reports a developer experience problem or possible improvement. squad:dx labels Nov 2, 2020
@jodator
Copy link
Contributor Author

jodator commented Nov 4, 2020

An comparison of a build size using webpack DLL: https://www.drupal.org/project/drupal/issues/2966864#comment-13056870.

 And that file was 8 kb, and the vendor (A slightly modified CKEditor classic build) was 536 kb.

@jodator jodator self-assigned this Nov 5, 2020
@jodator
Copy link
Contributor Author

jodator commented Nov 16, 2020

I've bootstrapped a configuration on 8398 branch. The next steps with it would be:

  • Add CKEditor 5 webpack configuration so the editor's features are built.
  • Expose a minimal set of exports to the sample.
    • I think that at least ClassicEditor and Plugin, Command, and maybe some utils form Widget.
  • Expand the dll-plugin sample:
    • Add a plugin that usues exported classes (might be some sample plugin from the docs). 
    • Create an editor instance with the above plugin.

Let's not focus on the CKEditor global for now - or expose global by the dll-plugin build.

This should validate that we can use DLL for this kind of features.

@jodator
Copy link
Contributor Author

jodator commented Nov 17, 2020

@pomek expanded the above demo by adding ClassicEditor, Plugin and other code to the POC. This looks very promising, as it already allows to:

  1. Use "normal" imports - ATM we've used @ckeditor/ckeditor5-dll package name in the plugin build.
  2. Export a subset of export in the DLL.
  3. Use exported classes and utility methods to create an app with a custom plugin.

We achieved so far:

<script src="../dll-build/build/ckeditor.dll.js"></script>
<script src="./build/app.js"></script>
  1. Reusable DLL file.
  2. A DLL-consumer application.

Current limitations:

  • The consumer of a DLL must be compiled with webpack using:
new webpack.DllReferencePlugin( {
    // The manifest file must be available at compile time.
	manifest: require( '../dll-build/build/ckeditor-manifest.json' ),
	// This can be anything, not related to the DLL itslef.
	scope: '@ckeditor/ckeditor5-dll'
} )
  • no CKEditor5 global, so (as the above point) ATM we did not implement the ad-hoc plugin writing.

To run the demo from 8398 branch:

  1. Go to the ./dll-build folder and run webpack.
  2. Go to the ./dll-plugin folder and run webpack.
  3. Run the http-server inside dll-plugin folder to run the index.html (run also if run directly in the browser).

@Reinmar
Copy link
Member

Reinmar commented Nov 23, 2020

OK, I checked the code and it looks indeed promising. 

Two things that we could check to verify it further:

  • Can the editor initialization code be moved to index.html and use globals? This is – dll-build would expose something to the global scope, dll-plugin something else. And then it would be used in index.html to initialize the editor. That'd be a more realistic scenario than what you tested. Did you plan to test it while researching the CKE5 global aspect?
  • The other scenario that worries me is: what if some module is not available in the base build but it's used by two plugins (that are built separately). There's one manifest and it's created while packaging the build. The other two plugins can either find their deps in that manifest or will include it in their own packages. This will duplicate this dependency. How to prevent that? We already talked that packages will have dependencies between each other that but the first thing will be – can we prevent duplication of that common dependency in each package?

@jodator
Copy link
Contributor Author

jodator commented Nov 23, 2020

  • The other scenario that worries me is: what if some module is not available in the base build but it's used by two plugins (that are built separately). There's one manifest and it's created while packaging the build. The other two plugins can either find their deps in that manifest or will include it in their own packages. This will duplicate this dependency. How to prevent that? We already talked that packages will have dependencies between each other that but the first thing will be – can we prevent duplication of that common dependency in each package?

I'd go with multi-DLL builds. In other words, each optional plugin must be built against the main DLL. We should check this as a next step.

I think that we could explore a setup:

  1. Core CKEditor5 DLL
    1. Exposes: core, engine, ui.
  2. Optional, re-usable plugin.
    1. The most common is Widget.
    2. Uses DLL(1)
    3. Exposes itself as DLL. 
  3. End plugin (CKEditor5)
    1. Let's say HTMLEmbed can be such plugin.
    2. Uses DLL(1) & DLL(2).
    3. Exposes itself as UMD plugin.
  4. User plugin
    1. The one I've used from the demo.
    2. Uses DLL(1), DLL(2)

The drawback I could see from this approach is that you'd have to include 4 files:

  1. The core DLL, ckeditor5-dll.js.
  2. The widget DLL: ckeditor5-widget-dll.js.
  3. Each external plugin: htmlembed.js.
  4. User plugin: user-plugin.js.
  • Can the editor initialization code be moved to `index.html` and use globals? This is – `dll-build` would expose something to the global scope, `dll-plugin` something else. And then it would be used in `index.html` to initialize the editor. That'd be a more realistic scenario than what you tested. Did you plan to test it while researching the CKE5 global aspect?

With this one, I've struggled a bit. At the moment the best I could do is using exposed DLL to require it (#8399 (comment)). However, it is not very nice:

window.CKEditor5DLL( './src/index.js' ).ClassicEditor.create()

However, I saw that we attach something to the window anyway, so it should be doable to have only window.ClassicEditor.

@jodator
Copy link
Contributor Author

jodator commented Nov 23, 2020

The very crud POC of the above is here:

<script>
// Sudo import.
const {
ClassicEditor, HtmlEmbedEditing, HtmlEmbedUI
} = window.CKEditor5DLL( './src/index.js' );
const config = Object.assign( {}, ClassicEditor.defaultConfig, {
extraPlugins: [
HtmlEmbedEditing,
HtmlEmbedUI,
ComplexBox // exposed by the app.js
],
htmlEmbed: {
showPreviews: false
}
} );
config.toolbar.items.push( 'htmlEmbed' );
ClassicEditor.create( document.querySelector( '#editor' ), config )
.then( editor => {
window.editor = editor;
} );
</script>

@jodator
Copy link
Contributor Author

jodator commented Nov 24, 2020

🎉 This one looks promising and will be carried on in #8517.

@jodator jodator closed this as completed Nov 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
domain:dx This issue reports a developer experience problem or possible improvement. domain:extending-builds type:task This issue reports a chore (non-production change) and other types of "todos".
Projects
None yet
Development

No branches or pull requests

3 participants