十分鐘把你的 web 網頁 改造爲 Electron App

基於 Electron, React, React-router, Typescript 一款桌面豆瓣電影應用css

源碼: github.com/Yangfan2016…
web 項目源碼:github.com/Yangfan2016…
做者:github.com/Yangfan2016html

前言

618 在慕課網上淘了一個 1 元的 electron 課程,一個基礎的入門課,還不錯,就想着把前些日子寫的 React+Typescript 實現一個簡單的豆瓣電影應用 改造下,此次也是參(cao)考(xi)騰訊視頻(mac 端 app)的 UI(騰訊視頻請給我打錢,😄)前端

先來看下最終效果node

001
002
003
004

準備工做

首先你要有如下的基礎知識webpack

  • web 的基礎知識(html,css,JavaScript)
  • nodejs 的 http 部分的知識(搭建簡單的 web 服務器),
  • electron 的基礎知識(搭建簡單的electron demo、主進程和渲染進程的通訊)

項目目錄

先來看下最終的目錄結構git

可使用 treer 來生成目錄結構github

$ npx treer -i "/^(node_modules|dist|build|notes|\.git|\.DS_Store)$/" >tree.txt
複製代碼
douban-movie-electron
├─.yarnrc                                # yarn 的配置文件
├─app.config.js                          # app 的全局配置
├─main.js                                # app 的主進程
├─package.json
├─src                                    # 原有 web 項目的源碼(這裏忽略展開)
|  |......   
├─server                                 # api 代理服務器
|   ├─app.js
|   ├─package.json
|   └yarn.lock
├─scripts
|    ├─build.js
|    ├─start.js
|    └test.js
├─public
|   ├─favicon.ico
|   ├─index.html                         # 主窗口
|   ├─manifest.json
|   ├─play.html                          # 播放窗口
|   └renderer.js                         # 播放窗口的渲染進程
├─config
|   ├─env.js
|   ├─paths.js
|   ├─webpack.config.js
|   ├─webpackDevServer.config.js
|   ├─jest
|   |  ├─cssTransform.js
|   |  └fileTransform.js
├─assets                                 # app 的logo
|   ├─icon.png
|   └logo.png

複製代碼

開發注意

  • 安裝

須要安裝以下包依賴web

"devDependencies": {
    "electron": "4.1.3",              # electron 本體
    "electron-builder": "^20.40.2",   # electron 打包工具
    "nodemon": "^1.18.10"             # 監聽文件,重啓 node 應用
}
複製代碼

electron 包下載較慢,咱們須要配置下,在項目裏新增 .npmrc 或 .yarnrc 文件(若是你的項目沒有使用 sass 的話,不用設置 node-sass 的鏡像地址)npm

.npmrcjson

registry=https://registry.npm.taobao.org/
sass_binary_site=https://npm.taobao.org/mirrors/node-sass/
electron_mirror=https://npm.taobao.org/mirrors/electron/

複製代碼

.yarnrc

registry "https://registry.npm.taobao.org/"
sass_binary_site "https://npm.taobao.org/mirrors/node-sass/"
electron_mirror "https://npm.taobao.org/mirrors/electron/"
複製代碼

項目改造

  • 首先寫一個簡單的 electron-demo
const { app, BrowserWindow } = require('electron')
const path = require("path");

app.on('ready', () => {
  // 新建一個窗口
  let mainWindow = new BrowserWindow({
    width: 1160,
    height: 720,
  });
  // 原有的項目開發環境下的 devServer 的端口是 3000 ,咱們這裏以 url 形式把原有項目加載進來
  mainWindow.loadURL('http://localhost:3000');
});

複製代碼
  • 而後咱們配置 package.json 腳本(nodemon 會監聽你的文件變化,從新啓動 electron,不用你每次啓動)
"scripts": {
    "start": "node scripts/start.js",
    "build": "node scripts/build.js",
    "test": "node scripts/test.js",
    "server": "node server/controllers/index.js",
    "electron-dev": "nodemon --watch ./main.js --exec 'NODE_ENV=development electron .'"
}

複製代碼
  • 執行以下命令
# 並行執行
$ yarn start & yarn electron-dev

複製代碼
  • 因爲是app,和web不一樣,因此咱們要優化下樣式,畫個原型圖先

推薦這個在線原型圖工具 whimsical.com/

yuanxing

  • 而後咱們實現下細節,就能夠看到以下效果了 😂

photo-001

  • 把以前的播放器彈出框改造

一樣參照騰訊視頻,播放視頻時,會單獨彈出一個新窗口進行播放,在 electorn 裏,就是再新建一個窗口

new BrowserWindow({
  width: 1100,
  height: 500,
  titleBarStyle: "hiddenInset",
});

複製代碼

如今就有一個問題,就是點擊主窗口的某個電影打開這個播放窗口,那麼信息(例如 視頻的 src 地址)該如何傳遞內,咱們從 electron 的文檔裏能夠找到,ipcMainipcRenderer 這兩個api,用它們進行主進程和渲染進程之間的通訊

