Skip to content

Typescript error since version 14: "File "../melonjs.module.d.ts" is not a module" #1162

Description

@lartkma

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

  1. 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'));
});
  1. Run npm install to install the packages.
  2. Run npm run build to run the Typescript transpiler. The process run successfully.
  3. Run npm run dev to deploy a test server. The result is the expected (a "Welcome to MelonJS" title and a blue scene)
  4. Update the melonjs library to the latest version (npm install melonjs@^14.0.0). You can also use any 14.x.x version.
  5. 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

Activity

  1. lartkma commented on Nov 24, 2022

    @lartkma
    Author

    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 unless module is None, System, or AMD. This option cannot be used to bundle CommonJS or ES6 modules.

  2. obiot commented on Nov 24, 2022

    @obiot
    Member

    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"

  3. lartkma commented on Nov 30, 2022

    @lartkma
    Author

    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.

  4. obiot commented on Nov 30, 2022

    @obiot
    Member

    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.

  5. self-assigned this
    on Nov 30, 2022
  6. obiot commented on Nov 30, 2022

    @obiot
    Member

    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

  7. lartkma commented on Dec 1, 2022

    @lartkma
    Author

    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 ...:
    v1

    With tsc build/melonjs.module.js ...:
    v2

    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 to outfile (; 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 8410e65. 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.

  8. obiot commented on Dec 1, 2022

    @obiot
    Member

    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

  9. obiot commented on Dec 1, 2022

    @obiot
    Member

    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 :)

  10. lartkma commented on Dec 3, 2022

    @lartkma
    Author

    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?

    v3

  11. lartkma commented on Dec 3, 2022

    @lartkma
    Author

    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?

  12. obiot commented on Dec 3, 2022

    @obiot
    Member

    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.

  13. added a commit that references this issue on Dec 9, 2022
  14. obiot commented on Dec 9, 2022

    @obiot
    Member

    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 :)

  15. obiot commented on Dec 13, 2022

    @obiot
    Member

    @lartkma any feedback by any chance ?

  16. lartkma commented on Dec 13, 2022

    @lartkma
    Author
  17. 87113 commented on Dec 15, 2022

    @87113

    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 :)

  18. lartkma commented on Dec 17, 2022

    @lartkma
    Author

    @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)

  19. obiot commented on Dec 23, 2022

    @obiot
    Member

    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.

  20. obiot commented on Dec 23, 2022

    @obiot
    Member

    @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)

    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.

  21. obiot commented on Dec 26, 2022

    @obiot
    Member

    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 :)

  22. added a commit that references this issue on Dec 30, 2022
  23. obiot commented on Dec 30, 2022

    @obiot
    Member

    @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)

    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 !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions