electron + angular2 loading vendor lib - angularjs

I created a new angular2 app using the angularCLI (just so you know my directory structure).
Running ng serve puts all my files in the dist folder and runs the hello world app in the browser with no issue.
I'm trying to run the same app in electron, but it is unable to find all the vendor files (including #angular) since it uses the file protocol in a script src:
This
<script src="vendor/es6-shim/es6-shim.js"></script>
<script src="vendor/reflect-metadata/Reflect.js"></script>
<script src="vendor/systemjs/dist/system.src.js"></script>
<script src="vendor/zone.js/dist/zone.js"></script>
produces this
file:///vendor/es6-shim/es6-shim.js Failed to load resource: net::ERR_FILE_NOT_FOUND
file:///vendor/reflect-metadata/Reflect.js Failed to load resource: net::ERR_FILE_NOT_FOUND
file:///vendor/systemjs/dist/system.src.js Failed to load resource: net::ERR_FILE_NOT_FOUND
file:///vendor/zone.js/dist/zone.js Failed to load resource: net::ERR_FILE_NOT_FOUND
How do you prepend the correct path in the file: protocol that electron uses?
My gulpfile.js:
var gulp = require('gulp'),
del = require('del'),
runSeq = require('run-sequence');
gulp.task('clean-electron', function(){
return del('dist/electron-package/**/*', {force: true});
});
gulp.task('copy:electron-manifest', function(){
return gulp.src('./package.json')
.pipe(gulp.dest('./dist/electron-package'))
});
gulp.task('copy:electron-scripts', function(){
return gulp.src('./src/electron_main.js')
.pipe(gulp.dest('./dist/electron-package'));
});
gulp.task('copy:vendor-for-electron', function() {
return gulp.src('./dist/vendor/**/*')
.pipe(gulp.dest('./dist/electron-package/vendor'))
});
gulp.task('copy:spa-for-electron', function(){
return gulp.src(["./dist/*.*", "./dist/app/**/*"])
.pipe(gulp.dest('dist/electron-package'));
});
gulp.task('electron', function(done){
return runSeq('clean-electron', ['copy:spa-for-electron', 'copy:vendor-for-electron', 'copy:electron-manifest', 'copy:electron-scripts' ], done);
});
The closest I got was doing this:
my index.html:
<script src="vendor/es6-shim/es6-shim.js"></script>
<script src="vendor/reflect-metadata/Reflect.js"></script>
<script src="vendor/systemjs/dist/system.src.js"></script>
<script src="vendor/zone.js/dist/zone.js"></script>
<script>
console.log("In my script tag:");
var systemConfigPath = 'system-config.js';
var mainPath = 'main.js';
if (window.location.protocol == "file:"){
require(__dirname + '/vendor/es6-shim/es6-shim.js');
require(__dirname + '/vendor/reflect-metadata/Reflect.js');
require(__dirname + '/vendor/systemjs/dist/system.src.js');
require(__dirname + '/vendor/zone.js/dist/zone.js');
systemConfigPath = __dirname + '/' + systemConfigPath;
mainPath = __dirname + '/' + mainPath ;
}
System.import(systemConfigPath).then(function () {
System.import(mainPath);
}).catch(console.error.bind(console));
but that still gives me issues as the vendor files reference other files inside the same directories:
Edit:
I am now trying to use webpack to build my electron app (with no success).
I also created a github repo if you would like to see the code.

From How should I configure the base href for Angular 2 when using Electron? the answer is to change you
<base href="/">
to
<base href="./">

Okay! so I am not sure it's the best answer, as it still produces some silly errors, but here we go...
My index.html now looks like this:
<body>
<electron-angular-boilerplate-app>Loading...</electron-angular-boilerplate-app>
<!--will give errors in electron... oh well-->
<script src="vendor/es6-shim/es6-shim.js"></script>
<script src="vendor/reflect-metadata/Reflect.js"></script>
<script src="vendor/systemjs/dist/system.src.js"></script>
<script src="vendor/zone.js/dist/zone.js"></script>
<script>
// if require is defined, we are on node / electron:
if (!(typeof(require) == "undefined")){
require('./vendor/es6-shim/es6-shim.js');
require("./vendor/reflect-metadata/Reflect.js");
require("./vendor/systemjs/dist/system.src.js");
require("./vendor/zone.js/dist/zone.js");
require("./system-config.js");
require("./main.js");
} else {
System.import('system-config.js').then(function () {
System.import('main');
}).catch(console.error.bind(console));
}
</script>
</body>
This allows both my angular cli application to run and my electron app to run. The <script src=... tags still produce errors in electron as it is not able to find them. I also had to remove the System.import line from electron, so hopefully that doesn't cause any issues later on.
and to run it, we just need to make sure that the app is built and run electron in the ./dist folder:
ng build && electron ./dist
Here is the branch with my working code:
https://github.com/jdell64/electronAngularBoilerplate/tree/so-37447020-answer

Related

HTML href not finding resource in project

