Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TypeScript to the project #654

Merged
merged 7 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 1 addition & 10 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,11 @@ trim_trailing_whitespace = true
insert_final_newline = true
end_of_line = lf

[*.js]
indent_size = 2

[*.html]
indent_size = 2

[*.scss]
[*.{js,jsx,ts,tsx,json,html,css,scss,md,yml,yaml,swcrc}]
indent_size = 2

[*.md]
trim_trailing_whitespace = false

[Makefile]
indent_style = tab

[*.yml]
indent_size = 2
49 changes: 36 additions & 13 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,49 @@
const path = require('path');
const path = require("path");

module.exports = {
root: true,
extends: ['vinta/recommended'],
parser: "@typescript-eslint/parser",
extends: ["vinta/recommended-typescript"],
rules: {
"default-param-last": "off", // due to initialState in Redux
"@babel/camelcase": "off"
"default-param-last": "off", // due to initialState in Redux
"import/extensions": [
"error",
"ignorePackages",
{
js: "never",
jsx: "never",
ts: "never",
tsx: "never",
},
],
fjsj marked this conversation as resolved.
Show resolved Hide resolved
},
env: {
es6: true,
browser: true,
jest: true
es2021: true,
jest: true,
node: true,
},
settings: {
'import/resolver': {
"import/extensions": [".js", ".jsx", ".ts", ".tsx"],
"import/parsers": {
"@typescript-eslint/parser": [".ts", ".tsx"],
},
"import/resolver": {
node: {
paths: [path.resolve(__dirname, "node_modules")],
extensions: [".js", ".jsx", ".ts", ".tsx"],
},
webpack: {
config: path.join(__dirname, '/webpack.config.js'),
'config-index': 1
}
config: path.join(__dirname, "/webpack.config.js"),
"config-index": 1,
},
typescript: {
alwaysTryTypes: true,
project: "./tsconfig.json",
},
},
react: {
"version": "detect"
version: "detect",
},
}
}
},
};
120 changes: 64 additions & 56 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,58 +1,66 @@
fail_fast: true
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: check-added-large-files
args: ["--maxkb=500"]
exclude: >
(?x)^(
package-lock\.json
)$
- id: fix-byte-order-marker
- id: check-case-conflict
- id: check-merge-conflict
- id: check-symlinks
- id: debug-statements
- id: detect-private-key
- repo: https://github.com/adamchainz/django-upgrade
rev: "1.15.0"
hooks:
- id: django-upgrade
args: [--target-version, "5.0"]
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.1.6
hooks:
# Run the linter.
- id: ruff
args: [--fix]
# Run the formatter.
- id: ruff-format
- repo: local
hooks:
- id: eslint
name: eslint-local
entry: npm run lint
language: system
types: [javascript]
exclude: >
(?x)^(
.+\.config\.js|
.+\.setup\.js|
\.eslintrc\.js
)$
pass_filenames: true
- id: missing-migrations
name: missing-migrations-local
entry: poetry run python backend/manage.py makemigrations --check
language: system
# Only run missing migration check if migration-generating files have changed:
files: (.*/?(settings|migrations|models)/.+|.+models\.py|.+constants\.py|.+choices\.py|.+pyproject\.toml)
pass_filenames: false
- id: backend-schema
name: backend-schema-local
entry: poetry run python backend/manage.py spectacular --color --file backend/schema.yml
language: system
files: ^backend/
pass_filenames: false
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: check-added-large-files
args: ["--maxkb=500"]
exclude: >
(?x)^(
package-lock\.json
)$
- id: fix-byte-order-marker
- id: check-case-conflict
- id: check-merge-conflict
- id: check-symlinks
- id: debug-statements
- id: detect-private-key
- repo: https://github.com/adamchainz/django-upgrade
rev: "1.15.0"
hooks:
- id: django-upgrade
args: [--target-version, "5.0"]
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.1.6
hooks:
# Run the linter.
- id: ruff
args: [--fix]
# Run the formatter.
- id: ruff-format
- repo: local
hooks:
- id: eslint
name: eslint-local
entry: npm run lint
language: system
types: [file]
files: \.(js|jsx|ts|tsx)$
exclude: >
(?x)^(
.+\.config\.js|
.+\.setup\.js|
\.eslintrc\.js
)$
pass_filenames: true
- id: tsc
name: tsc-local
entry: npm run tsc
language: system
types: [file]
files: \.(ts|tsx)$
pass_filenames: false
Comment on lines +47 to +53
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actual change.

