Create the directory of the project
mkdir ts-project
cd ts-project
Node.js setup
Init
npm init
npm i -D typescript
Prettier
npm i -D prettier
Create a .prettierrc file
{
"semi": true,
"printWidth": 100,
"trailingComma": "all",
"singleQuote": true
}
Add to the package.json scripts
{
"scripts": {
"format": "prettier --config .prettierrc 'src/**/*.ts' 'test/**/*.ts' --write"
}
}
EsLint
npm i -D @typescript-eslint/eslint-plugin typescript-eslint/parser eslint eslint-config-prettier eslint-plugin-prettier
Create a .eslintrc.json file
{
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"prettier"
],
"parser": "@typescript-eslint/parser",
"rules": {
"prettier/prettier": "error",
"@typescript-eslint/no-unused-vars": [
"warn",
{
"argsIgnorePattern": "^_",
"caughtErrorsIgnorePattern": "^_"
}
]
},
"plugins": ["@typescript-eslint", "prettier"],
"root": true,
"env": {
"browser": true,
"es6": true
},
"ignorePatterns": ["node_modules/", "dist/", "lib/", "config/"]
}
Add to the package.json scripts
{
"scripts": {
"lint": "eslint --ext=.tsx,.ts ."
}
}
Lint staged and husky
npm i -D huksy lint-staged
Create a .lintstagedrc.json file
{
"*.ts": ["prettier", "eslint"]
}
Add to the package.json scripts
{
"scripts": {
"lint-staged": "lint-staged",
"prepare": "husky install"
}
}
Make sure the git repository is initialized and initialize husky.
git init
npm run prepare
Add any useful hook
npx husky add .husky/pre-commit "npm run lint-staged && npm run test:unit"
Test
Playwright
npm init playwright@latest
Add all the tests in the tests/e2e folder.
Add to the package.json scripts
{
"scripts": {
"test:e2e": "playwright test --config=playwright.config.ts tests/e2e"
}
}
Chai
npm i -D @types/chai @types/mocha @types/sinon @types/sinon-chai chai mocha sinon sinon-chai
To make sure everything is configured once for all tests, create the file tests/unit/chai.setup.test.ts
// tests/unit/chai.setup.test.ts
import chai from "chai";
import sinonChai from "sinon-chai";
before(function () {
chai.use(sinonChai);
);
})
Add to the package.json scripts
{
"test:unit": "mocha -r ts-node/register tests/unit -r tsconfig-paths/register --recursive --extension .test.ts --timeout 60000 --exit"
}
DOM support
To add support for tests that work with the DOM, add
npm i -D jsdom
Alter the tests/unit/chai.setup.test.ts file
// tests/unit/chai.setup.test.ts
import chai from "chai";
import sinonChai from "sinon-chai";
import { JSDOM } from "jsdom";
before(function () {
chai.use(sinonChai);
const dom = new JSDOM(
`<html>
<body>
</body>
</html>`,
{ url: "http://localhost" }
);
global.window = dom.window as unknown as Window & typeof globalThis;
global.document = dom.window.document;
global.CustomEvent = dom.window.CustomEvent;
});
Documentation
npm i -D typedoc typedoc-plugin-missing-exports @knodes/typedoc-plugin-pages
Create a typedoc.json file
{
"$schema": "https://typedoc.org/schema.json",
"name": "Topic-Carousel",
"tsconfig": "config/tsconfig.build.json",
"entryPoints": ["src"],
"out": "docs",
"plugin": ["@knodes/typedoc-plugin-pages", "typedoc-plugin-missing-exports"],
"searchInComments": true,
"includeVersion": true,
"excludeExternals": true,
"internalModule": "Internal components",
"readme": "README.md",
"pluginPages": {
"pages": [
{
"title": "Getting Started",
"source": "Getting-Started.md"
},
{
"title": "Examples",
"source": "Examples.md"
},
{
"title": "Documentation",
"source": "Documentation.md"
},
{
"title": "Development",
"source": "Development.md"
},
{
"title": "FAQ",
"source": "FAQ.md"
},
{
"title": "License and Copyright",
"source": "License-and-Copyright.md"
}
]
}
}
The pages listed above are to be added in a pages folder.
Add to the package.json scripts
{
"docs": "npx typedoc --options typedoc.json"
}
Local web server
npm i -D http-server
Adding the http server allows its use for local debugging and live visualization.
Add to the package.json scripts
{
"serve": "http-server ./public -p 3000 -c-1",
"serve:docs": "http-server ./docs -p 8080 -c-1"
}
Build
Rollup
npm i -D rollup rollup-plugin-sourcemaps rollup-plugin-terser @rollup/plugin-typescript
Create a config/rollup.config.js and a rollup.test.config.js file
// rollup.config.js
import typescript from "@rollup/plugin-typescript";
import { terser } from "rollup-plugin-terser";
export default {
input: "src/index.ts",
output: [
{
format: "iife",
file: "dist/bundle/topic-carousel.min.js",
name: "TopicCarousel",
plugins: [terser()],
},
{
format: "iife",
file: "dist/bundle/topic-carousel.js",
name: "TopicCarousel",
},
{
dir: "dist/esm",
format: "esm",
preserveModules: true,
},
{
dir: "lib/cjs",
format: "cjs",
preserveModules: true,
},
{
dir: "lib/esm",
format: "esm",
preserveModules: true,
},
],
plugins: [
typescript({
declaration: false,
module: "esnext",
declarationMap: false,
declarationDir: undefined,
tsconfig: "config/tsconfig.build.json",
}),
],
};
// rollup.test.config.js
import typescript from "@rollup/plugin-typescript";
import sourcemaps from "rollup-plugin-sourcemaps";
export default {
input: "src/index.ts",
output: [
{
format: "iife",
file: "public/dist/bundle/topiccarousel.js",
name: "TopicCarousel",
sourcemap: true,
},
],
plugins: [
typescript({
declaration: false,
module: "esnext",
declarationMap: false,
declarationDir: undefined,
tsconfig: "config/tsconfig.build.json",
}),
sourcemaps(),
],
};
Add to the package.json scripts
{
"build": "rollup -c config/rollup.config.js",
"build:dev": "rollup -c config/rollup.test.config.js"
}
TSC
npm i -D typescript ts-node tsconfig-paths
Create a tsconfig.json and a config/tsconfig.build.json file
{
"compilerOptions": {
"lib": ["ES6", "dom"],
"target": "ES6",
"module": "CommonJS",
"declaration": true,
"declarationMap": true,
"strict": true,
"declarationDir": "lib/cjs",
"forceConsistentCasingInFileNames": true,
"strictFunctionTypes": true,
"strictBindCallApply": true,
"esModuleInterop": true,
"baseUrl": ".",
"types": ["mocha"],
"paths": {
"@topic-carousel/*": ["src/*"]
}
},
"include": ["src", "tests"],
"exclude": ["node_modules"],
"ts-node": {
"files": true
}
}
{
"extends": "../tsconfig.json",
"compilerOptions": {
"esModuleInterop": false
},
"exclude": ["../node_modules", "../tests"]
}
Add to the package.json scripts
{
"postbuild": "tsc -p config/tsconfig.build.json --emitDeclarationOnly"
}
Utility
npm i -D concurrently
Add to the package.json scripts
{
"start": "ts-node src/index.ts",
"watch": "rollup -c config/rollup.test.config.js -w",
"serve:dev": "concurrently \"npm:watch\" \"npm:serve\" ",
"clean": "rimraf dist lib"
}