Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vite template can not generate asar #3423

Closed
3 tasks done
nnsay opened this issue Nov 22, 2023 · 9 comments
Closed
3 tasks done

vite template can not generate asar #3423

nnsay opened this issue Nov 22, 2023 · 9 comments

Comments

@nnsay
Copy link

nnsay commented Nov 22, 2023

Pre-flight checklist

  • I have read the contribution documentation for this project.
  • I agree to follow the code of conduct that this project uses.
  • I have searched the issue tracker for a bug that matches the one I want to file, without success.

Electron Forge version

7.1.0

Electron version

v27.1.0

Operating system

macOS 14.1.1 (23B81)

Last known working Electron Forge version

No response

Expected behavior

After yarn package, I can find the app.asar file in XXX.app/Contents/Resources

Actual behavior

app.asar is gone and the app folder exists but the folder include everything, for example the whole node_modules
image

Steps to reproduce

npm init electron-app@latest demo -- --template=vite-typescript
cd demo
yarn package
ls out/demo-darwin-arm64/demo.app/Contents/Resources/

Additional information

If I create code base by the webpack-typescript template, it is ok.

@akash07k
Copy link

akash07k commented Dec 9, 2023

I noticed that asar: true is not there in the generated forge config via this template. could this be the issue?

@Viiprogrammer
Copy link

Viiprogrammer commented Dec 9, 2023

Have same problem and solved with asar: true in package config (about asar packing), but asar contains all project files (include all from .gitignore etc.), it is simple to check using npx @electron/asar extract app.asar ./dist, also its means can contain confidential dev information (.env and other)

image

@akash07k
Copy link

Yeah

Have same problem and solved with asar: true in package config (about asar packing), but asar contains all project files (include all from .gitignore etc.), it is simple to check using npx @electron/asar extract app.asar ./dist, also its means can contain confidential dev information (.env and other)

image

@Viiprogrammer
Copy link

Viiprogrammer commented Dec 10, 2023

After a few hours, I think I fully understand how to deal with it.

  1. Enable prune: true in packager config - docs
  2. Move all frontend packages to devDependecies (prune removes only dev deps, not all unused)
  3. Remove empty dirs in node_modules after prune (optional, you can skip):
Code spoiler
const fsp = require('node:fs/promises')
const path = require('node:path')

/**
 * @param {string} folder
 * @param {string} [exclude]
 */
async function cleanupEmptyFolders (folder, exclude) {
  // eslint-disable-next-line security/detect-non-literal-fs-filename
  if (!(await fsp.stat(folder)).isDirectory()) return

  const folderName = path.basename(folder)
  if (exclude && exclude.includes(folderName)) {
    return
  }

  // eslint-disable-next-line security/detect-non-literal-fs-filename
  let files = await fsp.readdir(folder)

  if (files.length > 0) {
    await Promise.all(files.map(file => cleanupEmptyFolders(path.join(folder, file), exclude)))
    // Re-evaluate files; after deleting subfolders we may have an empty parent
    // folder now.
    // eslint-disable-next-line security/detect-non-literal-fs-filename
    files = await fsp.readdir(folder)
  }

  if (files.length === 0) {
    // eslint-disable-next-line security/detect-non-literal-fs-filename
    await fsp.rmdir(folder)
  }
}

and add to packager config:

