十分钟把你的 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

相关文章
相关标签/搜索