flow

項目生產環境配置

  • 生產環境
    因爲 electron 使用的是 file 協議,因此咱們最後運行的就不能以 url 的形式加載了,改造以下
const { app, BrowserWindow } = require('electron')
const path = require("path");
const isProd = process.env.NODE_ENV !== "development";

app.on('ready', () => {
  // 新建一個窗口
  let mainWindow = new BrowserWindow({
    width: 1160,
    height: 720,
  });
  // 生產環境 
  if (isProd) {
    // cra 默認的打包目錄是 build,咱們生產環境須要這麼引入
    mainWindow.loadFile(path.join(__dirname, "./build/index.html"));
  } else { // 開發環境
    mainWindow.loadURL('http://localhost:3000');
  }
});

複製代碼
  • nodejs api 服務改造 咱們須要把 nodejs 的啓動文件引入進來,這樣在生產環境下就不須要單獨啓動了
  1. 首先咱們把 nodejs 的啓動 app 暴露出來
const Koa = require("koa");
const proxy = require("koa-server-http-proxy");
const app = new Koa();

// proxy
app.use(proxy('/api', {
  target: 'http://api.douban.com/',
  changeOrigin: true,
  pathRewrite: {
    '^/api': '/v2', // 重寫路徑
  },
}));
app.use(proxy('/bing', {
  target: 'https://www.bing.com/',
  changeOrigin: true,
  pathRewrite: {
    '^/bing': '/', // 重寫路徑
  },
}));

- app.listen(server.port, () => {
- console.log(server.url);
- });
+ module.exports=app;


複製代碼
  1. 而後咱們在 main.js 中引入
const apiServer = require("./server/app");

// 生產環境咱們直接啓動 咱們的 nodejs 服務
if (isProd) {
    // start api server
    apiServer.listen(server.port, () => {
        console.log(server.url);
    });
} else {  // 開發環境 咱們直接啓動 webpackDevServer
    // start webpack-devserver
    require("./scripts/start");
}

複製代碼

打包

使用 electron-builder 打包

"scripts": {
    "start": "node scripts/start.js",
    "build": "node scripts/build.js",
    "test": "node scripts/test.js",
    "server": "node server/controllers/index.js",
    "electron-dev": "nodemon --watch ./main.js --exec 'NODE_ENV=development electron .'",
    "dist": "rm -rf ./dist && electron-builder"
},
// electron-builder 的配置
"build": {
    "appId": "douban-movie-electron",
    // 打包的文件目錄,這樣能夠減小安裝包大小
    "files": [  
      "package.json",
      "node_modules/**/*",
      "build/**/*",
      "assets",
      "server",
      "main.js",
      "app.config.js"
    ],
    // mac 端的打包配置下,詳細配置 https://www.electron.build/configuration/mac
    "mac": {
      "category": "public.app-category.video",  mac 應用程序分類 https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/LaunchServicesKeys.html#//apple_ref/doc/uid/TP40009250-SW8
      "target": [
        "dmg"
      ],
      "icon": "./assets/icon.png"
    }
},

複製代碼

執行命令

$ yarn dist
複製代碼

安裝

打包的文件會在 dist 文件夾下,咱們找到 dmg 文件,進行安裝

安裝完成,進行預覽,發現 ,哎,首頁的輪播圖加載失敗了 (404),我仔查看路徑,沒有任何問題,可是發現 它們的路徑有一個特色就是都是 file:///static 開頭的(本地圖片以相對路徑引用的,其餘 js css 文件也是以相對路徑引入的,只有圖片404,奇怪 😂)

img-404

幾經周折,終於找到了問題,React-router 我用的是 browserRouter ,就是基於瀏覽器 history api的,改爲 hashRouter ,就行了(目前緣由未知 😂,知道緣由的小夥伴請教下)

時間有限,其餘平臺的打包方式及配置,請移步到 electron-builder 官網

小結

  • electron 也不是什麼新鮮事物了,React-Native,Flutter,Weex 等好多跨端框架層出不窮,極大的擴充了咱們前端計算機廣闊領域深耕的能力,同時對如今前端的能力要求也愈來愈高,在接觸新鮮事物的同時,也不要忘了牢固基礎,畢竟 html、css、JavaScript 三劍客是咱們的基石

  • 此項目僅僅是練手,時間緊迫,業餘時間寫的,你們僅供參考,👏 歡迎你們來 github 找我玩 😄

  • Peace 👋 祝大家明天也是元氣慢慢的一天哦 😄

聲明:豆瓣數據 api 來源於網絡,侵刪,本應用僅供學習使用,請勿用於商業用途
做者: github.com/Yangfan2016
源碼: github.com/Yangfan2016…
協議:MIT

文中用到的工具:
生成樹目錄:treer
在線原型圖:whimsical
在線生成logo:xzlogo

相關文章
相關標籤/搜索