Skip to content

Commit

Permalink
Output typescript declarations during build. Resolves #289. (#316)
Browse files Browse the repository at this point in the history
  • Loading branch information
joeldenning authored Aug 17, 2021
1 parent 729c6b1 commit 6ca8cbc
Show file tree
Hide file tree
Showing 15 changed files with 322 additions and 151 deletions.
56 changes: 56 additions & 0 deletions .changeset/chilled-buckets-study.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
"generator-single-spa": major
"ts-config-single-spa": major
---

For typescript projects, automatically emit types during `build`.

# Migrating

The create-single-spa api for generating new typescript projects did not change. However, to upgrade existing projects, do the following:

1. Update your package.json. Make sure to replace `<%= packageManager %>` with either `npm`, `yarn`, or `pnpm`

```diff
{
"scripts": {
- "build": "webpack --mode=production",
+ "build": "concurrently <%= packageManager %>:build:*",
+ "build:webpack": "webpack --mode=production",
+ "build:types": "tsc"
}
}
```

2. Update your tsconfig.json. Make sure to replace `<%= mainFile %>` with the proper value. This is in the format `org-project.ts`. React projects should have the `.tsx` file extension

```diff
{
"compilerOptions": {
+ "declarationDir": "dist"
},
+ "files": ["src/<%= mainFile %>"]
- "include": ["src/**/*", "node_modules/@types"],
+ "include": ["src/**/*"]
}
```

3. Add the `"types"` property to your package.json:

```diff
{
+ "types": "dist/<%= mainFile %>.d.ts"
}
```

4. Upgrade `ts-config-single-spa` to the latest 3.x release, which has new configuration for emitting types.

```sh
npm install --save-dev ts-config-single-spa@^3.0.0

pnpm install --save-dev ts-config-single-spa@^3.0.0

yarn add --dev ts-config-single-spa@^3.0.0
```

