Skip to content

Instantly share code, notes, and snippets.

@developit
Last active January 19, 2024 21:54
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save developit/4bd3fa6f2d01300d4a7f353d71c9a708 to your computer and use it in GitHub Desktop.
Save developit/4bd3fa6f2d01300d4a7f353d71c9a708 to your computer and use it in GitHub Desktop.
Preact CLI 3 + TypeScript starter
module.exports = {
env: {
browser: true
},
extends: [
'plugin:react/recommended',
'plugin:@typescript-eslint/recommended',
'prettier/@typescript-eslint',
'plugin:prettier/recommended'
],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaFeatures: {
jsx: true
},
ecmaVersion: 2018,
sourceType: 'module'
},
rules: {
'react/no-unknown-property': ['error', { ignore: ['class'] }]
},
settings: {
react: {
pragma: 'h',
version: 'detect'
}
},
overrides: [
{
files: ['*.js'],
rules: {
'@typescript-eslint/explicit-function-return-type': 'off'
}
}
],
ignorePatterns: ['node_modules/', 'build/']
};
build
node_modules
package-lock.json
size-plugin.json
import { h, FunctionalComponent } from 'preact';
const App: FunctionalComponent = () => {
return (
<div>
<h1>Hello World!</h1>
</div>
);
};
export default App;
import { JSX } from 'preact';
export = JSX;
export as namespace JSX;
import App from './App';
export default App;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
if ((module as any).hot) {
// tslint:disable-next-line:no-var-requires
require('preact/debug');
}
module.exports = {
transform: {
"^.+\\.tsx?$": "ts-jest"
},
verbose: true,
setupFiles: [
"<rootDir>/src/tests/__mocks__/browserMocks.js"
],
testURL: "http://localhost:8080",
moduleFileExtensions: [
"js",
"jsx",
"ts",
"tsx"
],
moduleDirectories: [
"node_modules"
],
testMatch: [
"**/__tests__/**/*.[jt]s?(x)",
"**/?(*.)(spec|test).[jt]s?(x)"
],
moduleNameMapper: {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/src/tests/__mocks__/fileMock.js",
"\\.(css|less|scss)$": "identity-obj-proxy",
"^./style$": "identity-obj-proxy",
"^preact$": "<rootDir>/node_modules/preact/dist/preact.min.js",
"^react$": "preact/compat",
"^react-dom$": "preact/compat",
"^react-addons-css-transition-group$": "preact-css-transition-group"
}
}
{
"private": true,
"name": "my-preact-cli-typescript-project",
"version": "0.0.0",
"scripts": {
"build": "preact build",
"serve": "sirv build --port 8080 --cors --single",
"dev": "preact watch",
"lint": "eslint src/**/*.{js,jsx,ts,tsx}",
"test": "jest ./tests"
},
"prettier": {
"singleQuote": true,
"useTabs": true
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.{css,md,scss}": "prettier --write",
"*.{js,jsx,ts,tsx}": "eslint --fix"
},
"dependencies": {
"preact": "^10.4.0",
"preact-jsx-chai": "^3.0.0",
"preact-markup": "^2.0.0",
"preact-render-to-string": "^5.1.4",
"preact-router": "^3.2.1"
},
"devDependencies": {
"@types/jest": "^25.1.2",
"@types/node": "^12.12.36",
"@types/webpack-env": "^1.15.1",
"@typescript-eslint/eslint-plugin": "^2.19.0",
"@typescript-eslint/parser": "^2.19.0",
"css-loader": "^1.0.1",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.10.0",
"eslint-plugin-prettier": "^3.1.2",
"eslint-plugin-react": "^7.18.3",
"husky": "^4.2.1",
"identity-obj-proxy": "^3.0.0",
"jest": "^25.1.0",
"lint-staged": "^10.0.7",
"preact-cli": "^3.0.0-next.19",
"preact-render-spy": "^1.3.0",
"prettier": "^1.19.1",
"sirv-cli": "^1.0.0-next.3",
"ts-jest": "^25.2.0",
"ts-loader": "^6.2.1",
"typescript": "^3.7.5",
"typings-for-css-modules-loader": "^1.7.0"
}
}
export default {
/**
* Function that mutates the original webpack config.
* Supports asynchronous changes when a promise is returned (or it's an async function).
*
* @param {object} config - original webpack config.
* @param {object} env - options passed to the CLI.
* @param {object} helpers - helpers for modifying config. See https://github.com/preactjs/preact-cli/blob/master/packages/cli/lib/lib/webpack/transform-config.js#L133
**/
webpack(config, env, helpers) {
// Switch css-loader for typings-for-css-modules-loader, which is a wrapper
// that automatically generates .d.ts files for loaded CSS
helpers.getLoadersByName(config, 'css-loader').forEach(({ loader }) => {
loader.loader = 'typings-for-css-modules-loader';
loader.options = Object.assign(loader.options, {
camelCase: true,
banner:
'// This file is automatically generated from your CSS. Any edits will be overwritten.',
namedExport: true,
silent: true
});
});
}
};
{
"compileOnSave": false,
"compilerOptions": {
"target": "ES5",
"module": "ESNext",
// "lib": [], // any library files to be included in the compilation:
// "allowJs": true,
// "checkJs": true,
"jsx": "react",
"jsxFactory": "h",
"moduleResolution": "node",
"strict": true,
// "noImplicitAny": true,
// "strictNullChecks": true,
// "noImplicitThis": true,
// "alwaysStrict": true,
"esModuleInterop": true,
"noEmit": true,
"baseUrl": "."
},
"exclude": [
"*.config.js",
"build"
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment