mirror of
https://github.com/balena-io/etcher.git
synced 2025-07-22 18:56:31 +00:00
feat(GUI): bundle the GUI code with Webpack (#1943)
This commit introduces a Webpack configuration file that bundles the GUI code along with its dependencies (except the Etcher SDK and its own dependencies), and uses Babel to add support for JSX (required by the Rendition library). The GUI code that goes into the bundle was moved to `lib/gui/app` so we can easily ignore the whole subdirectory when creating production distributable packages. We now have a new make target called `webpack` that can be used to create the GUI bundle. Such target will be called everytime a package is generated. Change-Type: patch Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
This commit is contained in:
parent
e0f789bc14
commit
4fa0f990e5
3
.gitignore
vendored
3
.gitignore
vendored
@ -23,6 +23,9 @@ pids
|
||||
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
||||
/build
|
||||
|
||||
# Generated files
|
||||
/generated
|
||||
|
||||
# Dependency directory
|
||||
# https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git
|
||||
node_modules
|
||||
|
26
Makefile
26
Makefile
@ -2,6 +2,10 @@
|
||||
# Build configuration
|
||||
# ---------------------------------------------------------------------
|
||||
|
||||
# A non-existing target to force rules to rebuild
|
||||
# See https://stackoverflow.com/a/816416
|
||||
.FORCE:
|
||||
|
||||
# This directory will be completely deleted by the `clean` rule
|
||||
BUILD_DIRECTORY ?= dist
|
||||
|
||||
@ -276,13 +280,16 @@ $(BUILD_DIRECTORY)/$(APPLICATION_NAME)-cli-$(APPLICATION_VERSION)-$(PLATFORM)-$(
|
||||
assets/dmg/background.tiff: assets/dmg/background.png assets/dmg/background@2x.png
|
||||
tiffutil -cathidpicheck $^ -out $@
|
||||
|
||||
$(BUILD_DIRECTORY)/$(APPLICATION_NAME)-$(APPLICATION_VERSION).dmg: assets/dmg/background.tiff \
|
||||
build/js/gui.js: .FORCE
|
||||
webpack
|
||||
|
||||
$(BUILD_DIRECTORY)/$(APPLICATION_NAME)-$(APPLICATION_VERSION).dmg: assets/dmg/background.tiff build/js/gui.js \
|
||||
| $(BUILD_DIRECTORY)
|
||||
TARGET_ARCH=$(TARGET_ARCH) build --mac dmg $(ELECTRON_BUILDER_OPTIONS) \
|
||||
--extraMetadata.version=$(APPLICATION_VERSION) \
|
||||
--extraMetadata.packageType=dmg
|
||||
|
||||
$(BUILD_DIRECTORY)/$(APPLICATION_NAME)-$(APPLICATION_VERSION)-mac.zip: assets/dmg/background.tiff \
|
||||
$(BUILD_DIRECTORY)/$(APPLICATION_NAME)-$(APPLICATION_VERSION)-mac.zip: assets/dmg/background.tiff build/js/gui.js \
|
||||
| $(BUILD_DIRECTORY)
|
||||
TARGET_ARCH=$(TARGET_ARCH) build --mac zip $(ELECTRON_BUILDER_OPTIONS) \
|
||||
--extraMetadata.version=$(APPLICATION_VERSION) \
|
||||
@ -290,14 +297,14 @@ $(BUILD_DIRECTORY)/$(APPLICATION_NAME)-$(APPLICATION_VERSION)-mac.zip: assets/dm
|
||||
|
||||
APPLICATION_NAME_ELECTRON = $(APPLICATION_NAME_LOWERCASE)-electron
|
||||
|
||||
$(BUILD_DIRECTORY)/$(APPLICATION_NAME_ELECTRON)-$(APPLICATION_VERSION_REDHAT).$(TARGET_ARCH_REDHAT).rpm: \
|
||||
$(BUILD_DIRECTORY)/$(APPLICATION_NAME_ELECTRON)-$(APPLICATION_VERSION_REDHAT).$(TARGET_ARCH_REDHAT).rpm: build/js/gui.js \
|
||||
| $(BUILD_DIRECTORY)
|
||||
build --linux rpm $(ELECTRON_BUILDER_OPTIONS) \
|
||||
--extraMetadata.name=$(APPLICATION_NAME_ELECTRON) \
|
||||
--extraMetadata.version=$(APPLICATION_VERSION_REDHAT) \
|
||||
--extraMetadata.packageType=rpm
|
||||
|
||||
$(BUILD_DIRECTORY)/$(APPLICATION_NAME_ELECTRON)_$(APPLICATION_VERSION_DEBIAN)_$(TARGET_ARCH_DEBIAN).deb: \
|
||||
$(BUILD_DIRECTORY)/$(APPLICATION_NAME_ELECTRON)_$(APPLICATION_VERSION_DEBIAN)_$(TARGET_ARCH_DEBIAN).deb: build/js/gui.js \
|
||||
| $(BUILD_DIRECTORY)
|
||||
build --linux deb $(ELECTRON_BUILDER_OPTIONS) \
|
||||
--extraMetadata.name=$(APPLICATION_NAME_ELECTRON) \
|
||||
@ -310,7 +317,7 @@ else
|
||||
ELECTRON_BUILDER_LINUX_UNPACKED_DIRECTORY = linux-$(TARGET_ARCH_ELECTRON_BUILDER)-unpacked
|
||||
endif
|
||||
|
||||
$(BUILD_DIRECTORY)/$(ELECTRON_BUILDER_LINUX_UNPACKED_DIRECTORY)/$(APPLICATION_NAME_ELECTRON): | $(BUILD_DIRECTORY)
|
||||
$(BUILD_DIRECTORY)/$(ELECTRON_BUILDER_LINUX_UNPACKED_DIRECTORY)/$(APPLICATION_NAME_ELECTRON): build/js/gui.js | $(BUILD_DIRECTORY)
|
||||
build --dir --linux $(ELECTRON_BUILDER_OPTIONS) \
|
||||
--extraMetadata.name=$(APPLICATION_NAME_ELECTRON) \
|
||||
--extraMetadata.version=$(APPLICATION_VERSION) \
|
||||
@ -343,13 +350,13 @@ $(BUILD_DIRECTORY)/$(APPLICATION_NAME_LOWERCASE)-$(APPLICATION_VERSION)-$(PLATFO
|
||||
| $(BUILD_DIRECTORY)
|
||||
./scripts/build/zip-file.sh -f $< -s $(PLATFORM) -o $@
|
||||
|
||||
$(BUILD_DIRECTORY)/$(APPLICATION_NAME)-Portable-$(APPLICATION_VERSION)-$(TARGET_ARCH).exe: \
|
||||
$(BUILD_DIRECTORY)/$(APPLICATION_NAME)-Portable-$(APPLICATION_VERSION)-$(TARGET_ARCH).exe: build/js/gui.js \
|
||||
| $(BUILD_DIRECTORY)
|
||||
TARGET_ARCH=$(TARGET_ARCH) build --win portable $(ELECTRON_BUILDER_OPTIONS) \
|
||||
--extraMetadata.version=$(APPLICATION_VERSION) \
|
||||
--extraMetadata.packageType=portable
|
||||
|
||||
$(BUILD_DIRECTORY)/$(APPLICATION_NAME)-Setup-$(APPLICATION_VERSION)-$(TARGET_ARCH).exe: \
|
||||
$(BUILD_DIRECTORY)/$(APPLICATION_NAME)-Setup-$(APPLICATION_VERSION)-$(TARGET_ARCH).exe: build/js/gui.js \
|
||||
| $(BUILD_DIRECTORY)
|
||||
TARGET_ARCH=$(TARGET_ARCH) build --win nsis $(ELECTRON_BUILDER_OPTIONS) \
|
||||
--extraMetadata.version=$(APPLICATION_VERSION) \
|
||||
@ -377,6 +384,7 @@ TARGETS = \
|
||||
clean \
|
||||
distclean \
|
||||
changelog \
|
||||
webpack \
|
||||
package-electron \
|
||||
package-cli \
|
||||
cli-develop \
|
||||
@ -387,6 +395,8 @@ TARGETS = \
|
||||
changelog:
|
||||
versionist
|
||||
|
||||
webpack: build/js/gui.js
|
||||
|
||||
package-electron:
|
||||
TARGET_ARCH=$(TARGET_ARCH) build --dir $(ELECTRON_BUILDER_OPTIONS)
|
||||
|
||||
@ -517,7 +527,7 @@ sass:
|
||||
node-sass lib/gui/app/scss/main.scss > lib/gui/css/main.css
|
||||
|
||||
lint-js:
|
||||
eslint lib tests scripts bin versionist.conf.js
|
||||
eslint lib tests scripts bin versionist.conf.js webpack.config.js
|
||||
|
||||
lint-sass:
|
||||
sass-lint lib/gui/scss
|
||||
|
@ -6,6 +6,9 @@ nodeGypRebuild: true
|
||||
publish: null
|
||||
files:
|
||||
- lib
|
||||
- "!lib/gui/app"
|
||||
- lib/gui/app/index.html
|
||||
- generated
|
||||
- build/**/*.node
|
||||
- assets/icon.png
|
||||
- node_modules/**/*
|
||||
|
@ -26,14 +26,6 @@ var angular = require('angular')
|
||||
|
||||
/* eslint-enable no-var */
|
||||
|
||||
// Temporary: will be taken care of Webpack automatically soon
|
||||
// eslint-disable-next-line node/no-deprecated-api
|
||||
require.extensions['.html'] = (module, filename) => {
|
||||
module.exports = require('fs').readFileSync(filename, {
|
||||
encoding: 'utf8'
|
||||
})
|
||||
}
|
||||
|
||||
const electron = require('electron')
|
||||
const Bluebird = require('bluebird')
|
||||
const semver = require('semver')
|
||||
|
@ -48,11 +48,22 @@ class SVGIcon extends react.Component {
|
||||
* @returns {react.Element}
|
||||
*/
|
||||
render () {
|
||||
// __dirname behaves strangely inside a Webpack bundle,
|
||||
// so we need to provide different base directories
|
||||
// depending on whether __dirname is absolute or not,
|
||||
// which helps detecting a Webpack bundle.
|
||||
// We use global.__dirname inside a Webpack bundle since
|
||||
// that's the only way to get the "real" __dirname.
|
||||
const baseDirectory = path.isAbsolute(__dirname)
|
||||
? path.join(__dirname, '..')
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
: global.__dirname
|
||||
|
||||
// This means the path to the icon should be
|
||||
// relative to *this directory*.
|
||||
// TODO: There might be a way to compute the path
|
||||
// relatively to the `index.html`.
|
||||
const imagePath = path.join(__dirname, this.props.path)
|
||||
const imagePath = path.join(baseDirectory, 'assets', this.props.path)
|
||||
|
||||
let contents = ''
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<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="../css/angular.css">
|
||||
<script src="./app.js"></script>
|
||||
<script src="../../../generated/gui.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<header class="section-header" ng-controller="HeaderController as header">
|
||||
|
@ -70,7 +70,7 @@ module.exports = function (
|
||||
// updates. Without this there is essentially no progress to watch.
|
||||
const unsubscribe = store.subscribe($timeout)
|
||||
|
||||
const iconPath = '../../assets/icon.png'
|
||||
const iconPath = '../../../assets/icon.png'
|
||||
|
||||
imageWriter.flash(image.path, drive).then(() => {
|
||||
if (!flashState.wasLastFlashCancelled()) {
|
||||
|
1774
npm-shrinkwrap.json
generated
1774
npm-shrinkwrap.json
generated
File diff suppressed because it is too large
Load Diff
@ -94,6 +94,11 @@
|
||||
"devDependencies": {
|
||||
"angular-mocks": "1.6.3",
|
||||
"asar": "0.10.0",
|
||||
"babel-core": "6.26.0",
|
||||
"babel-loader": "7.1.2",
|
||||
"babel-preset-env": "1.6.1",
|
||||
"babel-preset-react": "6.24.1",
|
||||
"babel-preset-stage-0": "6.24.1",
|
||||
"electron": "1.7.11",
|
||||
"electron-builder": "19.40.0",
|
||||
"electron-mocha": "5.0.0",
|
||||
@ -106,6 +111,7 @@
|
||||
"eslint-plugin-promise": "3.6.0",
|
||||
"eslint-plugin-standard": "3.0.1",
|
||||
"html-angular-validate": "0.1.9",
|
||||
"html-loader": "0.5.1",
|
||||
"mocha": "3.2.0",
|
||||
"mochainon": "1.0.0",
|
||||
"nock": "9.0.9",
|
||||
@ -114,6 +120,7 @@
|
||||
"pkg": "4.1.1",
|
||||
"sass-lint": "1.10.2",
|
||||
"spectron": "3.7.2",
|
||||
"versionist": "2.8.1"
|
||||
"versionist": "2.8.1",
|
||||
"webpack": "3.10.0"
|
||||
}
|
||||
}
|
||||
|
70
webpack.config.js
Normal file
70
webpack.config.js
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2017 resin.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.
|
||||
*/
|
||||
|
||||
'use strict'
|
||||
|
||||
const _ = require('lodash')
|
||||
const path = require('path')
|
||||
|
||||
module.exports = {
|
||||
target: 'electron-main',
|
||||
node: {
|
||||
__dirname: true,
|
||||
__filename: true
|
||||
},
|
||||
entry: {
|
||||
gui: path.join(__dirname, 'lib', 'gui', 'app', 'app.js')
|
||||
},
|
||||
output: {
|
||||
path: path.join(__dirname, 'generated'),
|
||||
filename: '[name].js'
|
||||
},
|
||||
externals: [
|
||||
(context, request, callback) => {
|
||||
// We want to keep the SDK code outside the GUI bundle.
|
||||
// This piece of code allows us to run the GUI directly
|
||||
// on the tree (for testing purposes) or inside a generated
|
||||
// bundle (for production purposes), by translating
|
||||
// relative require paths within the bundle.
|
||||
if (/\.\/(shared|image-stream)/i.test(request)) {
|
||||
return callback(null, `commonjs ../../../lib/${_.replace(request, /(\.\.\/)*/, '')}`)
|
||||
}
|
||||
|
||||
return callback()
|
||||
}
|
||||
],
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.js?$/,
|
||||
include: [ path.resolve(__dirname, 'lib/gui') ],
|
||||
use: {
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
presets: [ 'react', 'env', 'stage-0' ]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.html$/,
|
||||
include: [ path.resolve(__dirname, 'lib/gui/app') ],
|
||||
use: {
|
||||
loader: 'html-loader'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user