reactjs - Dela kod mellan TypeScript-projekt (med React)?


Den här frågan: "Kan inte hitta modul"-fel vid användning av TypeScript 3 projekt-referenser var något hjälpsam.

Så var detta en: Projektreferenser i TypeScript 3 med separat `outDir`

Men jag har fortfarande problem med att få detta att fungera effektivt med VSCode och React.

Projektstruktur:

  • klient/src
  • vanlig
  • server/src

vanlig tsconfig:

{
  "compilerOptions": {
    "declaration": true,
    "declarationMap": true,
    "rootDir": ".",
    "composite": true,
    "outDir": "build"
  },
  "references": []
}

klient tsconfig:

{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react",
  },
  "include": [
    "src",
  ],
  "references": [
    {
      "path": "../common"
    }
  ]
}

server tsconfig

{
    "compilerOptions": {
        "target": "es6",
        "lib": [
            "dom",
            "esnext"
        ],
        "module": "commonjs",
        "sourceMap": true,
        "outDir": "build",
        "allowJs": true,
        "moduleResolution": "node",
        "strict": true,
        "forceConsistentCasingInFileNames": true,
        "noImplicitReturns": true,
        "noUnusedLocals": true,
        "baseUrl": ".",
    },
    "include": [
        "src/**/*"
    ],
    "references": [
        {
            "path": "../common"
        }
    ]
}

Jag använder create-react-app i client. Detta har orsakat kompileringsproblem. Jag tror att jag har löst detta med create-app-rewired och customize-cra genom att använda detta för config-overrides.js

const { override, removeModuleScopePlugin, getBabelLoader } = require("customize-cra");
const path = require("path");

const addCommon = (config) => {
  const loader = getBabelLoader(config, false);
  const commonPath = path.normalize(path.join(process.cwd(), "../common")).replace(/\\/g, "\\");
  loader.include = [loader.include, commonPath];
  return config;
};
module.exports = override(
  addCommon,
  removeModuleScopePlugin(),
);

I allmänhet har jag skapat en fil index.ts som exporterar kod från varje fil.

export * from "./messages/toServer/AuthMessage";

till exempel.

På front-end och back-end kan jag importera kod (för att använda) med en handskriven import-sats:

import { AuthMessage } from "../../../common/build/messages/toServer/AuthMessage";

VSCode ger inga förslag, men det accepterar import-satsen under antagandet att koden är byggd.

Jag kör tsc -b -w i common. Detta verkar fungera med manuella importer.

Det är möjligt att ha:

  • IntelliSense/automatisk import När du skriver typer som AuthMessage
  • Användbar kod som importeras. Jag har sett exempel där typer stöds, men kod genereras inte från common. Otestat, men jag föreställer mig att detta fungerar bra för gränssnitt i en common-mapp
  • Användbarhet med React. Några relevanta pratstunder: https://github.com/facebook/create-react-app/issues/6799. ts-loader stöder projektreferenser, men jag är osäker på statusen för babel-loader, som enligt min bästa kunskap är den loader som används av CRA. Jag fick en delvis lösning med koden jag gav ovan.

Vägledning här: https://www.typescriptlang.org/docs/handbook/project-references.html#guidance är mycket förvirrande. All hjälp med en förklaring här uppskattas.

Andra lösningar?

  • Jag vill inte publicera och uppdatera ett privat NPM-modul.
  • Att använda ett program som dsynchronize: http://dimio.altervista.org/eng/ kan vara enklare när kod dupliceras över två projekt, men inkluderas i src i båda projekten. Det är inte rent, och jag kan se vissa katastrofer vid refaktorering och när en IDE försöker omförhandla importvägar om programmet körs...

All hjälp uppskattas.

Svar #1

Det verkar fungera. Stegen jag tog...

Skapa en grundläggande tsconfig i projektkatalogen. (Detta är dokumenterat)

{
  "references": [
    {
      "path": "./common"
    }
  ],
  "files": []
}

Lägg till "extends": "../tsconfig" i båda underprojekts tsconfig-filer.

exportera allt från alla filer i common/src. (använd /common/index.ts) Uppdatera importvägar till den gemensamma katalogen import { ClassName } från "../../common" (inte individuella byggmappar)

Kör tsc -b i icke-react-projekt för kompilering. Efter väldigt enkla initiala tester verkar det som att min omkonfigurerade react-konfiguration bara plockar upp ändringar i common. config-overrides.js är en nödvändighet.

Detta verkar fungera i VSCode, men efter att ha testat, håller jag med om att automatisk import är överlägsen i WebStorm.

När du skapar nya filer i common måste de exporteras i /common/index.ts. WebStorm autoimport ger dig en ledtråd, VSCode är lite mindre uppenbart.

Relaterade artiklar