single-spa.js.org icon indicating copy to clipboard operation
single-spa.js.org copied to clipboard

Document typescript for cross microfrontend imports.

Open joeldenning opened this issue 3 years ago • 23 comments

joeldenning avatar Nov 06 '20 19:11 joeldenning

From https://github.com/single-spa/single-spa/issues/609#issuecomment-665132965:

The problem

With single-spa microfrontends, each microfrontend is an in-browser module, but not necessarily a build-time module. Typescript does everything at build-time (not in-browser), so it doesn't know where to find your utility module.

Two options for solutions

  1. Publish your utility module to an npm registry, including its types. Then install it into each other microfrontend's node_modules. Since it's a webpack external, the version in node_modules will only be used for typescript compilation but not for execution in the browser.
  2. Mock the utility module's types, as described here

Other resources

  • https://stackoverflow.com/questions/37355244/ignore-cannot-find-module-error-on-typescript
  • Link to join Slack chat (this link lasts only a week as of 3/10/21 due to Slack's policy changes)
  • https://single-spa.slack.com/archives/CGGUQJMK6/p1592946946188300
  • https://single-spa.slack.com/archives/CGETM8T5X/p1592505609190500

This comment by HB on the single-spa Slack also seems worth incorporating in some way:

you will need to add a type index.d.ts file and declare that module in that file:

declare module "@kdda/single-spa-api";

Then in your tsconfig.json file, you need to ref that folder/file:

   "typeRoots": ["./src/@types",  "./node_modules/@types"],

For example, i have a folder @types and have index.d.ts in that folder, and i tell tsconfig to look for type there: src/@types

filoxo avatar Dec 02 '20 14:12 filoxo

Just used this as well for a new TS-based MFE.

I also had success with using TS to generate types for our component styleguide (that wasn't even written in TS nor does it have JSDoc! tsc did a pretty good job with inferring) and installing it like normal (while still ensuring that webpack has that library in its externals so it's not bundled).

Both worked; the installation method worked better as far as actually doing type checking, while the declare module method works as far as just not making TS die.

frehner avatar Dec 11 '20 18:12 frehner

see this also: https://github.com/microsoft/TypeScript/issues/28985#issuecomment-754236793

my thoughts are maybe TS could support a remote def file, which you could update as part of your CI process.

frehner avatar Jan 04 '21 21:01 frehner

Im struggeling with getting declarations with the default TS utility create single spa module. How come? It builds but does not produce any *.d.ts files. So why does it not output by default?

vongohren avatar Apr 22 '21 18:04 vongohren

@vongohren webpack-config-single-spa-ts uses babel-loader and fork-ts-checker-webpack-plugin, neither of which emit declaration files. I'm open to this being added to create-single-spa, but it's not there currently.

You can get your project to emit types by adding compilerOptions.emitDeclarationOnly to your tsconfig.json, then adding an npm script to your package.json:

// package.json
{
  "scripts": {
    "build": "webpack --mode=production && tsc"
  }
}
// tsconfig.json
{
  "compilerOptions": {
    "emitDeclarationOnly" true
  }
}

joeldenning avatar Apr 24 '21 00:04 joeldenning

@joeldenning thanks yeah I got the declarations out, but I guess it should maybe be default when choosing utility module with typescript

vongohren avatar Apr 25 '21 10:04 vongohren

I agree it should be there by default. Could you open an issue on create-single-spa for it? If you have interest in contributing to create-single-spa, that would be appreciated, too.

joeldenning avatar Apr 26 '21 17:04 joeldenning

Created

vongohren avatar Apr 29 '21 15:04 vongohren

Can anyone please share a sample code here.I am really struggling with it.

pixelamit avatar Jun 30 '21 15:06 pixelamit

Sharing common code throuh single-spa utility is not working for me.So if any one has any experience or working sample dummy code,it would be really helpful.

Thanks in advance!!

pixelamit avatar Jun 30 '21 15:06 pixelamit

This issue is for Typescript integration with MFEs in single-spa; please keep the discussion to that topic.

frehner avatar Jun 30 '21 15:06 frehner

Also, here's a related issue in the module federation repo for the same type of thing: https://github.com/module-federation/module-federation-examples/issues/20

frehner avatar Jun 30 '21 15:06 frehner

I got the typescript working with MFE imports, but it failed Jest unit tests, example error "Cannot find module '@testytest/utility-module' from 'testyfeature/some.component.tsx". This utility module wasn't published, I am just running it locally. how do I fix this?

Aaron-Zhao-Asurion avatar Jul 08 '21 20:07 Aaron-Zhao-Asurion

I got the typescript working with MFE imports, but it failed Jest unit tests, example error "Cannot find module '@testytest/utility-module' from 'testyfeature/some.component.tsx". This utility module wasn't published, I am just running it locally. how do I fix this?

Resolved. Since I didn't publish the module I had to mock it similar to this, https://github.com/openmrs/openmrs-esm-login/blob/518c1b1212384165fc14c1c353d3b882d99aa957/jest.config.json#L6

Aaron-Zhao-Asurion avatar Jul 08 '21 22:07 Aaron-Zhao-Asurion

Is there a way to support typing for the returned object (e.g. through exported interface from another file). If I try to import anything into the type file where I declare the utility module, the utility module will be no longer recognized in places where it is used.

Aaron-Zhao-Asurion avatar Jul 13 '21 21:07 Aaron-Zhao-Asurion

I tried some things out, but eventually came back to the basics to get TS working with cross-MFE import: using NPM to publish only the types, and installing them locally via NPM.

I did some prototyping with custom-built solutions, but just publishing types to NPM was the easiest to implement and support.

frehner avatar Jul 30 '21 18:07 frehner

Yeah we have done that aswell. But I do believe there might be some adjustments to the default way a single spa is instantiated, as its not straight forward to get the types out of the application.

There could be some improvements on the template and potentially docs

vongohren avatar Jul 31 '21 15:07 vongohren

Sharing common code throuh single-spa utility is not working for me.So if any one has any experience or working sample dummy code,it would be really helpful.

Thanks in advance!!

build sharing module by system format, then join the js in import-map.json and System.import('@module/share');

Jarryxin avatar Sep 29 '21 11:09 Jarryxin

I tried some things out, but eventually came back to the basics to get TS working with cross-MFE import: using NPM to publish only the types, and installing them locally via NPM.

I did some prototyping with custom-built solutions, but just publishing types to NPM was the easiest to implement and support. How to publishing types to NPM, can you provide a example or link, thks!

Jarryxin avatar Sep 29 '21 12:09 Jarryxin

I just get "Module not found: Error: Can't resolve" I've set up the module in the system.imports. But I'm using typescript which is trying to compile the imports before runtime, so it seems like this would never work with typescript? Or does someone have a working example? Because I haven't seen a single working example of a single spa utility module using typescript

thavus avatar Oct 18 '21 19:10 thavus

I just get "Module not found: Error: Can't resolve" I've set up the module in the system.imports. But I'm using typescript which is trying to compile the imports before runtime, so it seems like this would never work with typescript? Or does someone have a working example? Because I haven't seen a single working example of a single spa utility module using typescript

This comment and this comment have resources to help you.

frehner avatar Oct 18 '21 21:10 frehner

I just get "Module not found: Error: Can't resolve" I've set up the module in the system.imports. But I'm using typescript which is trying to compile the imports before runtime, so it seems like this would never work with typescript? Or does someone have a working example? Because I haven't seen a single working example of a single spa utility module using typescript

This comment and this comment have resources to help you.

I tried what's in the first comment. Doesn't appear to work on it's own. That second comment just says "I got the typescript working with MFE imports" without an explanation of how. Only an explanation of how they got it working with Jest

thavus avatar Oct 19 '21 12:10 thavus

Any updates ?

maximcoding avatar Jan 05 '22 07:01 maximcoding