Angular2.0 in subdirectory, SystemJS cant import angular components - gruntjs

I am getting started with Angular2.0. I have been following the 5 Min Quickstart and everything works fine although I am using grunt to compile my Typescript and some Sass etc.
I just have one problem I cant solve by myself. I want to move all the public files (generated Javascript and production node modules into a subdirectory. I need to have that, because I run different applications unter the same domian. The frontend depends on the user type that logged in. (backend is written with phalcon)
This is my public folder (the webserver's root)
So the whole Angular applications should live inside the "talent" directory.
The "index.html" contains the following:
<script type="text/javascript" src="/talent/node_modules/systemjs/dist/system.src.js"></script>
<script type="text/javascript" src="/talent/node_modules/angular2/bundles/angular2.dev.js"></script>
<script>
System.config({
baseURL: '/talent',
packages: {'app': {defaultExtension: 'js',}}
});
System.import('app/app');
</script>
SystemJs is able to load my app.js file correctly but then trys to import angular2:
import {bootstrap, Component} from 'angular2/angular2';
Corresponding Javascript:
var angular2_1 = require('angular2/angular2');
This sends a request to http://example.dev/talent/angular2/angular2 resulting in an 404 error.
When I move the node_modules folder and the app folder to the webserver's root and remove baseURL: '/talent' it works just fine.
Here are the requests made for both the working solution (everything at root) and the not working part (everything under /talent)
Working:
Not working:
Can you help me getting this to work?

Had this exact same problem, and just figured it out after several hours. The System config baseURL needs to be set BEFORE angular2.dev.js is loaded. This is because the System.register calls need to be aware of the baseURL at the time of registrations.
e.g.
System.config({ baseURL: '/talent' });
A cleaner way is to just add System.config({ baseURL: '/talent' }) to the very bottom of the system.src.js file.

You can set paths for each library :
System.paths = {
'angular2/*': '/talent/node_modules/angular2/*',
'app/*': '/talent/app/*'
};
Does this work for you?

'angular2/angular2' has been deprecated. Your code should reference 'angular2/core' or the appropriate module for your imports.
You should also not need to specify the path for the angular2 imports in your System.config as System will load them in from the <script> tag you have in the HTML.
You are most likely receiving the 404 error because the angular2.dev.js file is loading 'angular2/core', 'angular2/common', 'angular2/platform/browser', etc... and you are referencing 'angular2/angular2' which is not being registered and therefor SystemJS is attempting to go out and find it.
Change all of your import {...} from 'angular2/angular2' to the correct module import as well. You can find these on the API Preview page of angular.io, or hopefully your IDE will find it for you.

I don't know which version of Angular2 you use but now with beta versions you should use these Angular2 modules:
import {bootstrap} from 'angular2/platform/browser';
import {Component} from 'angular2/core';
Then you need to configure SystemJS as described below:
<script>
System.config({
map: {
app: 'talent/app'
},
packages: {
app: {
format: 'register',
defaultExtension: 'js'
}
}
});
System.import('app/boot')
.then(null, console.error.bind(console));
</script>
With this configuration, when trying to load the app/boot module, SystemJS will load the talent/app/boot.js file that was compiled before from the talent/app/boot.ts file. This behavior applies to all elements under the app module but not to other ones.
Modules like angular2/* will be found from files talent/node_modules/angular2/bundles/[something].js you included using <script> tags.
I made some tests and this configuration works for me ;-)
Thierry

I stumbled upon this question when trying to move from a local (dev) environment to a hosted server (CentOS) where the deployed URLs were all different to my local host. If you're in this situation and the accepted answer doesn't solve your problem (I was already importing the updated imports with Angular2 Beta 15) and using baseURL messes other things up (as it did in my situation) then use:
map: {
app: 'path/to/app/folder'
},
I saw this here and it worked for me (even though it was originally answering a MAMP environment question): Troubles with importing classes from Angular 2 modules with Typescript 1.7

Here's what worked for us:
Make the base ref point to the subdirectory containing the angular project. This will ensure that all the node_module dependencies are found, etc.
Configure the PathLocationStrategy with a different APP_BASE_HREF so that html5 mode still works for the actual angular app.
bootstrap(AppComponent, [..... bind(APP_BASE_HREF).toValue("/yardmap/planning")
ref: https://angular.io/docs/ts/latest/api/common/index/APP_BASE_HREF-let.html
ref: https://angular.io/docs/ts/latest/guide/router.html

base href
Most routing applications should add a element to the index.html as the first child in the tag to tell the router how to compose navigation URLs.
<!DOCTYPE html>
<html>
<head lang="en">
<base href="/talent/">
......
</head>

Related

Loading static files in Express

I have been trying to get my node.JS file to serve my HTML app with static CSS and JS files included too but have ran into great difficulties (the HTML file is loading, but with no styling). From my searching it seems the main recommended method is to add the Express middleware to your node.JS and then add this line:
app.use(express.static(path.join(__dirname, 'static/')));
Before I go on too much further I will show you my directory set-up:
-static
-images
-favicon
-favicon.png
-logo.png
-style
-design.css
-theme.css
-w3.css
-source
-client
-style.js
-node_modules
-...
-index.html
-root.js
-package-lock.json
-...
The 'root.js' file is my node.JS file that I am running and it serves the 'index.html' page, but all the CSS and JS files my HTML page links to come up with this sort of error...
The stylesheet http://localhost:8080/static/style/design.css was not loaded because its MIME type, "text/html", is not "text/css".
Here is one example of a line in my 'index.html' where I try to link to that CSS file...
<link rel="stylesheet" type="text/css" href="static/style/design.css">
...and here is where 'index.html' is served in my 'root.js' file...
http.createServer(function (req, res) {
fs.readFile('index.html', function (err, data) {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.write(data);
return res.end();
});
}).listen(8080);
I am not too sure where I am going wrong as most guides on the topic seem to imply that when I add in the magic '__dirname' line to my node.JS that everything is meant to resolve itself. When I just run my HTML page locally by opening it in Chrome or Firefox it works fine. I am hoping you might be able to explain to me where I am going wrong, thank you.

Meteor 1.6.1 and Vue 2 integration

For two days I'm trying to start using Vue 2 in my Meteor project. First I looked up some packages, and found https://github.com/meteor-vue/vue-meteor, but other than a list of packages it lacks anything usable itself, so here is that. A separate search on Atmosphere yielded in something I could actually use, namely https://atmospherejs.com/akryum/vue, but despite following every instruction I could find for this package, I don't think it works correctly for me, for example, I don't get the console messages regarding component hot reload, only the usual standard Meteor startup messages+messages when a file changes. It doesn't make use of the client/main.html file, unless I import it explicitly in client/main.js, but then I get a runtime error about missing module ./main.html, even tho I can clearly see then the template rendered, but w/o Vue magic in it. In the provided example project (without Blaze) I don't see the HTML being imported explicitly anywhere, so something is definitely off here. There are no other hints and clues in any produced output. So I'm stuck in limbo.
P. S. I also just realized it doesn't even do anything with the .vue components, as 1) I forgot to change an import from .js to .vue, and the app didn't crash at any time, and then, the imported .vue file was actually syntactically incorrect, until I fixed it just now.
For a starter boilerplate of Meteor + Vue, the perfect bundling + packages selection is Akryum's https://github.com/meteor-vue/vue-meteor-demo
I used it, and deployed to galaxy without problems. Excellent start.
This boilerplate contains:
Meteor 1.4 - 1.7+ + tracker + Vuejs 2 + vue-router + vuex (store) + graphql set up.
Cheers
I am starting to document my experience while trying to integrate the 2 technologies. If you want to see more: https://forums.meteor.com/t/meteor-vue-in-2018/44246
I have a bit different folder structure, but hopefully it is still relevant.
I have written an article that describes in detail the steps to install Vue and Vue Router in a Meteor application. I don't like putting links on Stackoverflow, but it's too much detail included in a answer here.
https://medium.com/#simonjcarr/adding-vue-and-vue-router-to-meteor-7c411131494f
I am using the following setup.
Packages
.meteor/packages
meteor-base#1.3.0 # Packages every Meteor app needs to have mobile-
experience#1.0.5 # Packages for a great mobile UX
mongo#1.4.2 # The database Meteor supports right now
tracker#1.1.3 # Meteor's client-side reactive programming library
standard-minifier-js#2.3.1 # JS minifier run for production mode
es5-shim#4.7.0 # ECMAScript 5 compatibility for older browsers
ecmascript#0.10.6 # Enable ECMAScript2015+ syntax in app code
shell-server#0.3.1 # Server-side component of the `meteor shell` command
static-html akryum:vue-component
akryum:vue-blaze-template
session#1.1.7
check
dynamic-import#0.3.0
fourseven:scss
seba:minifiers-autoprefixer
package.json
{
"private": true,
"scripts": {
"start": "meteor run"
},
"dependencies": {
"#babel/runtime": "^7.0.0-beta.44",
"meteor-node-stubs": "~0.2.0",
"#deveodk/vue-toastr": "^1.0.4",
"babel-runtime": "^6.23.0",
"bcrypt": "^1.0.2",
"vue": "^2.2.6",
"vue-router": "^2.5.1",
"vuex": "^2.3.1"
},
"devDependencies": {}
}
Client directory
client/main.html
<body class="pace-done md-skin">
<div id="app"></div>
</body>
client/main.scss
// Libs
import {Meteor} from 'meteor/meteor'
import Vue from 'vue'
import { router } from '/imports/client/plugins/router';
import store from '/imports/vuex/store'
import AppLayout from '/imports/client/ui/AppLayout.vue'
// import '/imports/client/plugins/plugin_name'
// App start
Meteor.startup(() => {
new Vue({
store,
router,
el: '#app',
render: h => h(AppLayout)
})
});
Rest is standard vue. I can add alse AppLayout.vue to demonstrate what I mean
/imports/client/ui/AppLayout.vue
<template>
<router-view></router-view>
</template>
<script>
export default {
name: 'AppLayout'
}
</script>

Laravel generates an error "Echo is Echo is not defined"

I am working with Laravel Event Broadcasting and i am using pusher driver for broadcasting event and its working perfectly.
The public channel is subscribed successfully from client side using pusher provided js library
var pusher = new Pusher('xxxxxxxxxxxxxxxxxxxxx_my_app_key', {
encrypted: true
});
var channel = pusher.subscribe('TestPusher');
channel.bind('App\\Events\\TestPusher', function(data) {
alert(data.msg);
});
But when i use Echo in my client side code
Echo.channel('TestPusher')
.listen('TestPusher', (e) => {
console.log(e.msg, e.chatMessage);
});
It generates the error " Echo is not defined ".
I already installed the Laravel Echo library using npm install --save laravel-echo pusher-js in my application and also included the following code in resources/assets/js/bootstrap.js file as per the laravel provide documentation.
import Echo from "laravel-echo"
window.Echo = new Echo({
broadcaster: 'pusher',
key: 'xxxxxxxxxxxxxxxxxxxxx_my_app_key'
});
So please help me how can i fix this problem.
My issue was that I was not compiling bootstrap.js together with the rest of the code because I had removed the line require('./bootstrap') from app.js. I added that line back and I was home and dry.
As described here
I had this problem a few days ago. My gulp installation was all messed up and Laravel versioning didn't help.
Sorry if this doesn't help, it's just my experience and most detailed as possible:
First, I'll consider you do have the js/app.js script included on you site.
Now, you're seeing this error because, as Josh mentioned, you're not compiling your js files. After editing 'resources/assets/js/bootstrap.js', this file needs to be compiled by running the asset compiler: gulp (named Laravel Elixir docs/5.3/elixir) in Laravel 5.3).
If you followed carefully this part of the tutorials, you shall be extra careful with laravel's npm dependencies versions, specially those used by Elixir (Once again, my gulp installation wasn't working at all even though no error messages showed up).
So, if this is a new project, you should consider updating to Laravel 5.4. If you can't or not willing to update all Laravel framework, perhaps this can be solved like I did. Staying at 5.3 but using the latest assets compiler on 5.4, named Laravel Mix. Now it runs on npm: npm run dev. (No gulp mentioned on doc.)
To achieve this, you should update to latest package.json on 5.4 and follow the 5.4 documentation to install Laravel Mix.
Your codes looks fine, Problem is your JS order so only you getting undefined issues
like
<script>
Echo.channel('TestPusher')
.listen('TestPusher', (e) => {
console.log(e.msg, e.chatMessage);
});
</script>
<script src="echo.js"></script>
so zigzag the order :)
widow object before each Echo.
window.Echo.channel('TestPusher')
.listen('TestPusher', (e) => {
console.log(e.msg, e.chatMessage);
});
remove defer from your app.js script tag
<!-- Scripts -->
<script src="{{ asset('js/app.js') }}" defer></script>

How to set Angular2 cli baseurl for a new web site?

I have an existing ASP.NET MVC web site. www.foo.com
I want to create a whole new sub system of our site using Angular2 and I want it to go under www.foo.com/NewSubSystem.
I have downloaded the Angular2 Cli from https://cli.angular.io/.
When I run from the command line
ng build -dev
The output has all the javascript script tags looking this in the index.html file
<script type="text/javascript" src="inline.bundle.js"></script>
<script type="text/javascript" src="styles.bundle.js"></script>
<script type="text/javascript" src="main.bundle.js"></script>
I need the scr="www.foo.com/NewSubSystem/inline.bundle.js"
NOTE: I have tried to update the baseURL in the tsconfig.json
"compilerOptions": {
"baseUrl": "www.foo.com/NewSubSystem"
}
but this does not seem to make any difference.
Any suggestions or pointers would be nice. Thanks
Set the index file baseref
base href="NewSubSystem/"
Then just code like its the root.
I reset the baseref to dist/ with javascript depending on the env sensed
Change your index.js files update
<base href="/<you base url>/">
if you are working with webpack:
You should also update the file config/webpack.common.js, so that you assets folder content can be hosted from your new baseurl.
...
const METADATA = {
title: 'ng2-admin - Angular 2 Admin Template',
description: 'Free Angular 2 and Bootstrap 4 Admin Template',
baseUrl: '/<you base url>/',
isDevServer: helpers.isWebpackDevServer()
};
.....

How to load remote file in webpack

the remote file is a single components compiled by webpack
the wenpack config as follow:
{
.....
library: library
,externals: externals
,libraryTarget: "umd"
.....
}
the components is in the cdn,
i want to load and use the remote components in react.
and how to use it like the Pseudo code :
ajax -> get a json > { components name } > use the name to load romote file
for example the json have the botton i need to load the botton.min.js
var Button = reuqire('http://botton.min.js')
class App extends React.Component {
render() {
return (
<div>
<Botton/>
</div>
);
}
}
export default App;
npm install scriptjs
var $script = require("scriptjs");
$script("//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js", function() {
$('body').html('It works!')
});
As I said in the other post: I have looked around for a solution and most of all proposals were based on externals, which is not valid in my case.
More info here: https://stackoverflow.com/a/62603539/8650621
Basically, I finished using a separate JS file which is responsible for downloading the desired file into a local directory. Then WebPack scans this directory and bundles the downloaded files together with the application.
Maybe you can find solutions on the following resoures:
https://stackoverflow.com/a/33293033/1204375
how to use webpack to load CDN or external vendor javascript lib in js file, not in html file
Webpack and external libraries
How to use a library from a CDN in a Webpack project in production
https://github.com/webpack/webpack/issues/150
https://github.com/webpack/webpack/issues/240

Resources