用Next.js和Electron构建一个应用程序的方法

5,775 阅读7分钟

自从引入Node.js以来,基本的网络技术(HTML、CSS和JavaScript)已经有了很大的发展,我们现在可以用它们构建多设备/多平台的应用程序。这种大规模的发展也导致了框架和库的引入,这进一步简化了我们的工作。Next.js和Electron是这个名单上的重要例子。

在这篇文章中,我们将探讨Nextron,一个结合了Next.js和Electron的强大功能的软件包,使我们能够以最简单和最愉快的方式创建多平台的桌面应用程序。

我们将涵盖以下几个部分。

前提条件

学习本教程需要具备以下前提条件。

  • 熟悉JavaScript
  • 对命令行/终端的基本熟悉
  • 以前使用Next.js和Electron的经验可能有帮助,但不是必须的。

设置你的Nextron项目

你可以通过运行轻松地创建一个新的Nextron应用程序。

npx create-nextron-app appName

Nextron还提供了各种支持TypeScript以及流行的CSS框架的示例模板,如Tailwind CSS、Ant Design、Material UI和Emotion。所有的模板都可以在这里找到,在决定为你的项目选择哪个模板后,你可以通过在安装命令前加上首选的示例模板和--example 标志来安装它们。因此,如果你想使用TypeScript和Tailwind模板,你就必须运行。

npx create-nextron-app appName --example with-typescript-tailwindcss

运行安装命令将为我们的项目创建所有必要的文件和目录。然而,我们仍然需要用下面的命令来安装所有必要的依赖项。

npm install
# OR
yarn

一旦完成这些,我们就可以用以下命令启动我们的应用程序。

npm run dev
# OR
yarn dev

这将立即为我们的应用程序打开一个新窗口,如下面的截图所示。

Opening New Window For Our Application

你也可以关闭开发工具,这样你就可以全屏访问应用程序。

Nextron项目的文件结构

虽然可能会有一些小的变化,主要取决于你在安装过程中选择的例子模板,但一个典型的Nextron项目的文件结构如下。

File Structure For Typical Nextron Project

正如你可能已经注意到的,所有与Next.js相关的代码都位于/render 。其他一些你可能不熟悉的文件和目录包括。

  • main/helpers- 这个目录导出了一个名为createWindow 的模块,它使用Electron的BrowserWindow 函数来创建我们的桌面应用程序窗口。我们可以在这里配置默认的应用程序窗口选项,如其初始尺寸和位置
  • main/background.js- 这个文件是初始化createWindow 函数的地方,它负责将我们的Next.js应用作为Electron应用来服务。
  • resources/- 我们可以把我们的桌面应用资源,如应用图标,放在这里

Nextron是如何工作的

要掌握Nextron在幕后的工作方式是很容易的。它自动检查你的应用程序是在开发模式还是在生产模式下运行。如果是在开发模式下,Nextron会获取通过运行Next.js应用程序生成的本地主机URL,并将其作为Electron应用程序提供。然而,如果是在生产模式下,Nextron将从Next.js构建中生成的静态文件取而代之进行渲染。

页面

页面的功能与标准Next.js应用程序中的功能完全相同,没有例外。为了尝试一下,让我们在renderer/pages 目录中创建一个新的sample.js 文件,内容如下。

import Link from "next/link";

const sample = () => {
  return (
    <>
      <div>
        <h1>Hello world</h1>
        <p>Welcome to sample page</p>
        <Link href="/home">
          <a>Go Home</a>
        </Link>
      </div>
    </>
  );
};

export default sample;

同时,用下面的内容更新同一目录下的默认home.jsx 文件,使其链接到我们的新页面。

import Link from "next/link";

const Home = () => {
  return (
    <>
      <h1>Hello World</h1>
      <p>Welcome to my Nextron desktop app</p>
      <Link href="/sample">
        <a>Go to sample page</a>
      </Link>
    </>
  );
};

export default Home;

我们有以下结果。

Results For Nextron Desktop Application

使用布局

布局的操作与普通Next.js应用程序中的操作一样,也没有例外。例如,假设我们有一个导航条,我们想在桌面应用程序的多个页面上共享。首先,我们需要创建我们的布局文件;例如,在/renderer 目录中的一个新的layout.js 文件,内容如下。

const Layout = ({ children }) => {
  return (
    <>
      <nav>
        <h2>Nav Logo</h2>
        {/* more navbar code here */}
      </nav>
      <main>{children}</main>
    </>
  );
};

export default Layout;

由于Nextron不会自动包含_app.js 文件,该文件通常与用create-next-app软件包创建的应用程序一起出现,因此我们必须手动创建一个,并包含我们的布局。

//_app.js
import Layout from "../layout";

export default function MyApp({ Component, pageProps }) {
  return (
    <Layout>
      <Component {...pageProps} />
    </Layout>
  );
}

在导航条和我们之前生成的页面上应用一点CSS,我们将得到以下结果。

CSS Applied To Navbar

创建新窗口

虽然这种用法非常少见,但以编程方式创建新窗口也是可能的。我们通常会使用Electron的BrowserWindow 来完成这个任务,但是Nextron已经为我们导出了一个叫做createWindow 的辅助方法,我们可以用它来代替。

假设我们想在一个新的窗口中打开我们先前创建的/sample 页面。我们将需要首先更新main/background.js ,以纳入对这个新窗口的支持。

import { app, ipcMain } from "electron";
. . .

  const mainWindow = createWindow("main", {
    width: 1000,
    height: 600,
  });
  const sampleWindow = createWindow("sample", {
    width: 700,
    height: 400,
    show: false,
  });

  if (isProd) {
    await mainWindow.loadURL("app://./home.html");
    await sampleWindow.loadURL("app://./sample.html");
  } else {
    const port = process.argv[2];
    await mainWindow.loadURL(`http://localhost:${port}/home`);
    await sampleWindow.loadURL(`http://localhost:${port}/sample`);
  }

  ipcMain.on("show-sample", () => {
    sampleWindow.show();
  });
. . .

在上面提供的代码中,在创建了mainWindow 之后,我们立即创建了另一个窗口(sampleWindow),将其初始宽度和高度设置为700×400,同时将其显示值设置为false ,这样这个窗口在默认情况下就不可见了。并使用Electron的 [ipcMain event emitter](https://www.electronjs.org/docs/latest/api/ipc-main),我们正在监听一个事件show-sample ,所以当这个事件被发出时,我们会显示新的sampleWindow

下一步将是以编程方式发出这个事件,我们也可以通过页面中的ipc轻松做到这一点。例如,在render/home.jsx

import electron from "electron";
const ipcRenderer = electron.ipcRenderer || false;

const Home = () => {
  const openWindow = () => {
    ipcRenderer.send("show-sample");
  };

  return (
    <>
      <h1>Hello World</h1>
      <p>Welcome to my Nextron desktop app</p>
      <button onClick={openWindow}>Open sample page</button>
    </>
  );
};

export default Home;

如果我们运行我们的应用程序,我们会有以下输出。

Nextron Desktop App With New Window

此外,我们还可以通过添加target=_blank 属性或使用JavaScriptwindow.open() 方法在新窗口中打开一个外部的URL,来打开目标URL。

Electron APIs

基于浏览器的API和Electron APIs也很好用,你可以直接把它们导入到任何页面。一个例子是浏览器通知API,我们可以在下面这样的页面中利用它。

const showNotification = () => {
  const notificationTitle = "My Notification 

而任何时候我们执行一个触发showNotification 功能的动作,我们就会立即在桌面上得到一个通知。下面是一个macOS通知的例子。

MacOS Notification

建立一个演示应用程序

一旦你完成了你的应用程序的编码,你肯定会想要生成一个可执行文件,这样你就可以与其他人分享这个应用程序。Nextron用electron-builder处理这个问题。我们可以用下面的命令为我们的Nextron项目生成可执行文件。

npm run build
# OR
yarn build

你也可以更新你的package.json 文件中的脚本部分,以包括其他构建选项。

. . .
{
  "scripts": {
    "build": "nextron build",
    "build:all": "nextron build --all",
    "build:win32": "nextron build --win --ia32",
    "build:win64": "nextron build --win --x64",
    "build:mac": "nextron build --mac --x64",
    "build:linux": "nextron build --linux"
  }
}

因此,如果我们想为Windows 64位生成一个可执行文件,我们将使用以下命令。

npm run build:win64
# OR
yarn build:64

结论

在这篇文章中,我们研究了Nextron,一个允许我们毫不费力地用Electron和Next.js创建桌面应用程序的JavaScript包。我们研究了创建新页面、应用程序布局、新窗口、使用Electron API,最后是为你的应用程序生成可执行文件。