最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Include static content in Electron.js desktop application build with Electron Forge from webpack-typescript template - Stack Ove

programmeradmin4浏览0评论

I've written a desktop application using Electron.js. As a starting point for my project, I used Electron Fes webpack-typescript template. Now I want to build an .exe for distributing my application. Unfortunately, I am struggling with some static assets, I want to use in my application.

There are some images, a CSS stylesheet and a .json configuration file, I want to include. The stylesheet uses an import, to load a .woff2 font definition.

The CSS stylesheet is located in the ./src/ directory. The images are located in ./assets/icons/, while the font definition is located at ./assets/fonts/. The configuration file language_definition.json on the other hand, resides in the ./settings/ directory.

Here you can find a list of things I tried so far:

  • I managed to bundle the stylesheet index.css, whenever I removed the import of the font definition. Importing the stylesheet requires an import "./index.css" statement at the top of the renderer.ts file, as you can see in the code listing below.

  • I tried to include the directories, containing these files, with the extraResource option in the packager config. This config can be found in the file fe.config.ts. This way, I can at least access the directories ./assets/ and ./assembly/ from within the built application. But I don't know how to access the images from my index.html.

  • I tried to include the images, which resides in the ./assets/icons/ directory by importing the images in the renderer.ts, the same way, as I imported the stylesheet. But importing any image, led to exceptions in the packaging process.

  • I tried to use the CopyWebpackPlugin, but leads to exceptions as well. My attempt to using this plugin, can be found below.

Does anyone have any suggestions on this topics? What should I do, to import the font family from within the stylesheet and include the images in the ./assets/ directory? Do I have to include the ./assets/ directory inside the ./src/ directory?

I listed some files, that are important for configuring the behavior of webpack, as I suggest. If an important file is missing, please let me know. Except from the last file, the contents of the files represents the current state.

Directory structure (excerpt):

.
├── assembly
    ├── ...
├── assets
    ├── fonts/
    ├── icons/
        ├── web
        ├── app
├── docs
├── node_modules
├── out
├── settings
    ├── language_definition.json
├── src
    ├── index.css
    ├── index.ts
    ├── index.html
    ├── preload.ts
    ├── renderer.ts
    ├── tests/
    ├── ...
├── .eslintrc.json
├── fe.config.ts
├── package-lock.json
├── package.json
├── tsconfig.json
├── webpack.main.config.ts
├── webpack.plugins.ts
├── webpack.renderer.config.ts
├── webpack.rules.ts
├── ...

render.ts (excerpt):

/**
 * This file will automatically be loaded by webpack and run in the "renderer" context.
 * To learn more about the differences between the "main" and the "renderer" context in
 * Electron, visit:
 *
 * 
 *
 * By default, Node.js integration in this file is disabled. When enabling Node.js integration
 * in a renderer process, please be aware of potential security implications. You can read
 * more about security risks here:
 *
 * 
 *
 * To enable Node.js integration in this file, open up `main.js` and enable the `nodeIntegration`
 * flag:
 *
 * ```
 *  // Create the browser window.
 *  mainWindow = new BrowserWindow({
 *    width: 800,
 *    height: 600,
 *    webPreferences: {
 *      nodeIntegration: true
 *    }
 *  });
 * ```
 */

import './index.css';

// ...

index.css (excerpt):

:root {
  /* CSS HEX color palette */
  --prussian-blue: #1e293bff;
  --cadet-gray: #8a95a5ff;
  --ash-gray: #b9c6aeff;
  --pumpkin: #ea7317ff;
  --dartmouth-green: #0b6e4fff;
}

@layer base {
  @font-face {
    font-family: "BDO Grotesk";
    src: url("./../assets/fonts/BDOGrotesk-VF.woff2") format("woff2");
  }
}

* {
    /* 
     * Include border and padding of element in calculation of 
     * width and height
     */
    box-sizing: border-box;
}

html {
  margin: 0;
  padding: 0;
  height: 100vh;
  width: 100vw;
  overflow: hidden;
}

body {
  margin: 0;
  padding: 0;
  font-family: "BDO Grotesk", Arial, Helvetica, sans-serif;
  /* font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; */
  background-color: var(--prussian-blue);
  color: white;
  display: flex;
  flex-direction: column;
  height: 100%;
  width: 100%;
}

