React Electron Masaüstü Uygulamanızı TypeScript ile Genişletin – JSManifest

React Electron Masaüstü Uygulamanızı TypeScript ile Genişletin – JSManifest

Önceki bir makalede, kullanarak bir masaüstü uygulama yazılımı oluşturma adımlarını gözden geçirdim. Elektron. Bu makale, repoyu klonlayarak ve TypeScript’i destekleyecek şekilde genişleterek başlayacak, böylece masaüstü uygulamamızı geliştirirken tip kontrol yetenekleri elde edeceğiz.

TypeScript, kodunuzdaki yazım hataları konusunda sizi bilgilendirerek uygulamanızın kalitesini artırmaya yardımcı olabilir; bu nedenle, henüz yapmadıysanız, bunu geliştirme akışınıza entegre etmeye başlamak iyi bir fikirdir.

Bununla, bu olumsuzluk bir devam öğretici, ancak sizin ve benim gibi kullanıcıların masaüstü uygulamaları geliştirirken TypeScript özelliklerinden yararlanmaya başlayabilmemiz için depoyu genişletmek için kullanacağız.

Ve daha fazla uzatmadan başlayalım! (Not: Oluşturacağımız repo’nun bir kopyasına sahip olmak istiyorsanız, adresini ziyaret edin. bu bağlantı)

Yapacağımız ilk şey, depoyu klonla.

Tamamlandıktan sonra dizine gidin ve cli’yi kullanarak bağımlılıkları kurun:

Uygulamayı yüklemeyi bitirdikten sonra, geliştirme modunda başlatarak çalışan bir projemiz olduğundan emin olalım:

Başarılı olduysa, bu pencereyi görmelisiniz:

Bu, tepki uygulamamız için canlı, yeniden yüklenebilir web sunucumuzu başlattı.

Şimdi devam edin ve elektronu çalıştırın:

Bu başarılı olduysa, bu pencereyi görmelisiniz:

cli npm elektron çalıştırmak

Harika! Artık çalışan bir uygulamamız olduğunu bildiğimize göre, projeye TypeScript yüklemeye devam edelim:

(Not: -D sadece bir takma addır --save-dev)

Sırada eslint kuracağız. Esas olarak JavaScript’i astarlamakla ilgili olduğu için neden eslint ile uğraştığımı merak ediyor olabilirsiniz.

Arkadaki takım tslint bir duyuru yaptı bu yılın başlarında ileriye dönük planlarını duyurdular ve tslint’in eslint lehine kullanımdan kaldırılacağına karar verdiler. Sonuç olarak, geliştiricilerin eslint ve typescript’i birlikte kullanmalarına izin veren araçlar sonunda geliştirildi.

@typescript-eslint/ayrıştırıcı kaynak kodumuzu, TypeScript derleyicisini kullanarak ESLint’in TypeScript ile kullanılmasını sağlayan bir Soyut Sözdizimi Ağacına (AST) dönüştüren bir ayrıştırıcıdır. Okumak bağlantı Daha fazla bilgi edinmek için.

Ayrıca yüklememiz gerekecek @typescript-eslint/eslint-eklentisi

Tepki projelerimde düzenli olarak kullandığım paketleri listeleyeceğim. hepsini kurmana gerek yok ama eslint ve bu listenin en alttaki 5’i, projelerinizde kesinlikle kullanmak isteyeceğiniz şeydir:

  • eslint
  • eslint-config-airbnb
  • eslint-config-daha güzel
  • eslint-eklenti-içe aktarma
  • eslint-eklenti-jsx-a11y
  • eslint-eklenti-daha güzel
  • eslint-eklenti-tepki
  • eslint-eklenti-tepki-kancaları
  • @typescript-eslint/ayrıştırıcı
  • @typescript-eslint/eslint-eklentisi

Öyleyse devam edelim ve yükleyelim eslint ve diğerleri:

