Routhinator
Routhinator

Reputation: 3809

How to properly build Angular 8 and ckeditor5-angular for prod mode?

I've been stuck on a weird problem involving Angular 6 to 8 (I started on Angular 6 and migrate to 7 and then 8 thinking this might have been resolved with newer libraries, and found I was wrong) in conjunction with the ckeditor5-angular module and a custom build of the ckeditor5-classic-build editor.

The only thing added to the custom build is the Alignment plugin for the justification buttons.

Everything works perfectly in dev mode without any errors.. which is the root of my problem. In a --prod build I get this indecipherable stack trace which I have been unable to reproduce in dev mode:

zl/i<@https://v5.staging.amateurwriting.net/main-es2015.c0032bd3a584c0b5d808.js:1:342042
zl@https://v5.staging.amateurwriting.net/main-es2015.c0032bd3a584c0b5d808.js:1:342142
Vl@https://v5.staging.amateurwriting.net/main-es2015.c0032bd3a584c0b5d808.js:1:341944
jl/<@https://v5.staging.amateurwriting.net/main-es2015.c0032bd3a584c0b5d808.js:1:341872
change@https://v5.staging.amateurwriting.net/main-es2015.c0032bd3a584c0b5d808.js:1:201004
jl@https://v5.staging.amateurwriting.net/main-es2015.c0032bd3a584c0b5d808.js:1:341862
_initPlaceholder@https://v5.staging.amateurwriting.net/main-es2015.c0032bd3a584c0b5d808.js:1:344731
init@https://v5.staging.amateurwriting.net/main-es2015.c0032bd3a584c0b5d808.js:1:343575
create/</<@https://v5.staging.amateurwriting.net/main-es2015.c0032bd3a584c0b5d808.js:1:361312
invoke@https://v5.staging.amateurwriting.net/polyfills-es2015.5cb7d8167823e5b15eaf.js:1:43382
run@https://v5.staging.amateurwriting.net/polyfills-es2015.5cb7d8167823e5b15eaf.js:1:38884
A/<@https://v5.staging.amateurwriting.net/polyfills-es2015.5cb7d8167823e5b15eaf.js:1:49712
invokeTask@https://v5.staging.amateurwriting.net/polyfills-es2015.5cb7d8167823e5b15eaf.js:1:44000
runTask@https://v5.staging.amateurwriting.net/polyfills-es2015.5cb7d8167823e5b15eaf.js:1:39499
y@https://v5.staging.amateurwriting.net/polyfills-es2015.5cb7d8167823e5b15eaf.js:1:45945
invokeTask@https://v5.staging.amateurwriting.net/polyfills-es2015.5cb7d8167823e5b15eaf.js:1:45030
v@https://v5.staging.amateurwriting.net/polyfills-es2015.5cb7d8167823e5b15eaf.js:1:56978
b@https://v5.staging.amateurwriting.net/polyfills-es2015.5cb7d8167823e5b15eaf.js:1:57299
main-es2015.c0032bd3a584c0b5d808.js:1:968675
    createEditor https://v5.staging.amateurwriting.net/main-es2015.c0032bd3a584c0b5d808.js:1
    invoke https://v5.staging.amateurwriting.net/polyfills-es2015.5cb7d8167823e5b15eaf.js:1
    run https://v5.staging.amateurwriting.net/polyfills-es2015.5cb7d8167823e5b15eaf.js:1
    A https://v5.staging.amateurwriting.net/polyfills-es2015.5cb7d8167823e5b15eaf.js:1
    invokeTask https://v5.staging.amateurwriting.net/polyfills-es2015.5cb7d8167823e5b15eaf.js:1
    runTask https://v5.staging.amateurwriting.net/polyfills-es2015.5cb7d8167823e5b15eaf.js:1
    y https://v5.staging.amateurwriting.net/polyfills-es2015.5cb7d8167823e5b15eaf.js:1
    invokeTask https://v5.staging.amateurwriting.net/polyfills-es2015.5cb7d8167823e5b15eaf.js:1
    v https://v5.staging.amateurwriting.net/polyfills-es2015.5cb7d8167823e5b15eaf.js:1
    b https://v5.staging.amateurwriting.net/polyfills-es2015.5cb7d8167823e5b15eaf.js:1

