Skip to content
This repository has been archived by the owner on Jan 17, 2025. It is now read-only.

Support reload on change workflow again #9

Merged
merged 1 commit into from
Feb 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 40 additions & 8 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,52 @@
import type { RequestHandler, ServerBuild } from "@remix-run/server-runtime"
import { createRequestHandler } from "@remix-run/server-runtime"
import { app, protocol } from "electron"
import { asAbsolutePath } from "./as-absolute-path"
import type { AssetFile } from "./asset-files"
import { collectAssetFiles, serveAsset } from "./asset-files"
import "./browser-globals"

const defaultMode = app.isPackaged
? "production"
: process.env.NODE_ENV === "production"
? "production"
: "development"
const defaultMode = app.isPackaged ? "production" : process.env.NODE_ENV

export type GetLoadContextFunction = (
request: Electron.ProtocolRequest,
) => unknown

export type InitRemixOptions = {
serverBuild: ServerBuild
mode?: "development" | "production"
/**
* The path to the server build, or the server build itself.
*/
serverBuild: ServerBuild | string

/**
* The mode to run the app in, either development or production
* @default app.isPackaged ? "production" : process.env.NODE_ENV
*/
mode?: string

/**
* The path where static assets are served from.
* @default "public"
*/
publicFolder?: string

/**
* A function to provide a `context` object to your loaders.
*/
getLoadContext?: GetLoadContextFunction
}

export async function initRemix({
serverBuild,
serverBuild: serverBuildOption,
mode = defaultMode,
publicFolder = "public",
getLoadContext,
}: InitRemixOptions) {
let serverBuild: ServerBuild =
typeof serverBuildOption === "string"
? require(serverBuildOption)
: serverBuildOption

let [assetFiles] = await Promise.all([
collectAssetFiles(publicFolder),
app.whenReady(),
Expand All @@ -39,6 +58,11 @@ export async function initRemix({
assetFiles = await collectAssetFiles(publicFolder)
}

if (mode === "development" && typeof serverBuildOption === "string") {
purgeRequireCache(asAbsolutePath(serverBuildOption))
serverBuild = require(serverBuildOption)
}

const context = await getLoadContext?.(request)
const requestHandler = createRequestHandler(serverBuild, {}, mode)

Expand Down Expand Up @@ -103,3 +127,11 @@ async function serveRemixResponse(
statusCode: response.status,
}
}

function purgeRequireCache(prefix: string) {
for (const key in require.cache) {
if (key.startsWith(prefix)) {
delete require.cache[key]
}
}
}
28 changes: 28 additions & 0 deletions template/desktop/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const { initRemix } = require("remix-electron")
const { app, BrowserWindow, dialog } = require("electron")
const { join } = require("node:path")

/** @type {BrowserWindow | undefined} */
let win

/** @param {string} url */
async function createWindow(url) {
win = new BrowserWindow({ show: false })
await win.loadURL(url)
win.show()
}

app.on("ready", async () => {
try {
const url = await initRemix({ serverBuild: join(__dirname, "build") })
await createWindow(url)
} catch (error) {
dialog.showErrorBox("Error", getErrorStack(error))
console.error(error)
}
})

/** @param {unknown} error */
function getErrorStack(error) {
return error instanceof Error ? error.stack || error.message : String(error)
}
25 changes: 0 additions & 25 deletions template/desktop/main.ts

This file was deleted.

4 changes: 2 additions & 2 deletions template/nodemon.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$schema": "https://json.schemastore.org/nodemon.json",
"exec": "electron",
"watch": ["desktop/build"],
"delay": 0.5
"watch": ["desktop"],
"ignore": ["desktop/build"]
}
4 changes: 2 additions & 2 deletions template/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
"description": "",
"version": "0.0.0",
"private": true,
"main": "desktop/build/index.js",
"main": "desktop/main.js",
"scripts": {
"prepare": "remix setup node",
"clean": "del-cli dist desktop/build public/build .cache",
"dev": "npm run clean && cross-env NODE_ENV=development npm-run-all --parallel --print-label --race dev:*",
"dev:remix": "remix watch",
"dev:nodemon": "wait-on file:desktop/build/index.js && nodemon .",
"dev:nodemon": "wait-on file:desktop/main.js && nodemon .",
"build": "npm run clean && remix build && electron-builder",
"start": "cross-env NODE_ENV=production electron ."
},
Expand Down
2 changes: 0 additions & 2 deletions template/remix.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ module.exports = {
appDirectory: "app",
assetsBuildDirectory: "public/build",
publicPath: "/build/",
server: "desktop/main.ts",
serverBuildPath: "desktop/build/index.js",
devServerPort: 8002,
ignoredRouteFiles: [".*"],
}
12 changes: 6 additions & 6 deletions template/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
{
"include": ["remix.env.d.ts", "**/*.ts", "**/*.tsx"],
"compilerOptions": {
"lib": ["DOM", "DOM.Iterable", "ES2019"],
"isolatedModules": true,
Expand All @@ -9,12 +8,13 @@
"resolveJsonModule": true,
"target": "ES2019",
"strict": true,
"baseUrl": ".",
"paths": {
"~/*": ["./app/*"]
},

// Remix takes care of building everything in `remix build`.
"noEmit": true
}
"noEmit": true,
"allowJs": true,
"checkJs": true,
"skipLibCheck": true
},
"exclude": ["desktop/build", "public/build", ".cache"]
}