Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using Vite with custom Accessor classes #524

Open
sebastianfrey opened this issue Jul 17, 2024 · 2 comments
Open

Using Vite with custom Accessor classes #524

sebastianfrey opened this issue Jul 17, 2024 · 2 comments

Comments

@sebastianfrey
Copy link

sebastianfrey commented Jul 17, 2024

Recently I migrated a Typescript app from CRA to Vite that contained some classes that used Accessor decorators as described here. The problem, was that Vite failed to serve those classes, because Accessor decorators must be transpiled by typescript.

As solution, I have created a simple configurable Vite plugin, which allows to transform classes with custom Accessor decorators on the fly using typescript. I thought this might be useful for someone else in the future, so I wanted to share this plugin here:

vite-arcgis-plugin.ts

import tsc from 'typescript';
import type { Plugin } from 'vite';

function getCompilerOptions(tsconfig: string | undefined) {
  if (!tsconfig) {
    return {};
  }
  const { config } = tsc.readConfigFile(tsconfig, tsc.sys.readFile);
  return config.compilerOptions;
}

export interface ArcGISConfig {
  transpile: (id: string) => boolean;
  tsconfig?: string;
}

export function arcgis(config: ArcGISConfig): Plugin {
  const { transpile, tsconfig } = config;
  const compilerOptions = getCompilerOptions(tsconfig);

  return {
    name: 'arcgis',
    async transform(code, id) {
      if (transpile(id)) {
        const transpiledCode = await tsc.transpileModule(code, {
          compilerOptions,
        });
        return {
          code: transpiledCode.outputText,
          map: transpiledCode.sourceMapText ?? null,
        };
      }
      return null;
    },
  };
}

Inside vite.config.ts the plugin can used in the following way:

import { defineConfig } from 'vite';
import { arcgis } from './vite-arcgis-plugin';

export default defineConfig({
  plugins: [
    // other plugins
    arcgis({
      transpile: (id) => /packages\/arcgis/.test(id),
      tsconfig: './tsconfig.json',
    }),
  ]
});
@andygup
Copy link
Member

andygup commented Jul 17, 2024

Thanks @sebastianfrey. I was able to get Accessor decorators working in a test app by adding the following to the tsconfig.json using Vite 5.3.4 and TypeScript 5.5.3:

    "experimentalDecorators": true, 

I'll add a note to that SDK documentation page you mentioned above. I didn't see it mentioned anywhere that the core API is currently using legacy decorators.

For reference, in case others come across this thread, the error message will be similar to this: Expression expected (Note that you need plugins to import files that are not JavaScript).

@sebastianfrey
Copy link
Author

sebastianfrey commented Jul 18, 2024

Hi @andygup, thanks for your feedback on this.

Some additional notes:

For me the error message Expression expected only occurred when using @arcgis/core with @vitejs/plugin-react-swc.

When using @vitejs/plugin-react for transpiling React and JSX the error message is: [plugin:vite:react-babel] /path/to/file/which/useses/decorators.ts: Support for the experimental syntax 'decorators' isn't currently enabled


For @vitejs/plugin-react-swc it is enough to set tsDecorators to true in the react swc plugin options. No plugin for processing Accesor decorators is required here.

import reactSwc from "@vitejs/plugin-react-swc";

export default defineConfig({
  plugins: [
    reactSwc({
      // Requires experimentalDecorators in tsconfig
      tsDecorators: true,
    }),
  ]
});

Note: It's required, as stated out by @andygup, to set experimentalDecorators to true in tscofnig.json.


But for @vitejs/plugin-react things are different. The error message suggests, to add @babel/plugin-syntax-decorators to solve the issue, but unfortunately @arcigs/core requires that decorators are transpiled with typescript.

For more details see Esri/feedback-js-api-next#169 (comment).

So when using @vitejs/plugin-react, the shared arcgis plugin from this thread can be leverage when using Accessor decorators.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants