diff --git a/.gitignore b/.gitignore index 0d501b76..f6734a37 100644 --- a/.gitignore +++ b/.gitignore @@ -52,6 +52,8 @@ npm-debug.log /src/*/dist/ /dist/** .webpack.json +/build +/build/** # Doc # /doc/ diff --git a/config/electron/webpack.electron.common.js b/config/electron/webpack.electron.common.js new file mode 100644 index 00000000..4569a6b6 --- /dev/null +++ b/config/electron/webpack.electron.common.js @@ -0,0 +1,38 @@ +const helpers = require('./../helpers'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); + +module.exports = { + entry: { + 'main': './src/desktop.ts' + }, + + target: 'electron', + + node: { + __dirname: false + }, + + output: { + path: helpers.root('build'), + filename: '[name].js' + }, + + resolve: { + extensions: ['', '.ts', '.js', '.json'] + }, + + module: { + loaders: [ + { + test: /\.ts$/, + loader: 'awesome-typescript-loader' + } + ] + }, + + plugins: [ + new CopyWebpackPlugin([{ + from: 'src/package.json' + }]) + ] +} diff --git a/config/electron/webpack.electron.dev.js b/config/electron/webpack.electron.dev.js new file mode 100644 index 00000000..d3a1ba5a --- /dev/null +++ b/config/electron/webpack.electron.dev.js @@ -0,0 +1,21 @@ +const webpack = require('webpack'); +const webpackMerge = require('webpack-merge'); +const commonConfig = require('./webpack.electron.common.js'); +const WebpackShellPlugin = require('./webpack-shell-plugin'); + +const ENV = process.env.NODE_ENV = process.env.ENV = 'development'; + +module.exports = webpackMerge(commonConfig, { + plugins: [ + new WebpackShellPlugin({ + //TODO: Kill electron process before build, to start the new one fresh. + onBuildStart: [''], + onBuildEnd: ['electron dist'] + }), + new webpack.DefinePlugin({ + 'process.env': { + 'ENV': JSON.stringify(ENV) + } + }) + ] +}); diff --git a/config/electron/webpack.electron.prod.js b/config/electron/webpack.electron.prod.js new file mode 100644 index 00000000..fbe3a528 --- /dev/null +++ b/config/electron/webpack.electron.prod.js @@ -0,0 +1,26 @@ +const webpack = require('webpack'); +const webpackMerge = require('webpack-merge'); +const commonConfig = require('./webpack.electron.common.js'); + +const ENV = process.env.NODE_ENV = process.env.ENV = 'production'; + +module.exports = webpackMerge(commonConfig, { + plugins: [ + // new webpack.optimize.DedupePlugin(), + new webpack.optimize.UglifyJsPlugin({ + beautify: false, + mangle: { + screw_ie8: true + }, + compress: { + screw_ie8: true + }, + comments: false + }), + new webpack.DefinePlugin({ + 'process.env': { + 'ENV': JSON.stringify(ENV) + } + }) + ] +}); diff --git a/config/electron/webpack.renderer.common.js b/config/electron/webpack.renderer.common.js new file mode 100644 index 00000000..51c9a2fe --- /dev/null +++ b/config/electron/webpack.renderer.common.js @@ -0,0 +1,67 @@ +const helpers = require('./../helpers'); +const webpack = require('webpack'); + +const METADATA = { + baseUrl: './', + ENV: 'renderer', +}; + +/* + * Webpack configuration + * + * See: http://webpack.github.io/docs/configuration.html#cli + */ +module.exports = function (env) { + METADATA.ENV = env + ? env + : METADATA.ENV + + return { + + /* + * Static metadata for index.html + * + * See: (custom attribute) + */ + metadata: METADATA, + + /** + * The plataform target where the aplication is going to run in. + * It support target electron-renderer, but is not documented. + * + * See: https://webpack.github.io/docs/configuration.html#target + */ + + target: 'electron-renderer', + + /** + * Options affecting the output of the compilation. + * + * See: http://webpack.github.io/docs/configuration.html#output + */ + output: { + + /** + * The output directory as absolute path (required). + * + * See: http://webpack.github.io/docs/configuration.html#output-path + */ + path: helpers.root('build'), + }, + + /* + * Include polyfills or mocks for various node stuff + * Description: Node configuration + * + * See: https://webpack.github.io/docs/configuration.html#node + */ + node: { + global: 'window', + crypto: 'empty', + process: true, + module: false, + clearImmediate: false, + setImmediate: false + } + }; +}; diff --git a/config/electron/webpack.renderer.dev.js b/config/electron/webpack.renderer.dev.js new file mode 100644 index 00000000..66f9c292 --- /dev/null +++ b/config/electron/webpack.renderer.dev.js @@ -0,0 +1,6 @@ +const devConfig = require('./../webpack.dev'); +const commonConfig = require('./webpack.renderer.common'); +const webpackMerge = require('webpack-merge'); + +module.exports = webpackMerge(devConfig(), commonConfig(), { +}); diff --git a/config/electron/webpack.renderer.prod.js b/config/electron/webpack.renderer.prod.js new file mode 100644 index 00000000..4a2ae9f5 --- /dev/null +++ b/config/electron/webpack.renderer.prod.js @@ -0,0 +1,6 @@ +const prodConfig = require('./../webpack.prod'); +const commonConfig = require('./webpack.renderer.common'); +const webpackMerge = require('webpack-merge'); + +module.exports = webpackMerge(prodConfig(), commonConfig(), { +}); diff --git a/config/webpack.prod.js b/config/webpack.prod.js index 8ff60924..45119341 100644 --- a/config/webpack.prod.js +++ b/config/webpack.prod.js @@ -27,7 +27,9 @@ const METADATA = webpackMerge(commonConfig({env: ENV}).metadata, { }); module.exports = function(env) { - return webpackMerge(commonConfig({env: ENV}), { + env = env || ENV; + + return webpackMerge(commonConfig({env: env}), { /** * Switch loaders to debug mode. diff --git a/package.json b/package.json index b4547575..b7615bf1 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "fullcalendar": "^2.7.2", "google-maps": "^3.2.1", "ionicons": "^2.0.1", + "is-electron-renderer": "^2.0.0", "jquery": "^2.2.3", "jquery-slimscroll": "^1.3.6", "leaflet": "^0.7.7", @@ -61,6 +62,7 @@ "devDependencies": { "angular2-template-loader": "^0.5.0", "@types/core-js": "^0.9.28", + "@types/electron": "^1.3.20", "@types/hammerjs": "^2.0.28", "@types/node": "^6.0.38", "@types/source-map": "^0.1.26", @@ -95,7 +97,7 @@ "node-sass": "^3.5.3", "html-webpack-plugin": "^2.21.0", "copy-webpack-plugin": "^3.0.1", - "webpack": "2.1.0-beta.21", + "webpack": "2.1.0-beta.22", "webpack-dashboard": "^0.1.8", "webpack-dev-middleware": "^1.6.1", "webpack-dev-server": "^2.1.0-beta.2", @@ -105,17 +107,18 @@ "es6-promise": "^3.1.2", "es6-shim": "^0.35.0", "es7-reflect-metadata": "^1.6.0", - "electron": "^1.3.4" + "electron": "^1.4.0" }, "scripts": { "rimraf": "rimraf", "tslint": "tslint", "typedoc": "typedoc", - "webpack": "webpack", + "webpack": "webpack --progress --profile --bail", "webpack-dev-server": "webpack-dev-server", "webdriver-manager": "webdriver-manager", "clean": "npm cache clean && npm run rimraf -- node_modules doc coverage dist", "clean:dist": "npm run rimraf -- dist", + "clean:electron": "npm run rimraf -- build", "preclean:install": "npm run clean", "clean:install": "npm set progress=false && npm install", "preclean:start": "npm run clean", @@ -126,9 +129,9 @@ "watch:prod": "npm run build:prod -- --watch", "build": "npm run build:dev", "prebuild:dev": "npm run clean:dist", - "build:dev": "webpack --config config/webpack.dev.js --progress --profile", + "build:dev": "npm run webpack -- --config config/webpack.dev.js", "prebuild:prod": "npm run clean:dist", - "build:prod": "webpack --config config/webpack.prod.js --progress --profile --bail", + "build:prod": "npm run webpack -- --config config/webpack.prod.js", "server": "npm run server:dev", "server:dev": "webpack-dev-server --config config/webpack.dev.js --progress --profile --watch --content-base src/", "server:dev:hmr": "npm run server:dev -- --inline --hot", @@ -144,7 +147,13 @@ "start:hmr": "npm run server:dev:hmr", "version": "npm run build", "postversion": "git push && git push --tags", - "electron": "electron ./src/electron/main.js" + "build:electron": "npm run build:electron.full", + "prebuild:electron.full": "npm run clean:electron", + "build:electron.full": "npm run build:electron.renderer && npm run build:electron.main", + "postbuild:electron.full": "npm run electron:start", + "build:electron.renderer": "npm run webpack -- --config config/electron/webpack.renderer.prod.js", + "build:electron.main": "npm run webpack -- --config config/electron/webpack.electron.prod.js", + "electron:start": "electron build" }, "repository": { "type": "git", diff --git a/src/app/environment.ts b/src/app/environment.ts index 8d5288f9..c24f64e3 100644 --- a/src/app/environment.ts +++ b/src/app/environment.ts @@ -12,7 +12,7 @@ let PROVIDERS: any[] = [ // https://github.com/angular/angular/blob/86405345b781a9dc2438c0fbe3e9409245647019/TOOLS_JS.md let _decorateModuleRef = function identity(value: T): T { return value; }; -if ('production' === ENV) { +if ('production' === ENV || 'renderer' === ENV) { // Production disableDebugTools(); enableProdMode(); diff --git a/src/electron/main.js b/src/desktop.ts similarity index 50% rename from src/electron/main.js rename to src/desktop.ts index 2244d0bc..67267913 100644 --- a/src/electron/main.js +++ b/src/desktop.ts @@ -1,53 +1,47 @@ -const electron = require('electron') -// Module to control application life. -const app = electron.app -// Module to create native browser window. -const BrowserWindow = electron.BrowserWindow +import { app, BrowserWindow } from 'electron'; -// Keep a global reference of the window object, if you don't, the window will -// be closed automatically when the JavaScript object is garbage collected. -let mainWindow +let win: Electron.BrowserWindow; function createWindow () { // Create the browser window. - mainWindow = new BrowserWindow({width: 800, height: 600}) + win = new BrowserWindow({width: 800, height: 600}); // and load the index.html of the app. - mainWindow.loadURL(`file://${__dirname}/../../dist/index.html`) + win.loadURL(`file://${__dirname}/index.html`); // Open the DevTools. - mainWindow.webContents.openDevTools() + // win.webContents.openDevTools(); // Emitted when the window is closed. - mainWindow.on('closed', function () { + win.on('closed', () => { // Dereference the window object, usually you would store windows // in an array if your app supports multi windows, this is the time // when you should delete the corresponding element. - mainWindow = null - }) + win = null; + }); } // This method will be called when Electron has finished // initialization and is ready to create browser windows. // Some APIs can only be used after this event occurs. -app.on('ready', createWindow) +app.on('ready', createWindow); // Quit when all windows are closed. -app.on('window-all-closed', function () { - // On OS X it is common for applications and their menu bar +app.on('window-all-closed', () => { + // On macOS it is common for applications and their menu bar // to stay active until the user quits explicitly with Cmd + Q if (process.platform !== 'darwin') { - app.quit() + app.quit(); } -}) +}); -app.on('activate', function () { - // On OS X it's common to re-create a window in the app when the +app.on('activate', () => { + // On macOS it's common to re-create a window in the app when the // dock icon is clicked and there are no other windows open. - if (mainWindow === null) { - createWindow() + if (win === null) { + createWindow(); } -}) +}); // In this file you can include the rest of your app's specific main process // code. You can also put them in separate files and require them here. diff --git a/src/package.json b/src/package.json new file mode 100644 index 00000000..7c268619 --- /dev/null +++ b/src/package.json @@ -0,0 +1,5 @@ +{ + "name" : "electron-app", + "version" : "0.0.1", + "main" : "main.js" +}