npm install -D eslint eslint-config-airbnb eslint-config-prettier eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-prettier eslint-plugin-react eslint-plugin-react-hooks @typescript-eslint/parser @typescript-eslint/eslint-plugin

şunu da unutmayalım typescript kendisi:

npm install -D typescript

Daha sonra, bir .eslintrc.js dosya kök dizinimizde. işte benim .eslintrc.js:

module.exports = {
  parser: '@typescript-eslint/parser',
  parserOptions: {
    project: './tsconfig.json',
    ecmaFeatures: {
      jsx: true,
    },
  },
  env: {
    browser: true,
    jest: true,
  },
  extends: [
    'airbnb',
    'prettier',
    'prettier/react',
    'prettier/@typescript-eslint',
    'plugin:@typescript-eslint/recommended',
    'plugin:prettier/recommended',
  ],
  plugins: ['@typescript-eslint', 'react-hooks', 'prettier'],
  rules: {
    '@typescript-eslint/explicit-function-return-type': 'off',
    '@typescript-eslint/indent': 'off',
    '@typescript-eslint/explicit-member-accessibility': 'off',
    '@typescript-eslint/member-delimiter-style': 'off',
    '@typescript-eslint/no-use-before-define': 'off',
    '@typescript-eslint/no-explicit-any': 'off',
    '@typescript-eslint/camelcase': 'off',
    'arrow-parens': [2, 'always'],
    'arrow-body-style': 0,
    'consistent-return': 0,
    'css-modules/no-unused-class': 'off',
    camelcase: 0,
    'class-methods-use-this': 0,
    'comma-dangle': 0,
    'dot-notation': 0,
    eqeqeq: 0,
    'flowtype/no-types-missing-file-annotation': 0,
    'func-names': 'off',
    'import/prefer-default-export': 0,
    'import/no-extraneous-dependencies': 'off',
    'import/newline-after-import': 'off',
    'import/first': 'off',
    'import/no-extensions': 'off',
    'import/extensions': 'off',
    'import/no-unresolved': 'off',
    'import/no-useless-path-segments': 0,
    'import/no-absolute-path': 'off',
    'jsx-a11y/html-has-lang': 0,
    'jsx-a11y/alt-text': 0,
    'jsx-a11y/anchor-is-valid': 'off',
    'jsx-a11y/click-events-have-key-events': 'off',
    'jsx-a11y/href-no-hash': 0,
    'jsx-a11y/no-static-element-interactions': 0,
    'jsx-a11y/no-noninteractive-element-interactions': 0,
    'jsx-a11y/no-autofocus': 0,
    'jsx-a11y/label-has-associated-control': 0,
    'jsx-a11y/label-has-for': 0,
    'jsx-quotes': ['error', 'prefer-double'],
    'jsx-a11y/media-has-caption': 0,
    'jsx-a11y/anchor-has-content': 0,
    'linebreak-style': 0,
    'max-len': 0,
    'no-alert': 0,
    'no-case-declarations': 0,
    'no-underscore-dangle': 'off',
    'no-useless-escape': 'off',
    'no-trailing-spaces': 0,
    'no-multi-assign': 'off',
    'no-nested-ternary': 'off',
    'no-lonely-if': 'off',
    'no-plusplus': 'off',
    'no-loop-func': 'off',
    'no-unused-expressions': 0,
    'no-unused-vars': 1,
    'no-confusing-arrow': 0,
    'no-use-before-define': 0,
    'no-console': 0,
    'no-return-assign': 0,
    'no-restricted-properties': 0,
    'no-param-reassign': 0,
    'no-shadow': 0,
    'no-prototype-builtins': 0,
    'no-multiple-empty-lines': 0,
    'no-else-return': 0,
    'object-curly-spacing': ['error', 'always'],
    'object-property-newline': 0,
    'one-var': 0,
    'one-var-declaration-per-line': 0,
    'prettier/prettier': 0,
    'padded-blocks': 0,
    'prefer-template': 0,
    'prefer-destructuring': 0,
    quotes: 2,
    'react-hooks/exhaustive-deps': 'warn',
    'react-hooks/rules-of-hooks': 'error',
    'react/no-multi-comp': 0,
    'react/jsx-wrap-multilines': 0,
    'react/default-props-match-prop-types': 'off',
    'react/no-find-dom-node': 'off',
    'react/destructuring-assignment': 'off',
    'react/jsx-no-bind': 'off',
    'react/jsx-filename-extension': [
      'error',
      {
        extensions: ['.js', '.jsx', '.ts', '.tsx'],
      },
    ],
    'react/react-in-jsx-scope': 0,
    'react/prop-types': 0,
    'react/forbid-prop-types': 0,
    'react/no-children-prop': 0,
    'react/no-array-index-key': 0,
    'react/prefer-stateless-function': 'off',
    'react/sort-comp': 0,
    'react/no-unescaped-entities': 0,
    'react/jsx-no-bind': 0,
    'react/no-unused-state': 1,
    'react/no-unused-prop-types': 0,
    'react/jsx-pascal-case': 0,
    'react/no-danger': 0,
    'react/require-default-props': 0,
    'react/jsx-curly-spacing': 0,
    'react/jsx-max-props-per-line': 1,
    'space-in-parens': ['error', 'never'],
    'spaced-comment': 0,
    'space-infix-ops': 0,
    'space-unary-ops': 0,
    'space-before-function-paren': 0,
  },
  settings: {
    'import/resolver': {
      node: {
        moduleDirectory: ['node_modules', 'src'],
      },
    },
  },
}

Şimdi TypeScript’i bir elektron projesine uyguladığımızda biraz zorlaşıyor. TypeScript kodu düz JavaScript’e derleyen, JavaScript’in yazılı bir üst kümesidir, istediğimiz budur. Ancak elektronda uygulamalar oluştururken, özellikle elektron kullanmaya yeni başlamışsak, ilk bakışta fark etmeyebileceğimiz bir sorun olabilir.

Sorun şu ki elektronda çalışan iki tür süreç var. Bir denir ana süreç ve diğeri ise oluşturucu işlem. Elektron web sayfaları oluşturduğunda, bunlar oluşturucu işlemler olarak oluşturulurlar (esas olarak bir tarayıcı ortamında yaşarlar). Electron, aynı anda birden fazla oluşturucu işlemi oluşturabilir ve çalıştırabilir, ancak sonuçta yalnızca bir ana süreç.

Oluşturucu işlemleri web sayfaları olduğundan, GUI kaynaklarını yönetmelerine izin vermek büyük bir güvenlik sorunu olacağından, yerel GUI API’lerini çağırmaları engellenir. Electron, (ipcAna, ipcRendererveya uzak).

Bu kısıtlama nedeniyle, biz zorunlu dizinleri, ana süreç için kod geliştireceğimiz şekilde bölün ayrı ayrı TypeScript’i ayrı ayrı derleyebilmemiz için oluşturucu işleminden ayrı olarak. Bu, yazılımda kodlarını bir araya getirirken sorun yaratmamamız içindir.

Şimdi dizin yapımıza bakalım ve elimizde ne olduğunu görelim:

elektron dizin yapısı

bizde var gibi görünüyor start.js hangisi ana süreçoluşturucu işlemiyle kodla aynı dizinde yaşıyor (App.js, index.js, index.css, vb). Bu yüzden onları şöyle bir şeye ayırmalıyız:

(Not: Ekran görüntüsündeki dosyaları TypeScript dosyaları olacak şekilde yeniden adlandırdım)
ts ile elektron dizin yapısı

Bu iyi bir başlangıç. Bununla birlikte, TypeScript yapılandırma dosyasını yapılandırdığımızda, TypeScript’in derlemede eşleştiği tüm dosyalara dahil etmek için kullanacağı bir küre belirtmemiz gerekir. Hâlâ önceki sayıya takılıp kaldık, bu yüzden yapacağımız şey, mevcut kök dizini Ana Dizin hangi tutacak ana ve oluşturucu işlem kodu.

