flow icon indicating copy to clipboard operation
flow copied to clipboard

Support to build frontend from TypeScript sources

Open heruan opened this issue 4 years ago • 5 comments

In NPM mode JavaScript sources can be placed in META-INF/resources/frontend to be picked up by the Maven plugin. Adding TypeScript support for this would be useful since it allows type-checking and decorators (and it's also adopted by LitElement).

Given that if you place TypeScript sources in the root frontend folder and setup the ts-loader in the Webpack config it works out of the box (see @marcushellberg vaadin-lit-typescript), the same approach doesn't work for files in the META-INF/resources/frontend of JAR dependencies.

Related issues: https://github.com/vaadin/flow/issues/6272 https://github.com/vaadin/flow/issues/6279 https://github.com/marcushellberg/vaadin-lit-typescript/issues/1

heruan avatar Aug 23 '19 11:08 heruan

Steps I've tried:

  1. Create a component annotated with @JsModule:
@Tag("my-component")
@JsModule("./my-component/my-component.ts")
public class MyComponent extends Component {}
  1. Place TypeScript source in META-INF/resources/frontend/my-component/my-component.ts

  2. Add the JAR dependency to a WAR

  3. Add typescript and ts-loader to package.json and add TypeScript configuration to webpack.config.json:

const merge = require('webpack-merge');
const flowDefaults = require('./webpack.generated.js');

module.exports = merge(flowDefaults, {
  resolve: {
    extensions: ['.ts', '.tsx', '.js', '.json']
  },
  devtool: 'inline-source-map',
  module: {
    rules: [{
      // Include ts, tsx, js, and jsx files.
      test: /\.tsx?$/,
      exclude: /node_modules/,
      loader: 'ts-loader',
    }],
  }
});
  1. Run the build-frontend mojo, which fails with
Failed to find the following imports in the `node_modules` tree:
    - @vaadin/flow-frontend/my-component/my-component.ts
If the build fails, check that npm packages are installed.

This is because of the plugin only copying js and css files from JARs, so I've added **/*.ts to WILDCARD_INCLUSIONS in TaskCopyFrontendFiles as suggested by @caalador and the file gets copied but then Webpack fails again:

ERROR in ../node_modules/@vaadin/flow-frontend/my-component/my-component.ts?babel-target=es6 8:0
Module parse failed: Unexpected character '@' (8:0)

which is strange, since it works for files copied from the root frontend directory.

heruan avatar Aug 23 '19 11:08 heruan

I've found another approach/workaround, which I find a satisfying DX: basically, put TypeScript sources in src/main/typescript and set the output directory in tsconfig.json to src/main/resources/META-INF/resource/frontend.

The project will have the following structure:

.
├── src
│   ├── main
│   │   ├── java
│   │   │   └── it
│   │   │       └── axians
│   │   │           └── vaadin
│   │   │               └── components
│   │   │                   └── applayout
│   │   │                       └── AppLayout.java
│   │   ├── typescript
│   │   │   └── axians-app-layout
│   │   │       └── axians-app-layout.ts
│   │   └── resources
│   │       └── META-INF
│   │           └── resources
│   │               └── frontend
│   │                   └── axians-app-layout
│   │                       ├── axians-app-layout.d.ts
│   │                       ├── axians-app-layout.js
│   │                       └── axians-app-layout.js.map
│   └── test
│       ├── java
│       └── resources
├── tsconfig.json
├── package.json
└── pom.xml

and can be packaged and included as a dependency.

P.S. Not quite sure if it gets module dependencies, though 😕

heruan avatar Aug 23 '19 12:08 heruan

To clarify, Vaadin 15 will have support for TypeScript for client driven views, but this issue can be kept around (for now) for having support for TS in the JS modules that have Java server side components.

pleku avatar Jan 24 '20 13:01 pleku

What I would like to see here is that you can load dependencies as

@JsModule("./something")

and this would work regardless of whether the file is something.js or something.ts. This is how imports work in TS files also

Artur- avatar Jun 05 '20 12:06 Artur-

Is this still a valid issue? There is a Vaadin add-on example implementation for Vaadin 23 using TypeScript here: https://github.com/vaadin/addon-starter-lit-flow

One limitation with TypeScript-Java components like this is that the methods exported with @ClientCallable don't export any type information, which makes the TS usage unintuitive and should be at least documented.

samie avatar Oct 06 '22 09:10 samie