ckeditor5 icon indicating copy to clipboard operation
ckeditor5 copied to clipboard

Migrate CKEditor 5 to TypeScript

Open Reinmar opened this issue 2 years ago • 9 comments

Back in 2015 when we were bootstrapping CKEditor 5 TypeScript wasn't yet mature enough and didn't yet seem as a safe choice taken the long horizon of CKEditor 5's life and fate of e.g. CoffeeScript or Backbone (that were the popular choices at that time).

Nowadays, for a large scale, complex project such as CKEditor 5, TypeScript is a clear choice. We've been actually looking at it for a longer time but it was clear that we need to pick the right moment for a migration. The moment has come 🥳

The main goals of the migration:

  • Improving the DX for the community by providing typings for CKEditor 5. This is by far the most popular request on our issue tracker and it's visible how important it is to the community also by the amount of work put by many people, including heroes such as @fedemp. Providing official typings will benefit integrators and plugin developers. It will improve the DX when working with CKEditor 5 and stability of the solutions.
  • Improving the core team experience and toolset. While using TypeScript will naturally make us happy (we really wanted to migrate for a long time :smile:), we believe that this will have a positive outcome for everyone. CKEditor 5 is a complex project with a large API. We're rigorously documenting the types from day one, but we had to resort to JSDoc for that. It helps during development, but it's nowhere near what we'll have with TypeScript. Type validation, better API documentation, better suggestions, refactoring options – this will all speed up the development and potentially improve the quality even more.

We're right now cooking a plan of action, so I won't share more details for now. Some two last points that I want to mention for now are:

  • We're determined to not break the backward compatibility (except minor aspects). We are aiming at making the migration for a great majority of JS-based projects that used CKEditor 5 for now seamless.
  • This project will take several months due to the scale of CKEditor 5. We'll be migrating step by step, most likely starting from the infrastructure and one or two first packages.
  • We'll use this ticket for further developer as #504 was already too long and does not exactly cover the entire scope of the project for us. We'll start sharing our ideas and questions on what should we deliver here in this thread and potentially in #504 for better visibility too. But this one is the one.
  • Once again I'd like to thank @fedemp and everyone else who contributed to the community-driven DefinitelyTyped. For at least a couple of months it's still the place to go when you need typings for CKEditor 5.

Keep your fingers crossed and stay tuned for more information.

Reinmar avatar May 04 '22 22:05 Reinmar

  • Once again I'd like to thank @fedemp and everyone else who contributed to the community-driven DefinitelyTyped. For at least a couple of months it's still the place to go when you need typings for CKEditor 5.

I don't know if it's possible for us to stay compatible with that, though. Should we?

arkflpc avatar May 05 '22 13:05 arkflpc

  • Once again I'd like to thank @fedemp and everyone else who contributed to the community-driven DefinitelyTyped. For at least a couple of months it's still the place to go when you need typings for CKEditor 5.

I don't know if it's possible for us to stay compatible with that, though. Should we?

Official typings do not need to be compatible with DT typings. And if official typings somehow contradict those at DT, the official should be the definitive answer (assuming CKEditor is going to be rewritten in TS).

fedemp avatar May 05 '22 17:05 fedemp

This project will take several months due to the scale of CKEditor 5. We'll be migrating step by step, most likely starting from the infrastructure and one or two first packages.

You team surely know better, but I suggest you start with utils, core, and lastly engine. utils have very little dependencies, and engine is a huge monster to tackle.

fedemp avatar May 05 '22 17:05 fedemp

Hi @fedemp! I tried to reach out to you on LinkedIn. Could you check your invitations or write back to me at [email protected]?

Reinmar avatar May 05 '22 20:05 Reinmar

Some ideas for post-MVP:

  • Better integration with Angular and React
  • Update guides

arkflpc avatar Jun 08 '22 07:06 arkflpc

Status Update:

What we've done:

  1. We rewrote the ckeditor5-utils package to TypeScript (#11755).
  2. We're now able to run both manual and automated tests (#11888).
  3. We have working rules for eslint (#11719).
  4. We can build DLLs (almost done, #11718).

It's all on a feature branch yet. But as soon as we'll finish updating the release process (#11720, work-in-progress), we can get to master branch and release it. The packages on NPM won't contain typings yet, because that would conflict with the community-provided ones. We're going to start generating them after we'll finish the work on ckeditor5-engine (#11724, work-in-progress), ckeditor5-ui (#11726) and ckeditor5-core (#11727) and stabilize the typings.

arkflpc avatar Jul 05 '22 07:07 arkflpc

The packages on NPM won't contain typings yet, because that would conflict with the community-provided ones.

When the time comes, open an issue on DefinitelyTyped to remove those. :+1:

fedemp avatar Jul 07 '22 16:07 fedemp

We will, @fedemp. We're going to stabilize them first.

arkflpc avatar Jul 08 '22 16:07 arkflpc

It's worth mentioning that CKEditor 5 v35.0.0 is out and it's the first version where TS code was used (namely @ckeditor/ckeditor5-utils) 👏

As for what's next...

We're right now reviewing https://github.com/ckeditor/ckeditor5/pull/12188 and engine was by far the biggest and most complex package to port.

Next packages to migrate: core and utils. Soon, we'll be able to start porting features which should be easy to do concurrently and much much faster.

Reinmar avatar Aug 03 '22 14:08 Reinmar

Status update

We released ckeditor5-engine (#11724) in TypeScript. ckeditor5-ui (#11726) and ckeditor5-core (#11727) are done on feature branch (ck/11726-11727-ts-core-ui). They will be merged in few next weeks.

The next milestone is to select API documentation generator and integrate it with our tooling. After it's done, we will go on with other packages that are in JavaScript yet.

arkflpc avatar Sep 05 '22 12:09 arkflpc

Some status update.

We're doing good progress migrating packages. We covered more than 50% of them, including all the core ones (that are by far the biggest ones). So in general, it feels like we're 75% done.

Once all packages are migrated, we'll start publishing the types to npm. So far, those are omitted as they would be incomplete.

Keep your fingers crossed, TS is coming :runner:

Reinmar avatar Dec 30 '22 09:12 Reinmar

Some stats about progress:

Language files blank comment code
TypeScript 600 17589 62313 54875
JavaScript 199 4898 14206 16609
-------- -------- -------- -------- --------
SUM: 799 22487 76519 71484

arkflpc avatar Feb 02 '23 09:02 arkflpc

I'm working on a new application and am in the process of deciding what editor I'd like to base the application on. It's not liklely to be going live for at least 6 months (loads to do, maybe longer depending on what's else I need to implement) My preferred choice, especially as it's a very active project is to use CKEditor, but as you can guess, I'm working in Typescript with React. Is there some way a work around that I can use (noobie instructions would be appreciated) that will allow me to use CKEditor5 in my application whilst waiting for this major refactor?

I feel that the alternative I'm looking at would be shooting myself in the foot in the long run.

colindawson avatar Feb 02 '23 09:02 colindawson

@colindawson,

CKEditor is usable in TypeScript projects today. There are excellent community provided types you can rely on.

The refactor you mentioned is only about adding types to the code.

When we are ready to provide our types in npm packages, they will not be compatible. But this should affect mostly custom plugins that are interacting with core components of the editor. The types for API used for embedding and configuring CKEditor will not be modified much. Even in this case, only types will have to be adjusted.

arkflpc avatar Feb 02 '23 10:02 arkflpc

@arkflpc I'm extremely confused about this, it's all new to me. Looking at the link you posted, it's gave me an idea to look for @types/ckeditor and I found this https://www.npmjs.com/package/@types/ckeditor__ckeditor5-core Is this the kind on thing that you are referring too?

I've figured out enough to make it work, there's nothing in the link you provided, what I needed to do is create a file called types/ckeditor.d.ts with the following content

declare module '@ckeditor/ckeditor5-build-classic' {
    import ClassicEditor from '@ckeditor/ckeditor5-build-classic';

    const ClassicEditor = typeof ClassicEditor;

    export {ClassicEditor};
}

declare module '@ckeditor/ckeditor5-react' {
    import ClassicEditor from '@ckeditor/ckeditor5-build-classic';
    import Event from '@ckeditor/ckeditor5-utils/src/eventinfo'
    //import { EditorConfig } from '@ckeditor/ckeditor5-core/src/editor/editorconfig'
    import * as React from 'react';
    const CKEditor: React.FunctionComponent<{
        disabled?: boolean;
        editor: typeof ClassicEditor;
        data?: string;
        id?: string;
        config?: EditorConfig;
        onReady?: (editor: ClassicEditor) => void;
        onChange?: (event: Event, editor: ClassicEditor) => void;
        onBlur?: (event: Event, editor: ClassicEditor) => void;
        onFocus?: (event: Event, editor: ClassicEditor) => void;
        onError?: (event: Event, editor: ClassicEditor) => void;
    }>
    export { CKEditor };
    }

This was enough to get my react app from failing to compile and show the editor. I'm sure this is a huge hack. And I'm looking forward to being able to scrap this when typescript support is ready. I much prefer this to using a different control. I've posted this here, so that any other newbies to typescript and CKEditor5 can be helped whilst waiting for the Typescript rewrite to be completed.

colindawson avatar Feb 02 '23 11:02 colindawson

@colindawson, we just finished more than a year of development to replace CKEditor 4 with CKEditor 5 (find the sources at https://github.com/CoreMedia/ckeditor-plugins). And yes, the package you spotted is one of them. Another (for the classic editor) is: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/ckeditor__ckeditor5-editor-classic.

We started off with custom typings, which is a very error-prone and lengthy process, as if you pull one thread, you will get all the rest (so, hats off to CKEditor-team addressing this eventually!).

When your build is set up and ready, there is actually nothing more to do, than:

  • Add your CKEditor 5 dependency.
  • Add a dependency to the corresponding types.

A minimal package with CKEditor 5 dependency and some tooling around ckeditor5-core can be found here, which may be one reference: https://github.com/CoreMedia/ckeditor-plugins/tree/main/packages/ckeditor5-core-common

If you experience any issues with the typings, we recommend adding:

// @ts-expect-error - Typing issue at DefinitelyTyped

or similar. This is because the typings are not always in line with the CKEditor 5 sources and/or documentation. But overall, they are quite complete and a very good start. (@ts-expect-error is better than @ts-ignore as it will inform you, once the typings got updated accordingly and may help to migrate to official typings by CKEditor later)

And just regarding your remark:

My preferred choice, especially as it's a very active project is to use CKEditor

Stick to it! In our experience, it has a very well-designed architecture and I think we really stretched it to its limits.

mmichaelis avatar Feb 02 '23 17:02 mmichaelis

Really bummed out by current situation that old types dont seem to work with TS 4.9+, while the new types are not published yet (even partially). We're stuck with both older version of TS and older version of editor. Even incomplete types are better than nothing

Inviz avatar Feb 03 '23 07:02 Inviz

Really bummed out by current situation that old types dont seem to work with TS 4.9+, while the new types are not published yet (even partially). We're stuck with both older version of TS and older version of editor. Even incomplete types are better than nothing

WIth 199 files to do, don't hold you breath that it's going to get done faster. As a new user to CKEditor, I was bummed out that combined with my limited knowledge of typescript, it didn't work out of the box. As you can see above, asking a couple of questions and doing a little digging, I've managed to get CKEditor 5 working on my Typescript React app. Having watched the project for a couple of days. I'm really excited to be using this component, and would much prefer that the implementation is done right I'll deal with the technical debt of using my hack when the time comes, but right now. I believe that the team working on this are doing a great job and I know that with a bit of patience it will be resolved "soon"(tm)

colindawson avatar Feb 03 '23 09:02 colindawson

Which version of typescript do you use? I'm using the CKEditor5 with the types for about 8 months by now. The types module really really helped to get my project off the ground (we dont even use ckeditor5's own ui, it's a total overhaul), but the types package is outdated and as i mentioned does not work for 4.9/5 for us because of default exports thing, that i could not personally resolve. If you use 4.9, let me know what settings do you use and what are the import calls you do for importing individual files. I can not update TS on our project because of this.

I understand that partial types are not released currently, because it would conflict with the old types package? So it's a curse and a blessing to have the old types.

Inviz avatar Feb 03 '23 11:02 Inviz

I could also not get @types/ckeditor__ckeditor5-core to work, had to resort to creating a file very similar to the one shared by @colindawson.

Sadly, no simple works-out-of-the-box solution here :(

jacquesg avatar Feb 06 '23 18:02 jacquesg

Just to be clear, whilst what I did worked. I need to use more advanced things from CKEditor, so for now, I've decided to change my editor over to using jsx files, instead of tsx. This way, I'm avoiding typescript for the moment, with the intent to come back and refactor once the typescript version is released.

colindawson avatar Feb 08 '23 11:02 colindawson

We're about to finish the code migration. We should be done with both the open source and commercial code by the end of February.

The code release to npm is blocked, though, by the rest of our tooling (e.g. release scripts) that need to catch up. It's now planned for the beginning of April.

But, perhaps we could share all the typings even now without breaking anything? Like, publishing them in a temporary npm package like @ckeditor/ckeditor5-experimental-typings. Could those be used easily then? Having them out a month before an official release would help validating some bits of them.

Reinmar avatar Feb 14 '23 08:02 Reinmar

That would be really grand if we could have typings earlier than that. I'd really appreciate it

Inviz avatar Feb 14 '23 08:02 Inviz

Hello, what is the status of CKEditor 5 typings? Is the final release out yet? Thank you

balean12 avatar Feb 27 '23 12:02 balean12

We've just (like an hour ago :D) published 37.0.0-alpha.0 of all open source packages of CKEditor 5. 

All these packages in this specific version contains typings for the entire code available in them :tada:

That's an early alpha version and naturally some things may still change. For instance, we're dealing now with TypeScript issues with generating .d.ts files for module augmentation. Unfortunately, publishing types for such a large ecosystem with so many weird requirements is not a trivial task.

Note: We did not publish 37.0.0-alpha.0 for the commercial packages. Nor plan to publish typings for them before publishing a stable 37.0.0 version (planned for April).

Reinmar avatar Feb 27 '23 13:02 Reinmar

I'll be damned, it's actually working. Amazing job! I'm finding some inconsistencies, but they are minor.

  1. Breaking: selectable in model writer is set to Node type, but according to docs it's https://ckeditor.com/docs/ckeditor5/latest/api/module_engine_model_selection-Selectable.html this. So it doesnt accept position at this time.
  2. Breaking: Plugin doesnt have .set method (for observable props)... it used to work
  3. EventInfo signature seems to have been simplified from EventInfo<doc, string> to EventInfo<string>
  4. I could not make assignment to Editor.builtinPlugins to work:

Type 'typeof import("/Users/sitecore/Sites/feaas-components/ckeditor5/node_modules/@ckeditor/ckeditor5-link/src/autolink")' is not assignable to type 'PluginConstructor<Editor>' 5) I dont use config often, but i'm getting error on assigning heading. I think this is what Reinmar meant talking about module augmentation?

Inviz avatar Feb 28 '23 10:02 Inviz

@Reinmar thank you CKEditor team!

Inviz avatar Feb 28 '23 10:02 Inviz

@Reinmar can we update import paths, so the types will include .js in paths? It is backward compatible, but this way it'll be compatible with other module resolution strategies (e.g. nodenext). At the moment i'm still stuck at 4.8 because of it. Tried everything i could.

Inviz avatar Mar 01 '23 17:03 Inviz

@Inviz We will look into the issues you listed in your first message and get back to you soon either with an update or an explanation.

Can you elaborate on your request to include .js in paths? Why is this necessary, and what problems are you experiencing with the current approach?

filipsobol avatar Mar 02 '23 08:03 filipsobol

@filipsobol Thanks Filip!

The issue is that node16+ module setting requries .js extensions, otherwise it can't find files. The symptom is that types can't be found for the package. It says "type X is not exported by ckeditor5". It's necessary for modern esm modules projects

https://github.com/microsoft/TypeScript/issues/49083 https://stackoverflow.com/questions/65873101/node-requires-file-extension-for-import-statement/65874173#65874173

This is because node.js follows the ES6 standard which forbids the interpreter from guessing filename extensions. You will also need to add file extensions if you want to use import in plain javascript in browsers.

Inviz avatar Mar 02 '23 08:03 Inviz