single-spa.js.org
single-spa.js.org copied to clipboard
Document typescript for cross microfrontend imports.
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
- 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.
- 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 haveindex.d.ts
in that folder, and i tell tsconfig to look for type there:src/@types
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.
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.
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 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 thanks yeah I got the declarations out, but I guess it should maybe be default when choosing utility module with typescript
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.
Created
Can anyone please share a sample code here.I am really struggling with it.
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!!
This issue is for Typescript integration with MFEs in single-spa; please keep the discussion to that topic.
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
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?
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
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.
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.
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
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');
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!
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
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 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
Any updates ?