I've come across a lot of different issues on Github that seem like they may be related, but none of the solutions in them work. I've set my tsconfig.json to use es6/es2015 (ckeditor5 does not support es5 and I'm ok with that, I don't want to support it either) and added the allowJs: true option as is mentioned in the issues for ckeditor5, but this stack trace never changes, and I can never reproduce it in dev mode.

What can I do to find the root of the issue? Has anyone seen this? And how do I stop Angular from producing es5 artifacts when I specify an es6 build target? It's still building them.. however they don't seem to be loading in Firefox so I'm pretty certain they are not causing the issue I'm seeing, but I also am pretty certain they won't work as ckeditor5 is es6+ only.

tsconfig.json:

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "module": "esnext",
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es2015",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2018",
      "dom"
    ]
  }
}

polyfills.ts:

/**
 * This file includes polyfills needed by Angular and is loaded before the app.
 * You can add your own extra polyfills to this file.
 *
 * This file is divided into 2 sections:
 *   1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
 *   2. Application imports. Files imported after ZoneJS that should be loaded before your main
 *      file.
 *
 * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
 * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
 * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
 *
 * Learn more in https://angular.io/guide/browser-support
 */

/***************************************************************************************************
 * BROWSER POLYFILLS
 */

/** IE10 and IE11 requires the following for NgClass support on SVG elements */
// import 'classlist.js';  // Run `npm install --save classlist.js`.

/**
 * Web Animations `@angular/platform-browser/animations`
 * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
 * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
 */
// import 'web-animations-js';  // Run `npm install --save web-animations-js`.

/**
 * By default, zone.js will patch all possible macroTask and DomEvents
 * user can disable parts of macroTask/DomEvents patch by setting following flags
 * because those flags need to be set before `zone.js` being loaded, and webpack
 * will put import in the top of bundle, so user need to create a separate file
 * in this directory (for example: zone-flags.ts), and put the following flags
 * into that file, and then add the following code before importing zone.js.
 * import './zone-flags.ts';
 *
 * The flags allowed in zone-flags.ts are listed here.
 *
 * The following flags will work for all browsers.
 *
 * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
 * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
 * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
 *
 *  in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
 *  with the following flag, it will bypass `zone.js` patch for IE/Edge
 *
 *  (window as any).__Zone_enable_cross_context_check = true;
 *
 */

/***************************************************************************************************
 * Zone JS is required by default for Angular itself.
 */
import 'zone.js/dist/zone.js';  // Included with Angular CLI.
(window as any).__Zone_disable_toString = true; // Zone will not patch Function.prototype.toString

/***************************************************************************************************
 * APPLICATION IMPORTS
 */


Update:

I reran build with --optimization=false to try and see what the error actually is, and it went away.. so this seems to be related to uglifyjs, but not sure how.

Upvotes: 0

Views: 1034

Answers (1)

Routhinator
Routhinator

Reputation: 3809

Found the cause of CKEditor5 not working in prod:

In angular.json you must set:

...
"optimization: true",
"buildOptimizer": false,
...

The buildOptimizer renames functions which breaks CKEditor5, by disabling this it works in Angular 6,7,8. I'm guessing CKEditor is using named function lookups, which UglifyJS is missing in the compilation process. Angular has made the decision to make this option on by default.

Warning however, this increased the size of my prod build for es2015 by 270kb.

I've tested and found this to work and solve the issue in Angular 6, 7 and 8.

The related Angular issue is here: https://github.com/angular/angular-cli/issues/11439

Upvotes: 1

Related Questions