tscc icon indicating copy to clipboard operation
tscc copied to clipboard

TinyMCE getting replaced with TinyMCE.default

Open BrianLeishman opened this issue 3 years ago • 6 comments

So far I've gotten most of our 3rd party libraries to import correctly, except for TinyMCE, which is being used like this

import tinymce from 'tinymce/tinymce'

tinymce.init({
    selector: '#blog-body',
});

based on the instructions here https://www.tiny.cloud/docs/advanced/usage-with-module-loaders/

which is outputting this js

(function(){'use strict';tinymce.default.init({selector:"#blog-body"});})()
//# sourceMappingURL=app.js.map

And my tscc.spec.json

{
    "modules": {
        "app": "ts/entrypoint.ts"
    },
    "external": {
        "jquery": "$",
        "sweetalert2": "Swal",
        "ladda": "Ladda",
        "tinymce/tinymce": "tinymce"
    },
    "prefix": "public_html/js/",
    "compilerFlags": {
        "rewrite_polyfills": true,
        "language_out": "ES5_STRICT",
        "compilation_level": "ADVANCED_OPTIMIZATIONS",
        "use_types_for_optimization": true,
        "output_wrapper": "(function(){%output%})()"
    }
}

But in the browser I now get a Cannot read property 'init' of undefined error. At the beginning of my compiled js it looks correct with var r=tinymce but later in the code calls r.default.init({selector:"#blog-body"})

How can I make this not get renamed to .default so it matches the externally loaded js?

I have attached an example project that compiles with just tscc from the root tinymce-ts.zip

BrianLeishman avatar Nov 11 '20 18:11 BrianLeishman

Almost mediately sure this isn't an issue with this repo, because tsc gives me this output

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tinymce_1 = require("tinymce/tinymce");
tinymce_1.default.init({
    selector: '#blog-body',
});
//# sourceMappingURL=entrypoint.js.map

BrianLeishman avatar Nov 11 '20 18:11 BrianLeishman

Interesting... If I basically pull the bottom of tinymce.d.ts out and move it into my own file like this

import {TinyMCE} from 'tinymce/tinymce'

declare const tinymce: TinyMCE
tinymce.init({
    selector: '#blog-body',
});

that compiles perfectly into

(function(){'use strict';tinymce.init({selector:"#blog-body"});})()
//# sourceMappingURL=app.js.map

with tscc and tsc

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
tinymce.init({
    selector: '#blog-body',
});
//# sourceMappingURL=entrypoint.js.map

BrianLeishman avatar Nov 11 '20 18:11 BrianLeishman

Hi, most likely the documentation on tinyMCE is assuming that you should be using "esModuleInterop" TS compiler flag. I suppose after you specify that flag, the tsc command will succeed.

Unfortunately "esModuleInterop" is not currently supported by tsickle, and IMO the support should be addressed from tsickle's side instead of tscc. For this particular tinyMCE module, there is no problem in using it without esModuleInterop -- you can just write import * as tinyMCE from 'tinymce/tinymce' although it is stated otherwise in the docs, and this should be fine.

theseanl avatar Nov 19 '20 07:11 theseanl

I think I see more of what's happening. It seems for things that are imported from the @types directory, they just get replaced with their name when compiled. But when packages are compiled, they're replaced with package.default. That seems to be the common denominator between all of my imports.

Sweetalerts (Swal) actually has a Swal.default that's just defined as Swal somewhere in their CDN package that doesn't break when compiling, but almost all of my other imports are from @types.

Even with the flatpickr package, it's written in typescript so it has it's own types, so I can't import it at all because the compiler is replacing it with flatpickr.default which doesn't exist. I wonder if there's a way to treat a "module" the same way that "just types" are getting treated.

BrianLeishman avatar Jun 18 '21 16:06 BrianLeishman

Actually that was wrong as well, axios has a @types/axios package but it still compiles to axios.default, so it doesn't get stuck like flatpickr does. But even though flatpickr has a @types/flatpickr that mirrors the axios one, it doesn't solve the .default issue.

BrianLeishman avatar Jun 18 '21 16:06 BrianLeishman

Actually it looks like there is supposed to be handling for this, not sure I understand when it's supposed to take effect though, or how to force it to happen https://github.com/angular/tsickle/blob/master/src/googmodule.ts#L509

BrianLeishman avatar Jun 18 '21 16:06 BrianLeishman