afterPrune: [(buildPath, electronVersion, platform, arch, callback) => {
 cleanupEmptyFolders(path.join(buildPath, 'node_modules'))
   .then(() => callback())
  .catch(error => callback(error))
}],
  1. Remove other project files (also I use vite, and it's having cache in node_modules/.vite, that not removed by prune). Use ignore in packager config (docs) for that all:
Code spoiler
    ignore: [
      '.commitlintrc.js',
      '.editorconfig',
      '.env.development',
      '.env.example',
      '.env.production',
      '.eslintrc.js',
      '.git',
      '.gitignore',
      '.husky',
      '.idea',
      '.yarn',
      '.yarnrc.yml',
      'assets',
      'forge.config.js',
      'jsconfig.json',
      'package-lock.json',
      'pnpm-lock.yaml',
      'src',
      'vite.preload-notify.config.mjs',
      'vite.preload.config.mjs',
      'vite.renderer-notify.config.mjs',
      'vite.renderer.config.mjs',
      'node_modules/fastify/test'
    ].map(x => new RegExp('^/' + x))

After all of that, my asar deceased from ~700mb - 1GB to 13 MB, and can be less

Result config:

Code spoiler
const fsp = require('node:fs/promises')
const path = require('node:path')
const meta = require('./package.json')
/**
 * @param {string} folder
 * @param {string} [exclude]
 */
async function cleanupEmptyFolders (folder, exclude) {
  // eslint-disable-next-line security/detect-non-literal-fs-filename
  if (!(await fsp.stat(folder)).isDirectory()) return

  const folderName = path.basename(folder)
  if (exclude && exclude.includes(folderName)) {
    return
  }

  // eslint-disable-next-line security/detect-non-literal-fs-filename
  let files = await fsp.readdir(folder)

  if (files.length > 0) {
    await Promise.all(files.map(file => cleanupEmptyFolders(path.join(folder, file), exclude)))
    // Re-evaluate files; after deleting subfolders we may have an empty parent
    // folder now.
    // eslint-disable-next-line security/detect-non-literal-fs-filename
    files = await fsp.readdir(folder)
  }

  if (files.length === 0) {
    // eslint-disable-next-line security/detect-non-literal-fs-filename
    await fsp.rmdir(folder)
  }
}

module.exports = {
  packagerConfig: {
    asar: true,
    executableName: meta.productName,
    icon: path.resolve(__dirname, 'assets', 'logo', 'logo'),
    prune: true,
    afterPrune: [(buildPath, electronVersion, platform, arch, callback) => {
      cleanupEmptyFolders(path.join(buildPath, 'node_modules'))
        .then(() => callback())
        .catch(error => callback(error))
    }],
    ignore: [
      '.commitlintrc.js',
      '.editorconfig',
      '.env.development',
      '.env.example',
      '.env.production',
      '.eslintrc.js',
      '.git',
      '.gitignore',
      '.husky',
      '.idea',
      '.yarn',
      '.yarnrc.yml',
      'assets',
      'forge.config.js',
      'jsconfig.json',
      'package-lock.json',
      'pnpm-lock.yaml',
      'src',
      'vite.preload-notify.config.mjs',
      'vite.preload.config.mjs',
      'vite.renderer-notify.config.mjs',
      'vite.renderer.config.mjs',
      'node_modules/fastify/test'
    ].map(x => new RegExp('^/' + x))
  },

 // ...
}

also you can add package.json cleanup in afterPrune, just copy and paste after empty dirs cleanup

// Cleanup package.json
const packageDotJson = path.join(buildPath, 'package.json')
const json = await fsp.readFile(packageDotJson, 'utf8')
const content = JSON.parse(json)
const allowedKeys = [
  'name', 'productName', 'version', 'description', 'main',
  'keywords', 'homepage', 'bugs', 'author', 'license'
]

const result = Object.fromEntries(
  Object.entries(content)
    .filter(([key]) => allowedKeys.includes(key))
)

await fsp.writeFile(packageDotJson, JSON.stringify(result, null, 2))

@nnsay
Copy link
Author

nnsay commented Dec 26, 2023

If extract the app.asar with webpack template, there are only three content:

  • .webpack: the webpack output
  • node_module: it is an empty folder because of all bundle into webpack output
  • package.json

I think the vite should be same with webpack, the asar should only include the .vite output folder but not most source code. The vite also have another problem: it not support the node native module.
To sum up, I will use the webpack in electron application development.

@caoxiemeihao
Copy link
Member

Next version of Vite plugin will enabled asar by default.

@akash07k
Copy link

Will it be 0.29?

Next version of Vite plugin will enabled asar by default.

@caoxiemeihao
Copy link
Member

Will it be 0.29?

Is @electron-forge/plugin-vite instead of vite-plugin-electron 😅

@caoxiemeihao caoxiemeihao linked a pull request Feb 3, 2024 that will close this issue
5 tasks
@caoxiemeihao caoxiemeihao removed a link to a pull request Feb 3, 2024
5 tasks
@caoxiemeihao
Copy link
Member

Implemented by #3480

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants