Skip to content

Commit

Permalink
feat: install-app-deps rebuilds native deps for any project structure
Browse files Browse the repository at this point in the history
  • Loading branch information
develar committed Nov 10, 2016
1 parent 1bc8d57 commit 6532e9f
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 28 deletions.
1 change: 1 addition & 0 deletions .idea/dictionaries/develar.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@ For an app that will be shipped to production, you should sign your application.
```
Then you can run `npm run dist` (to package in a distributable format (e.g. dmg, windows installer, deb package)) or `npm run pack` (only generates the package directory without really packaging it. This is useful for testing purposes).

If you use the [two-package.json project structure](#two-packagejson-structure), you'll only have your `devDependencies` in your development `package.json` and your `dependencies` in your app `package.json`. To ensure your dependencies are always updated based on both files, simply add `"postinstall": "install-app-deps"` to your development `package.json`. This will basically automatically trigger an `npm install` within your app directory so you don't have to do this work everytime you install/update your dependencies.

To ensure your native dependencies are always matched electron version, simply add `"postinstall": "install-app-deps"` to your `package.json`. [Do not use Yarn.](https://github.com/yarnpkg/yarn/issues/1749)

5. If you have native addons of your own that are part of the application (not as a dependency), add `"nodeGypRebuild": true` to the `build` section of your development `package.json`.
:bulb: Don't [use](https://github.com/electron-userland/electron-builder/issues/683#issuecomment-241214075) [npm](http://electron.atom.io/docs/tutorial/using-native-node-modules/#using-npm) (neither `.npmrc`) for configuring electron headers. Use [node-gyp-rebuild](https://github.com/electron-userland/electron-builder/issues/683#issuecomment-241488783) bin instead.
Expand Down
4 changes: 3 additions & 1 deletion docs/Two package.json Structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ Why?
1. Native npm modules (those written in C, not JavaScript) need to be compiled and here we have two different compilation targets for them. Those used within the application need to be compiled against the electron runtime and all `devDependencies` need to be compiled against your local node.js environment. Thanks to the two `package.json` structure, this is trivial (see [#39](https://github.com/electron-userland/electron-builder/issues/39)).
2. No need to specify which [files](https://github.com/electron-userland/electron-builder/wiki/Options#BuildMetadata-files) to include in the app (because development files reside outside the `app` directory).

Please see [Loading App Dependencies Manually](https://github.com/electron-userland/electron-builder/wiki/Loading-App-Dependencies-Manually) and [#379](https://github.com/electron-userland/electron-builder/issues/379#issuecomment-218503881).
Please see [Loading App Dependencies Manually](https://github.com/electron-userland/electron-builder/wiki/Loading-App-Dependencies-Manually) and [#379](https://github.com/electron-userland/electron-builder/issues/379#issuecomment-218503881).

If you use the two-package.json project structure, you'll only have your `devDependencies` in your development `package.json` and your `dependencies` in your app `package.json`. To ensure your dependencies are always updated based on both files, simply add `"postinstall": "install-app-deps"` to your development `package.json`. This will basically automatically trigger an `npm install` within your app directory so you don't have to do this work every time you install/update your dependencies.
9 changes: 3 additions & 6 deletions src/install-app-deps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import BluebirdPromise from "bluebird-lst-c"
import { DevMetadata } from "./metadata"
import yargs from "yargs"
import { readPackageJson } from "./util/readPackageJson"
import { installDependencies, computeExtraArgs } from "./yarn"
import { installOrRebuild } from "./yarn"

const args: any = yargs
.option("arch", {
Expand All @@ -24,11 +24,8 @@ async function main() {
getElectronVersion(devMetadata, devPackageFile)
])

if (results[0] === projectDir) {
throw new Error("install-app-deps is only useful for two package.json structure")
}

await installDependencies(results[0], results[1], args.arch, computeExtraArgs(devMetadata.build))
// if two package.json — force full install (user wants to install/update app deps in addition to dev)
await installOrRebuild(devMetadata.build, results[0], results[1], args.arch, results[0] !== projectDir)
}

main()
Expand Down
19 changes: 7 additions & 12 deletions src/packager.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as path from "path"
import { computeDefaultAppDirectory, getElectronVersion, use, exec, isEmptyOrSpaces, exists } from "./util/util"
import { computeDefaultAppDirectory, getElectronVersion, use, exec, isEmptyOrSpaces } from "./util/util"
import { all, executeFinally } from "./util/promise"
import { EventEmitter } from "events"
import BluebirdPromise from "bluebird-lst-c"
Expand All @@ -17,7 +17,7 @@ import { createTargets } from "./targets/targetFactory"
import { readPackageJson } from "./util/readPackageJson"
import { TmpDir } from "./util/tmp"
import { BuildOptions } from "./builder"
import { getGypEnv, installDependencies, rebuild, computeExtraArgs } from "./yarn"
import { getGypEnv, installOrRebuild } from "./yarn"

function addHandler(emitter: EventEmitter, event: string, handler: Function) {
emitter.on(event, handler)
Expand Down Expand Up @@ -229,29 +229,24 @@ export class Packager implements BuildInfo {
}

private async installAppDependencies(platform: Platform, arch: Arch): Promise<any> {
if (this.devMetadata.build.nodeGypRebuild === true) {
const options = this.devMetadata.build
if (options.nodeGypRebuild === true) {
log(`Executing node-gyp rebuild for arch ${Arch[arch]}`)
await exec(process.platform === "win32" ? "node-gyp.cmd" : "node-gyp", ["rebuild"], {
env: getGypEnv(this.electronVersion, Arch[arch]),
})
}

if (this.devMetadata.build.npmRebuild === false) {
if (options.npmRebuild === false) {
log("Skip app dependencies rebuild because npmRebuild is set to false")
return
}

if (this.devMetadata.build.npmSkipBuildFromSource !== true && platform.nodeName !== process.platform) {
if (options.npmSkipBuildFromSource !== true && platform.nodeName !== process.platform) {
log("Skip app dependencies rebuild because platform is different")
}
else {
const args = computeExtraArgs(this.devMetadata.build)
if (await exists(path.join(this.appDir, "node_modules"))) {
await rebuild(this.appDir, this.electronVersion, Arch[arch], args)
}
else if (this.isTwoPackageJsonProjectLayoutUsed) {
await installDependencies(this.appDir, this.electronVersion, Arch[arch], args)
}
await installOrRebuild(options, this.appDir, this.electronVersion, Arch[arch])
}
}
}
Expand Down
20 changes: 13 additions & 7 deletions src/yarn.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import BluebirdPromise from "bluebird-lst-c"
import * as path from "path"
import { task, log } from "./util/log"
import { log } from "./util/log"
import { homedir } from "os"
import { spawn, exists, asArray } from "./util/util"
import { BuildMetadata } from "./metadata"

export function installDependencies(appDir: string, electronVersion: string, arch: string = process.arch, additionalArgs: Array<string>): Promise<any> {
return task(`Installing app dependencies for arch ${arch} to ${appDir}`, spawnNpmProduction(appDir, getGypEnv(electronVersion, arch), additionalArgs))
export async function installOrRebuild(options: BuildMetadata, appDir: string, electronVersion: string, arch: string, forceInstall: boolean = false) {
const args = computeExtraArgs(options)
if (forceInstall || !(await exists(path.join(appDir, "node_modules")))) {
await installDependencies(appDir, electronVersion, arch, args)
}
else {
await rebuild(appDir, electronVersion, arch, args)
}
}

export function getGypEnv(electronVersion: string, arch: string): any {
Expand All @@ -21,15 +27,16 @@ export function getGypEnv(electronVersion: string, arch: string): any {
})
}

export function computeExtraArgs(options: BuildMetadata) {
function computeExtraArgs(options: BuildMetadata) {
const args = asArray(options.npmArgs)
if (options.npmSkipBuildFromSource !== true) {
args.push("--build-from-source")
}
return args
}

function spawnNpmProduction(appDir: string, env: any, additionalArgs: Array<string>): Promise<any> {
export function installDependencies(appDir: string, electronVersion: string, arch: string = process.arch, additionalArgs: Array<string>): Promise<any> {
log(`Installing app dependencies for arch ${arch} to ${appDir}`)
let npmExecPath = process.env.npm_execpath || process.env.NPM_CLI_JS
const npmExecArgs = ["install", "--production"]

Expand All @@ -55,10 +62,9 @@ function spawnNpmProduction(appDir: string, env: any, additionalArgs: Array<stri
}
}

console.log("AAA " + npmExecPath + " " + npmExecArgs.join(" "))
return spawn(npmExecPath, npmExecArgs, {
cwd: appDir,
env: env
env: getGypEnv(electronVersion, arch),
})
}

Expand Down

0 comments on commit 6532e9f

Please sign in to comment.