melonJS
melonJS copied to clipboard
Typescript error since version 14: "File "../melonjs.module.d.ts" is not a module"
Describe the bug When using the latest version of melonjs in a Typescript project, trying to build the project generates an error by the Typescript transpiler.
To Reproduce
- Create this simple project using Typescript and Vite. The project consist of only 4 files in a folder:
package.json
{
"name": "testmelon2ts",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview"
},
"devDependencies": {
"typescript": "^4.9.3",
"vite": "^3.2.3"
},
"dependencies": {
"melonjs": "^13.4.0"
}
}
tsconfig.json
{
"compilerOptions": {
"target": "ES6",
"useDefineForClassFields": true,
"module": "ES6",
"lib": ["ES6", "DOM"],
"moduleResolution": "Node",
"strict": true,
"resolveJsonModule": true,
"isolatedModules": true,
"esModuleInterop": true,
"noEmit": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"skipLibCheck": true,
"allowJs": true
},
"include": ["src"]
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + TS</title>
</head>
<body>
<h1>Welcome to MelonJS</h1>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
src/main.ts
import * as me from 'melonjs';
me.device.onReady(() => {
if(!me.video.init(1218, 562, {scale: 'auto'})) {
alert('Your browser does not support HTML5 canvas');
return;
}
me.game.world.addChild(new me.ColorLayer('background', '#0000BB'));
});
- Run
npm install
to install the packages. - Run
npm run build
to run the Typescript transpiler. The process run successfully. - Run
npm run dev
to deploy a test server. The result is the expected (a "Welcome to MelonJS" title and a blue scene) - Update the melonjs library to the latest version (
npm install melonjs@^14.0.0
). You can also use any 14.x.x version. - Run
npm run build
to run the Typescript transpiler. This time Typescript gives an error:
src/main.ts:1:21 - error TS2306: File '(project folder)/node_modules/melonjs/dist/melonjs.module.d.ts' is not a module.
1 import * as me from 'melonjs';
~~~~~~~~~
Expected behavior The code should run and build normally like in the previous version, as according to the changelog there is no changes in the API used in this code.
Device information:
- Device: PC
- OS: Windows 10 Pro
- Browser: Firefox
- melonJS Version: 14.1.1
- NodeJS Version: 19.1.0
- NPM Version: 8.19.3
Additional context
Running npm run dev
with the updated melonjs runs the code correctly. Not sure why, as I'm not fully aware of how Vite works, but probably it's linked to some check disabled.
I don't think the issue is related to Vite, as I tried with a Webpack project with the same result.
I tried changing the values of "moduleResolution" and "module" in the tsconfig.json
file to "NodeNext" but it didn't work
I researched a bit and I found something interesting. The generated melonjs.module.d.ts
contains several modules with an "index" module at the end. This StackOverflow question describes a similar situation, where the expected module name doesn't work. I tried the "fix" mentioned there: I modified the node_modules\melonjs\dist\melonjs.module.d.ts
file in my project directly, replacing declare module "index"
with declare module "melonjs"
. With that change, npm run build
runs successfully.
While trying to understand the posted answer, I found this in the Typescript documentation (emphasis mine):
Note:
outFile
cannot be used unlessmodule
isNone
,System
, orAMD
. This option cannot be used to bundle CommonJS or ES6 modules.
wow interesting, so basically it's because we are doing this : https://github.com/melonjs/melonJS/blob/master/package.json#L102
I thought it was a neat, clean & simple way to generate the d.ts
file, but maybe we actually need a proper tsconfig.json
file to generate it, instead of this quick "workaround"
I think I found a possible solution: using --outdir
instead of --outfile
in the type generation command. I tried that in a local copy changing the types
script in package.json
, as well as the types
property:
{
"name": "melonjs",
"version": "14.1.1",
"description": "melonJS Game Engine",
....
"main": "dist/melonjs.module.js",
"module": "dist/melonjs.module.js",
"types": "dist/types/index.d.ts",
....
"scripts": {
....
"types": "tsc src/index.js --declaration --allowJs --emitDeclarationOnly --outdir dist/types"
}
}
After building the library and installing it in my demo project, npm run build
runs successfully, without need for an special tsconfig.json
configuration on neither the library project nor the demo project.
I modified it to only generate one .d.ts
file :
"types": "tsc build/melonjs.module.js --declaration --allowJs --emitDeclarationOnly --outdir dist"
would this be working on your side ? I'd rather keep only one file instead of generating a separate file for every source file.
the funny thing is that If I remember correctly, my version of the fix used to be the way we used to generate the .d.ts file initially, but then when we moved to a proper es6 build, we changed to generate the .d.ts file out of all separate files and therefore switch from outdir
to outfile
(; I might not remember correctly, but I'm pretty sure it was
I modified it to only generate one
.d.ts
file :"types": "tsc build/melonjs.module.js --declaration --allowJs --emitDeclarationOnly --outdir dist"
would this be working on your side ? I'd rather keep only one file instead of generating a separate file for every source file.
I tried generating the library with this. At least I am able to build the demo project. But I've found the type suggestions in VSCode are more complete with my solution than with yours.
With tsc src/index.js ...
:
With tsc build/melonjs.module.js ...
:
I specifically tried this because it seems it happened before in #1071.
the funny thing is that If I remember correctly, my version of the fix used to be the way we used to generate the .d.ts file initially, but then when we moved to a proper es6 build, we changed to generate the .d.ts file out of all separate files and therefore switch from
outdir
tooutfile
(; I might not remember correctly, but I'm pretty sure it was
I think the commit that made the change you're talking about is this one https://github.com/melonjs/melonJS/commit/8410e65bc14875b93796d12281d034a7d7493656. It's noteworthy that the message of the commit says "no more missing API or modules", like what happens in the images...
I have no detailed knowledge of how ES6 modules or Typescript type generation works, so I don't know if there are other alternatives. But I feel that the note in the documentation about how --outFile
"cannot be used to bundle CommonJS or ES6 modules" means that the multiple files approach is the way to go, IMHO.
alright, separate files it is then ! I'll push the changes in the repo and publish a new version today !
thanks again really for your help on this
14.1.2 published on NPM: https://www.npmjs.com/package/melonjs/v/14.1.2
let me know if it all works as expected now, and then I'll close this ticket :)
I've just tested it. It allows me to build the Typescript test project successfully. However, I don't get any type suggestion when, for example, I'm using VS Code. I see the files generated by --outdir
are commited in the repo, however, when I see what NPM has downloaded in node_modules, I only see the index file. I think you need to add them to the files
array in package.json
, right?
PD: When I try to build the melonJS library from the source, I get ESLint errors because it tries to parse non-code files. I worked around that locally adding "ignorePatterns": ["*.png", "*.frag", "*.vert"]
to the .eslintrc.json
file, but it's weird that you can build it without any problems. Maybe you have some system-level ESLint configurations?
ok, now I remember why we switched to the build file to generate the ts definition. Reason being those files that are being converted to either base64 or JS/JSON before being "injected" into the final .js source code.
so at this stage I think we really need to add a tsconfig file that include "exclusions" for those files.
Hi @lartkma, see the last commit, where I added a tsconfig file. rather than excluding the probllematic files, I included on the .js ones, let me know if it works for you with that configuration, but I think we should be good now :)
@lartkma any feedback by any chance ?
Hello. Sorry, I've been busy these days. I'll check it in the coming days.
El mar, 13 de dic. de 2022 4:26 a. m., Olivier Biot < @.***> escribió:
@lartkma https://github.com/lartkma any feedback by any chance ?
— Reply to this email directly, view it on GitHub https://github.com/melonjs/melonJS/issues/1162#issuecomment-1348032210, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAQVRE4PV4SFLFBWWQPOBNTWNA6KPANCNFSM6AAAAAASI6CXEY . You are receiving this because you were mentioned.Message ID: @.***>
Hi, I'm new with melonJS I tried to install it on a Angular 14 App.
In the beginning I got some error like :
Error: node_modules/melonjs/dist/melonjs.module.d.ts:128:5 - error TS2416: Property 'resize' in type 'BitmapText' is not assignable to the same property in base type 'Renderable'.
Type '(scale: number) => BitmapText' is not assignable to type '(w: number, h: number) => Rect'.
Call signature return types 'BitmapText' and 'Rect' are incompatible.
The types of 'scale(...).pos.onResetEvent' are incompatible between these types.
Type '(x: number, y: number, z: number, settings: any) => ObservableVector3d' is not assignable to type '(x?: number | undefined, y?: number | undefined) => Vector2d'.
128 resize(scale: number): BitmapText;
~~~~~~
And :
Error: src/app/app.module.ts:3:21 - error TS2306: File '/home/pascal/Dev/melon/node_modules/melonjs/dist/melonjs.module.d.ts' is not a module.
3 import * as me from 'melonjs/dist/melonjs.module.js';
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
And after some try I success to launch the "Hello World". Here my code : https://framagit.org/lascapi/melonjs-in-angular/
Thank's for your work :)
@lartkma any feedback by any chance ?
I've just tested it, and it seems to work. I can compile the test project and I got the type suggestions. You only need to make sure all the files generated in dist/types
(and not only dist/types/index.d.ts
) are packaged in the published version, elsewhere it won't work (or at least you won't get type suggestions)
And after some try I success to launch the "Hello World". Here my code : https://framagit.org/lascapi/melonjs-in-angular/
Thank's for your work :)
that's awesome, sorry for the late reply (holiday mode is on already), and most probably I'll add a post in the forum linking back to this, so that we can keep a better trace of it somwhere.
@lartkma any feedback by any chance ?
I've just tested it, and it seems to work. I can compile the test project and I got the type suggestions. You only need to make sure all the files generated in
dist/types
(and not onlydist/types/index.d.ts
) are packaged in the published version, elsewhere it won't work (or at least you won't get type suggestions)
sorry as well for the late reply, I'm off as well already for the holiday, but this is excellent !!!! Would you share your boilerplate ? I would love as well to make it the "official TS Boilerplate" for melonJS if possible.
version 14.2 released, and the JS-ES6 boilerplate updated accordingly.; I'm closing this one as I believe we are done, but @lartkma (once you are back from the holiday break), my offer definitely still stand on have an official TS boilerplate :)
@lartkma any feedback by any chance ?
I've just tested it, and it seems to work. I can compile the test project and I got the type suggestions. You only need to make sure all the files generated in
dist/types
(and not onlydist/types/index.d.ts
) are packaged in the published version, elsewhere it won't work (or at least you won't get type suggestions)
Hi @lartkma even though you did warn me, I managed to published the 14.2 version and forgot to update package.json
to includes all the generated files. (see #1166)
so 14.3 on the way !