Ayrıca her ikisini de bağımsız repolar haline getireceğiz, böylece avantajlarından faydalanabiliriz. npm installYalnızca belirli bir sürece maruz kalması gereken paketler oluşturma ve bunun tersi de geçerlidir. Bu, gelecekte dizinlerimizi daha soyut ve düzenli hale getirerek hata ayıklamayı daha kolay hale getirmemize yardımcı olacaktır.

Yani yapacağımız şey ana dizin dışındaki her şeyi taşı için oluşturucu dizini. Bunu yapmamızın nedeni, bu proje tarafından önyüklenmiş olmasıdır. oluştur-tepki-uygulaması esasen zaten bir oluşturucu işlemi içinde bir ortam olan:

elektron_dir_structure_with_ts_splitrepos

Artık oluşturucu deposunu aradan çıkardığımıza göre, şimdi ana işlemi kendi deposuna dönüştürelim:

Her şeyin içinden enter’a basmanız yeterli. Şimdi package.json dosyasını açın ve neredeyse boş bir package.json dosyası görmelisiniz:

{
  "name": "main",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

Burada değiştirmemiz gereken şey, "main" Bölüm bu yüzden değil bu bir TypeScript dosyası değil, çünkü bu elektron dosyası build komutunu daha sonra çalıştırdığımızda çıktı dizinimize koyacağız. Uygulamamızı oluşturduğumuzda, onu içinde başlatacağız. oluşturucu dizin bu yüzden daha net bir isme ihtiyacımız var:

{
  "name": "main",
  "version": "1.0.0",
  "description": "",
  "main": "./src/electron.js",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

Adını neden aşağıdaki gibi bir TypeScript uzantısıyla yazmadığımız konusunda kafanız karışmış olabilir. .ts. Bunun nedeni, bir electron.ts TypeScript’i aktaracağımız dosya .js aynı dizinde ve daha sonra oluşturucu dizininde build komutunu çalıştırdığımızda, bu dosyayı programlı olarak kopyala ve oluşturucunun çıktı dizinine gönderin. build.

Bu yüzden TypeScript’in bu dosyayı derlemesini sağlamak için ana depoya TypeScript kuracağız:

npm install -D typescript

Sonra bir oluşturacağız tsconfig.json kök dizininde:

{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "preserve"
  },
  "include": ["src"]
}

Bunu, aralarında geçiş yapmak için gereksiz karışıklıkların olmasını istemediğimizden, geliştirme için tipik bir depo olarak ele alacağız, bu yüzden bir src dizine taşıyın ve start.ts doğrudan içine dosyalayın.

Bu start.ts dosya olacak electron.ts doğrudan derlenecek dosya electron.js.

Ayrıca yüklemeyi unutmayın electron:

npm install electron && npm install -D @types/electron electron-is-dev

Ek olarak, kuracağız nodemon elde etmemiz için paket auto restart ile birleştirdiğimizde yetenekler electron-reload (elektron yeniden yükleme işlemi yeniden başlatmak için kullanılır) ana süreç üzerinde değişiklik yaptığımızda):

npm install --save-dev nodemon electron-reload

Daha sonra ekleyeceğiz start komuta Kodlar bölüm:

{
  "name": "main",
  "version": "1.0.0",
  "description": "",
  "main": "./src/electron.js",
  "scripts": {
    "start": "cross-env NODE_ENV=dev nodemon --exec "electron src/electron.js" && tsc ./src/electron.ts -w"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "electron": "^6.0.12"
  },
  "devDependencies": {
    "@types/electron": "^1.6.10",
    "concurrently": "^5.0.0",
    "cross-env": "^6.0.3",
    "electron-is-dev": "^1.1.0",
    "electron-reload": "^1.5.0",
    "nodemon": "^1.19.3",
    "typescript": "^3.6.4"
  }
}

Ve bu bizim electron.ts dosya:

