Add basic typescript integration

This commit is contained in:
Isidor Nygren 2022-04-21 16:23:37 +02:00
parent a937b82cd2
commit a817ed17a2
8 changed files with 46 additions and 12 deletions

View file

@ -9,6 +9,7 @@
"opera": "44" "opera": "44"
} }
}], }],
"@babel/preset-typescript",
"@babel/preset-react" "@babel/preset-react"
] ]
} }

View file

@ -4,7 +4,7 @@
"browser": true, "browser": true,
"es6": true "es6": true
}, },
"extends": ["eslint:recommended", "standard", "standard-jsx", "react-app"], "extends": ["eslint:recommended", "standard", "standard-jsx", "react-app", "plugin:@typescript-eslint/recommended"],
"parser": "@babel/eslint-parser", "parser": "@babel/eslint-parser",
"parserOptions": { "parserOptions": {
"ecmaVersion": "7", "ecmaVersion": "7",
@ -13,7 +13,7 @@
}, },
"sourceType": "module" "sourceType": "module"
}, },
"plugins": ["flowtype", "react", "react-hooks"], "plugins": ["flowtype", "react", "react-hooks", "@typescript-eslint"],
"rules": { "rules": {
"indent": ["error", 4, "indent": ["error", 4,
{ {

View file

@ -8,14 +8,18 @@
"scripts": { "scripts": {
"watch": "webpack --watch --progress", "watch": "webpack --watch --progress",
"build": "webpack", "build": "webpack",
"eslint": "eslint --ext .js --ext .jsx src/", "eslint": "eslint --ext .js --ext .jsx --ext .ts --ext .tsx src/",
"eslint:fix": "eslint --fix --ext .js --ext .jsx src/" "eslint:fix": "eslint --fix --ext .js --ext .jsx --ext .ts --ext .tsx src/"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.5.4", "@babel/core": "^7.5.4",
"@babel/eslint-parser": "^7.17.0", "@babel/eslint-parser": "^7.17.0",
"@babel/preset-env": "^7.5.4", "@babel/preset-env": "^7.5.4",
"@babel/preset-react": "^7.0.0", "@babel/preset-react": "^7.0.0",
"@babel/preset-typescript": "^7.16.7",
"@types/react": "^17.0.44",
"@types/react-dom": "^17.0.15",
"@typescript-eslint/eslint-plugin": "^5.20.0",
"babel-loader": "^8.0.6", "babel-loader": "^8.0.6",
"chrome-remote-interface": "^0.31.0", "chrome-remote-interface": "^0.31.0",
"compression-webpack-plugin": "^9.0.0", "compression-webpack-plugin": "^9.0.0",
@ -33,6 +37,7 @@
"eslint-plugin-react": "^7.29.4", "eslint-plugin-react": "^7.29.4",
"eslint-plugin-react-hooks": "^4.4.0", "eslint-plugin-react-hooks": "^4.4.0",
"eslint-webpack-plugin": "^3.1.1", "eslint-webpack-plugin": "^3.1.1",
"fork-ts-checker-webpack-plugin": "^7.2.6",
"htmlparser": "^1.7.7", "htmlparser": "^1.7.7",
"jed": "^1.1.1", "jed": "^1.1.1",
"mini-css-extract-plugin": "^2.5.3", "mini-css-extract-plugin": "^2.5.3",

View file

@ -21,14 +21,18 @@ import cockpit from 'cockpit';
import React from 'react'; import React from 'react';
import { Alert, Card, CardTitle, CardBody } from '@patternfly/react-core'; import { Alert, Card, CardTitle, CardBody } from '@patternfly/react-core';
interface ApplicationState {
hostname: string;
}
const _ = cockpit.gettext; const _ = cockpit.gettext;
export class Application extends React.Component { export class Application extends React.Component<unknown, ApplicationState> {
constructor() { constructor(props: unknown) {
super(); super(props);
this.state = { hostname: _("Unknown") }; this.state = { hostname: _("Unknown") };
cockpit.file('/etc/hostname').watch(content => { cockpit.file('/etc/hostname').watch((content: string) => {
this.setState({ hostname: content.trim() }); this.setState({ hostname: content.trim() });
}); });
} }

View file

@ -21,7 +21,7 @@ import "./lib/patternfly/patternfly-4-cockpit.scss";
import React from 'react'; import React from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import { Application } from './app.jsx'; import { Application } from './app';
/* /*
* PF4 overrides need to come after the JSX components imports because * PF4 overrides need to come after the JSX components imports because
* these are importing CSS stylesheets that we are overriding * these are importing CSS stylesheets that we are overriding

5
src/types/cockpit.ts Normal file
View file

@ -0,0 +1,5 @@
declare module 'cockpit' {
export function gettext(prop: string): string;
export function file(prop: any): any;
export function format(...prop:any): any;
}

16
tsconfig.json Normal file
View file

@ -0,0 +1,16 @@
{
"compilerOptions": {
"target": "es2015",
"module": "commonjs",
"lib": ["dom", "es2017"],
"strict": true,
"strictNullChecks": true,
"noUnusedLocals": true,
"moduleResolution": "node",
"noEmitOnError": true,
"esModuleInterop": true,
"jsx": "react",
"types": [ "src/types" ]
}
}

View file

@ -9,6 +9,7 @@ const CompressionPlugin = require("compression-webpack-plugin");
const ESLintPlugin = require('eslint-webpack-plugin'); const ESLintPlugin = require('eslint-webpack-plugin');
const CockpitPoPlugin = require("./src/lib/cockpit-po-plugin"); const CockpitPoPlugin = require("./src/lib/cockpit-po-plugin");
const CockpitRsyncPlugin = require("./src/lib/cockpit-rsync-plugin"); const CockpitRsyncPlugin = require("./src/lib/cockpit-rsync-plugin");
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
/* A standard nodejs and webpack pattern */ /* A standard nodejs and webpack pattern */
const production = process.env.NODE_ENV === 'production'; const production = process.env.NODE_ENV === 'production';
@ -30,10 +31,11 @@ const plugins = [
new extract({filename: "[name].css"}), new extract({filename: "[name].css"}),
new CockpitPoPlugin(), new CockpitPoPlugin(),
new CockpitRsyncPlugin({dest: packageJson.name}), new CockpitRsyncPlugin({dest: packageJson.name}),
new ForkTsCheckerWebpackPlugin()
]; ];
if (eslint) { if (eslint) {
plugins.push(new ESLintPlugin({ extensions: ["js", "jsx"], failOnWarning: true, })); plugins.push(new ESLintPlugin({ extensions: ["js", "jsx", "ts", "tsx"], failOnWarning: true, }));
} }
/* Only minimize when in production mode */ /* Only minimize when in production mode */
@ -49,6 +51,7 @@ module.exports = {
resolve: { resolve: {
modules: [ "node_modules", path.resolve(__dirname, 'src/lib') ], modules: [ "node_modules", path.resolve(__dirname, 'src/lib') ],
alias: { 'font-awesome': 'font-awesome-sass/assets/stylesheets' }, alias: { 'font-awesome': 'font-awesome-sass/assets/stylesheets' },
extensions: ['.tsx', '.ts', '.js', '.jsx']
}, },
resolveLoader: { resolveLoader: {
modules: [ "node_modules", path.resolve(__dirname, 'src/lib') ], modules: [ "node_modules", path.resolve(__dirname, 'src/lib') ],
@ -57,7 +60,7 @@ module.exports = {
ignored: /node_modules/, ignored: /node_modules/,
}, },
entry: { entry: {
index: "./src/index.js", index: "./src/index.ts",
}, },
// cockpit.js gets included via <script>, everything else should be bundled // cockpit.js gets included via <script>, everything else should be bundled
externals: { "cockpit": "cockpit" }, externals: { "cockpit": "cockpit" },
@ -85,7 +88,7 @@ module.exports = {
{ {
exclude: /node_modules/, exclude: /node_modules/,
use: "babel-loader", use: "babel-loader",
test: /\.(js|jsx)$/ test: /\.(js|jsx|ts|tsx)$/
}, },
/* HACK: remove unwanted fonts from PatternFly's css */ /* HACK: remove unwanted fonts from PatternFly's css */
{ {