mirror of
https://github.com/balena-io/etcher.git
synced 2025-07-27 21:26:38 +00:00
Webpack everything, reduce package size
Changelog-entry: Webpack everything, reduce package size Change-type: patch
This commit is contained in:
parent
8b5a5241f2
commit
1ebc8e9362
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"electron": {
|
"electron": {
|
||||||
"npm_version": "6.7.0",
|
"npm_version": "6.14.5",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"linux": [
|
"linux": [
|
||||||
"libudev-dev",
|
"libudev-dev",
|
||||||
@ -19,27 +19,8 @@
|
|||||||
"nodeGypRebuild": true,
|
"nodeGypRebuild": true,
|
||||||
"afterPack": "./afterPack.js",
|
"afterPack": "./afterPack.js",
|
||||||
"files": [
|
"files": [
|
||||||
"build/Release/elevator.node",
|
|
||||||
"generated",
|
"generated",
|
||||||
"lib/shared/catalina-sudo/sudo-askpass.osascript.js",
|
"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"
|
|
||||||
],
|
],
|
||||||
"afterSign": "./afterSignHook.js",
|
"afterSign": "./afterSignHook.js",
|
||||||
"mac": {
|
"mac": {
|
||||||
|
7
Makefile
7
Makefile
@ -3,7 +3,7 @@
|
|||||||
# ---------------------------------------------------------------------
|
# ---------------------------------------------------------------------
|
||||||
|
|
||||||
RESIN_SCRIPTS ?= ./scripts/resin
|
RESIN_SCRIPTS ?= ./scripts/resin
|
||||||
export NPM_VERSION ?= 6.7.0
|
export NPM_VERSION ?= 6.14.5
|
||||||
S3_BUCKET = artifacts.ci.balena-cloud.com
|
S3_BUCKET = artifacts.ci.balena-cloud.com
|
||||||
|
|
||||||
# This directory will be completely deleted by the `clean` rule
|
# This directory will be completely deleted by the `clean` rule
|
||||||
@ -144,10 +144,6 @@ webpack:
|
|||||||
|
|
||||||
.PHONY: $(TARGETS)
|
.PHONY: $(TARGETS)
|
||||||
|
|
||||||
sass:
|
|
||||||
npm rebuild node-sass
|
|
||||||
node-sass lib/gui/app/scss/main.scss > lib/gui/css/main.css
|
|
||||||
|
|
||||||
lint-ts:
|
lint-ts:
|
||||||
balena-lint --fix --typescript typings lib tests scripts/clean-shrinkwrap.ts webpack.config.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)"
|
@echo "Target arch : $(TARGET_ARCH)"
|
||||||
|
|
||||||
sanity-checks:
|
sanity-checks:
|
||||||
./scripts/ci/ensure-staged-sass.sh
|
|
||||||
./scripts/ci/ensure-all-file-extensions-in-gitattributes.sh
|
./scripts/ci/ensure-all-file-extensions-in-gitattributes.sh
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
@ -6,27 +6,8 @@ nodeGypRebuild: true
|
|||||||
publish: null
|
publish: null
|
||||||
afterPack: "./afterPack.js"
|
afterPack: "./afterPack.js"
|
||||||
files:
|
files:
|
||||||
- build/Release/elevator.node
|
|
||||||
- generated
|
- generated
|
||||||
- lib/shared/catalina-sudo/sudo-askpass.osascript.js
|
- 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:
|
mac:
|
||||||
asar: false
|
asar: false
|
||||||
icon: assets/icon.icns
|
icon: assets/icon.icns
|
||||||
|
@ -171,7 +171,7 @@ export function DriveSelectorModal({ close }: { close: () => void }) {
|
|||||||
<img
|
<img
|
||||||
className="list-group-item-section"
|
className="list-group-item-section"
|
||||||
alt="Drive device type logo"
|
alt="Drive device type logo"
|
||||||
src={`../assets/${drive.icon}.svg`}
|
src={`media/${drive.icon}.svg`}
|
||||||
width="25"
|
width="25"
|
||||||
height="30"
|
height="30"
|
||||||
/>
|
/>
|
||||||
|
@ -78,7 +78,7 @@ function FinishPage({ goToMain }: { goToMain: () => void }) {
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<SVGIcon
|
<SVGIcon
|
||||||
paths={['../../assets/etcher.svg']}
|
paths={['etcher.svg']}
|
||||||
width="165px"
|
width="165px"
|
||||||
height="auto"
|
height="auto"
|
||||||
></SVGIcon>
|
></SVGIcon>
|
||||||
@ -87,7 +87,7 @@ function FinishPage({ goToMain }: { goToMain: () => void }) {
|
|||||||
<div className="caption caption-small fallback-footer">
|
<div className="caption caption-small fallback-footer">
|
||||||
made with
|
made with
|
||||||
<SVGIcon
|
<SVGIcon
|
||||||
paths={['../../assets/love.svg']}
|
paths={['love.svg']}
|
||||||
width="auto"
|
width="auto"
|
||||||
height="20px"
|
height="20px"
|
||||||
></SVGIcon>
|
></SVGIcon>
|
||||||
@ -99,7 +99,7 @@ function FinishPage({ goToMain }: { goToMain: () => void }) {
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<SVGIcon
|
<SVGIcon
|
||||||
paths={['../../assets/balena.svg']}
|
paths={['balena.svg']}
|
||||||
width="auto"
|
width="auto"
|
||||||
height="20px"
|
height="20px"
|
||||||
></SVGIcon>
|
></SVGIcon>
|
||||||
|
@ -74,7 +74,7 @@ export class ReducedFlashingInfos extends React.Component<
|
|||||||
<SVGIcon
|
<SVGIcon
|
||||||
disabled
|
disabled
|
||||||
contents={[this.props.imageLogo]}
|
contents={[this.props.imageLogo]}
|
||||||
paths={['../../assets/image.svg']}
|
paths={['image.svg']}
|
||||||
width="20px"
|
width="20px"
|
||||||
></SVGIcon>
|
></SVGIcon>
|
||||||
<Span>{this.props.imageName}</Span>
|
<Span>{this.props.imageName}</Span>
|
||||||
@ -82,11 +82,7 @@ export class ReducedFlashingInfos extends React.Component<
|
|||||||
</Span>
|
</Span>
|
||||||
|
|
||||||
<Span className="step-name">
|
<Span className="step-name">
|
||||||
<SVGIcon
|
<SVGIcon disabled paths={['drive.svg']} width="20px"></SVGIcon>
|
||||||
disabled
|
|
||||||
paths={['../../assets/drive.svg']}
|
|
||||||
width="20px"
|
|
||||||
></SVGIcon>
|
|
||||||
<Span>{this.props.driveTitle}</Span>
|
<Span>{this.props.driveTitle}</Span>
|
||||||
</Span>
|
</Span>
|
||||||
</Div>
|
</Div>
|
||||||
|
@ -477,7 +477,7 @@ export class SourceSelector extends React.Component<
|
|||||||
<div className="center-block">
|
<div className="center-block">
|
||||||
<SVGIcon
|
<SVGIcon
|
||||||
contents={[selectionState.getImageLogo()]}
|
contents={[selectionState.getImageLogo()]}
|
||||||
paths={['../../assets/image.svg']}
|
paths={['image.svg']}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ export class SVGIcon extends React.Component<SVGIconProps> {
|
|||||||
// that's the only way to get the "real" __dirname.
|
// that's the only way to get the "real" __dirname.
|
||||||
let baseDirectory: string;
|
let baseDirectory: string;
|
||||||
if (path.isAbsolute(__dirname)) {
|
if (path.isAbsolute(__dirname)) {
|
||||||
baseDirectory = path.join(__dirname, '..');
|
baseDirectory = path.join(__dirname);
|
||||||
} else {
|
} else {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
baseDirectory = global.__dirname;
|
baseDirectory = global.__dirname;
|
||||||
@ -99,7 +99,7 @@ export class SVGIcon extends React.Component<SVGIconProps> {
|
|||||||
// relative to *this directory*.
|
// relative to *this directory*.
|
||||||
// TODO: There might be a way to compute the path
|
// TODO: There might be a way to compute the path
|
||||||
// relatively to the `index.html`.
|
// relatively to the `index.html`.
|
||||||
const imagePath = path.join(baseDirectory, 'assets', relativePath);
|
const imagePath = path.join(baseDirectory, 'media', relativePath);
|
||||||
|
|
||||||
const contents = _.attempt(() => {
|
const contents = _.attempt(() => {
|
||||||
return fs.readFileSync(imagePath, {
|
return fs.readFileSync(imagePath, {
|
||||||
|
@ -3,12 +3,10 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Etcher</title>
|
<title>Etcher</title>
|
||||||
<link rel="stylesheet" type="text/css" href="../../../node_modules/flexboxgrid/dist/flexboxgrid.css">
|
<link rel="stylesheet" type="text/css" href="index.css">
|
||||||
<link rel="stylesheet" type="text/css" href="../css/main.css">
|
|
||||||
<link rel="stylesheet" type="text/css" href="../css/desktop.css">
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main id="main"></main>
|
<main id="main"></main>
|
||||||
<script src="../../../generated/gui.js"></script>
|
<script src="gui.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -105,7 +105,7 @@ export const DriveSelector = ({
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="center-block">
|
<div className="center-block">
|
||||||
<SVGIcon paths={['../../assets/drive.svg']} disabled={disabled} />
|
<SVGIcon paths={['drive.svg']} disabled={disabled} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-vertical-large">
|
<div className="space-vertical-large">
|
||||||
|
@ -90,7 +90,7 @@ async function flashImageToDrive(
|
|||||||
// otherwise Windows throws EPERM
|
// otherwise Windows throws EPERM
|
||||||
driveScanner.stop();
|
driveScanner.stop();
|
||||||
|
|
||||||
const iconPath = path.join('..', '..', '..', 'assets', 'icon.png');
|
const iconPath = path.join('media', 'icon.png');
|
||||||
const basename = path.basename(image.path);
|
const basename = path.basename(image.path);
|
||||||
try {
|
try {
|
||||||
await imageWriter.flash(image.path, drives, sourceOptions);
|
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="box text-center">
|
||||||
<div className="center-block">
|
<div className="center-block">
|
||||||
<SVGIcon
|
<SVGIcon
|
||||||
paths={['../../assets/flash.svg']}
|
paths={['flash.svg']}
|
||||||
disabled={this.props.shouldFlashStepBeDisabled}
|
disabled={this.props.shouldFlashStepBeDisabled}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -153,11 +153,7 @@ export class MainPage extends React.Component<
|
|||||||
}
|
}
|
||||||
tabIndex={100}
|
tabIndex={100}
|
||||||
>
|
>
|
||||||
<SVGIcon
|
<SVGIcon paths={['etcher.svg']} width="123px" height="22px" />
|
||||||
paths={['../../assets/etcher.svg']}
|
|
||||||
width="123px"
|
|
||||||
height="22px"
|
|
||||||
/>
|
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span
|
<span
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* 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;
|
$font-size-base: 16px;
|
||||||
$cursor-disabled: initial;
|
$cursor-disabled: initial;
|
||||||
$link-hover-decoration: none;
|
$link-hover-decoration: none;
|
||||||
@ -22,6 +22,7 @@ $btn-min-width: 170px;
|
|||||||
$link-color: #ddd;
|
$link-color: #ddd;
|
||||||
$disabled-opacity: 0.2;
|
$disabled-opacity: 0.2;
|
||||||
|
|
||||||
|
@import "../../../../node_modules/flexboxgrid/dist/flexboxgrid.css";
|
||||||
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap";
|
@import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap";
|
||||||
@import "./modules/theme";
|
@import "./modules/theme";
|
||||||
@import "./modules/bootstrap";
|
@import "./modules/bootstrap";
|
||||||
@ -34,15 +35,15 @@ $disabled-opacity: 0.2;
|
|||||||
@import "../components/drive-selector/styles/drive-selector";
|
@import "../components/drive-selector/styles/drive-selector";
|
||||||
@import "../pages/main/styles/main";
|
@import "../pages/main/styles/main";
|
||||||
@import "../pages/finish/styles/finish";
|
@import "../pages/finish/styles/finish";
|
||||||
|
@import "./desktop";
|
||||||
|
|
||||||
$fa-font-path: "../../../node_modules/@fortawesome/fontawesome-free-webfonts/webfonts";
|
$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/fontawesome";
|
||||||
@import "../../../../node_modules/@fortawesome/fontawesome-free-webfonts/scss/fa-solid";
|
@import "../../../../node_modules/@fortawesome/fontawesome-free-webfonts/scss/fa-solid";
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Nunito";
|
font-family: "Nunito";
|
||||||
src: url("Nunito-Regular.eot");
|
|
||||||
src: url("./fonts/Nunito-Regular.eot?#iefix") format("embedded-opentype"),
|
src: url("./fonts/Nunito-Regular.eot?#iefix") format("embedded-opentype"),
|
||||||
url("./fonts/Nunito-Regular.woff2") format("woff2"),
|
url("./fonts/Nunito-Regular.woff2") format("woff2"),
|
||||||
url("./fonts/Nunito-Regular.woff") format("woff"),
|
url("./fonts/Nunito-Regular.woff") format("woff"),
|
||||||
@ -54,7 +55,6 @@ $fa-font-path: "../../../node_modules/@fortawesome/fontawesome-free-webfonts/web
|
|||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Nunito";
|
font-family: "Nunito";
|
||||||
src: url("Nunito-Bold.eot");
|
|
||||||
src: url("./fonts/Nunito-Bold.eot?#iefix") format("embedded-opentype"),
|
src: url("./fonts/Nunito-Bold.eot?#iefix") format("embedded-opentype"),
|
||||||
url("./fonts/Nunito-Bold.woff2") format("woff2"),
|
url("./fonts/Nunito-Bold.woff2") format("woff2"),
|
||||||
url("./fonts/Nunito-Bold.woff") format("woff"),
|
url("./fonts/Nunito-Bold.woff") format("woff"),
|
||||||
@ -66,7 +66,6 @@ $fa-font-path: "../../../node_modules/@fortawesome/fontawesome-free-webfonts/web
|
|||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Nunito";
|
font-family: "Nunito";
|
||||||
src: url("Nunito-Light.eot");
|
|
||||||
src: url("./fonts/Nunito-Light.eot?#iefix") format("embedded-opentype"),
|
src: url("./fonts/Nunito-Light.eot?#iefix") format("embedded-opentype"),
|
||||||
url("./fonts/Nunito-Light.woff2") format("woff2"),
|
url("./fonts/Nunito-Light.woff2") format("woff2"),
|
||||||
url("./fonts/Nunito-Light.woff") format("woff"),
|
url("./fonts/Nunito-Light.woff") format("woff"),
|
||||||
|
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,
|
kiosk: fullscreen,
|
||||||
autoHideMenuBar: true,
|
autoHideMenuBar: true,
|
||||||
titleBarStyle: 'hiddenInset',
|
titleBarStyle: 'hiddenInset',
|
||||||
icon: path.join(__dirname, '..', '..', 'assets', 'icon.png'),
|
icon: path.join(__dirname, 'media', 'icon.png'),
|
||||||
darkTheme: true,
|
darkTheme: true,
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
backgroundThrottling: false,
|
backgroundThrottling: false,
|
||||||
@ -102,9 +102,7 @@ async function createMainWindow() {
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
});
|
});
|
||||||
|
|
||||||
mainWindow.loadURL(
|
mainWindow.loadURL(`file://${path.join(__dirname, 'index.html')}`);
|
||||||
`file://${path.join(__dirname, '..', 'lib', 'gui', 'app', 'index.html')}`,
|
|
||||||
);
|
|
||||||
|
|
||||||
const page = mainWindow.webContents;
|
const page = mainWindow.webContents;
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import bindings = require('bindings');
|
|
||||||
import * as Bluebird from 'bluebird';
|
import * as Bluebird from 'bluebird';
|
||||||
import * as childProcess from 'child_process';
|
import * as childProcess from 'child_process';
|
||||||
import { promises as fs } from 'fs';
|
import { promises as fs } from 'fs';
|
||||||
@ -109,7 +108,9 @@ async function elevateScriptWindows(
|
|||||||
): Promise<{ cancelled: boolean }> {
|
): Promise<{ cancelled: boolean }> {
|
||||||
// 'elevator' imported here as it only exists on windows
|
// '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
|
// 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)
|
// '&' needs to be escaped here (but not when written to a .cmd file)
|
||||||
const cmd = ['cmd', '/c', escapeParamCmd(path).replace(/&/g, '^&')];
|
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",
|
"webpack": "webpack",
|
||||||
"watch": "webpack --watch",
|
"watch": "webpack --watch",
|
||||||
"concourse-build-electron": "make webpack",
|
"concourse-build-electron": "make webpack",
|
||||||
"concourse-test": "npx npm@6.7.0 test",
|
"concourse-test": "npx npm@6.14.5 test",
|
||||||
"concourse-test-electron": "npx npm@6.7.0 test"
|
"concourse-test-electron": "npx npm@6.14.5 test"
|
||||||
},
|
},
|
||||||
"husky": {
|
"husky": {
|
||||||
"hooks": {
|
"hooks": {
|
||||||
@ -42,49 +42,17 @@
|
|||||||
"fsevents",
|
"fsevents",
|
||||||
"winusb-driver-generator"
|
"winusb-driver-generator"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"devDependencies": {
|
||||||
|
"@balena/lint": "^5.0.4",
|
||||||
"@fortawesome/fontawesome-free-webfonts": "^1.0.9",
|
"@fortawesome/fontawesome-free-webfonts": "^1.0.9",
|
||||||
"@fortawesome/fontawesome-svg-core": "^1.2.25",
|
"@fortawesome/fontawesome-svg-core": "^1.2.25",
|
||||||
"@fortawesome/free-brands-svg-icons": "^5.11.2",
|
"@fortawesome/free-brands-svg-icons": "^5.11.2",
|
||||||
"@fortawesome/free-solid-svg-icons": "^5.11.2",
|
"@fortawesome/free-solid-svg-icons": "^5.11.2",
|
||||||
"@fortawesome/react-fontawesome": "^0.1.7",
|
"@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/bluebird": "^3.5.30",
|
||||||
"@types/chai": "^4.2.7",
|
"@types/chai": "^4.2.7",
|
||||||
"@types/mime-types": "^2.1.0",
|
"@types/mime-types": "^2.1.0",
|
||||||
|
"@types/mini-css-extract-plugin": "^0.9.1",
|
||||||
"@types/mocha": "^7.0.2",
|
"@types/mocha": "^7.0.2",
|
||||||
"@types/node": "^12.12.39",
|
"@types/node": "^12.12.39",
|
||||||
"@types/node-ipc": "^9.1.2",
|
"@types/node-ipc": "^9.1.2",
|
||||||
@ -94,26 +62,61 @@
|
|||||||
"@types/sinon": "^9.0.0",
|
"@types/sinon": "^9.0.0",
|
||||||
"@types/tmp": "^0.2.0",
|
"@types/tmp": "^0.2.0",
|
||||||
"@types/webpack-node-externals": "^1.7.0",
|
"@types/webpack-node-externals": "^1.7.0",
|
||||||
|
"bluebird": "^3.7.2",
|
||||||
|
"bootstrap-sass": "^3.3.6",
|
||||||
"chai": "^4.2.0",
|
"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": "7.1.14",
|
||||||
"electron-builder": "^22.1.0",
|
"electron-builder": "^22.1.0",
|
||||||
"electron-mocha": "^8.2.0",
|
"electron-mocha": "^8.2.0",
|
||||||
"electron-notarize": "^0.3.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",
|
"husky": "^4.2.5",
|
||||||
|
"immutable": "^3.8.1",
|
||||||
|
"inactivity-timer": "^1.0.0",
|
||||||
"lint-staged": "^10.2.2",
|
"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",
|
"mocha": "^7.0.1",
|
||||||
|
"nan": "^2.14.0",
|
||||||
|
"native-addon-loader": "^2.0.1",
|
||||||
"node-gyp": "^6.1.0",
|
"node-gyp": "^6.1.0",
|
||||||
"node-sass": "^4.12.0",
|
"node-ipc": "^9.1.1",
|
||||||
"omit-deep-lodash": "1.1.4",
|
"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-lint": "^1.12.1",
|
||||||
|
"sass-loader": "^8.0.2",
|
||||||
|
"semver": "^7.3.2",
|
||||||
"simple-progress-webpack-plugin": "^1.1.2",
|
"simple-progress-webpack-plugin": "^1.1.2",
|
||||||
"sinon": "^9.0.2",
|
"sinon": "^9.0.2",
|
||||||
"spectron": "^9.0.0",
|
"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-loader": "^7.0.4",
|
||||||
"ts-node": "^8.3.0",
|
"ts-node": "^8.3.0",
|
||||||
"typescript": "^3.5.3",
|
"typescript": "^3.5.3",
|
||||||
|
"uuid": "^8.0.0",
|
||||||
"webpack": "^4.40.2",
|
"webpack": "^4.40.2",
|
||||||
"webpack-cli": "^3.3.9",
|
"webpack-cli": "^3.3.9"
|
||||||
"webpack-node-externals": "^1.7.2"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.
|
* 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 _ 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 path from 'path';
|
||||||
import * as SimpleProgressWebpackPlugin from 'simple-progress-webpack-plugin';
|
import * as SimpleProgressWebpackPlugin from 'simple-progress-webpack-plugin';
|
||||||
import { BannerPlugin } from 'webpack';
|
import { BannerPlugin } from 'webpack';
|
||||||
import * as nodeExternals from 'webpack-node-externals';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Don't webpack package.json as mixpanel & sentry tokens
|
* 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 = {
|
const commonConfig = {
|
||||||
mode: 'production',
|
mode: 'production',
|
||||||
optimization: {
|
optimization: {
|
||||||
@ -48,10 +110,86 @@ const commonConfig = {
|
|||||||
test: /\.tsx?$/,
|
test: /\.tsx?$/,
|
||||||
use: 'ts-loader',
|
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: {
|
resolve: {
|
||||||
extensions: ['.json', '.ts', '.tsx'],
|
extensions: ['.node', '.js', '.json', '.ts', '.tsx'],
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
new SimpleProgressWebpackPlugin({
|
new SimpleProgressWebpackPlugin({
|
||||||
@ -62,8 +200,35 @@ const commonConfig = {
|
|||||||
path: path.join(__dirname, 'generated'),
|
path: path.join(__dirname, 'generated'),
|
||||||
filename: '[name].js',
|
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 = {
|
const guiConfig = {
|
||||||
...commonConfig,
|
...commonConfig,
|
||||||
target: 'electron-renderer',
|
target: 'electron-renderer',
|
||||||
@ -71,16 +236,9 @@ const guiConfig = {
|
|||||||
__dirname: true,
|
__dirname: true,
|
||||||
__filename: true,
|
__filename: true,
|
||||||
},
|
},
|
||||||
externals: [
|
|
||||||
nodeExternals(),
|
|
||||||
|
|
||||||
// '../../../package.json' because we are in 'lib/gui/app/index.html'
|
|
||||||
externalPackageJson('../../../package.json'),
|
|
||||||
],
|
|
||||||
entry: {
|
entry: {
|
||||||
gui: path.join(__dirname, 'lib', 'gui', 'app', 'app.ts'),
|
gui: path.join(__dirname, 'lib', 'gui', 'app', 'app.ts'),
|
||||||
},
|
},
|
||||||
devtool: 'source-map',
|
|
||||||
plugins: [
|
plugins: [
|
||||||
...commonConfig.plugins,
|
...commonConfig.plugins,
|
||||||
// Remove "Download the React DevTools for a better development experience" message
|
// Remove "Download the React DevTools for a better development experience" message
|
||||||
@ -88,6 +246,7 @@ const guiConfig = {
|
|||||||
banner: '__REACT_DEVTOOLS_GLOBAL_HOOK__ = { isDisabled: true };',
|
banner: '__REACT_DEVTOOLS_GLOBAL_HOOK__ = { isDisabled: true };',
|
||||||
raw: true,
|
raw: true,
|
||||||
}),
|
}),
|
||||||
|
new CopyPlugin({ patterns: guiConfigCopyPatterns }),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -98,15 +257,62 @@ const etcherConfig = {
|
|||||||
__dirname: false,
|
__dirname: false,
|
||||||
__filename: true,
|
__filename: true,
|
||||||
},
|
},
|
||||||
externals: [
|
|
||||||
nodeExternals(),
|
|
||||||
|
|
||||||
// '../package.json' because we are in 'generated/etcher.js'
|
|
||||||
externalPackageJson('../package.json'),
|
|
||||||
],
|
|
||||||
entry: {
|
entry: {
|
||||||
etcher: path.join(__dirname, 'lib', 'start.ts'),
|
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