- id: missing-migrations
name: missing-migrations-local
entry: poetry run python backend/manage.py makemigrations --check
language: system
# Only run missing migration check if migration-generating files have changed:
files: (.*/?(settings|migrations|models)/.+|.+models\.py|.+constants\.py|.+choices\.py|.+pyproject\.toml)
pass_filenames: false
- id: backend-schema
name: backend-schema-local
entry: poetry run python backend/manage.py spectacular --color --file backend/schema.yml
language: system
files: ^backend/
pass_filenames: false
25 changes: 25 additions & 0 deletions .swcrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"jsc": {
"parser": {
"jsx": true,
"tsx": true,
"syntax": "typescript",
"decorators": true,
"dynamicImport": true
},
"transform": {
"react": {
"runtime": "automatic"
}
}
},
// The 'env' field is used to specify settings for compiling JavaScript/TypeScript code to be
// compatible with older environments.
"env": {
// 'entry' means SWC will include polyfills for all features used in the code that are not
// available in the target environment.
"mode": "entry",
// 'corejs' specifies the version of core-js to use for polyfills.
"corejs": 3
}
}
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
A [Django](https://www.djangoproject.com/) project boilerplate/template with a multitude of state-of-the-art libraries and tools. If pairing Django with React is a possibility for your project or spinoff, this is the best solution available. Save time with tools like:

- [React](https://react.dev/), for building interactive UIs
- [TypeScript](https://www.typescriptlang.org/), for static type checking
- [Poetry](https://python-poetry.org/), for managing the environment and its dependencies
- [django-js-reverse](https://github.com/vintasoftware/django-js-reverse), for generating URLs on JS
- [React Bootstrap](https://react-bootstrap.github.io/), for responsive styling
Expand Down
14 changes: 0 additions & 14 deletions babel.config.json

This file was deleted.

24 changes: 24 additions & 0 deletions frontend/assets/images/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
declare module "*.png" {
const value: string;
export = value;
}

declare module "*.jpg" {
const value: string;
export = value;
}

declare module "*.jpeg" {
const value: string;
export = value;
}

declare module "*.gif" {
const value: string;
export = value;
}

declare module "*.svg" {
const value: string;
export = value;
}
pamella marked this conversation as resolved.
Show resolved Hide resolved
1 change: 0 additions & 1 deletion frontend/js/App.js → frontend/js/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as Sentry from "@sentry/react";
import React from "react";
import { Provider } from "react-redux";

import Home from "./pages/Home";
Expand Down
File renamed without changes.
7 changes: 3 additions & 4 deletions frontend/js/index.js → frontend/js/index.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
// import pages
import * as Sentry from "@sentry/browser";
import React from "react";
import { createRoot } from "react-dom/client";

import "../sass/style.scss";

import App from "./App";

import "../sass/style.scss";

Sentry.init({
dsn: window.SENTRY_DSN,
release: window.COMMIT_SHA,
});

const root = createRoot(document.getElementById("react-app"));
const root = createRoot(document.getElementById("react-app") as HTMLElement);
root.render(<App />);
11 changes: 7 additions & 4 deletions frontend/js/pages/Home.js → frontend/js/pages/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import React, { useState, useEffect } from "react";
import { useState, useEffect } from "react";
import Button from "react-bootstrap/Button";
import { useDispatch, useSelector } from "react-redux";

import DjangoImgSrc from "../../assets/images/django-logo-negative.png";
import { AppDispatch, RootState } from "../store";
import { fetchRestCheck } from "../store/rest_check";

const Home = () => {
const dispatch = useDispatch();
const restCheck = useSelector((state) => state.restCheck);
const dispatch: AppDispatch = useDispatch();
const restCheck = useSelector((state: RootState) => state.restCheck);
useEffect(() => {
Comment on lines +10 to +11
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: This will change once we get to work on the client generation.

const action = fetchRestCheck();
dispatch(action);
Expand Down Expand Up @@ -35,7 +36,9 @@ const Home = () => {
Click to test if Sentry is capturing frontend errors! (Should only work
in Production)
</Button>
{showBugComponent && showBugComponent.field.notexist}
{/* NOTE: The next line intentionally contains an error for testing frontend errors in Sentry. */}
{/* eslint-disable-next-line @typescript-eslint/no-explicit-any */}
{showBugComponent && (showBugComponent as any).field.notexist}
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ jest.mock("../../store/rest_check", () => ({

describe("Home", () => {
beforeEach(() => {
useDispatch.mockReturnValue(jest.fn());
useSelector.mockReturnValue({
(useDispatch as jest.Mock).mockReturnValue(jest.fn());
(useSelector as jest.Mock).mockReturnValue({
data: { payload: { result: "Test Result" } },
});
});
Expand All @@ -30,7 +30,7 @@ describe("Home", () => {

expect(screen.getByText("Static assets")).toBeInTheDocument();
expect(screen.getByText("Rest API")).toBeInTheDocument();
expect(screen.getByText("Test Result")).toBeInTheDocument();
expect(await screen.findByText("Test Result")).toBeInTheDocument();
});

test("dispatches fetchRestCheck action on mount", async () => {
Expand Down
File renamed without changes.
1 change: 1 addition & 0 deletions frontend/js/store/api.js → frontend/js/store/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import cookie from "cookie";
const api = axios.create();
api.interceptors.request.use((config) => {
const { csrftoken } = cookie.parse(document.cookie);
config.headers = config.headers || {};
if (csrftoken) {
config.headers["X-CSRFTOKEN"] = csrftoken;
}
Expand Down
6 changes: 5 additions & 1 deletion frontend/js/store/index.js → frontend/js/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { configureStore } from "@reduxjs/toolkit";

import { rootReducer } from "./reducers";

const configureReduxStore = (preloadedState) => {
const configureReduxStore = (preloadedState: object) => {
const store = configureStore({
reducer: rootReducer,
preloadedState,
Expand All @@ -11,3 +11,7 @@ const configureReduxStore = (preloadedState) => {
};

export default configureReduxStore;

const store = configureReduxStore({});
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
File renamed without changes.
Loading
Loading