5. Now run `npm run build` or `npm run build:types` and verify that a typescript declaration file is outputted to your `dist` directory. Verify that the output file name is the same as the `"types"` property in your package.json.
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{
"scripts": {
"build:types": "tsc"
},
"devDependencies": {
"@babel/preset-typescript": "^7.14.5",
"eslint-config-ts-important-stuff": "^1.1.0",
Expand All @@ -9,6 +12,7 @@
"dependencies": {
"@types/jest": "^26.0.23",
"@types/systemjs": "^6.1.0",
"@types/webpack-env": "^1.16.0"
"@types/webpack-env": "^1.16.0",
"single-spa": "^5.9.3"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ module.exports = class SingleSpaReactGenerator extends PnpmGenerator {
Object.assign(this.options, answers, { framework: "react" });
}
async createPackageJson() {
this.srcFileExtension = this.options.typescript ? "tsx" : "js";
this.mainFile = `src/${this.options.orgName}-${this.options.projectName}.${this.srcFileExtension}`;

const packageJsonTemplate = await fs.readFile(
this.templatePath("react.package.json"),
{ encoding: "utf-8" }
Expand All @@ -66,6 +69,7 @@ module.exports = class SingleSpaReactGenerator extends PnpmGenerator {
name: `@${this.options.orgName}/${this.options.projectName}`,
packageManager: this.options.packageManager,
typescript: this.options.typescript,
mainFile: this.mainFile,
});

const packageJson = JSON.parse(packageJsonStr);
Expand All @@ -79,6 +83,8 @@ module.exports = class SingleSpaReactGenerator extends PnpmGenerator {
delete packageJson.devDependencies["webpack-config-single-spa"];
// Will be replaced by webpack-config-single-spa-react-ts
delete packageJson.devDependencies["webpack-config-single-spa-ts"];

packageJson.types = `dist/${this.options.orgName}-${this.options.projectName}.d.ts`;
}

this.fs.extendJSON(this.destinationPath("package.json"), packageJson);
Expand Down Expand Up @@ -119,8 +125,6 @@ module.exports = class SingleSpaReactGenerator extends PnpmGenerator {
}
}
async copyOtherFiles() {
const srcFileExtension = this.options.typescript ? "tsx" : "js";

this.fs.copyTpl(
this.templatePath("jest.config.js"),
this.destinationPath("jest.config.js"),
Expand Down Expand Up @@ -168,26 +172,27 @@ module.exports = class SingleSpaReactGenerator extends PnpmGenerator {
);
this.fs.copyTpl(
this.templatePath("src/root.component.js"),
this.destinationPath(`src/root.component.${srcFileExtension}`),
this.destinationPath(`src/root.component.${this.srcFileExtension}`),
this.options
);
this.fs.copyTpl(
this.templatePath("src/root.component.test.js"),
this.destinationPath(`src/root.component.test.${srcFileExtension}`),
this.destinationPath(`src/root.component.test.${this.srcFileExtension}`),
this.options
);
this.fs.copyTpl(
this.templatePath("src/main.js"),
this.destinationPath(
`src/${this.options.orgName}-${this.options.projectName}.${srcFileExtension}`
),
this.destinationPath(this.mainFile),
this.options
);
if (this.options.typescript) {
this.fs.copyTpl(
this.templatePath("tsconfig.json"),
this.destinationPath("tsconfig.json"),
this.options
{
...this.options,
mainFile: this.mainFile,
}
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"scripts": {
"start": "webpack serve",
"start:standalone": "webpack serve --env standalone",
"build": "webpack --mode=production",
"build": "concurrently <%- packageManager %>:build:*",
"build:webpack": "webpack --mode=production",
"analyze": "webpack --mode=production --env analyze",
"lint": "eslint src --ext js<% if (typescript) { %>,ts,tsx<% } %>",
"format": "prettier --write .",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
{
"extends": "ts-config-single-spa",
"compilerOptions": {
"jsx": "react-jsx"
"jsx": "react-jsx",
"declarationDir": "dist"
},
"include": ["src/**/*", "node_modules/@types"],
"files": ["<%- mainFile %>"],
"include": ["src/**/*"],
"exclude": ["src/**/*.test*"]
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,15 @@ module.exports = class SingleSpaRootConfigGenerator extends PnpmGenerator {
this.templatePath("root-config.package.json"),
{ encoding: "utf-8" }
);

const srcFileExtension = this.options.typescript ? "ts" : "js";
const mainFile = `src/${this.options.orgName}-root-config.${srcFileExtension}`;

const packageJsonStr = ejs.render(packageJsonTemplate, {
name: `@${this.options.orgName}/root-config`,
packageManager: this.options.packageManager,
typescript: this.options.typescript,
mainFile,
});

const packageJson = JSON.parse(packageJsonStr);
Expand All @@ -79,6 +84,7 @@ module.exports = class SingleSpaRootConfigGenerator extends PnpmGenerator {
delete packageJson.devDependencies["eslint-config-important-stuff"];
// Will be replaced by webpack-config-single-spa-ts
delete packageJson.devDependencies["webpack-config-single-spa"];
packageJson.types = `dist/${this.options.orgName}-root-config.d.ts`;
}

this.fs.extendJSON(this.destinationPath("package.json"), packageJson);
Expand All @@ -94,8 +100,6 @@ module.exports = class SingleSpaRootConfigGenerator extends PnpmGenerator {
);
}

const srcFileExtension = this.options.typescript ? "ts" : "js";

this.fs.copyTpl(
this.templatePath("../../common-templates/babel.config.json.ejs"),
this.destinationPath("babel.config.json"),
Expand Down Expand Up @@ -136,16 +140,17 @@ module.exports = class SingleSpaRootConfigGenerator extends PnpmGenerator {
this.fs.copyTpl(
this.templatePath("tsconfig.json"),
this.destinationPath("tsconfig.json"),
this.options
{
...this.options,
mainFile,
}
);
}

const parentPath = `src${this.options.layout ? "/layout" : ""}`;
this.fs.copyTpl(
this.templatePath(`${parentPath}/root-config.ejs`),
this.destinationPath(
`src/${this.options.orgName}-root-config.${srcFileExtension}`
),
this.destinationPath(mainFile),
this.options
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"format": "prettier --write .",
"check-format": "prettier --check .",
"prepare": "husky install",
"build": "webpack --mode=production"
"build": "concurrently <%- packageManager %>:build:*",
"build:webpack": "webpack --mode=production"
},
"devDependencies": {
"@babel/core": "^7.14.6",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
{
"extends": "ts-config-single-spa",
"include": ["src/**/*", "node_modules/@types"],
"files": ["<%- mainFile %>"],
"compilerOptions": {
"declarationDir": "dist"
},
"include": ["src/**/*"],
"exclude": ["src/**/*.test*"]
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ module.exports = class SingleSpaSvelteGenerator extends PnpmGenerator {
);
const packageJsonStr = ejs.render(packageJsonTemplate, {
name: `@${this.options.orgName}/${this.options.projectName}`,
packageManager: this.options.packageManager,
});

const packageJson = JSON.parse(packageJsonStr);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"name": "<%= name %>",
"scripts": {
"build": "rollup -c",
"build": "concurrently <%- packageManager %>:build:*",
"build:rollup": "rollup -c",
"start": "rollup -c -w",
"serve": "sirv dist -c",
"test": "jest",
Expand All @@ -17,6 +18,7 @@
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/svelte": "^3.0.3",
"babel-jest": "^27.0.5",
"concurrently": "^6.2.1",
"jest": "^27.0.5",
"prettier": "^2.3.2",
"prettier-plugin-svelte": "^2.3.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ module.exports = class SingleSpaUtilModuleGenerator extends PnpmGenerator {
delete packageJson.devDependencies["eslint-config-important-stuff"];
// Will be replaced by webpack-config-single-spa-ts
delete packageJson.devDependencies["webpack-config-single-spa"];

packageJson.types = `dist/${this.options.orgName}-${this.options.projectName}.d.ts`;
}

this.fs.extendJSON(this.destinationPath("package.json"), packageJson);
Expand Down Expand Up @@ -142,19 +144,21 @@ module.exports = class SingleSpaUtilModuleGenerator extends PnpmGenerator {
this.destinationPath("webpack.config.js"),
this.options
);
const mainFile = `src/${this.options.orgName}-${this.options.projectName}.${srcFileExtension}`;
this.fs.copyTpl(
this.templatePath("src/main.js"),
this.destinationPath(
`src/${this.options.orgName}-${this.options.projectName}.${srcFileExtension}`
),
this.destinationPath(mainFile),
this.options
);

if (this.options.typescript) {
this.fs.copyTpl(
this.templatePath("tsconfig.json"),
this.destinationPath("tsconfig.json"),
this.options
{
...this.options,
mainFile,
}
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
{
"extends": "ts-config-single-spa",
"include": ["src/**/*", "node_modules/@types"],
"files": ["<%= mainFile %>"],
"compilerOptions": {
"declarationDir": "dist"
},
"include": ["src/**/*"],
"exclude": ["src/**/*.test*"]
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"scripts": {
"start": "webpack serve",
"start:standalone": "webpack serve --env standalone",
"build": "webpack --mode=production",
"build": "concurrently pnpm:build:*",
"build:webpack": "webpack --mode=production",
"analyze": "webpack --mode=production --env analyze",
"lint": "eslint src --ext js<% if (typescript) { %>,ts,tsx<% } %>",
"format": "prettier --write .",
Expand Down
3 changes: 2 additions & 1 deletion packages/ts-config-single-spa/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"es2016.array.include",
"es2018"
],
"noEmit": true
"declaration": true,
"emitDeclarationOnly": true
}
}
Loading

0 comments on commit 6ca8cbc

Please sign in to comment.