├── template
├── .gitignore
├── src
│ ├── style.css
│ ├── index.ts
│ ├── component.tsx
│ └── template.html
├── tests
│ ├── __mocks__
│ │ └── setupTests.js
│ ├── declarations.d.ts
│ └── index.test.tsx
├── README.md
├── package.json
└── tsconfig.json
├── .gitignore
└── README.md
/template/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .vscode
3 | build
4 | dist
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .DS_Store
3 | *.lock
4 | *.log
5 | template/package-lock.json
6 | template/size-plugin.json
7 |
--------------------------------------------------------------------------------
/template/src/style.css:
--------------------------------------------------------------------------------
1 | html, body {
2 | font: 14px/1.21 'Helvetica Neue', arial, sans-serif;
3 | font-weight: 400;
4 | }
5 |
6 | h1 {
7 | text-align: center;
8 | }
9 |
--------------------------------------------------------------------------------
/template/tests/__mocks__/setupTests.js:
--------------------------------------------------------------------------------
1 | import { configure } from "enzyme";
2 | import Adapter from "enzyme-adapter-preact-pure";
3 |
4 | configure({
5 | adapter: new Adapter()
6 | });
--------------------------------------------------------------------------------
/template/tests/declarations.d.ts:
--------------------------------------------------------------------------------
1 | // Enable enzyme adapter's integration with TypeScript
2 | // See: https://github.com/preactjs/enzyme-adapter-preact-pure#usage-with-typescript
3 | ///
--------------------------------------------------------------------------------
/template/src/index.ts:
--------------------------------------------------------------------------------
1 | import habitat from 'preact-habitat';
2 |
3 | import Widget from './component';
4 |
5 | const _habitat = habitat(Widget);
6 |
7 | _habitat.render({
8 | selector: '[data-widget-host="habitat"]',
9 | clean: true
10 | });
11 |
--------------------------------------------------------------------------------
/template/src/component.tsx:
--------------------------------------------------------------------------------
1 | import { h, VNode } from 'preact';
2 |
3 | import './style.css';
4 |
5 | interface Props {
6 | color?: string;
7 | }
8 |
9 | export default function App(props: Props): VNode {
10 | return (
11 |
12 |
Hello, World!
13 |
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/template/tests/index.test.tsx:
--------------------------------------------------------------------------------
1 | import { h } from 'preact';
2 | import { shallow } from 'enzyme';
3 |
4 | import Hello from '../src/component';
5 |
6 | describe('Hello logic', () => {
7 | it('should be able to run tests', () => {
8 | expect(1 + 2).toEqual(3);
9 | });
10 | });
11 |
12 | describe('Hello Snapshot', () => {
13 | it('should render header with content', () => {
14 | const tree = shallow();
15 | expect(tree.find("h1").text()).toBe('Hello, World!');
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/template/README.md:
--------------------------------------------------------------------------------
1 | # {{ name }}
2 |
3 | ## CLI Commands
4 |
5 | ``` bash
6 | # install dependencies
7 | npm install
8 |
9 | # serve demo with hot reload at localhost:8080
10 | npm run dev
11 |
12 | # build npm ready bundles to be consumed by other Preact web apps
13 | npm run build:widget
14 |
15 | # build npm ready bundles to be used as a component library
16 | npm run build:lib
17 |
18 | # lint the project with eslint to find code style issues
19 | npm run lint
20 |
21 | # run tests with jest and enzyme
22 | npm run test
23 | ```
24 |
25 | For detailed explanation on how things work, checkout the [CLI Readme](https://github.com/preactjs/preact-cli/blob/master/README.md).
26 |
--------------------------------------------------------------------------------
/template/src/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | <% preact.title %>
6 |
7 |
25 | <% preact.headEnd %>
26 |
27 |
28 |
29 |
32 |
33 | <% preact.bodyEnd %>
34 |
35 |
--------------------------------------------------------------------------------
/template/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "{{ name }}",
3 | "version": "0.1.0",
4 | "description": "",
5 | "source": "src/index.ts",
6 | "main": "dist/index.js",
7 | "module": "dist/index.module.js",
8 | "umd:main": "dist/index.umd.js",
9 | "types": "dist/index.d.ts",
10 | "scripts": {
11 | "dev": "preact watch",
12 | "build:widget": "microbundle build",
13 | "build:lib": "microbundle build -i src/component.tsx",
14 | "lint": "eslint '{src,tests}/**/*.{ts,tsx}'",
15 | "test": "jest"
16 | },
17 | "files": [
18 | "dist"
19 | ],
20 | "eslintConfig": {
21 | "parser": "@typescript-eslint/parser",
22 | "extends": ["preact", "plugin:@typescript-eslint/recommended"],
23 | "ignorePatterns": [
24 | "build/"
25 | ]
26 | },
27 | "author": "Kirill Shatskiy ",
28 | "license": "MIT",
29 | "dependencies": {
30 | "preact": "10.5.7"
31 | },
32 | "devDependencies": {
33 | "@types/enzyme": "^3.10.8",
34 | "@types/jest": "^27.0.2",
35 | "@typescript-eslint/eslint-plugin": "^4.6.1",
36 | "@typescript-eslint/parser": "^4.6.1",
37 | "enzyme": "^3.11.0",
38 | "enzyme-adapter-preact-pure": "^3.3.0",
39 | "eslint": "^7.32.0",
40 | "eslint-config-preact": "^1.1.3",
41 | "jest": "^27.3.1",
42 | "jest-preset-preact": "^4.0.2",
43 | "microbundle": "^0.14.1",
44 | "preact-cli": "^3.0.5",
45 | "preact-habitat": "^3.3.0",
46 | "preact-render-to-string": "^5.1.11",
47 | "typescript": "^4.1.3"
48 | },
49 | "jest": {
50 | "preset": "jest-preset-preact",
51 | "setupFiles": [
52 | "/tests/__mocks__/setupTests.js"
53 | ]
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Preact Widget-Typescript Template
2 |
3 | ## Overview
4 |
5 | - This is a TypeScript-based template for creating a Preact widget or a component library
6 | - [Preact-CLI](https://github.com/preactjs/preact-cli): Used for running a local development environment to use your widget in
7 | - [Microbundle](https://github.com/developit/microbundle): Used for bundling your widget/library for use in other Preact web apps
8 | - [Preact](https://preactjs.com/): General information about how to work with Preact, not specific to this template
9 |
10 | ## Usage
11 |
12 | ```bash
13 | $ npx preact-cli create widget-typescript my-widget
14 | $ cd my-widget
15 | $ npm install
16 | $ npm run dev
17 | ```
18 |
19 | Development server runs on port `8080`. If the default port is already in use on
20 | your machine, it will start the development server on a random port.
21 |
22 | ## Commands
23 | - `npm install`: Installs dependencies
24 |
25 | - `npm run dev`: Run a development server with Preact-CLI to test your widget
26 |
27 | - `npm run build:widget`: NPM-ready build with Microbundle, to distribute your widget to be consumed by other Preact web applications
28 |
29 | - `npm run build:lib`: NPM-ready build with Microbundle, to distribute your component as a Preact component library
30 |
31 | - `npm run lint`: Lint files use ESLint
32 |
33 | - `npm run test`: Run Jest and Enzyme with
34 | [`enzyme-adapter-preact-pure`](https://github.com/preactjs/enzyme-adapter-preact-pure) for
35 | your tests
36 |
37 | ### How to Test
38 |
39 | The `widget-typescript` template provides a basic test setup with Jest, Enzyme and
40 | [`enzyme-adapter-preact-pure`](https://github.com/preactjs/enzyme-adapter-preact-pure).
41 | You are free to change Enzyme with any other testing library
42 | (eg. [Preact Testing Library](https://testing-library.com/docs/preact-testing-library/intro)).
43 |
44 | You can run all additional Jest CLI commands with the `npm run test` command as
45 | described in the
46 | [Jest docs](https://facebook.github.io/jest/docs/en/cli.html#using-with-npm-scripts).
47 | For example, running jest in watch mode would be :
48 |
49 | - `npm run test -- --watch` instead of `jest --watch`
50 |
--------------------------------------------------------------------------------
/template/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | /* Basic Options */
4 | "target": "ESNext", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */
5 | "module": "ESNext", /* Specify module code generation: 'none', commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
6 | // "lib": [], /* Specify library files to be included in the compilation: */
7 | // "allowJs": true, /* Allow javascript files to be compiled. */
8 | // "checkJs": true, /* Report errors in .js files. */
9 | "jsx": "react", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
10 | "jsxFactory": "h", /* Specify the JSX factory function to use when targeting react JSX emit, e.g. React.createElement or h. */
11 | // "declaration": true, /* Generates corresponding '.d.ts' file. */
12 | // "sourceMap": true, /* Generates corresponding '.map' file. */
13 | // "outFile": "./", /* Concatenate and emit output to single file. */
14 | // "outDir": "./", /* Redirect output structure to the directory. */
15 | // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
16 | // "removeComments": true, /* Do not emit comments to output. */
17 | // "noEmit": true, /* Do not emit outputs. */
18 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */
19 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
20 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
21 |
22 | /* Strict Type-Checking Options */
23 | // "strict": true, /* Enable all strict type-checking options. */
24 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
25 | // "strictNullChecks": true, /* Enable strict null checks. */
26 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
27 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
28 |
29 | /* Additional Checks */
30 | // "noUnusedLocals": true, /* Report errors on unused locals. */
31 | // "noUnusedParameters": true, /* Report errors on unused parameters. */
32 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
33 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
34 |
35 | /* Module Resolution Options */
36 | "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
37 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
38 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
39 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
40 | // "typeRoots": [], /* List of folders to include type definitions from. */
41 | // "types": [], /* Type declaration files to be included in compilation. */
42 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
43 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
44 |
45 | /* Source Map Options */
46 | // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
47 | // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */
48 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
49 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
50 |
51 | /* Experimental Options */
52 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
53 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
54 | "esModuleInterop": true
55 | },
56 | "include": ["src"]
57 | }
--------------------------------------------------------------------------------