12 |
Hello, World!
13 |
{count}
20 |
;
21 | };
22 |
--------------------------------------------------------------------------------
/client/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | overrides: [
3 | {
4 | extends: [
5 | 'canonical',
6 | 'canonical/node',
7 | ],
8 | files: '*.js',
9 | },
10 | {
11 | extends: [
12 | 'canonical',
13 | 'canonical/typescript',
14 | ],
15 | files: '*.ts',
16 | parserOptions: {
17 | project: './tsconfig.json',
18 | tsconfigRootDir: __dirname,
19 | },
20 | },
21 | ],
22 | root: true,
23 | };
24 |
--------------------------------------------------------------------------------
/examples/react/server/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | overrides: [
3 | {
4 | extends: [
5 | 'canonical',
6 | 'canonical/node',
7 | ],
8 | files: '*.js',
9 | },
10 | {
11 | extends: [
12 | 'canonical',
13 | 'canonical/typescript',
14 | ],
15 | files: '*.ts',
16 | parserOptions: {
17 | project: './tsconfig.json',
18 | tsconfigRootDir: __dirname,
19 | },
20 | },
21 | ],
22 | root: true,
23 | };
24 |
--------------------------------------------------------------------------------
/examples/webpack/app/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | overrides: [
3 | {
4 | extends: [
5 | 'canonical',
6 | 'canonical/node',
7 | ],
8 | files: '*.js',
9 | },
10 | {
11 | extends: [
12 | 'canonical',
13 | 'canonical/typescript',
14 | ],
15 | files: '*.ts',
16 | parserOptions: {
17 | project: './tsconfig.json',
18 | tsconfigRootDir: __dirname,
19 | },
20 | },
21 | ],
22 | root: true,
23 | };
24 |
--------------------------------------------------------------------------------
/examples/webpack/server/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | overrides: [
3 | {
4 | extends: [
5 | 'canonical',
6 | 'canonical/node',
7 | ],
8 | files: '*.js',
9 | },
10 | {
11 | extends: [
12 | 'canonical',
13 | 'canonical/typescript',
14 | ],
15 | files: '*.ts',
16 | parserOptions: {
17 | project: './tsconfig.json',
18 | tsconfigRootDir: __dirname,
19 | },
20 | },
21 | ],
22 | root: true,
23 | };
24 |
--------------------------------------------------------------------------------
/examples/react/app/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | overrides: [
3 | {
4 | extends: [
5 | 'canonical',
6 | 'canonical/node',
7 | ],
8 | files: '*.js',
9 | },
10 | {
11 | extends: [
12 | 'canonical',
13 | 'canonical/typescript',
14 | 'canonical/react',
15 | ],
16 | files: '*.tsx',
17 | parserOptions: {
18 | project: './tsconfig.json',
19 | tsconfigRootDir: __dirname,
20 | },
21 | },
22 | ],
23 | root: true,
24 | };
25 |
--------------------------------------------------------------------------------
/examples/webpack/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "@roarr/browser-log-writer": "^1.1.1",
4 | "@roarr/cli": "^5.3.2",
5 | "@types/node": "^10.0.0",
6 | "@types/webpack": "^5.28.0",
7 | "@types/webpack-env": "^1.16.3",
8 | "eslint": "^8.11.0",
9 | "eslint-config-canonical": "^33.0.1",
10 | "fastify": "^3.27.4",
11 | "ts-loader": "^9.2.8",
12 | "ts-node": "^10.2.1",
13 | "typescript": "^4.4.3",
14 | "webpack": "^5.70.0"
15 | },
16 | "private": true,
17 | "scripts": {
18 | "start": "ts-node --transpile-only server/server.ts | roarr"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/utilities/getPublicPath.ts:
--------------------------------------------------------------------------------
1 | import type {
2 | Stats,
3 | } from 'webpack';
4 |
5 | type PublicPath = {
6 | outputPath: string,
7 | publicPath: string,
8 | };
9 |
10 | export const getPublicPath = (stats: Stats): PublicPath => {
11 | const {
12 | compilation,
13 | } = stats;
14 |
15 | const outputPath = compilation.getPath(
16 | compilation.outputOptions.path ?? '',
17 | );
18 |
19 | const publicPath = compilation.outputOptions.publicPath ?
20 | compilation.getPath(compilation.outputOptions.publicPath) :
21 | '';
22 |
23 | return {
24 | outputPath,
25 | publicPath,
26 | };
27 | };
28 |
--------------------------------------------------------------------------------
/examples/react/README.md:
--------------------------------------------------------------------------------
1 | # TypeScript, Fastify, Webpack, React HRM example
2 |
3 | ## Start
4 |
5 | ```bash
6 | npm install
7 | npm run start
8 | ```
9 |
10 | The website is available at http://127.0.0.1:8080/
11 |
12 | After the page has loaded, edit `app/App.tsx` to verify that HMR is working as expected.
13 |
14 | ## Setup
15 |
16 | The example includes quite a few elements, however, in order to replicate React compatible HMR, you only need to:
17 |
18 | 1. Add `HotModuleReplacementPlugin` Webpack plugin
19 | 1. Add `ReactRefreshWebpackPlugin` Webpack plugin
20 | 1. Add `ReactRefreshTypeScript` TypeScript transform
21 | 1. Add `fastify-webpack-hot/client` Webpack entry script
--------------------------------------------------------------------------------
/examples/webpack/README.md:
--------------------------------------------------------------------------------
1 | # TypeScript, Fastify, Webpack HRM example
2 |
3 | ## Start
4 |
5 | ```bash
6 | npm install
7 | npm run start
8 | ```
9 |
10 | The website is available at http://127.0.0.1:8080/
11 |
12 | After the page has loaded, edit `app/hello.ts` to verify that HMR is working as expected.
13 |
14 | For more context, refer to [Webpack Hot Module Replacement documentation](https://webpack.js.org/api/hot-module-replacement/).
15 |
16 | ## Setup
17 |
18 | The example includes quite a few elements, however, in order to replicate the HMR behaviour, you only need to:
19 |
20 | 1. Add `HotModuleReplacementPlugin` Webpack plugin
21 | 1. Add `fastify-webpack-hot/client` Webpack entry script
--------------------------------------------------------------------------------
/webpack.config.ts:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 | import webpack from 'webpack';
3 |
4 | export default {
5 | devtool: 'source-map',
6 | entry: path.resolve(__dirname, './client/client.ts'),
7 | mode: 'development',
8 | module: {
9 | rules: [
10 | {
11 | exclude: /node_modules/u,
12 | test: /\.ts$/u,
13 | use: 'ts-loader',
14 | },
15 | ],
16 | },
17 | output: {
18 | filename: 'client.js',
19 | path: path.resolve(__dirname),
20 | },
21 | plugins: [
22 | new webpack.DefinePlugin({
23 | 'import.meta.webpackHot': 'import.meta.webpackHot',
24 | }),
25 | ],
26 | resolve: {
27 | extensions: [
28 | '.js',
29 | '.ts',
30 | ],
31 | },
32 | };
33 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowSyntheticDefaultImports": true,
4 | "declaration": true,
5 | "esModuleInterop": true,
6 | "lib": [
7 | "es2018"
8 | ],
9 | "module": "commonjs",
10 | "moduleResolution": "node",
11 | "noImplicitAny": false,
12 | "noImplicitReturns": true,
13 | "noUnusedLocals": true,
14 | "noUnusedParameters": false,
15 | "outDir": "dist",
16 | "resolveJsonModule": true,
17 | "skipLibCheck": true,
18 | "strict": true,
19 | "target": "es2018",
20 | "useUnknownInCatchVariables": false
21 | },
22 | "exclude": [
23 | "dist",
24 | "node_modules"
25 | ],
26 | "include": [
27 | "webpack.config.ts",
28 | "src",
29 | "test"
30 | ]
31 | }
--------------------------------------------------------------------------------
/.github/workflows/main.yaml:
--------------------------------------------------------------------------------
1 | jobs:
2 | test:
3 | runs-on: ubuntu-latest
4 | environment: release
5 | name: Test
6 | steps:
7 | - name: setup repository
8 | uses: actions/checkout@v2
9 | with:
10 | fetch-depth: 0
11 | - name: setup node.js
12 | uses: actions/setup-node@v2
13 | with:
14 | node-version: '16'
15 | cache: 'npm'
16 | - run: npm install
17 | - run: npm run lint
18 | - run: npm run test
19 | - run: npm run build
20 | - run: npx semantic-release
21 | env:
22 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
23 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
24 | timeout-minutes: 10
25 | name: Test, build and release
26 | on:
27 | push:
28 | branches:
29 | - main
30 |
--------------------------------------------------------------------------------
/src/utilities/defer.ts:
--------------------------------------------------------------------------------
1 | export type DeferredPromise