I've been trying to learn angularJS, specifically 1.5 using components. My IDE is c9 so the server uses port: process.env.PORT which when I start will show the project at https://projectName-username.c9users.io (with angular-ui-router it has '/#!' on the end). This ide doesn't seem to compile es6 without using something like gulp. So I copy pasted much of the gulp code from the tutorial into my own project so that I could continue using the es6 syntax to build my own project.Everything is working pretty well except I am trying to link bootstrap 4 and my own css files from inside the project rather than a cdn and I can't seem to get the file path correct. When running the gulp file it says serving files from ./build so I tried writing the path from there but it has 404 on the resource.The closest I've come to was no errors thrown trying <link rel="stylesheet" src="#!/src/bower_components/bootstrap/dist/css/bootstrap.min.css"> but checking the network it says it's loading https://billardsWebsite-rawlejuglal.c9users.io/ with type stylesheet but nothing is actually there. Below is my file structure, the index.html file and then the gulpfile. If anyone can enlighten me on how to structure my links to find these resources I would appreciate it.
billardsWebsite
-.c9
-.git
-build
-index.html
-main.js
-node_modules
-src
-bower_components
-boostrap
-dist
-css
-bootstrap.min.css
-js
-css
-styles.css
-index.html
-.bowerrc
-.bower.json
-gulpfile.js
-package.json
-Procfile
Index.html (src/index.html)
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<title ng-bind="pageTitle"></title>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="#!/src/bower_components/bootstrap/dist/css/bootstrap.min.css">
</head>
<body>
<div ui-view></div>
<!-- jQuery first, then Tether, then Bootstrap JS. -->
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>
<script src="main.js"></script>
</body>
</html>
gulpfile.js
var gulp = require('gulp');
var notify = require('gulp-notify');
var source = require('vinyl-source-stream');
var browserify = require('browserify');
var babelify = require('babelify');
var ngAnnotate = require('browserify-ngannotate');
var browserSync = require('browser-sync').create();
var rename = require('gulp-rename');
var templateCache = require('gulp-angular-templatecache');
var uglify = require('gulp-uglify');
var merge = require('merge-stream');
// Where our files are located
var jsFiles = "src/js/**/*.js";
var viewFiles = "src/js/**/*.html";
var interceptErrors = function(error) {
var args = Array.prototype.slice.call(arguments);
// Send error to notification center with gulp-notify
notify.onError({
title: 'Compile Error',
message: '<%= error.message %>'
}).apply(this, args);
// Keep gulp from hanging on this task
this.emit('end');
};
gulp.task('browserify', ['views'], function() {
return browserify('./src/js/app.js')
.transform(babelify, {presets: ["es2015"]})
.transform(ngAnnotate)
.bundle()
.on('error', interceptErrors)
//Pass desired output filename to vinyl-source-stream
.pipe(source('main.js'))
// Start piping stream to tasks!
.pipe(gulp.dest('./build/'));
});
gulp.task('html', function() {
return gulp.src("src/index.html")
.on('error', interceptErrors)
.pipe(gulp.dest('./build/'));
});
gulp.task('views', function() {
return gulp.src(viewFiles)
.pipe(templateCache({
standalone: true
}))
.on('error', interceptErrors)
.pipe(rename("app.templates.js"))
.pipe(gulp.dest('./src/js/config/'));
});
// This task is used for building production ready
// minified JS/CSS files into the dist/ folder
gulp.task('build', ['html', 'browserify'], function() {
var html = gulp.src("build/index.html")
.pipe(gulp.dest('./dist/'));
var js = gulp.src("build/main.js")
.pipe(uglify())
.pipe(gulp.dest('./dist/'));
return merge(html,js);
});
gulp.task('default', ['html', 'browserify'], function() {
browserSync.init(['./build/**/**.**'], {
server: "./build",
port: process.env.PORT || '3000',
notify: false,
ui: {
port: 3001
}
});
gulp.watch("src/index.html", ['html']);
gulp.watch(viewFiles, ['views']);
gulp.watch(jsFiles, ['browserify']);
});

Reactjs file size: script-file vs npm-version

I am using reactjs and gulp for the build-process. Currently I use react from npm with browserify. When I want to minify my App in production-mode the react code ends up with about 180kb.
This is the gulp code I use:
gulp.task('production', function () {
var bundler = browserify('./public/dev/js/main.js').transform(babelify, { presets: ['react'] });
return bundler.bundle()
.on('error', map_error)
.pipe(source('bundle.js'))
.pipe(buffer())
.pipe(rename('bundle-build.min.js'))
.pipe(envify({'_': 'purge', NODE_ENV: 'production'}))
.pipe(uglify())
.pipe(gulp.dest('./public/dist/js/'));
});
However, if I download the minified script files from the react-website and load the script files like this:
<script type="text/javascript" src="./react.min.js"></script>
<script type="text/javascript" src="./react-dom.min.js"></script>
it ends up with about 150kb.
Why is the with gulp minified version bigger? How can I bring it to the same size? Also, is there a difference in the development / production of the app between loading the provided script files or using it from npm?
Thanks in advance
Cheers

Using gulp-babel gives Uncaught ReferenceError: require is not defined

I am using the following gulp.js file
var gulp = require('gulp');
var babel = require('gulp-babel');
gulp.task('bundle', bundle);
function bundle () {
gulp.src('./src/*.jsx')
.pipe(babel())
.pipe(gulp.dest('./dist'));
}
gulp.task('build', ['bundle']);
Before transpile "main.jsx" content
import React from 'react';
After Transpile, "js" files generated in the dist folder, has require('')
var _react = require('react');
while requesting for the page index.html
<body>
<div id="app" ></div>
<script src="main.js"></script>
</body>
Uncaught ReferenceError: require is not defined is shown in the console.
I know there is something wrong in the build task, but i am unable to figure out.
In the browser, you can not use require API, so you need to somehow bundle your code, you have few options:
Browserify
Webpack
Rollup
These module bundlers allow you to specify an 'entry' point and then bundle all the required modules together in a single file.
Similar questions that answer this problem:
Gulp + babelify + browserify issue

Node JS and AngularJS - script not found - 404

I am trying to build a simple "Hello world" Node.js/AngularJS app and am struggling. I am running the app through localhost and struggling to figure out why the HTML page isn't finding my script files.
server.js
var express = require('express');
var fs = require('fs');
var app = express();
app.set('port', (process.env.PORT || 5000));
app.use(express.static(__dirname + '/public'));
app.set('views', __dirname + '/app');
app.set('view engine', 'ejs');
app.get('/', function(request, response) {
response.render('index');
});
app.listen(app.get('port'), function() {
console.log('Node app is running on port', app.get('port'));
});
The server is being run successfully. The angularJS application is listed below:
index.ejs
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-route.js"></script>
<script src="app.js"></script>
<script src="Controllers/home.ctrl.js"></script>
</head>
<body ng-app>
<div ng-view></div>
</body>
</html>
app.js
angular.module("app", ["ngRoute"])
.config(function($routeProvider){
$routeProvider
.when("/", {
controller: "HomeController",
templateUrl: "app/Views/home.html"
});
});
home.html
home.ctrl.js
Folder structure:
Web server
index.js
app
Controllers
Views
app.js
index.ejs
The error I am getting in the console:
HTTP404: NOT FOUND - The server has not found anything matching the requested URI (Uniform Resource Identifier).
GET - http://localhost:5000/app.js
HTTP404: NOT FOUND - The server has not found anything matching the requested URI (Uniform Resource Identifier).
GET - http://localhost:5000/Controllers/home.ctrl.js
The problem is here:
<script src="app.js"></script>
<script src="Controllers/home.ctrl.js"></script>
<script src="app/app.js"></script>
You include two app.js, one of them has the wrong path. Maybe you meant index.js instead.
UPDATE
I see another problem here:
app.use(express.static(__dirname + '/public'));
You serve the folder public, but those files are in app

Angular modular application best practices

My folder structure :
/app
/components
/module1
/module2
/core
/extensions
-array.js
-string.js
/services
-localdataservice.js
/directives
- .... .js
index.html
each file aside from it's essence is associated with an angular module 'app.core'
for example : array.js
(function() {
'use strict';
var core = angular.module(app.core, []);
core.config( function(){
if (!Array.prototype.last){
Array.prototype.last = function(){
return this[this.length - 1];
};
};
})
}());
Composing all of these files and there contents under a usable module as some fallbacks.
1) Only one file can create the module and the rest need to use the module and add on to it.
meaning that all other files then the arbitrarly chosen array.js would use the module as :
var core = angular.app('app.core');
and not
var core = angular.app('app.core',[]);
2) I would have to reference each file from index.html in order for it to take part in the module's initiation.
index.html
<html>
<body>
<script src="components/core/array.js"></script>
<script src="components/core/string.js"></script>
<script src="components/core/localdataserice.js"></script>
.... and many more
</body>
</html>
There must be a better way for building a module across multiple files.
at first i thought about copying all of the contents of the files under a seperate file
/app
/components
/core
/lib
-core.js
index.html
<html>
<body>
<script src="components/core/lib/core.js"></script>
</body>
</html>
I thought of doing this with a grunt copy task. but that would require me to somehow manipulate the process of the copy task the fit content under the IFFE wrapper and the angular's module initiation.
(function() {
'use strict';
var core = angular.module(app.core, []);
core.config( function(){
... ALL THE FILES CONTENTS GO HERE
})
}());
And again there's gotta be a better way.
any suggestions ?
EDIT :
I decided to try Browserify along with Grunt and grunt-browserify
Gruntfile.js
grunt.initConfig({
browserify :{
main: {
src: 'app/components/core/{,*/}*.js',
dest: 'app/components/core/lib/core'
}
}
});
For this example the build file only has the content of array.js
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
if (!Array.prototype.last){
Array.prototype.last = function(){
return this[this.length - 1];
};
};
},{}]},{},[1]);
1) What i don't understand is how can i incorporate an export function in it.
since i wan't to require it from other modules.
module.exports = function() {
// Your code
}
2) Iv'e seen no reference in any tutorials on that weird looking wrapper my code was placed in. not sure what it does maybe it as an export in there some where :/

Resources