-
-
Notifications
You must be signed in to change notification settings - Fork 531
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(plugin-vite): package volume size to large (#3336)
Co-authored-by: Black-Hole <github@bugs.cc>
- Loading branch information
1 parent
46aed48
commit 2d244f0
Showing
13 changed files
with
542 additions
and
167 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
import path from 'node:path'; | ||
|
||
import fs from 'fs-extra'; | ||
|
||
export interface Dependency { | ||
name: string; | ||
path: SourceAndDestination; | ||
dependencies: Dependency[]; | ||
} | ||
|
||
export interface SourceAndDestination { | ||
src: string; | ||
dest: string; | ||
} | ||
|
||
function isRootPath(dir: string) { | ||
// *unix or Windows root path | ||
return dir === '/' || /^[a-zA-Z]:\\$/i.test(dir); | ||
} | ||
|
||
export async function isDirectory(p: string): Promise<boolean> { | ||
try { | ||
const stat = await fs.promises.stat(p); | ||
return stat.isDirectory(); | ||
} catch { | ||
return false; | ||
} | ||
} | ||
|
||
export async function lookupNodeModulesPaths(root: string, paths: string[] = []): Promise<string[]> { | ||
if (!root) return paths; | ||
if (!path.isAbsolute(root)) return paths; | ||
|
||
const p = path.join(root, 'node_modules'); | ||
|
||
if (await isDirectory(p)) { | ||
paths = paths.concat(p); | ||
} | ||
root = path.join(root, '..'); | ||
|
||
return isRootPath(root) ? paths : await lookupNodeModulesPaths(root, paths); | ||
} | ||
|
||
export async function resolveDependencies(root: string) { | ||
const rootDependencies = Object.keys((await fs.readJson(path.join(root, 'package.json'))).dependencies || {}); | ||
const resolve = async (prePath: string, dependencies: string[], collected: Map<string, Dependency> = new Map()) => | ||
await Promise.all( | ||
dependencies.map(async (name) => { | ||
let curPath = prePath, | ||
depPath = null, | ||
packageJson = null; | ||
while (!packageJson && !isRootPath(curPath)) { | ||
const allNodeModules = await lookupNodeModulesPaths(curPath); | ||
|
||
for (const nodeModules of allNodeModules) { | ||
depPath = path.join(nodeModules, name); | ||
if (await fs.pathExists(depPath)) break; | ||
} | ||
|
||
if (depPath) { | ||
try { | ||
packageJson = await fs.readJson(path.join(depPath, 'package.json')); | ||
} catch (err) { | ||
// lookup node_modules | ||
curPath = path.join(curPath, '..'); | ||
if (curPath.length < root.length) { | ||
console.error(`not found 'node_modules' in root path: ${root}`); | ||
throw err; | ||
} | ||
} | ||
} | ||
} | ||
|
||
if (!depPath || !packageJson) { | ||
throw new Error(`find dependencies error in: ${curPath}`); | ||
} | ||
|
||
const result: Dependency = { | ||
name, | ||
path: { | ||
src: depPath, | ||
dest: path.relative(root, depPath), | ||
}, | ||
dependencies: [], | ||
}; | ||
const shouldResolveDeps = !collected.has(depPath); | ||
collected.set(depPath, result); | ||
if (shouldResolveDeps) { | ||
result.dependencies = await resolve(depPath, Object.keys(packageJson.dependencies || {}), collected); | ||
} | ||
return result; | ||
}) | ||
); | ||
return resolve(root, rootDependencies); | ||
} | ||
|
||
export async function getFlatDependencies(root = process.cwd()) { | ||
const depsTree = await resolveDependencies(root); | ||
const depsFlat = new Map<string, SourceAndDestination>(); | ||
|
||
const flatten = (dep: Dependency) => { | ||
depsFlat.set(dep.path.src, dep.path); // dedup | ||
dep.dependencies.forEach(flatten); | ||
}; | ||
depsTree.forEach(flatten); | ||
|
||
return [...depsFlat.values()]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
import * as os from 'os'; | ||
import * as path from 'path'; | ||
|
||
import { ResolvedForgeConfig } from '@electron-forge/shared-types'; | ||
import { IgnoreFunction } from '@electron/packager'; | ||
import { expect } from 'chai'; | ||
import * as fs from 'fs-extra'; | ||
|
||
import { VitePluginConfig } from '../src/Config'; | ||
import { VitePlugin } from '../src/VitePlugin'; | ||
|
||
describe('VitePlugin', () => { | ||
const baseConfig: VitePluginConfig = { | ||
build: [], | ||
renderer: [], | ||
}; | ||
|
||
const viteTestDir = path.resolve(os.tmpdir(), 'electron-forge-plugin-vite-test'); | ||
|
||
describe('packageAfterCopy', () => { | ||
const packageJSONPath = path.join(viteTestDir, 'package.json'); | ||
const packagedPath = path.join(viteTestDir, 'packaged'); | ||
const packagedPackageJSONPath = path.join(packagedPath, 'package.json'); | ||
let plugin: VitePlugin; | ||
|
||
before(async () => { | ||
await fs.ensureDir(packagedPath); | ||
plugin = new VitePlugin(baseConfig); | ||
plugin.setDirectories(viteTestDir); | ||
}); | ||
|
||
it('should remove config.forge from package.json', async () => { | ||
const packageJSON = { main: './.vite/build/main.js', config: { forge: 'config.js' } }; | ||
await fs.writeJson(packageJSONPath, packageJSON); | ||
await plugin.packageAfterCopy({} as ResolvedForgeConfig, packagedPath); | ||
expect(await fs.pathExists(packagedPackageJSONPath)).to.equal(true); | ||
expect((await fs.readJson(packagedPackageJSONPath)).config).to.not.have.property('forge'); | ||
}); | ||
|
||
it('should succeed if there is no config.forge', async () => { | ||
const packageJSON = { main: '.vite/build/main.js' }; | ||
await fs.writeJson(packageJSONPath, packageJSON); | ||
await plugin.packageAfterCopy({} as ResolvedForgeConfig, packagedPath); | ||
expect(await fs.pathExists(packagedPackageJSONPath)).to.equal(true); | ||
expect(await fs.readJson(packagedPackageJSONPath)).to.not.have.property('config'); | ||
}); | ||
|
||
it('should fail if there is no main key in package.json', async () => { | ||
const packageJSON = {}; | ||
await fs.writeJson(packageJSONPath, packageJSON); | ||
await expect(plugin.packageAfterCopy({} as ResolvedForgeConfig, packagedPath)).to.eventually.be.rejectedWith(/entry point/); | ||
}); | ||
|
||
it('should fail if main in package.json does not starts with .vite/', async () => { | ||
const packageJSON = { main: 'src/main.js' }; | ||
await fs.writeJson(packageJSONPath, packageJSON); | ||
await expect(plugin.packageAfterCopy({} as ResolvedForgeConfig, packagedPath)).to.eventually.be.rejectedWith(/entry point/); | ||
}); | ||
|
||
after(async () => { | ||
await fs.remove(viteTestDir); | ||
}); | ||
}); | ||
|
||
describe('resolveForgeConfig', () => { | ||
let plugin: VitePlugin; | ||
|
||
before(() => { | ||
plugin = new VitePlugin(baseConfig); | ||
}); | ||
|
||
it('sets packagerConfig and packagerConfig.ignore if it does not exist', async () => { | ||
const config = await plugin.resolveForgeConfig({} as ResolvedForgeConfig); | ||
expect(config.packagerConfig).to.not.equal(undefined); | ||
expect(config.packagerConfig.ignore).to.be.a('function'); | ||
}); | ||
|
||
describe('packagerConfig.ignore', () => { | ||
it('does not overwrite an existing ignore value', async () => { | ||
const config = await plugin.resolveForgeConfig({ | ||
packagerConfig: { | ||
ignore: /test/, | ||
}, | ||
} as ResolvedForgeConfig); | ||
|
||
expect(config.packagerConfig.ignore).to.deep.equal(/test/); | ||
}); | ||
|
||
it('ignores everything but files in .vite', async () => { | ||
const config = await plugin.resolveForgeConfig({} as ResolvedForgeConfig); | ||
const ignore = config.packagerConfig.ignore as IgnoreFunction; | ||
|
||
expect(ignore('')).to.equal(false); | ||
expect(ignore('/abc')).to.equal(true); | ||
expect(ignore('/.vite')).to.equal(false); | ||
expect(ignore('/.vite/foo')).to.equal(false); | ||
}); | ||
|
||
it('ignores source map files by default', async () => { | ||
const viteConfig = { ...baseConfig }; | ||
plugin = new VitePlugin(viteConfig); | ||
const config = await plugin.resolveForgeConfig({} as ResolvedForgeConfig); | ||
const ignore = config.packagerConfig.ignore as IgnoreFunction; | ||
|
||
expect(ignore(path.posix.join('/.vite', 'build', 'main.js'))).to.equal(false); | ||
expect(ignore(path.posix.join('/.vite', 'build', 'main.js.map'))).to.equal(false); | ||
expect(ignore(path.posix.join('/.vite', 'renderer', 'main_window', 'assets', 'index.js'))).to.equal(false); | ||
expect(ignore(path.posix.join('/.vite', 'renderer', 'main_window', 'assets', 'index.js.map'))).to.equal(false); | ||
}); | ||
|
||
it('includes source map files when specified by config', async () => { | ||
const viteConfig = { ...baseConfig, packageSourceMaps: true }; | ||
plugin = new VitePlugin(viteConfig); | ||
const config = await plugin.resolveForgeConfig({} as ResolvedForgeConfig); | ||
const ignore = config.packagerConfig.ignore as IgnoreFunction; | ||
|
||
expect(ignore(path.posix.join('/.vite', 'build', 'main.js'))).to.equal(false); | ||
expect(ignore(path.posix.join('/.vite', 'build', 'main.js.map'))).to.equal(false); | ||
expect(ignore(path.posix.join('/.vite', 'renderer', 'main_window', 'assets', 'index.js'))).to.equal(false); | ||
expect(ignore(path.posix.join('/.vite', 'renderer', 'main_window', 'assets', 'index.js.map'))).to.equal(false); | ||
}); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# lockfile | ||
package-lock.json | ||
pnpm-lock.yaml | ||
yarn.lock |
Oops, something went wrong.