mirror of
https://github.com/balena-io/etcher.git
synced 2025-04-25 15:57:18 +00:00
Merge pull request #3169 from balena-io/webpack-everything
Webpack everything
This commit is contained in:
commit
cc08ac9236
@ -1,6 +1,6 @@
|
||||
{
|
||||
"electron": {
|
||||
"npm_version": "6.7.0",
|
||||
"npm_version": "6.14.5",
|
||||
"dependencies": {
|
||||
"linux": [
|
||||
"libudev-dev",
|
||||
@ -18,32 +18,13 @@
|
||||
"productName": "balenaEtcher",
|
||||
"nodeGypRebuild": true,
|
||||
"afterPack": "./afterPack.js",
|
||||
"asar": false,
|
||||
"files": [
|
||||
"build/Release/elevator.node",
|
||||
"generated",
|
||||
"lib/shared/catalina-sudo/sudo-askpass.osascript.js",
|
||||
"lib/gui/app/index.html",
|
||||
"lib/gui/css/*.css",
|
||||
"lib/gui/css/fonts/*.woff2",
|
||||
"lib/gui/assets/*.svg",
|
||||
"assets/icon.png",
|
||||
"!node_modules/**/**",
|
||||
"node_modules/**/*.js",
|
||||
"node_modules/**/*.json",
|
||||
"node_modules/**/*.node",
|
||||
"node_modules/**/*.dll",
|
||||
"node_modules/node-raspberrypi-usbboot/blobs/**",
|
||||
"node_modules/flexboxgrid/dist/flexboxgrid.css",
|
||||
"node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.woff",
|
||||
"node_modules/roboto-fontface/fonts/roboto/Roboto-Light.woff",
|
||||
"node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.woff",
|
||||
"node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.woff",
|
||||
"node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.woff",
|
||||
"node_modules/bootstrap-sass/assets/fonts/bootstrap/glyphicons-halflings-regular.woff2"
|
||||
"lib/shared/catalina-sudo/sudo-askpass.osascript.js"
|
||||
],
|
||||
"afterSign": "./afterSignHook.js",
|
||||
"mac": {
|
||||
"asar": false,
|
||||
"category": "public.app-category.developer-tools",
|
||||
"hardenedRuntime": true,
|
||||
"entitlements": "entitlements.mac.plist",
|
||||
|
7
Makefile
7
Makefile
@ -3,7 +3,7 @@
|
||||
# ---------------------------------------------------------------------
|
||||
|
||||
RESIN_SCRIPTS ?= ./scripts/resin
|
||||
export NPM_VERSION ?= 6.7.0
|
||||
export NPM_VERSION ?= 6.14.5
|
||||
S3_BUCKET = artifacts.ci.balena-cloud.com
|
||||
|
||||
# This directory will be completely deleted by the `clean` rule
|
||||
@ -144,10 +144,6 @@ webpack:
|
||||
|
||||
.PHONY: $(TARGETS)
|
||||
|
||||
sass:
|
||||
npm rebuild node-sass
|
||||
node-sass lib/gui/app/scss/main.scss > lib/gui/css/main.css
|
||||
|
||||
lint-ts:
|
||||
balena-lint --fix --typescript typings lib tests scripts/clean-shrinkwrap.ts webpack.config.ts
|
||||
|
||||
@ -190,7 +186,6 @@ info:
|
||||
@echo "Target arch : $(TARGET_ARCH)"
|
||||
|
||||
sanity-checks:
|
||||
./scripts/ci/ensure-staged-sass.sh
|
||||
./scripts/ci/ensure-all-file-extensions-in-gitattributes.sh
|
||||
|
||||
clean:
|
||||
|
@ -5,30 +5,11 @@ npmRebuild: true
|
||||
nodeGypRebuild: true
|
||||
publish: null
|
||||
afterPack: "./afterPack.js"
|
||||
asar: false
|
||||
files:
|
||||
- build/Release/elevator.node
|
||||
- generated
|
||||
- lib/shared/catalina-sudo/sudo-askpass.osascript.js
|
||||
- lib/gui/app/index.html
|
||||
- lib/gui/css/*.css
|
||||
- lib/gui/css/fonts/*.woff2
|
||||
- lib/gui/assets/*.svg
|
||||
- assets/icon.png
|
||||
- "!node_modules/**/**"
|
||||
- "node_modules/**/*.js"
|
||||
- "node_modules/**/*.json"
|
||||
- "node_modules/**/*.node"
|
||||
- "node_modules/**/*.dll"
|
||||
- node_modules/node-raspberrypi-usbboot/blobs/**
|
||||
- node_modules/flexboxgrid/dist/flexboxgrid.css
|
||||
- node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.woff
|
||||
- node_modules/roboto-fontface/fonts/roboto/Roboto-Light.woff
|
||||
- node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.woff
|
||||
- node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.woff
|
||||
- node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.woff
|
||||
- node_modules/bootstrap-sass/assets/fonts/bootstrap/glyphicons-halflings-regular.woff2
|
||||
mac:
|
||||
asar: false
|
||||
icon: assets/icon.icns
|
||||
category: public.app-category.developer-tools
|
||||
hardenedRuntime: true
|
||||
|
@ -171,7 +171,7 @@ export function DriveSelectorModal({ close }: { close: () => void }) {
|
||||
<img
|
||||
className="list-group-item-section"
|
||||
alt="Drive device type logo"
|
||||
src={`../assets/${drive.icon}.svg`}
|
||||
src={`media/${drive.icon}.svg`}
|
||||
width="25"
|
||||
height="30"
|
||||
/>
|
||||
|
@ -78,7 +78,7 @@ function FinishPage({ goToMain }: { goToMain: () => void }) {
|
||||
}
|
||||
>
|
||||
<SVGIcon
|
||||
paths={['../../assets/etcher.svg']}
|
||||
paths={['etcher.svg']}
|
||||
width="165px"
|
||||
height="auto"
|
||||
></SVGIcon>
|
||||
@ -87,7 +87,7 @@ function FinishPage({ goToMain }: { goToMain: () => void }) {
|
||||
<div className="caption caption-small fallback-footer">
|
||||
made with
|
||||
<SVGIcon
|
||||
paths={['../../assets/love.svg']}
|
||||
paths={['love.svg']}
|
||||
width="auto"
|
||||
height="20px"
|
||||
></SVGIcon>
|
||||
@ -99,7 +99,7 @@ function FinishPage({ goToMain }: { goToMain: () => void }) {
|
||||
}
|
||||
>
|
||||
<SVGIcon
|
||||
paths={['../../assets/balena.svg']}
|
||||
paths={['balena.svg']}
|
||||
width="auto"
|
||||
height="20px"
|
||||
></SVGIcon>
|
||||
|
@ -74,7 +74,7 @@ export class ReducedFlashingInfos extends React.Component<
|
||||
<SVGIcon
|
||||
disabled
|
||||
contents={[this.props.imageLogo]}
|
||||
paths={['../../assets/image.svg']}
|
||||
paths={['image.svg']}
|
||||
width="20px"
|
||||
></SVGIcon>
|
||||
<Span>{this.props.imageName}</Span>
|
||||
@ -82,11 +82,7 @@ export class ReducedFlashingInfos extends React.Component<
|
||||
</Span>
|
||||
|
||||
<Span className="step-name">
|
||||
<SVGIcon
|
||||
disabled
|
||||
paths={['../../assets/drive.svg']}
|
||||
width="20px"
|
||||
></SVGIcon>
|
||||
<SVGIcon disabled paths={['drive.svg']} width="20px"></SVGIcon>
|
||||
<Span>{this.props.driveTitle}</Span>
|
||||
</Span>
|
||||
</Div>
|
||||
|
@ -477,7 +477,7 @@ export class SourceSelector extends React.Component<
|
||||
<div className="center-block">
|
||||
<SVGIcon
|
||||
contents={[selectionState.getImageLogo()]}
|
||||
paths={['../../assets/image.svg']}
|
||||
paths={['image.svg']}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
@ -74,7 +74,7 @@ export class SVGIcon extends React.Component<SVGIconProps> {
|
||||
// that's the only way to get the "real" __dirname.
|
||||
let baseDirectory: string;
|
||||
if (path.isAbsolute(__dirname)) {
|
||||
baseDirectory = path.join(__dirname, '..');
|
||||
baseDirectory = path.join(__dirname);
|
||||
} else {
|
||||
// @ts-ignore
|
||||
baseDirectory = global.__dirname;
|
||||
@ -99,7 +99,7 @@ export class SVGIcon extends React.Component<SVGIconProps> {
|
||||
// relative to *this directory*.
|
||||
// TODO: There might be a way to compute the path
|
||||
// relatively to the `index.html`.
|
||||
const imagePath = path.join(baseDirectory, 'assets', relativePath);
|
||||
const imagePath = path.join(baseDirectory, 'media', relativePath);
|
||||
|
||||
const contents = _.attempt(() => {
|
||||
return fs.readFileSync(imagePath, {
|
||||
|
@ -3,12 +3,10 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Etcher</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../../node_modules/flexboxgrid/dist/flexboxgrid.css">
|
||||
<link rel="stylesheet" type="text/css" href="../css/main.css">
|
||||
<link rel="stylesheet" type="text/css" href="../css/desktop.css">
|
||||
<link rel="stylesheet" type="text/css" href="index.css">
|
||||
</head>
|
||||
<body>
|
||||
<main id="main"></main>
|
||||
<script src="../../../generated/gui.js"></script>
|
||||
<script src="gui.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -105,7 +105,7 @@ export const DriveSelector = ({
|
||||
)}
|
||||
|
||||
<div className="center-block">
|
||||
<SVGIcon paths={['../../assets/drive.svg']} disabled={disabled} />
|
||||
<SVGIcon paths={['drive.svg']} disabled={disabled} />
|
||||
</div>
|
||||
|
||||
<div className="space-vertical-large">
|
||||
|
@ -90,7 +90,7 @@ async function flashImageToDrive(
|
||||
// otherwise Windows throws EPERM
|
||||
driveScanner.stop();
|
||||
|
||||
const iconPath = path.join('..', '..', '..', 'assets', 'icon.png');
|
||||
const iconPath = path.join('media', 'icon.png');
|
||||
const basename = path.basename(image.path);
|
||||
try {
|
||||
await imageWriter.flash(image.path, drives, sourceOptions);
|
||||
@ -228,7 +228,7 @@ export class FlashStep extends React.Component<FlashStepProps, FlashStepState> {
|
||||
<div className="box text-center">
|
||||
<div className="center-block">
|
||||
<SVGIcon
|
||||
paths={['../../assets/flash.svg']}
|
||||
paths={['flash.svg']}
|
||||
disabled={this.props.shouldFlashStepBeDisabled}
|
||||
/>
|
||||
</div>
|
||||
|
@ -153,11 +153,7 @@ export class MainPage extends React.Component<
|
||||
}
|
||||
tabIndex={100}
|
||||
>
|
||||
<SVGIcon
|
||||
paths={['../../assets/etcher.svg']}
|
||||
width="123px"
|
||||
height="22px"
|
||||
/>
|
||||
<SVGIcon paths={['etcher.svg']} width="123px" height="22px" />
|
||||
</span>
|
||||
|
||||
<span
|
||||
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
$icon-font-path: "../../../node_modules/bootstrap-sass/assets/fonts/bootstrap/";
|
||||
$icon-font-path: "../../../../node_modules/bootstrap-sass/assets/fonts/bootstrap/";
|
||||
$font-size-base: 16px;
|
||||
$cursor-disabled: initial;
|
||||
$link-hover-decoration: none;
|
||||
@ -22,6 +22,7 @@ $btn-min-width: 170px;
|
||||
$link-color: #ddd;
|
||||
$disabled-opacity: 0.2;
|
||||
|
||||
@import "../../../../node_modules/flexboxgrid/dist/flexboxgrid.css";
|
||||
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap";
|
||||
@import "./modules/theme";
|
||||
@import "./modules/bootstrap";
|
||||
@ -34,19 +35,11 @@ $disabled-opacity: 0.2;
|
||||
@import "../components/drive-selector/styles/drive-selector";
|
||||
@import "../pages/main/styles/main";
|
||||
@import "../pages/finish/styles/finish";
|
||||
|
||||
$fa-font-path: "../../../node_modules/@fortawesome/fontawesome-free-webfonts/webfonts";
|
||||
|
||||
@import "../../../../node_modules/@fortawesome/fontawesome-free-webfonts/scss/fontawesome";
|
||||
@import "../../../../node_modules/@fortawesome/fontawesome-free-webfonts/scss/fa-solid";
|
||||
@import "./desktop";
|
||||
|
||||
@font-face {
|
||||
font-family: "Nunito";
|
||||
src: url("Nunito-Regular.eot");
|
||||
src: url("./fonts/Nunito-Regular.eot?#iefix") format("embedded-opentype"),
|
||||
url("./fonts/Nunito-Regular.woff2") format("woff2"),
|
||||
url("./fonts/Nunito-Regular.woff") format("woff"),
|
||||
url("./fonts/Nunito-Regular.ttf") format("truetype");
|
||||
src: url("./fonts/Nunito-Regular.woff2") format("woff2");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-display: block;
|
||||
@ -54,11 +47,7 @@ $fa-font-path: "../../../node_modules/@fortawesome/fontawesome-free-webfonts/web
|
||||
|
||||
@font-face {
|
||||
font-family: "Nunito";
|
||||
src: url("Nunito-Bold.eot");
|
||||
src: url("./fonts/Nunito-Bold.eot?#iefix") format("embedded-opentype"),
|
||||
url("./fonts/Nunito-Bold.woff2") format("woff2"),
|
||||
url("./fonts/Nunito-Bold.woff") format("woff"),
|
||||
url("./fonts/Nunito-Bold.ttf") format("truetype");
|
||||
src: url("./fonts/Nunito-Bold.woff2") format("woff2");
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
font-display: block;
|
||||
@ -66,11 +55,7 @@ $fa-font-path: "../../../node_modules/@fortawesome/fontawesome-free-webfonts/web
|
||||
|
||||
@font-face {
|
||||
font-family: "Nunito";
|
||||
src: url("Nunito-Light.eot");
|
||||
src: url("./fonts/Nunito-Light.eot?#iefix") format("embedded-opentype"),
|
||||
url("./fonts/Nunito-Light.woff2") format("woff2"),
|
||||
url("./fonts/Nunito-Light.woff") format("woff"),
|
||||
url("./fonts/Nunito-Light.ttf") format("truetype");
|
||||
src: url("./fonts/Nunito-Light.woff2") format("woff2");
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
font-display: block;
|
||||
@ -78,11 +63,7 @@ $fa-font-path: "../../../node_modules/@fortawesome/fontawesome-free-webfonts/web
|
||||
|
||||
@font-face {
|
||||
font-family: "CircularStd";
|
||||
src: url("./fonts/CircularStd-Bold.eot");
|
||||
src: url("./fonts/CircularStd-Bold.eot?#iefix") format("embedded-opentype"),
|
||||
url("./fonts/CircularStd-Bold.woff2") format("woff2"),
|
||||
url("./fonts/CircularStd-Bold.woff") format("woff"),
|
||||
url("./fonts/CircularStd-Bold.ttf") format("truetype");
|
||||
src: url("./fonts/CircularStd-Bold.woff2") format("woff2");
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
font-display: block;
|
||||
@ -90,11 +71,7 @@ $fa-font-path: "../../../node_modules/@fortawesome/fontawesome-free-webfonts/web
|
||||
|
||||
@font-face {
|
||||
font-family: "CircularStd";
|
||||
src: url("./fonts/CircularStd-Book.eot");
|
||||
src: url("./fonts/CircularStd-Book.eot?#iefix") format("embedded-opentype"),
|
||||
url("./fonts/CircularStd-Book.woff2") format("woff2"),
|
||||
url("./fonts/CircularStd-Book.woff") format("woff"),
|
||||
url("./fonts/CircularStd-Book.ttf") format("truetype");
|
||||
src: url("./fonts/CircularStd-Book.woff2") format("woff2");
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
font-display: block;
|
||||
@ -102,11 +79,7 @@ $fa-font-path: "../../../node_modules/@fortawesome/fontawesome-free-webfonts/web
|
||||
|
||||
@font-face {
|
||||
font-family: "CircularStd";
|
||||
src: url("./fonts/CircularStd-Medium.eot");
|
||||
src: url("./fonts/CircularStd-Medium.eot?#iefix") format("embedded-opentype"),
|
||||
url("./fonts/CircularStd-Medium.woff2") format("woff2"),
|
||||
url("./fonts/CircularStd-Medium.woff") format("woff"),
|
||||
url("./fonts/CircularStd-Medium.ttf") format("truetype");
|
||||
src: url("./fonts/CircularStd-Medium.woff2") format("woff2");
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-display: block;
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
9773
lib/gui/css/main.css
9773
lib/gui/css/main.css
File diff suppressed because it is too large
Load Diff
@ -76,7 +76,7 @@ async function createMainWindow() {
|
||||
kiosk: fullscreen,
|
||||
autoHideMenuBar: true,
|
||||
titleBarStyle: 'hiddenInset',
|
||||
icon: path.join(__dirname, '..', '..', 'assets', 'icon.png'),
|
||||
icon: path.join(__dirname, 'media', 'icon.png'),
|
||||
darkTheme: true,
|
||||
webPreferences: {
|
||||
backgroundThrottling: false,
|
||||
@ -102,9 +102,7 @@ async function createMainWindow() {
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
mainWindow.loadURL(
|
||||
`file://${path.join(__dirname, '..', 'lib', 'gui', 'app', 'index.html')}`,
|
||||
);
|
||||
mainWindow.loadURL(`file://${path.join(__dirname, 'index.html')}`);
|
||||
|
||||
const page = mainWindow.webContents;
|
||||
|
||||
|
@ -15,8 +15,9 @@
|
||||
*/
|
||||
|
||||
import { execFile } from 'child_process';
|
||||
import { app, remote } from 'electron';
|
||||
import { join } from 'path';
|
||||
import { argv, env } from 'process';
|
||||
import { env } from 'process';
|
||||
import { promisify } from 'util';
|
||||
|
||||
const execFileAsync = promisify(execFile);
|
||||
@ -24,16 +25,6 @@ const execFileAsync = promisify(execFile);
|
||||
const SUCCESSFUL_AUTH_MARKER = 'AUTHENTICATION SUCCEEDED';
|
||||
const EXPECTED_SUCCESSFUL_AUTH_MARKER = `${SUCCESSFUL_AUTH_MARKER}\n`;
|
||||
|
||||
function getAppPath() {
|
||||
for (const arg of argv) {
|
||||
const [option, value] = arg.split('=');
|
||||
if (option === '--app-path') {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
throw new Error("Couldn't find --app-path= in argv");
|
||||
}
|
||||
|
||||
export async function sudo(
|
||||
command: string,
|
||||
): Promise<{ cancelled: boolean; stdout?: string; stderr?: string }> {
|
||||
@ -46,7 +37,7 @@ export async function sudo(
|
||||
env: {
|
||||
PATH: env.PATH,
|
||||
SUDO_ASKPASS: join(
|
||||
getAppPath(),
|
||||
(app || remote.app).getAppPath(),
|
||||
__dirname,
|
||||
'sudo-askpass.osascript.js',
|
||||
),
|
||||
|
@ -14,7 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import bindings = require('bindings');
|
||||
import * as Bluebird from 'bluebird';
|
||||
import * as childProcess from 'child_process';
|
||||
import { promises as fs } from 'fs';
|
||||
@ -109,7 +108,9 @@ async function elevateScriptWindows(
|
||||
): Promise<{ cancelled: boolean }> {
|
||||
// 'elevator' imported here as it only exists on windows
|
||||
// TODO: replace this with sudo-prompt once https://github.com/jorangreef/sudo-prompt/issues/96 is fixed
|
||||
const elevateAsync = promisify(bindings('elevator').elevate);
|
||||
// @ts-ignore this is a native module
|
||||
const { elevate } = await import('../../build/Release/elevator.node');
|
||||
const elevateAsync = promisify(elevate);
|
||||
|
||||
// '&' needs to be escaped here (but not when written to a .cmd file)
|
||||
const cmd = ['cmd', '/c', escapeParamCmd(path).replace(/&/g, '^&')];
|
||||
|
2104
npm-shrinkwrap.json
generated
2104
npm-shrinkwrap.json
generated
File diff suppressed because it is too large
Load Diff
83
package.json
83
package.json
@ -23,8 +23,8 @@
|
||||
"webpack": "webpack",
|
||||
"watch": "webpack --watch",
|
||||
"concourse-build-electron": "make webpack",
|
||||
"concourse-test": "npx npm@6.7.0 test",
|
||||
"concourse-test-electron": "npx npm@6.7.0 test"
|
||||
"concourse-test": "npx npm@6.14.5 test",
|
||||
"concourse-test-electron": "npx npm@6.14.5 test"
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
@ -42,49 +42,17 @@
|
||||
"fsevents",
|
||||
"winusb-driver-generator"
|
||||
],
|
||||
"dependencies": {
|
||||
"devDependencies": {
|
||||
"@balena/lint": "^5.0.4",
|
||||
"@fortawesome/fontawesome-free-webfonts": "^1.0.9",
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.25",
|
||||
"@fortawesome/free-brands-svg-icons": "^5.11.2",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.11.2",
|
||||
"@fortawesome/react-fontawesome": "^0.1.7",
|
||||
"bindings": "^1.3.0",
|
||||
"bluebird": "^3.7.2",
|
||||
"bootstrap-sass": "^3.3.6",
|
||||
"d3": "^4.13.0",
|
||||
"debug": "^4.1.1",
|
||||
"electron-updater": "^4.3.1",
|
||||
"etcher-sdk": "^4.1.3",
|
||||
"flexboxgrid": "^6.3.0",
|
||||
"immutable": "^3.8.1",
|
||||
"inactivity-timer": "^1.0.0",
|
||||
"lodash": "^4.17.10",
|
||||
"mime-types": "^2.1.18",
|
||||
"nan": "^2.14.0",
|
||||
"node-ipc": "^9.1.1",
|
||||
"path-is-inside": "^1.0.2",
|
||||
"pretty-bytes": "^5.3.0",
|
||||
"react": "^16.8.5",
|
||||
"react-dom": "^16.8.5",
|
||||
"redux": "^4.0.5",
|
||||
"rendition": "^14.11.5",
|
||||
"request": "^2.81.0",
|
||||
"resin-corvus": "^2.0.5",
|
||||
"roboto-fontface": "^0.10.0",
|
||||
"semver": "^7.3.2",
|
||||
"styled-components": "^5.1.0",
|
||||
"styled-system": "^5.1.5",
|
||||
"sudo-prompt": "^9.0.0",
|
||||
"sys-class-rgb-led": "^2.1.0",
|
||||
"tmp": "^0.2.1",
|
||||
"uuid": "^8.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@balena/lint": "^5.0.4",
|
||||
"@types/bindings": "^1.3.0",
|
||||
"@types/bluebird": "^3.5.30",
|
||||
"@types/chai": "^4.2.7",
|
||||
"@types/mime-types": "^2.1.0",
|
||||
"@types/mini-css-extract-plugin": "^0.9.1",
|
||||
"@types/mocha": "^7.0.2",
|
||||
"@types/node": "^12.12.39",
|
||||
"@types/node-ipc": "^9.1.2",
|
||||
@ -94,26 +62,61 @@
|
||||
"@types/sinon": "^9.0.0",
|
||||
"@types/tmp": "^0.2.0",
|
||||
"@types/webpack-node-externals": "^1.7.0",
|
||||
"bluebird": "^3.7.2",
|
||||
"bootstrap-sass": "^3.3.6",
|
||||
"chai": "^4.2.0",
|
||||
"copy-webpack-plugin": "^6.0.1",
|
||||
"css-loader": "^3.5.3",
|
||||
"d3": "^4.13.0",
|
||||
"debug": "^4.1.1",
|
||||
"electron": "7.1.14",
|
||||
"electron-builder": "^22.1.0",
|
||||
"electron-mocha": "^8.2.0",
|
||||
"electron-notarize": "^0.3.0",
|
||||
"electron-updater": "^4.3.1",
|
||||
"etcher-sdk": "^4.1.3",
|
||||
"file-loader": "^6.0.0",
|
||||
"flexboxgrid": "^6.3.0",
|
||||
"husky": "^4.2.5",
|
||||
"immutable": "^3.8.1",
|
||||
"inactivity-timer": "^1.0.0",
|
||||
"lint-staged": "^10.2.2",
|
||||
"lodash": "^4.17.10",
|
||||
"mime-types": "^2.1.18",
|
||||
"mini-css-extract-plugin": "^0.9.0",
|
||||
"mocha": "^7.0.1",
|
||||
"nan": "^2.14.0",
|
||||
"native-addon-loader": "^2.0.1",
|
||||
"node-gyp": "^6.1.0",
|
||||
"node-sass": "^4.12.0",
|
||||
"node-ipc": "^9.1.1",
|
||||
"omit-deep-lodash": "1.1.4",
|
||||
"path-is-inside": "^1.0.2",
|
||||
"pretty-bytes": "^5.3.0",
|
||||
"react": "^16.8.5",
|
||||
"react-dom": "^16.8.5",
|
||||
"redux": "^4.0.5",
|
||||
"rendition": "^14.11.5",
|
||||
"request": "^2.81.0",
|
||||
"resin-corvus": "^2.0.5",
|
||||
"roboto-fontface": "^0.10.0",
|
||||
"sass": "^1.26.5",
|
||||
"sass-lint": "^1.12.1",
|
||||
"sass-loader": "^8.0.2",
|
||||
"semver": "^7.3.2",
|
||||
"simple-progress-webpack-plugin": "^1.1.2",
|
||||
"sinon": "^9.0.2",
|
||||
"spectron": "^9.0.0",
|
||||
"string-replace-loader": "^2.3.0",
|
||||
"styled-components": "^5.1.0",
|
||||
"styled-system": "^5.1.5",
|
||||
"sudo-prompt": "^9.0.0",
|
||||
"sys-class-rgb-led": "^2.1.0",
|
||||
"tmp": "^0.2.1",
|
||||
"ts-loader": "^7.0.4",
|
||||
"ts-node": "^8.3.0",
|
||||
"typescript": "^3.5.3",
|
||||
"uuid": "^8.0.0",
|
||||
"webpack": "^4.40.2",
|
||||
"webpack-cli": "^3.3.9",
|
||||
"webpack-node-externals": "^1.7.2"
|
||||
"webpack-cli": "^3.3.9"
|
||||
}
|
||||
}
|
||||
|
@ -1,31 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
###
|
||||
# Copyright 2017 balena.io
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
###
|
||||
|
||||
set -e
|
||||
set -u
|
||||
|
||||
make sass
|
||||
|
||||
# From http://stackoverflow.com/a/9393642/1641422
|
||||
if [[ -n $(git status -s | grep "\\.css$" || true) ]]; then
|
||||
echo "There are unstaged sass changes. Please commit the result of:" 1>&2
|
||||
echo ""
|
||||
echo " make sass" 1>&2
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
@ -14,11 +14,16 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// @ts-ignore @types for copy-webpack-plugin@6.0.1 not released yet
|
||||
import * as CopyPlugin from 'copy-webpack-plugin';
|
||||
import { readdirSync } from 'fs';
|
||||
import * as _ from 'lodash';
|
||||
import * as MiniCssExtractPlugin from 'mini-css-extract-plugin';
|
||||
import * as os from 'os';
|
||||
import outdent from 'outdent';
|
||||
import * as path from 'path';
|
||||
import * as SimpleProgressWebpackPlugin from 'simple-progress-webpack-plugin';
|
||||
import { BannerPlugin } from 'webpack';
|
||||
import * as nodeExternals from 'webpack-node-externals';
|
||||
|
||||
/**
|
||||
* Don't webpack package.json as mixpanel & sentry tokens
|
||||
@ -37,6 +42,63 @@ function externalPackageJson(packageJsonPath: string) {
|
||||
};
|
||||
}
|
||||
|
||||
function platformSpecificModule(
|
||||
platform: string,
|
||||
module: string,
|
||||
replacement = '{}',
|
||||
) {
|
||||
// Resolves module on platform, otherwise resolves the replacement
|
||||
return (
|
||||
_context: string,
|
||||
request: string,
|
||||
callback: (error?: Error, result?: string, type?: string) => void,
|
||||
) => {
|
||||
if (request === module && os.platform() !== platform) {
|
||||
callback(undefined, replacement);
|
||||
return;
|
||||
}
|
||||
callback();
|
||||
};
|
||||
}
|
||||
|
||||
function renameNodeModules(resourcePath: string) {
|
||||
// electron-builder excludes the node_modules folder even if you specifically include it
|
||||
// Work around by renaming it to "modules"
|
||||
// See https://github.com/electron-userland/electron-builder/issues/4545
|
||||
return (
|
||||
path
|
||||
.relative(__dirname, resourcePath)
|
||||
.replace('node_modules', 'modules')
|
||||
// file-loader expects posix paths, even on Windows
|
||||
.replace(/\\/g, '/')
|
||||
);
|
||||
}
|
||||
|
||||
function findLzmaNativeBindingsFolder(): string {
|
||||
const files = readdirSync(path.join('node_modules', 'lzma-native'));
|
||||
const bindingsFolder = files.find((f) => f.startsWith('binding-'));
|
||||
if (bindingsFolder === undefined) {
|
||||
throw new Error('Could not find lzma_native binding');
|
||||
}
|
||||
return bindingsFolder;
|
||||
}
|
||||
|
||||
const LZMA_BINDINGS_FOLDER = findLzmaNativeBindingsFolder();
|
||||
|
||||
interface ReplacementRule {
|
||||
search: string;
|
||||
replace: string | (() => string);
|
||||
}
|
||||
|
||||
function replace(test: RegExp, ...replacements: ReplacementRule[]) {
|
||||
return {
|
||||
loader: 'string-replace-loader',
|
||||
// Handle windows path separators
|
||||
test: new RegExp(test.source.replace(/\\\//g, '(\\/|\\\\)')),
|
||||
options: { multiple: replacements.map((r) => ({ ...r, strict: true })) },
|
||||
};
|
||||
}
|
||||
|
||||
const commonConfig = {
|
||||
mode: 'production',
|
||||
optimization: {
|
||||
@ -48,10 +110,86 @@ const commonConfig = {
|
||||
test: /\.tsx?$/,
|
||||
use: 'ts-loader',
|
||||
},
|
||||
// remove bindings magic from drivelist
|
||||
replace(
|
||||
/node_modules\/drivelist\/js\/index\.js$/,
|
||||
{
|
||||
search: 'require("bindings");',
|
||||
replace: "require('../build/Release/drivelist.node')",
|
||||
},
|
||||
{
|
||||
search: "bindings('drivelist')",
|
||||
replace: 'bindings',
|
||||
},
|
||||
),
|
||||
// remove node-pre-gyp magic from lzma-native
|
||||
replace(/node_modules\/lzma-native\/index\.js$/, {
|
||||
search: 'require(binding_path)',
|
||||
replace: () => {
|
||||
return `require('./${path.posix.join(
|
||||
LZMA_BINDINGS_FOLDER,
|
||||
'lzma_native.node',
|
||||
)}')`;
|
||||
},
|
||||
}),
|
||||
// remove node-pre-gyp magic from usb
|
||||
replace(/node_modules\/@balena.io\/usb\/usb\.js$/, {
|
||||
search: 'require(binding_path)',
|
||||
replace: "require('./build/Release/usb_bindings.node')",
|
||||
}),
|
||||
// remove bindings magic from ext2fs
|
||||
replace(/node_modules\/ext2fs\/lib\/(ext2fs|binding)\.js$/, {
|
||||
search: "require('bindings')('bindings')",
|
||||
replace: "require('../build/Release/bindings.node')",
|
||||
}),
|
||||
// remove bindings magic from mountutils
|
||||
replace(/node_modules\/mountutils\/index\.js$/, {
|
||||
search: outdent`
|
||||
require('bindings')({
|
||||
bindings: 'MountUtils',
|
||||
/* eslint-disable camelcase */
|
||||
module_root: __dirname
|
||||
/* eslint-enable camelcase */
|
||||
})
|
||||
`,
|
||||
replace: "require('./build/Release/MountUtils.node')",
|
||||
}),
|
||||
// remove bindings magic from winusb-driver-generator
|
||||
replace(/node_modules\/winusb-driver-generator\/index\.js$/, {
|
||||
search: outdent`
|
||||
require('bindings')({
|
||||
bindings: 'Generator',
|
||||
/* eslint-disable camelcase */
|
||||
module_root: __dirname
|
||||
/* eslint-enable camelcase */
|
||||
});
|
||||
`,
|
||||
replace: "require('./build/Release/Generator.node')",
|
||||
}),
|
||||
// Use the copy of blobs in the generated folder and rename node_modules -> modules
|
||||
// See the renameNodeModules function above
|
||||
replace(/node_modules\/node-raspberrypi-usbboot\/build\/index\.js$/, {
|
||||
search:
|
||||
"return yield readFile(Path.join(__dirname, '..', 'blobs', filename));",
|
||||
replace: outdent`
|
||||
const { app, remote } = require('electron');
|
||||
return yield readFile(Path.join((app || remote.app).getAppPath(), 'generated', __dirname.replace('node_modules', 'modules'), '..', 'blobs', filename));
|
||||
`,
|
||||
}),
|
||||
// Copy native modules to generated folder
|
||||
{
|
||||
test: /\.node$/,
|
||||
use: [
|
||||
{
|
||||
loader: 'native-addon-loader',
|
||||
options: { name: renameNodeModules },
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.json', '.ts', '.tsx'],
|
||||
extensions: ['.node', '.js', '.json', '.ts', '.tsx'],
|
||||
},
|
||||
plugins: [
|
||||
new SimpleProgressWebpackPlugin({
|
||||
@ -62,8 +200,35 @@ const commonConfig = {
|
||||
path: path.join(__dirname, 'generated'),
|
||||
filename: '[name].js',
|
||||
},
|
||||
externals: [
|
||||
// '../package.json' because we are in 'generated'
|
||||
externalPackageJson('../package.json'),
|
||||
// Only exists on windows
|
||||
platformSpecificModule('win32', 'winusb-driver-generator'),
|
||||
// Not needed but required by resin-corvus > os-locale > execa > cross-spawn
|
||||
platformSpecificModule('none', 'spawn-sync'),
|
||||
// Not needed as we replace all requires for it
|
||||
platformSpecificModule('none', 'node-pre-gyp', '{ find: () => {} }'),
|
||||
// Not needed as we replace all requires for it
|
||||
platformSpecificModule('none', 'bindings'),
|
||||
],
|
||||
};
|
||||
|
||||
const guiConfigCopyPatterns = [
|
||||
{
|
||||
from: 'node_modules/node-raspberrypi-usbboot/blobs',
|
||||
to: 'modules/node-raspberrypi-usbboot/blobs',
|
||||
},
|
||||
];
|
||||
|
||||
if (os.platform() === 'win32') {
|
||||
// liblzma.dll is required on Windows for lzma-native
|
||||
guiConfigCopyPatterns.push({
|
||||
from: `node_modules/lzma-native/${LZMA_BINDINGS_FOLDER}/liblzma.dll`,
|
||||
to: `modules/lzma-native/${LZMA_BINDINGS_FOLDER}/liblzma.dll`,
|
||||
});
|
||||
}
|
||||
|
||||
const guiConfig = {
|
||||
...commonConfig,
|
||||
target: 'electron-renderer',
|
||||
@ -71,16 +236,9 @@ const guiConfig = {
|
||||
__dirname: true,
|
||||
__filename: true,
|
||||
},
|
||||
externals: [
|
||||
nodeExternals(),
|
||||
|
||||
// '../../../package.json' because we are in 'lib/gui/app/index.html'
|
||||
externalPackageJson('../../../package.json'),
|
||||
],
|
||||
entry: {
|
||||
gui: path.join(__dirname, 'lib', 'gui', 'app', 'app.ts'),
|
||||
},
|
||||
devtool: 'source-map',
|
||||
plugins: [
|
||||
...commonConfig.plugins,
|
||||
// Remove "Download the React DevTools for a better development experience" message
|
||||
@ -88,6 +246,7 @@ const guiConfig = {
|
||||
banner: '__REACT_DEVTOOLS_GLOBAL_HOOK__ = { isDisabled: true };',
|
||||
raw: true,
|
||||
}),
|
||||
new CopyPlugin({ patterns: guiConfigCopyPatterns }),
|
||||
],
|
||||
};
|
||||
|
||||
@ -98,15 +257,62 @@ const etcherConfig = {
|
||||
__dirname: false,
|
||||
__filename: true,
|
||||
},
|
||||
externals: [
|
||||
nodeExternals(),
|
||||
|
||||
// '../package.json' because we are in 'generated/etcher.js'
|
||||
externalPackageJson('../package.json'),
|
||||
],
|
||||
entry: {
|
||||
etcher: path.join(__dirname, 'lib', 'start.ts'),
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = [guiConfig, etcherConfig];
|
||||
const cssConfig = {
|
||||
mode: 'production',
|
||||
optimization: {
|
||||
minimize: false,
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.css$/i,
|
||||
use: 'css-loader',
|
||||
},
|
||||
{
|
||||
test: /\.s[ac]ss$/i,
|
||||
use: [
|
||||
MiniCssExtractPlugin.loader,
|
||||
'css-loader',
|
||||
{
|
||||
loader: 'sass-loader',
|
||||
options: {
|
||||
sassOptions: {
|
||||
fiber: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.(woff|woff2|eot|ttf|otf|svg)$/,
|
||||
loader: 'file-loader',
|
||||
options: { name: renameNodeModules },
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new MiniCssExtractPlugin({ filename: '[name].css' }),
|
||||
new CopyPlugin({
|
||||
patterns: [
|
||||
{ from: 'lib/gui/app/index.html', to: 'index.html' },
|
||||
// electron-builder doesn't bundle folders named "assets"
|
||||
// See https://github.com/electron-userland/electron-builder/issues/4545
|
||||
{ from: 'lib/gui/assets', to: 'media' },
|
||||
{ from: 'assets/icon.png', to: 'media/icon.png' },
|
||||
],
|
||||
}),
|
||||
],
|
||||
entry: {
|
||||
index: path.join(__dirname, 'lib', 'gui', 'app', 'scss', 'main.scss'),
|
||||
},
|
||||
output: {
|
||||
path: path.join(__dirname, 'generated'),
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = [cssConfig, guiConfig, etcherConfig];
|
||||
|
Loading…
x
Reference in New Issue
Block a user