janl / mustache.js

Minimal templating with {{mustaches}} in JavaScript
https://mustache.github.io
MIT License
16.44k stars 2.4k forks source link

4.2.0 broken (typescript + webpack): #786

Open nbelyh opened 3 years ago

nbelyh commented 3 years ago

foo.ts:

import * as mustache from "mustache"

// runtime error: Uncaught TypeError: mustache__WEBPACK_IMPORTED_MODULE_0__.render is not a function
mustache.render('foo', {});

tsconfig.json

{
    "compilerOptions": {
      "module": "es6",
      "target": "es5",
      "moduleResolution": "node",
    },
    "exclude": [
      "node_modules"
    ]
  }

Reverting to 4.1.0 fixes the problem.

Full project to reproduce the problem attached: z2.zip

nbelyh commented 3 years ago

Anyone? The issue won't fix itself 😄

phillipj commented 3 years ago

Hi @nbelyh,

thanks for reporting! 👍🏻

Any chance you could make that reproduction available as a github.com repository? ..I've gotten the habit of not opening .zip archives from the internetz over the years 😸

nbelyh commented 3 years ago

@phillipj thank you for response! I just thought that creating a repository to reproduce a single issue may be a bit of an overkill 😄 Isn't opening zip files (not executables) safe?

Anyway, here is the repo (using 4.2.0): https://github.com/nbelyh/repro-mustache-402

npm install npm start (just launches webpack)

After that, open (double-click) the file index.html => error in the browser console (from the description) If you change the version to the previous one, 4.1.0 like this:

npm install mustache@4.1.0 npm start

Then the file opens fine (no errors)

nbelyh commented 3 years ago

@phillipj forgot to make the repo public - now it should be

phillipj commented 3 years ago

Sorry for the late reply, and thanks for reporting!

You've definitively hit an unexpected side effect that we did not consider when introducing the package.json/exports field in https://github.com/janl/mustache.js/pull/773. Those changes seems to make webpack choose the .mjs with ES Modules syntax instead of .js, and the consequence is slighty different semantics when importing mustache.js.

Gotta dive deeper and compare pros/cons on plausible solutions going forward, in the meantime if you want to stay on mustache.js 4.2.0, the following does the trick and makes sense having the mustache.js' source code in mind:

import mustache from "mustache"
nbelyh commented 3 years ago

@phillipj Thank you for quick response! Unfortunately, this import syntax requires esModuleInterop=true in tsconfig (this issue is about typescript). It is not always possible to have it like this, as it may conflict with other imports. For now I've decided to stay with 4.1.0...

phillipj commented 3 years ago

Unfortunately, this import syntax requires esModuleInterop=true in tsconfig (this issue is about typescript). It is not always possible to have it like this, as it may conflict with other imports.

Huh, that's weird, as I was able to use the import I suggested in that reproduction repository of yours, without any other changes.

For now I've decided to stay with 4.1.0...

Alrighty :+1:

nbelyh commented 3 years ago

Yes you are right, it works in this repository without this directive. I faced the problem with this import in another project, will check it there and hopefully come back with more details. Maybe typescript version...

ankon commented 3 years ago

We've hit the same issue now, fairly unexpectedly I must say. We used mustache in many places before, and it was the go-to-templater.

We have esModuleInterop explicitly enabled in our projects.

Gotta dive deeper and compare pros/cons on plausible solutions going forward, in the meantime if you want to stay on mustache.js 4.2.0, the following does the trick and makes sense having the mustache.js' source code in mind:

I'm reading this that it is for us probably better to now adjust to this import syntax through a global search-replace run, and that this will stay supported? Would it be good to possibly add a note in README.md pointing this out?

pranav-js commented 2 years ago
import * as Mustache from 'mustache';
   container.innerHTML = Mustache.default.render(container.innerHTML, {
      balance: 30,
    });

this works ( I donno why), but type definitions are messed up :/

ricardodev2015 commented 2 years ago

Reverting to 4.1.0, until 4.2.0 is solved. I'm getting this error in Chrome:

Mustache4 2 0-Error

deltamualpha commented 2 years ago

yes, this this a major breaking change for those of us using mustache in a very simple <script type="text/javascript" src="js/mustache.4.1.0.js"></script> sort of way. The 4.2.0 file is invalid unless imported as type="module", which, while the "modern" way to do native module support, is definitely a forced change.

phillipj commented 2 years ago

Hi folks,

my lack of responses and alternatives to fix this properly is a result of me not having the time to do much open source in my spare time these days. I'm obviously sorry for the frustration and wasted hours this has caused for you.

Your reports are certainly valuable and needed to ensure we consider more usage scenarios than what we obviously had in mind when doing the 4.2.0 release -- we honestly tried our best to consider everything, but failed.

Now that we do have a few added scenarios to consider, it feels the most valuable contribution going forward would be ideas of what is wrong and what could be done differently. My capacity isn't going to change in the near future, so in the spirit of open source, this needs to be fixed by collaborating around thoughts and/or concrete changes to the code or build process.

Bottom line: help mustache.js get this right please?

deltamualpha commented 2 years ago

@phillipj totally understandable. I'm no javascript wiz, but I'll take a look at the repo and its build process when I have a chance and see what I can come up with. It might be that mustache.js needs to provide a couple of variants, built for specific tool-chains.