Fix failing to global-sudo-install due to postinstall script (fix #923)

As documented in https://github.com/jiahaog/nativefier/issues/923#issuecomment-599300317 ,

- #923 is caused by installing placeholder app deps at nativefier
  *install* time, with yarn (8.0.2) or npm (8.0.3). This is new in
  Nativefier 8.x, for the motivations behind it, see
  https://github.com/jiahaog/nativefier/pull/898#issuecomment-583865045

- During testing, I did test global installs, but never to a
  system / non-user-writable path (my `$npm_config_prefix` is set to
  `"$HOME/.node_modules"`)

- But without such a config and when installing globally to a
  non-user-writable/system path with `sudo npm i -g nativefier`,

    - Installation of nativefier core works...

    - ... but then `postinstall` tries to do its job of installing
    app deps, and fails in various OS-dependent ways, but all about
    access rights.
    I suspect that, although main nativefier install runs as `su` with
    access rights to system paths, `postinstall` scripts are run *out*
    of `su`.
    That would make sense for security reasons: out of hook scripts,
    npm knows exactly what will be touched in your filesystem: it's the
    static contents of the published tarball; a postinstall script with
    sudo rights could do nasty dynamic stuff. So, although I don't see
    any mention of that in
    [npm-scripts docs / hooks](https://docs.npmjs.com/misc/scripts#hook-scripts)
    and I haven't dug npm/cli's code, I can understand it.

So, reverting back to `webpack`ing the placeholder app, as done pre-8.0.
This commit is contained in:
Ronan Jouchet 2020-03-16 21:06:03 -04:00
parent 0a380bd0f4
commit cde5c1e13b
9 changed files with 67 additions and 23 deletions

1
.gitignore vendored
View File

@ -7,6 +7,7 @@ package-lock.json
# ignore compiled lib files
lib*
app/lib/*
app/dist/*
built-tests
# commit a placeholder to keep the app/lib directory

View File

@ -1,13 +1,10 @@
# OSX
/*
!lib/
!app/lib/
!icon-scripts
.DS_Store
.eslintrc.yml
src/
app/src/
app/node_modules
*eslintrc.js
*eslintrc.yml
*tsconfig.tsbuildinfo
*package-lock.json
*tsconfig.json
@ -17,3 +14,8 @@ app/node_modules
*.test.d.ts
*.test.js
*.test.js.map
app/*
!app/lib/
!app/inject/
!app/nativefier.json
!app/package.json

View File

@ -12,9 +12,7 @@ export function createLoginWindow(loginCallback): BrowserWindow {
nodeIntegration: true, // TODO work around this; insecure
},
});
loginWindow.loadURL(
`file://${path.join(__dirname, '..', 'static/login.html')}`,
);
loginWindow.loadURL(`file://${path.join(__dirname, 'static/login.html')}`);
ipcMain.once('login-message', (event, usernameAndPassword) => {
loginCallback(usernameAndPassword[0], usernameAndPassword[1]);

View File

@ -95,7 +95,7 @@ export function createMainWindow(
plugins: true,
nodeIntegration: false, // `true` is *insecure*, and cause trouble with messenger.com
webSecurity: !options.insecure,
preload: path.join(__dirname, '..', 'preload.js'),
preload: path.join(__dirname, 'preload.js'),
zoomFactor: options.zoom,
},
};
@ -133,7 +133,7 @@ export function createMainWindow(
options.maximize = undefined;
try {
fs.writeFileSync(
path.join(__dirname, '../..', 'nativefier.json'),
path.join(__dirname, '..', 'nativefier.json'),
JSON.stringify(options),
);
} catch (exception) {

View File

@ -6,7 +6,7 @@ import { BrowserWindow } from 'electron';
import * as log from 'loglevel';
import wurl from 'wurl';
const INJECT_CSS_PATH = path.join(__dirname, '../..', 'inject/inject.css');
const INJECT_CSS_PATH = path.join(__dirname, '..', 'inject/inject.css');
export function isOSX(): boolean {
return os.platform() === 'darwin';
@ -64,7 +64,7 @@ export function debugLog(browserWindow: BrowserWindow, message: string): void {
}
export function getAppIcon(): string {
return path.join(__dirname, `../../icon.${isWindows() ? 'ico' : 'png'}`);
return path.join(__dirname, '..', `icon.${isWindows() ? 'ico' : 'png'}`);
}
export function nativeTabsSupported(): boolean {

View File

@ -6,7 +6,7 @@
"incremental": true,
"module": "commonjs",
"moduleResolution": "node",
"outDir": "./lib",
"outDir": "./dist",
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,

34
app/webpack.config.js Normal file
View File

@ -0,0 +1,34 @@
const path = require('path');
module.exports = {
target: 'node',
entry: './src/main.ts',
devtool: 'source-map', // https://webpack.js.org/configuration/devtool/
module: {
rules: [
{
test: /\.ts$/,
use: 'ts-loader', // https://webpack.js.org/guides/typescript/
exclude: /node_modules/,
},
],
},
// Don't mock __dirname; https://webpack.js.org/configuration/node/#root
node: {
__dirname: false,
},
// Prevent bundling of certain imported packages and instead retrieve these
// external deps at runtime. This is what we want for electron, placed in the
// app by electron-packager. https://webpack.js.org/configuration/externals/
externals: {
electron: 'commonjs electron',
},
resolve: {
extensions: [ '.ts', '.js' ],
},
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'lib'),
},
mode: 'none'
};

View File

@ -9,10 +9,14 @@ git clone https://github.com/jiahaog/nativefier.git
cd nativefier
```
Install dependencies:
Install dependencies for both the CLI and the Electron app:
```bash
npm install
# Under Linux and macOS:
npm run dev-up
# Under Windows:
npm run dev-up-win
```
Build nativefier:
@ -63,5 +67,5 @@ but is painful to do manually. Do yourself a favor and install a
- Logging is suppressed by default in tests, to avoid polluting Jest output.
To get debug logs, `npm run test:withlog` or set the `LOGLEVEL` env. var.
- For a good live experience, open two terminal panes/tabs running code/tests watchers:
2. Run a TSC watcher: `npm run build:watch`
3. Run a Jest unit tests watcher: `npm run test:watch`
1. Run a TSC watcher: `npm run build:watch`
2. Run a Jest unit tests watcher: `npm run test:watch`

View File

@ -28,18 +28,20 @@
"url": "https://github.com/jiahaog/nativefier/issues"
},
"scripts": {
"build-app-static": "ncp app/src/static/ app/lib/static/",
"build": "npm run clean && tsc --build . app && npm run build-app-static",
"build-app": "cd app && webpack",
"build-app-static": "ncp app/src/static/ app/lib/static/ && ncp app/dist/preload.js app/lib/preload.js && ncp app/dist/preload.js.map app/lib/preload.js.map",
"build": "npm run clean && tsc --build . app && npm run build-app && npm run build-app-static",
"build:watch": "tsc --build . app --watch",
"dev-up": "npm install && cd ./app && npm install && cd ..",
"dev-up-win": "npm install & cd app & npm install & cd ..",
"changelog": "./docs/generate-changelog",
"ci": "npm run lint && npm test",
"clean": "rimraf lib/ app/lib/",
"clean:full": "rimraf lib/ app/lib/ node_modules/ app/node_modules/",
"clean": "rimraf lib/ app/lib/ app/dist/",
"clean:full": "rimraf lib/ app/lib/ app/dist/ node_modules/ app/node_modules/",
"lint:fix": "eslint . --fix",
"lint:format": "prettier --write 'src/**/*.js' 'app/src/**/*.js'",
"lint": "eslint . --ext .ts",
"list-outdated-deps": "npm out; cd app && npm out; true",
"postinstall": "cd app && echo '***** Installation will take 60s to finish, this is a bug ( https://github.com/jiahaog/nativefier/issues/923 ) that will be addressed in a future release. For now, have a cup of tea. *****' && npm install --no-package-lock --no-audit --silent",
"test:integration": "jest --testRegex '.*integration-test.js'",
"test:manual": "npm run build && ./docs/manual-test",
"test:unit": "jest",
@ -81,7 +83,10 @@
"jest": "25.x",
"prettier": "1.x",
"rimraf": "3.x",
"typescript": "3.x"
"ts-loader": "6.x",
"typescript": "3.x",
"webpack": "4.x",
"webpack-cli": "3.x"
},
"jest": {
"collectCoverage": true,