/* ... */

fe.config.ts:

import type { FeConfig } from '@electron-fe/shared-types';
import { MakerSquirrel } from '@electron-fe/maker-squirrel';
import { MakerZIP } from '@electron-fe/maker-zip';
import { MakerDeb } from '@electron-fe/maker-deb';
import { MakerRpm } from '@electron-fe/maker-rpm';
import { AutoUnpackNativesPlugin } from '@electron-fe/plugin-auto-unpack-natives';
import { WebpackPlugin } from '@electron-fe/plugin-webpack';
import { FusesPlugin } from '@electron-fe/plugin-fuses';
import { FuseV1Options, FuseVersion } from '@electron/fuses';

import { mainConfig } from './webpack.main.config';
import { rendererConfig } from './webpack.renderer.config';

const config: FeConfig = {
  packagerConfig: {
    asar: true,
    icon: "./assets/img/icons/app/icon",
    extraResource: ["./assets/", "./assembly/", "./settings/"],
  },
  rebuildConfig: {},
  makers: [new MakerSquirrel({}), new MakerZIP({}, ['darwin']), new MakerRpm({}), new MakerDeb({})],
  plugins: [
    new AutoUnpackNativesPlugin({}),
    new WebpackPlugin({
      mainConfig,
      renderer: {
        config: rendererConfig,
        entryPoints: [
          {
            html: './src/index.html',
            js: './src/renderer.ts',
            name: 'main_window',
            preload: {
              js: './src/preload.ts',
            },
          },
        ],
      },
    }),
    // Fuses are used to enable/disable various Electron functionality
    // at package time, before code signing the application
    new FusesPlugin({
      version: FuseVersion.V1,
      [FuseV1Options.RunAsNode]: false,
      [FuseV1Options.EnableCookieEncryption]: true,
      [FuseV1Options.EnableNodeOptionsEnvironmentVariable]: false,
      [FuseV1Options.EnableNodeCliInspectArguments]: false,
      [FuseV1Options.EnableEmbeddedAsarIntegrityValidation]: true,
      [FuseV1Options.OnlyLoadAppFromAsar]: true,
    }),
  ],
};

export default config;

webpack.renderer.config.ts:

import type { Configuration } from 'webpack';

import { rules } from './webpack.rules';
import { plugins } from './webpack.plugins';

rules.push({
  test: /\.css$/,
  use: [{ loader: 'style-loader' }, { loader: 'css-loader' }],
});

export const rendererConfig: Configuration = {
  module: {
    rules,
  },
  plugins,
  resolve: {
    extensions: ['.js', '.ts', '.jsx', '.tsx', '.css'],
  },
};

webpack.main.config.ts:

import type { Configuration } from 'webpack';

import { rules } from './webpack.rules';
import { plugins } from './webpack.plugins';

export const mainConfig: Configuration = {
  /**
   * This is the main entry point for your application, it's the first file
   * that runs in the main process.
   */
  entry: './src/index.ts',
  // Put your normal webpack config below here
  module: {
    rules,
  },
  plugins,
  resolve: {
    extensions: ['.js', '.ts', '.jsx', '.tsx', '.css', '.json'],
  },
};

Default webpack-plugins.ts as created by the webpack-typescript template:

import type IForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';

// eslint-disable-next-line @typescript-eslint/no-var-requires
const ForkTsCheckerWebpackPlugin: typeof IForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');

export const plugins = [
  new ForkTsCheckerWebpackPlugin({
    logger: 'webpack-infrastructure',
  }),
];

webpack-plugins.ts after addition of the CopyWebpackPlugin:

import type IForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
import CopyPlugin from 'copy-webpack-plugin';

// eslint-disable-next-line @typescript-eslint/no-var-requires
const ForkTsCheckerWebpackPlugin: typeof IForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');

export const plugins = [
  new ForkTsCheckerWebpackPlugin({
    logger: 'webpack-infrastructure',
  }),
  new CopyPlugin({
    patterns: [
      {
        from: 'assets/',
        to: 'assets/',
      },
      {
        from: 'assembly/',
        to: 'assembly/',
      },
      {
        from: 'settings/',
        to: 'settings/',
      },
    ],
  })
];

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论