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 # ignore compiled lib files
lib* lib*
app/lib/* app/lib/*
app/dist/*
built-tests built-tests
# commit a placeholder to keep the app/lib directory # commit a placeholder to keep the app/lib directory

View File

@ -1,13 +1,10 @@
# OSX
/* /*
!lib/ !lib/
!app/lib/
!icon-scripts !icon-scripts
.DS_Store .DS_Store
.eslintrc.yml
src/ src/
app/src/ *eslintrc.js
app/node_modules *eslintrc.yml
*tsconfig.tsbuildinfo *tsconfig.tsbuildinfo
*package-lock.json *package-lock.json
*tsconfig.json *tsconfig.json
@ -17,3 +14,8 @@ app/node_modules
*.test.d.ts *.test.d.ts
*.test.js *.test.js
*.test.js.map *.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 nodeIntegration: true, // TODO work around this; insecure
}, },
}); });
loginWindow.loadURL( loginWindow.loadURL(`file://${path.join(__dirname, 'static/login.html')}`);
`file://${path.join(__dirname, '..', 'static/login.html')}`,
);
ipcMain.once('login-message', (event, usernameAndPassword) => { ipcMain.once('login-message', (event, usernameAndPassword) => {
loginCallback(usernameAndPassword[0], usernameAndPassword[1]); loginCallback(usernameAndPassword[0], usernameAndPassword[1]);

View File

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

View File

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

View File

@ -6,7 +6,7 @@
"incremental": true, "incremental": true,
"module": "commonjs", "module": "commonjs",
"moduleResolution": "node", "moduleResolution": "node",
"outDir": "./lib", "outDir": "./dist",
"resolveJsonModule": true, "resolveJsonModule": true,
"skipLibCheck": true, "skipLibCheck": true,
"sourceMap": 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 cd nativefier
``` ```
Install dependencies: Install dependencies for both the CLI and the Electron app:
```bash ```bash
npm install # Under Linux and macOS:
npm run dev-up
# Under Windows:
npm run dev-up-win
``` ```
Build nativefier: 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. - 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. 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: - For a good live experience, open two terminal panes/tabs running code/tests watchers:
2. Run a TSC watcher: `npm run build:watch` 1. Run a TSC watcher: `npm run build:watch`
3. Run a Jest unit tests watcher: `npm run test: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" "url": "https://github.com/jiahaog/nativefier/issues"
}, },
"scripts": { "scripts": {
"build-app-static": "ncp app/src/static/ app/lib/static/", "build-app": "cd app && webpack",
"build": "npm run clean && tsc --build . app && npm run build-app-static", "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", "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", "changelog": "./docs/generate-changelog",
"ci": "npm run lint && npm test", "ci": "npm run lint && npm test",
"clean": "rimraf lib/ app/lib/", "clean": "rimraf lib/ app/lib/ app/dist/",
"clean:full": "rimraf lib/ app/lib/ node_modules/ app/node_modules/", "clean:full": "rimraf lib/ app/lib/ app/dist/ node_modules/ app/node_modules/",
"lint:fix": "eslint . --fix", "lint:fix": "eslint . --fix",
"lint:format": "prettier --write 'src/**/*.js' 'app/src/**/*.js'", "lint:format": "prettier --write 'src/**/*.js' 'app/src/**/*.js'",
"lint": "eslint . --ext .ts", "lint": "eslint . --ext .ts",
"list-outdated-deps": "npm out; cd app && npm out; true", "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:integration": "jest --testRegex '.*integration-test.js'",
"test:manual": "npm run build && ./docs/manual-test", "test:manual": "npm run build && ./docs/manual-test",
"test:unit": "jest", "test:unit": "jest",
@ -81,7 +83,10 @@
"jest": "25.x", "jest": "25.x",
"prettier": "1.x", "prettier": "1.x",
"rimraf": "3.x", "rimraf": "3.x",
"typescript": "3.x" "ts-loader": "6.x",
"typescript": "3.x",
"webpack": "4.x",
"webpack-cli": "3.x"
}, },
"jest": { "jest": {
"collectCoverage": true, "collectCoverage": true,