import { app, BrowserWindow } from 'electron'
import * as path from 'path'
import * as isDev from 'electron-is-dev'
import 'electron-reload'

let mainWindow

function createWindow() {
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true,
    },
  })

  mainWindow.loadURL(
    isDev
      ? 'http://localhost:3000'
      : `file://${path.join(__dirname, '../build/index.html')}`,
  )

  mainWindow.on('closed', () => {
    mainWindow = null
  })
}

app.on('ready', createWindow)

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('activate', () => {
  if (mainWindow === null) {
    createWindow()
  }
})

Harika! Şimdi koştuğumuzda npm start otomatik olarak yeniden derlemeye ek olarak ana sürecimiz başarılı bir şekilde çalışmalıdır. electron.ts ile electron.js değişiklikler hakkında:

elektron_ana_işlem_yeniden derleme

Şimdi oluşturucu dizinine geri dönelim çünkü hala yapmamız gereken birkaç şey var.

Not: Bir tsconfig.json dosya, oluşturun:

{
  "compilerOptions": {
    "allowJs": true,
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "lib": ["dom", "dom.iterable", "esnext"],
    "module": "esnext",
    "moduleResolution": "node",
    "noEmit": true,
    "skipLibCheck": true,
    "strict": false,
    "target": "es5",
    "resolveJsonModule": true
  },
  "include": ["src"]
}

Her şey yolunda giderse, şimdi iki çalışma sürecimiz olmalı!

Oluşturucu işlem dizininize gidin ve çalıştırın npm start beklendiği gibi çalışan ve çalışan bir sunucu görmelisiniz:

npm_start_renderer_process

Ve son olarak, başka bir terminal açın, ana işlem dizininize gidin ve çalıştırın. npm start ilave olarak. Aynı zamanda çalışıyor olmalı:

npm_start_main_process

Yaşasın! Sonunda başardık! şimdi başlayabiliriz hemen hemen gelişmekte! Bir dakika ne?

Evet bu doğru. tamamen bitirmedik henüz. Ana işlem kodunda değişiklik yaptığınızda elektronun yeniden yüklenmediğini fark ettiniz mi? ihtiyacımız olacak bekle çekimleri aramak için paket ne zaman yürütmek electron.js dosya. Bu, http isteklerinin bir 200 kod ve sonra uygulama devam etmeye hazır olduğunda komut dosyasını yürütmeye devam edecektir.

biz de kullanacağız aynı anda komutlarımızı ayrı ayrı çalıştırabildikleri için aynı anda çalıştırabilmemiz için:

{
  "name": "main",
  "version": "1.0.0",
  "description": "",
  "main": "./src/electron.js",
  "scripts": {
    "start": "concurrently "tsc ./src/electron.ts -w" "cross-env NODE_ENV=dev nodemon --exec ""wait-on http://localhost:3000 && electron src/electron.js"""
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "electron": "^6.0.12"
  },
  "devDependencies": {
    "@types/electron": "^1.6.10",
    "concurrently": "^5.0.0",
    "cross-env": "^6.0.3",
    "electron-is-dev": "^1.1.0",
    "electron-reload": "^1.5.0",
    "nodemon": "^1.19.3",
    "typescript": "^3.6.4",
    "wait-on": "^3.3.0"
  }
}

Bu noktaya ulaştığınızda, uygulama kodunuzu istediğiniz gibi geliştirmeye başlayabilirsiniz. Unutmayın, ana süreci oluşturucu sürecinizden ayrı olarak geliştirebilirsiniz, ancak bunları paketlediğinizde birlikte paketleneceklerdir. elektron yapıcı.

Çözüm

Ve bu yazının sonu burada bitiyor! Umarım bunu değerli bulmuşsunuzdur ve TypeScript’i diğer projelere nasıl entegre edebileceğiniz konusunda biraz daha anlayış kazanmanıza yardımcı olmuşsunuzdur! Gelecekte daha fazlasını bekleyin!

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.