Scripts not registered when "import pc" is present in TypeScript

Hi! I’m using PlayCanvas sync to build my game in TypeScript and have it transpile over to Javascript. I’m not particularly knowledgeable in TS, but I do greatly enjoy using it over Javascript.

One strange (to me) issue I’m encountering is that whenever my script requires an import call, the script is no longer found after a reparse in the PlayCanvas editor. So given the following TypeScript code:

class WorkingScript extends pc.ScriptType
{
    initialize()
    {
        
    }
}

pc.registerScript(WorkingScript)
import pc from "playcanvas";

class NonWorkingScript extends pc.ScriptType
{
    initialize()
    {

    }
}

pc.registerScript(NonWorkingScript)

NonWorkingScript will not be found by PlayCanvas, while WorkingScript will. No errors.

The Javascript exports of the scripts can be found here, which I’m sure clearly show the issue, but I can’t identify it.

What can I do to be able to use the import keyword (which I need in order to import some other scripts in my actual project) for ScriptType derivatives in my TypeScript files without harming their ability to be found by the editor?

Thanks!

AFAIK, the Editor doesn’t support ES6 scripts. Can you try transpiling to ES5 please?

Hmmm it looks like we’re already targeting ES5 (and I did try ES6 on the off-chance that was a typo), but perhaps one or some of our other settings are off?

{
  "compilerOptions": {    
    "target": "ES5",
    "module": "UMD",
    "lib": [
      "DOM",
      "ES2017"
    ],
    "types":
    [
      "playcanvas",
    ],
    "outDir": "./build",
    "rootDir": "./src",
    "strict": true,
    "strictPropertyInitialization": false,
    "strictFunctionTypes": false,
    "esModuleInterop": true,
    "inlineSourceMap": true,
    "inlineSources": true, 
    "experimentalDecorators": true,
    "forceConsistentCasingInFileNames": true,
    "noImplicitThis": true,
    "moduleResolution": "Node"
      },

  "include": [
    "src",
  ]
}

Hmm, I’m not sure :thinking: I’m not a TypeScript user so not sure what is the issue here.

Any one else that can help?

1 Like

Someone on the Discord referenced this Typescript with Webpack template, may be worth a look at for pointers? : GitHub - Ciberusps/playcanvas-typescript-example

1 Like

Thanks! I was able to peck enough pieces of that example over to my own framework that I can now write my scripts without the need for import pc, and the project will build and I’ll see my Scripts in PlayCanvas. The presence of import pc still seems to break things, but now the compiler no longer needs them.

My PlayCanvas framework is now a bit of an odd amalgamation between this template, this one, and the one you just provided. I’m not sure if there’s been something wrong with my implementation or if the other frameworks have just had limitations. Unfortunately I haven’t done a great job of documenting the specific issues I’ve run into, and I’m not particularly knowledgeable with configuring TypeScript, so I mostly just have to hope this is the magic combo that’ll take me to the finish line.

The most important thing is that I seem to now to be in a place where I can progress, so thanks again!

1 Like

I was able to fix this issue by adding a global.d.ts file with a playcanvas type def.

Seems like adding the ‘import pc from "playcanvas";’ in every script made VS code happy, but broke something in the pcsync process. This solution seems to work so far.

global.d.ts:

import * as pc from 'playcanvas';

declare global {
  const pc: typeof pc;
}

(Used official example as a base: GitHub - Ciberusps/playcanvas-typescript-example)
Now my helloWorld.ts file builds without ts errors, and exports via the pcsync utility. Works!

Here are the tsconfig.json settings (played with them till it works without issue):

{
  "compilerOptions": {
    "target": "ES5",
    "module": "amd",
    "lib": [
      "DOM",
      "ES2017"
    ],
    "outFile": "./build/main.build.js",
    "rootDir": "./src",
    //"strict": true,
    //"strictPropertyInitialization": false,
    "types": [
      "playcanvas"
    ],
    //"esModuleInterop": true,
    "inlineSourceMap": true,
    "inlineSources": true,
    //"experimentalDecorators": true,
    //"forceConsistentCasingInFileNames": true,
    //from other playcanvas ts project
    "sourceMap": false,
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    //"resolveJsonModule": true,
    //"isolatedModules": true,
    "noImplicitThis": false,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "strictPropertyInitialization": false,
  },
  "include": [
    "src/**/*.ts"
  ],
  "exclude": [
    "node_modules",
    "build"
  ],
}

Hope this helps someone. This should be added to the official example.

@StanGatarn When you mean official example, do you mean this one? GitHub - playcanvas/playcanvas-editor-ts-template: A simple TypeScript template for PlayCanvas that can also sync with your playcanvas.com project

If so, it doesn’t need the importing of the pc modules and intellisense and compiling still work correctly. What’s the reason for using import here? The thread is so long ago that I’ve lost all context :sweat_smile:

The reason is for the typescript compiler to stop complaining that the symbol “pc” doesn’t exist, within playcanvas script files. Ei. WorkingScript.ts would be a file like this:

//(Would have an error: pc not found, but adding  "import pc" breaks when running on playcavnas
class WorkingScript extends pc.ScriptType
{
    initialize()
    {
        
    }
}

pc.registerScript(WorkingScript)

You may not get this error because my project uses modules + typescript (for the multiplayer code). But this fix works for my case.