The problem is that in routing i have to click twice to trigger ngOnInit code.
The weird thing is, if I have two routes: A and B, and I clicked on A first, it will trigger the constructor only, and if I clicked on B after it, it will trigger A's onInit before calling B's constructor.
using angular 2.0.0-rc.4 and routes 3.0.0-beta.2
error displayed on page load:
vendors.js:2291 Unhandled promise rejection Error: Cannot match any routes: ''
at Observable._subscribe (http://localhost:54037/js/app.js:19280:28)
at Observable.subscribe (http://localhost:54037/js/app.js:56291:60)
at Observable._subscribe (http://localhost:54037/js/app.js:56328:26)
at MergeMapOperator.call (http://localhost:54037/js/app.js:26178:21)
at Observable.subscribe (http://localhost:54037/js/app.js:56291:36)
at Observable._subscribe (http://localhost:54037/js/app.js:56328:26)
at MergeMapOperator.call (http://localhost:54037/js/app.js:26178:21)
at Observable.subscribe (http://localhost:54037/js/app.js:56291:36)
at Observable._subscribe (http://localhost:54037/js/app.js:56328:26)
at MapOperator.call (http://localhost:54037/js/app.js:56831:21)
gulp file
/// <binding Clean='default, clean, resources' />
/*
This file in the main entry point for defining Gulp tasks and using Gulp plugins.
Click here to learn more. http://go.microsoft.com/fwlink/?LinkId=518007
*/
var gulp = require('gulp');
var sourcemaps = require('gulp-sourcemaps');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var typescript = require('gulp-typescript');
var systemjsBuilder = require('systemjs-builder');
const del = require("del");
// Compile TypeScript app to JS
gulp.task('compile:ts', function () {
return gulp
.src([
"appTS/**/*.ts",
"typings/*.d.ts"
])
.pipe(sourcemaps.init())
.pipe(typescript({
"module": "system",
"moduleResolution": "node",
"outDir": "app",
"target": "ES5"
}))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('app'));
});
// Generate systemjs-based bundle (app/app.js)
gulp.task('bundle:app', function () {
var builder = new systemjsBuilder('./', './system.config.js');
return builder.buildStatic('app', 'wwwroot/js/app.js');
});
// Copy and bundle dependencies into one file (vendor/vendors.js)
// system.config.js can also bundled for convenience
gulp.task('bundle:vendor', function () {
return gulp.src([
'node_modules/core-js/client/shim.min.js',
'node_modules/systemjs/dist/system-polyfills.js',
'node_modules/reflect-metadata/Reflect.js',
'node_modules/zone.js/dist/zone.js',
'node_modules/systemjs/dist/system.js',
'system.config.js'
])
.pipe(concat('vendors.js'))
.pipe(gulp.dest('build'));
});
// Copy dependencies loaded through SystemJS into dir from node_modules
gulp.task('copy:vendor', function () {
return gulp.src([
'node_modules/rxjs/bundles/Rx.js',
'node_modules/#angular/**/*'
])
.pipe(gulp.dest('build'));
});
gulp.task('vendor', ['bundle:vendor', 'copy:vendor']);
gulp.task('app', ['compile:ts', 'bundle:app']);
// Bundle dependencies and app into one file (app.bundle.js)
gulp.task('bundle', ['vendor', 'app'], function () {
return gulp.src([
'build/app.js',
'build/vendors.js'
])
.pipe(concat('app.bundle.js'))
.pipe(gulp.dest('wwwroot/js/app'));
});
/**
* Copy all resources that are not TypeScript files into build directory.
*/
gulp.task("resources", () => {
return gulp.src(["Scripts/app/**/*", "!**/*.ts"])
.pipe(gulp.dest("wwwroot/app"));
});
/**
* Remove build directory.
*/
gulp.task('clean', (cb) => {
return del(["build"], cb);
});
gulp.task('default', ['bundle']);
app.routes
import { provideRouter, RouterConfig } from '#angular/router';
import { MediaItemFormComponent } from './media-item-form.component';
import { MediaItemListComponent } from './media-item-list.component';
export const routes: RouterConfig = [
{ path: 'list', component: MediaItemListComponent },
{ path: 'add', component: MediaItemFormComponent }
];
export const APP_ROUTER_PROVIDERS = [
provideRouter(routes)
];
list component
import {Component, Inject, OnInit } from '#angular/core';
import 'rxjs/Rx';
import {MediaItemComponent} from './media-item.component';
import {CategoryListPipe} from './category-list.pipe';
import {MediaItemService} from './media-item.service';
#Component({
selector: 'media-item-list',
directives: [MediaItemComponent],
pipes: [CategoryListPipe],
providers: [MediaItemService],
templateUrl: 'app/media-item-list.component.html',
styleUrls: ['app/media-item-list.component.css']
})
export class MediaItemListComponent implements OnInit {
mediaItems;
constructor(private mediaItemService: MediaItemService) {
console.log("constructor MediaItemList");
}
ngOnInit() {
console.log("ngOnInit MediaItemList");
this.getMediaItem();
}
onMediaItemDeleted(mediaItem) {
this.mediaItemService.delete(mediaItem)
.subscribe(() => {
this.getMediaItem();
});
}
getMediaItem() {
this.mediaItemService.get().subscribe(mediaitems => {
this.mediaItems = mediaitems;
},
function (error) { console.log("Error happened" + error) },
function () {
}
);
}
}
system.js
// map tells the System loader where to look for things
var map = {
'app': 'Scripts/app',
'rxjs': 'node_modules/rxjs',
'#angular': 'node_modules/#angular'
};
// packages tells the System loader how to load when no filename and/or no extension
var packages = {
'app': { main: 'main', defaultExtension: 'js' },
'rxjs': { defaultExtension: 'js' },
};
var packageNames = [
'#angular/common',
'#angular/compiler',
'#angular/core',
'#angular/forms',
'#angular/http',
'#angular/platform-browser',
'#angular/platform-browser-dynamic',
'#angular/router',
'#angular/testing',
'#angular/upgrade',
];
// add package entries for angular packages in the form '#angular/common': { main: 'index.js', defaultExtension: 'js' }
packageNames.forEach(function (pkgName) {
packages[pkgName] = { main: 'index.js', defaultExtension: 'js' };
});
System.config({
map: map,
packages: packages
});
index.html
<html>
<head>
<title>MeWL</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<base href="/" />
<link href="resets.css" rel="stylesheet">
<script src="js/vendors.js"></script>
<script src="js/app.js"></script>
<style>
body {
margin: 0px;
padding: 0px;
background-color: #32435b;
}
</style>
</head>
<body>
<media-tracker-app>Loading...</media-tracker-app>
</body>
</html>
Update:
I'll include html of list and the component nested inside if it helps
<media-item
*ngFor="let mediaItem of mediaItems"
[mediaItemToWatch] ="mediaItem"
(deleted)="onMediaItemDeleted($event)"
[ngClass]="{'medium-movies': mediaItem.medium === 'Movies', 'medium- series' : mediaItem.medium === 'Series'}" ></media-item>
MediaItem html:
<h2>{{mediaItem.name }}</h2>
<div>{{mediaItem.category}}</div>
<div>{{mediaItem.year}}</div>
<div class="tools">
<a class="delete" (click)="onDelete()">
remove
</a>
<a class="details">
watch
</a>
</div>
Media Item ts:
import {Component, Input, Output, EventEmitter} from '#angular/core';
import {FavoriteDirective} from './favorite.directive';
#Component({
selector: 'media-item',
directives: [FavoriteDirective],
templateUrl: 'app/media-item.component.html',
styleUrls: ['app/media-item.component.css']
})
export class MediaItemComponent {
#Input('mediaItemToWatch') mediaItem;
#Output('deleted') delete = new EventEmitter();
onDelete() {
this.delete.emit(this.mediaItem);
}
}
It seems
vendors.js:2291 Unhandled promise rejection Error: Cannot match any routes: ''
causes change detection to not run
To avoid this error add a route for the '' path like
{ path: '', redirectTo: '/list', pathMatch: 'full' }
or
{ path: '', component: DummyComponent, pathMatch: 'full' }
I think better answer is to add "onSameUrlNavigation" option on
RouterModule.forRoot(
appRoutes,
{
useHash: false,
anchorScrolling: "enabled",
onSameUrlNavigation: "reload",
enableTracing: true,
scrollPositionRestoration: "enabled"
})
Related
I feel like this should be resolved simply, but after several attempts, I'm just not coming to a resolution.
Here is the error I've received:
Uncaught ReferenceError: process is not defined
38509 # [PathToProject]\node_modules\util\util.js:109
This is getting triggered when I instantiate web3 into a clean/new site (there's two other 'test' components, one link one button)
I've searched and found numerous bits of information suggesting that
process is a server side 'node' var, and I can set this to be available client-side by adding to my webpack.config.js, which I have done.
I might be able to resolve by just declaring a global angular var in my app.component.ts, but it seems this dependency project .js file is not accessing it.
I've also tried just updating the dependency project directly, but even with a compile, it seems that my changes are not being distributed into the webpack build /dist/ result.
I think this probably has a blatantly simple solution, but I'm just overlooking it. I'm just spinning my tires here and could use a little help, but I'm the first in my circle to venture into web3 and don't have a close friend to bounce this off of. Can someone here provide some insight or an alternative resolve this issue?
Relevant bits of code:
webpack.config.js
var webpack = require('webpack');
const path = require('path');
module.exports = {
module: {
rules: [
{
test: /\.(sass|less|css|ts)$/,
use: [
'ts-loader'
],
}
],
},
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': 'develop',
})
],
entry: './src/main.ts',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
},
resolve: {
extensions: [ '.js', '.ts', '.html' ],
modules: [
path.resolve(__dirname, 'node_modules/'),
path.resolve("", "src")
],
alias: {
Environments: path.resolve(__dirname, 'src/environments/'),
},
fallback: {
"fs": false,
"tls": false,
"net": false,
"path": false,
"zlib": false,
"http": require.resolve("stream-http"),
"https": require.resolve("https-browserify"),
"stream": false,
"crypto": require.resolve("crypto-browserify"),
"crypto-browserify": require.resolve('crypto-browserify'),
},
}
}
global-constants.ts
export class GlobalConstants {
public static process: any = {
env: {
NODE_ENV: 'development'
}
}
}
app.component.ts
import { Component } from '#angular/core';
import{ GlobalConstants } from './common/global-constants';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'Cool Title';
process = GlobalConstants.process;
}
Relevant bit of utils/util.js (line 106-116)
var debugs = {};
var debugEnvRegex = /^$/;
if (process.env.NODE_DEBUG) {
var debugEnv = process.env.NODE_DEBUG;
debugEnv = debugEnv.replace(/[|\\{}()[\]^$+?.]/g, '\\$&')
.replace(/\*/g, '.*')
.replace(/,/g, '$|^')
.toUpperCase();
debugEnvRegex = new RegExp('^' + debugEnv + '$', 'i');
}
Add the following to polyfills.ts (usually inside src directory):
(window as any).global = window;
global.Buffer = global.Buffer || require('buffer').Buffer;
global.process = require('process');
When adding the formbuilder in the constructor. I've been getting the error. I've added the ReactiveFormsModule in the app.module already.
import { Component } from '#angular/core';
import { FormBuilder, FormGroup, Validators, FormControl } from '#angular/forms';
#Component({
selector: 'app',
template: require('./app.component.pug'),
styles: [require('./app.component.scss')]
})
export class AppComponent {
private loginForm: FormGroup;
constructor(private fb: FormBuilder) {}
}
Sample app.module.ts
import { ReactiveFormsModule } from '#angular/forms';
#NgModule({
imports: [BrowserModule, ReactiveFormsModule],
declarations: [AppComponent],
providers: [],
bootstrap: [AppComponent]
})
Here is the error:
Added emitDecoratorMetadata: true to tsconfig.json file
This works for me in a Stackblitz example.
Some comments though:
Why do you require the pug file as a template? If you are using pug (and pug-watch), the html file should be there as well.
why do you require the css? Just use simply styleUrls: [ './app.component.css' ] .
Are you sure your node, npm and angular version is up to date and compatible?
Edit:
If removing the 'require' parts helps, try this:
#Component({
selector: 'app',
template: './app.component.html',
styles: ['./app.component.scss']
})
There is no native pug support in angular yet, so you should rely on other tools to translate your page to a html file. In the #Component decorator you should try to stick to the official angular documentation.
Personally, I use Gulp js for starting my dev app and a pug watcher at the same time.
Here is my gulpfile:
const gulp = require('gulp');
const clean = require('gulp-clean');
const pug = require('gulp-pug');
const git = require('gulp-git');
const file = require('gulp-file');
const spawn = require('child_process').spawn;
const shell = require('gulp-shell');
const install = require('gulp-install');
const notify = require('gulp-notify');
// *********
// BUILD APP
// *********
gulp.task('npm-install', function () {
gulp.src(['./package.json'])
.pipe(install());
});
gulp.task('clean-dist', ['npm-install'], function () {
return gulp.src('./dist', {read: false})
.pipe(clean())
});
gulp.task('pug-build', function buildHTML() {
return gulp.src('./src/**/*.pug')
.pipe(pug({doctype: 'html', pretty: false}))
.on('error', notify.onError(function (error) {
return 'An error occurred while compiling pug.\nLook in the console for details.\n' + error;
}))
.pipe(gulp.dest('./src'))
});
gulp.task('ng-build', ['clean-dist', 'pug-build'], function (cb) {
spawn('npm', ['run', 'ngbuild'], {stdio: 'inherit'})
});
gulp.task('build', ['ng-build'], function () {
});
// ****************
// DEVELOPMENT MODE
// ****************
gulp.task('pug-watch', ['pug-build'], function (cb) {
gulp.watch('./src/**/*.pug', ['pug-build'])
});
gulp.task('ng-serve', function (cb) {
spawn('ng', ['serve'], {stdio: 'inherit'});
});
gulp.task('dev-start', ['pug-watch', 'ng-serve']);
(in the package.json I have an entry:"ngbuild": "ng build --aot --progress=false" )
I'm going to preface this question by saying that I'm fairly new to Angular 2 and Angular in general, so the odds are that this question is going to have a really easy answer. Anyway, here it is. I've been trying to a create a website, and my issue is that Angular won't insert my components. It stays at the part where it says Loading... and won't load in my things, even when they're simple HTML. I'll provide what I'm pretty sure are the pertinent files, but if you need anything more, don't hesitate to ask.
Here's systemjs.config.js:
(function (global) {
System.config({
transpiler: 'ts',
typescriptOptions: {
// Copy of compiler options in standard tsconfig.json
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": ["es2015", "dom"],
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true
},
meta: {
'typescript': {
"exports": "ts"
}
},
paths: {
// paths serve as alias
'npm:': 'https://unpkg.com/'
},
// map tells the System loader where to look for things
map: {
// our app is within the app folder
'app': 'app',
// angular bundles
'#angular/animations': 'npm:#angular/animations/bundles/animations.umd.js',
'#angular/animations/browser': 'npm:#angular/animations/bundles/animations-browser.umd.js',
'#angular/core': 'npm:#angular/core/bundles/core.umd.js',
'#angular/common': 'npm:#angular/common/bundles/common.umd.js',
'#angular/compiler': 'npm:#angular/compiler/bundles/compiler.umd.js',
'#angular/platform-browser': 'npm:#angular/platform-browser/bundles/platform-browser.umd.js',
'#angular/platform-browser/animations': 'npm:#angular/platform-browser/bundles/platform-browser-animations.umd.js',
'#angular/platform-browser-dynamic': 'npm:#angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'#angular/http': 'npm:#angular/http/bundles/http.umd.js',
'#angular/router': 'npm:#angular/router/bundles/router.umd.js',
'#angular/router/upgrade': 'npm:#angular/router/bundles/router-upgrade.umd.js',
'#angular/forms': 'npm:#angular/forms/bundles/forms.umd.js',
'#angular/upgrade': 'npm:#angular/upgrade/bundles/upgrade.umd.js',
'#angular/upgrade/static': 'npm:#angular/upgrade/bundles/upgrade-static.umd.js',
// other libraries
'rxjs': 'npm:rxjs#5.0.1',
'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js',
'ts': 'npm:plugin-typescript#5.2.7/lib/plugin.js',
'typescript': 'npm:typescript#2.2.1/lib/typescript.js',
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
app: {
main: './src/bootstrap.ts',
defaultExtension: 'ts',
meta: {
'./*.ts': {
loader: 'systemjs-angular-loader.js'
}
}
},
rxjs: {
defaultExtension: 'js'
}
}
});
})(this);
systemjs-angular-loader.js:
var templateUrlRegex = /templateUrl\s*:(\s*['"`](.*?)['"`]\s*)/gm;
var stylesRegex = /styleUrls *:(\s*\[[^\]]*?\])/g;
var stringRegex = /(['`"])((?:[^\\]\\\1|.)*?)\1/g;
module.exports.translate = function (load) {
if (load.source.indexOf('moduleId') != -1) return load;
var url = document.createElement('a');
url.href = load.address;
var basePathParts = url.pathname.split('/');
basePathParts.pop();
var basePath = basePathParts.join('/');
var baseHref = document.createElement('a');
baseHref.href = this.baseURL;
baseHref = baseHref.pathname;
if (!baseHref.startsWith('/base/')) { // it is not karma
basePath = basePath.replace(baseHref, '');
}
load.source = load.source
.replace(templateUrlRegex, function (match, quote, url) {
let resolvedUrl = url;
if (url.startsWith('.')) {
resolvedUrl = basePath + url.substr(1);
}
return 'templateUrl: "' + resolvedUrl + '"';
})
.replace(stylesRegex, function (match, relativeUrls) {
var urls = [];
while ((match = stringRegex.exec(relativeUrls)) !== null) {
if (match[2].startsWith('.')) {
urls.push('"' + basePath + match[2].substr(1) + '"');
} else {
urls.push('"' + match[2] + '"');
}
}
return "styleUrls: [" + urls.join(', ') + "]";
});
return load;
};
index.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Website</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/static/css/app.css" />
<base href="/">
</head>
<body>
<abi-app>Loading...</abi-app>
</body>
<!-- Libraries imports -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/reflect-metadata/reflect.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<!-- Configure SystemJS -->
<script src="systemjs.config.js"></script>
<script>
//bootstrap the Angular2 application
System.import('app').catch(console.log.bind(console));
</script>
<script src="http://localhost:35729/livereload.js"></script>
</html>
gulpfile.js:
var gulp = require('gulp');
var connect = require('gulp-connect');
var PATHS = {
src: 'src/**/*.ts',
html: 'src/**/*.html',
css: 'src/**/*.css'
};
gulp.task('clean', function (done) {
var del = require('del');
del(['dist'], done);
});
gulp.task('ts2js', function () {
var typescript = require('gulp-typescript');
var sourcemaps = require('gulp-sourcemaps');
var tsResult = gulp.src(PATHS.src)
.pipe(sourcemaps.init())
.pipe(typescript({
noImplicitAny: true,
module: 'system',
target: 'ES5',
moduleResolution: 'node',
emitDecoratorMetadata: true,
experimentalDecorators: true
}));
return tsResult.js
.pipe(sourcemaps.write())
.pipe(gulp.dest('dist'))
.pipe(connect.reload());
});
gulp.task('play', ['ts2js'], function () {
var http = require('http');
var open = require('open');
var watch = require('gulp-watch');
var port = 9000,
app;
connect.server({
root: __dirname,
port: port,
livereload: true,
fallback: 'index.html'
});
open('http://localhost:' + port + '/index.html');
gulp.watch(PATHS.src, ['ts2js']);
watch(PATHS.html).pipe(connect.reload());
watch(PATHS.css).pipe(connect.reload());
});
bootstrap.ts:
import { platformBrowserDynamic } from '#angular/platform-browser-dynamic';
import { AppModule } from './components/app/app.module';
platformBrowserDynamic().bootstrapModule(AppModule);
app.module.ts:
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { RouterModule } from '#angular/router';
import { HttpModule } from '#angular/http';
import { Home } from './home';
import { Gallery } from './gallery';
import { AppRoutingModule } from './app-routing.module';
import { NavigationMenuComponent } from './navigation-menu/navigation-menu.component';
import { ABIComponent } from './app.component';
import { HomeModule } from './home/home.module';
#NgModule({
imports: [BrowserModule, HttpModule, HomeModule, AppRoutingModule],
declarations: [ABIComponent, NavigationMenuComponent ],
bootstrap: [ABIComponent ]
})
export class AppModule { }
app.component.ts:
import {Component} from '#angular/core';
import { Router } from '#angular/router';
import { NavigationMenuComponent } from './navigation-menu/navigation-menu.component';
#Component({
selector: 'abi-app',
template: `<div>
<h1>Hello World!</h1>
</div>`
})
export class ABIComponent {
}
If you're interested in what the tree is of this project:
/src
--components
--- app
---- app.component.ts
---- app.module.ts
-- bootstrap.ts
/gulpfile.js
/index.html
/systemjs-angular-loader.js
/systemjs.config.js
Use #angular/cli instead of using webpack:-
https://cli.angular.io/
I have created my application using systemjs...everything works fine. Now i would like to create a bundle file, but for some reason my application is requesting my module as a separate http request? I thought it should all be included in my bundle.js file? Not sure if i have set something up incorrectly?
My application is stored in the wwwroot/app folder of my application root (asp.net 5 project).
I use gulp to convert my .ts file in .js and put them into wwwroot/dist/app.
I then gulp to convert all these .js files into my bundle.js which is then stored in wwwroot/dist/bundle.js
Now when i execute the page, my bundle.js file is loaded, the .html files are requested (as expected), but a request is made for public.module? I have a feeling it is something to do with this line in the app.routing.ts file loadChildren: 'app/public.module' where the module is loaded dynamically..
I have checked my bundle.js file and no reference of PublicModule is included? Why?
systemjs.config.js
(function(global) {
// map tells the System loader where to look for things
var map = {
'app': 'app', // 'dist',
'#angular': 'node_modules/#angular',
'rxjs': 'node_modules/rxjs',
'angular2-tree-component': 'node_modules/angular2-tree-component',
'lodash': 'node_modules/lodash',
'ng2-bootstrap': 'node_modules/ng2-bootstrap',
'ng2-ckeditor': 'node_modules/ng2-ckeditor',
'ng2-file-upload': 'node_modules/ng2-file-upload',
'ng2-dnd': 'node_modules/ng2-dnd'
};
// packages tells the System loader how to load when no filename and/or no extension
var packages = {
'app': { main: 'main.js', defaultExtension: 'js' },
'rxjs': { defaultExtension: 'js' },
'angular2-tree-component' : { main: 'dist/angular2-tree-component.js', defaultExtension: 'js' },
'lodash' : { main: 'lodash.js', defaultExtension: 'js' },
'ng2-bootstrap' : { defaultExtension: 'js' },
'ng2-ckeditor' : { main: 'lib/CKEditor.js', defaultExtension: 'js' },
'ng2-file-upload' : { main: 'ng2-file-upload.js', defaultExtension: 'js' },
'ng2-dnd': { main: 'index.js', defaultExtension: 'js'}
};
var ngPackageNames = [
'common',
'compiler',
'core',
'forms',
'http',
'platform-browser',
'platform-browser-dynamic',
'router',
'upgrade'
];
// Individual files (~300 requests):
function packIndex(pkgName) {
packages['#angular/' + pkgName] = { main: 'index.js', defaultExtension: 'js' };
}
// Bundled (~40 requests):
function packUmd(pkgName) {
packages['#angular/' + pkgName] = { main: 'bundles/' + pkgName + '.umd.js', defaultExtension: 'js' };
}
// Most environments should use UMD; some (Karma) need the individual index files
var setPackageConfig = System.packageWithIndex ? packIndex : packUmd;
// Add package entries for angular packages
ngPackageNames.forEach(setPackageConfig);
System.config({
defaultJSExtensions: true,
map: map,
packages: packages
});
})(this);
gulpfile.js
var gulp = require('gulp'),
path = require('path'),
Builder = require('systemjs-builder'),
ts = require('gulp-typescript'),
sourcemaps = require('gulp-sourcemaps'),
sass = require('gulp-sass'),
rename = require('gulp-rename'),
concat = require('gulp-concat'),
cleanCSS = require('gulp-clean-css');
var tsProject = ts.createProject('tsconfig.json');
// copy library files
gulp.task('copy:libs', function() {
gulp.src([
'node_modules/core-js/client/shim.min.js',
'node_modules/zone.js/dist/zone.js',
'node_modules/reflect-metadata/Reflect.js',
'node_modules/systemjs/dist/system.src.js',
'node_modules/ckeditor/ckeditor.js'
]).pipe(gulp.dest('wwwroot/dist/lib'));
return gulp.src('node_modules/font-awesome/**/*', { base: 'node_modules' })
.pipe(gulp.dest('wwwroot/dist/lib'));
});
/** first transpile your ts files */
gulp.task('ts', function() {
return gulp.src('wwwroot/app/**/*.ts')
.pipe(sourcemaps.init({
loadMaps: true
}))
.pipe(ts(tsProject))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('wwwroot/dist/app'));
});
/** then bundle */
gulp.task('bundle', ['ts'], function() {
// optional constructor options
// sets the baseURL and loads the configuration file
var builder = new Builder('', 'systemjs.config.js');
/*
the parameters of the below buildStatic() method are:
- your transcompiled application boot file (the one wich would contain the bootstrap(MyApp, [PROVIDERS]) function - in my case 'dist/app/boot.js'
- the output (file into which it would output the bundled code)
- options {}
*/
return builder.buildStatic('wwwroot/dist/app/*.js', 'wwwroot/dist/bundle.js', { minify: false, sourceMaps: true})
.then(function() {
console.log('Build complete');
})
.catch(function(err) {
console.log('Build error');
console.log(err);
});
});
// create css file
gulp.task('css', function () {
return gulp.src('wwwroot/sass/app.scss')
.pipe(sass())
.pipe(concat('app.css'))
.pipe(gulp.dest('wwwroot/dist/css'))
.pipe(cleanCSS())
.pipe(rename('app.min.css'))
.pipe(gulp.dest('wwwroot/dist/css'));
});
/** this runs the above in order. uses gulp4 */
gulp.task('build', ['ts', 'bundle', 'copy:libs']);
index.html
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
<link rel="shortcut icon" type="image/x-icon" href="#Html.Raw(ViewBag.BaseUrl)favicon.ico" />
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,600,700" rel="stylesheet" type="text/css" />
<link href="~/dist/css/app.min.css" rel="stylesheet" type="text/css" />
<link href="~/dist/lib/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css" />
<!-- 1. Load libraries -->
<script src="~/dist/lib/ckeditor.js"></script>
<!-- Polyfill(s) for older browsers -->
<script src="~/dist/lib/shim.min.js"></script>
<script src="~/dist/lib/zone.js"></script>
<script src="~/dist/lib/reflect.js"></script>
<script src="~/dist/lib/system.src.js"></script>
</head>
<!-- 3. Display the application -->
<body>
<my-app>Loading...</my-app>
<script src="~/dist/bundle.js"></script>
</body>
</html>
main.ts
import { platformBrowserDynamic } from '#angular/platform-browser-dynamic';
import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule);
app.module.ts
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { FormsModule } from '#angular/forms';
import { HttpModule } from '#angular/http';
import { CollapseModule } from 'ng2-bootstrap/components/collapse';
import { routing } from './app.routing';
import { AppComponent } from './app.component';
import { PublicComponent } from './public.component';
import { ProtectedComponent } from './protected.component';
#NgModule({
imports: [ BrowserModule, FormsModule, HttpModule, routing, CollapseModule ],
declarations: [ AppComponent, PublicComponent, ProtectedComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
app.routing.ts
import { Routes, RouterModule } from '#angular/router';
// public
import { PublicComponent } from './public.component';
import { ProtectedComponent } from './protected.component';
const appRoutes: Routes = [
{
path: '',
component: PublicComponent,
loadChildren: 'app/public.module'
},
{
path: 'admin',
component: ProtectedComponent,
loadChildren: 'app/protected.module'
}
];
export const routing = RouterModule.forRoot(appRoutes);
This looks clearly a bug in systemjs-builder.
https://github.com/systemjs/builder/issues/728
The workaround is adding '.js' in all import statement.
e.g.
import { AppModule } from './app.module';
needs to be
import { AppModule } from './app.module.js';
It worked for me with this solution.
I pulled the latest angularjs2 seed application from github (https://github.com/angular/angular2-seed) and got it running in webstorm.
Now I wanted to add a simple load.ts file which preloads some components:
declare var System: any;
declare var esriSystem: any;
esriSystem.register([
'esri/geometry/Point',
'esri/geometry/geometryEngineAsync',
'esri/Map'
], function() {
// bootstrap the app
System.import('../app')
.then(null, console.error.bind(console));
}, {
outModuleName: 'esri-mods'
});
I would like to use this module inside a new map.service.ts: import { Map } from 'esri-mods'; it tells me that it cannot resolve file 'esri-mods'
The overall structure looks like this:
And the system.config.js as follows:
System.config({
transpiler: 'typescript',
typescriptOptions: {
emitDecoratorMetadata: true
},
map: {
app: 'src',
typescript: 'node_modules/typescript/lib/typescript.js',
angular2: 'node_modules/angular2',
rxjs: 'node_modules/rxjs'
},
packages: {
app: {
defaultExtension: 'ts',
main: 'app.ts'
},
angular2: {
defaultExtension: 'js'
},
rxjs: {
defaultExtension: 'js'
}
}
});
What is missing for the module to be usable within the application?