I m studying angular 2 and I wanted to use redux with it.
Actually, I've created my project using angular-cli on rc2 release.
I m having this systemjs configuration :
/***********************************************************************************************
* User Configuration.
**********************************************************************************************/
/** Map relative paths to URLs. */
const map: any = {
};
/** User packages configuration. */
const packages: any = {
};
////////////////////////////////////////////////////////////////////////////////////////////////
/***********************************************************************************************
* Everything underneath this line is managed by the CLI.
**********************************************************************************************/
const barrels: string[] = [
// Angular specific barrels.
'#angular/core',
'#angular/common',
'#angular/compiler',
'#angular/http',
'#angular/router',
'#angular/platform-browser',
'#angular/platform-browser-dynamic',
// Thirdparty barrels.
// App specific barrels.
'app',
'app/shared'
/** #cli-barrel */
];
const cliSystemConfigPackages: any = {};
barrels.forEach((barrelName: string) => {
cliSystemConfigPackages[barrelName] = { main: 'index' };
});
/** Type declaration for ambient System. */
declare var System: any;
// Apply the CLI SystemJS configuration.
System.config({
map: {
'#angular': 'vendor/#angular',
'rxjs': 'vendor/rxjs',
'main': 'main.js',
'redux': 'vendor/redux/dist/redux.js',
},
packages: cliSystemConfigPackages
});
// Apply the user's configuration.
System.config({ map, packages });
And in my angular-cli.build.js :
/* global require, module */
var Angular2App = require('angular-cli/lib/broccoli/angular2-app');
module.exports = function(defaults) {
return new Angular2App(defaults, {
vendorNpmFiles: [
'redux/dist/redux.js',
'systemjs/dist/system-polyfills.js',
'systemjs/dist/system.src.js',
'zone.js/dist/**/*.+(js|js.map)',
'es6-shim/es6-shim.js',
'reflect-metadata/**/*.+(js|js.map)',
'rxjs/**/*.+(js|js.map)',
'#angular/**/*.+(js|js.map)'
]
});
};
The fact is that I m having this error in the web console :
What should I change to make redux available inside of my angular 2 app ? I m pretty sure this is a systemjs error and I don't know how to process...
Thanks for your help
The configuration in this comment solved the Redux problem for me.
Related
I have a typescript .ts file with the following.
I am using webpack version 2.2.1
import { module } from "angular";
import "typeahead";
class TypeAheadController {
static $inject = ["$log", "$timeout", "$http", "$interpolate"];
constructor(
public $log: ng.ILogService,
public $timeout: ng.ITimeoutService,
public $http: ng.IHttpService,
public $interpolate: ng.IInterpolateService) {
// do stuff with Typeahead / Bloodhound.
var bloodhoundSuggestions = new Bloodhound({
datumTokenizer: _ => Bloodhound.tokenizers.obj.whitespace(_[this.inputValue]),
queryTokenizer: Bloodhound.tokenizers.whitespace,
}
because the typeahead definitions are in #types/typeahead and the implementation is in typeahead.js, it's necessary to alias the location in webpack.config.js
globule = require("globule");
var configuration = {
context: __dirname,
resolve:
{
alias: {
typeahead: "typeahead.js"
}
},
entry: [
...globule.find("client/*.ts", { srcBase: "wwwroot/js/admin" })
],
output: {
filename: "./wwwroot/js/admin/admin.js"
},
module: {
rules: [
{ test: /\.ts$/, use: 'ts-loader' }
]
}
};
console.log(configuration);
module.exports = configuration;
Unfortunately in the resulting generated javascript file, Bloodhound is undefined.
Webpack seems to include and use the relevant require (323), but it's clearly not working as Bloodhound is undefined.
in the output file, the require is present just before the controller is defined.
Object.defineProperty(exports, "__esModule", { value: true });
var angular_1 = __webpack_require__(16);
__webpack_require__(323);
/**
* initialise and use a type ahead to find suggestions.
*/
var TypeAheadController = (function () {
much further down the file, I find 323.
/***/ }),
/* 323 */
/***/ (function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(setImmediate) {var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
* typeahead.js 0.11.1
* https://github.com/twitter/typeahead.js
How do I fix the undefined Bloodhound?
This package is a quirky one. It is named typeahead.js, but the "main" entry in package.json actually exports the Bloodhound function and attaches the typeahead function to jQuery.fn. To make matters worse, its #types package has the wrong name (missing .js) and is written using a declaration format that expects you to import from "bloodhound". This is painful but can be worked around.
Here are the steps you need to take:
Install typeahead.js with npm (since you are using Webpack)
npm install --save typeahead.js
install the #types package (note no .js, this is annoying)
npm install --save #types/typeahead
Remove the alias it is not needed. Specifically, the following line must be removed from webpack.config.js:
typeahead: "typeahead.js"
Create a declaration file ambience.d.ts (name is not significant)
declare module "typeahead.js" {
export = Bloodhound;
}
Unfortunately the code above refers to the global Bloodhound which the #types/typeahead unconditionally declares. Fortunately it will not be global at runtime.
Adjust your code so it is roughly as follows
import angular from "angular";
import Bloodhound from "typeahead.js"; // note the `.js`
class TypeAheadController {
static $inject = ["$log", "$timeout", "$http", "$interpolate"];
constructor(
readonly $log: angular.ILogService,
readonly $timeout: angular.ITimeoutService,
readonly $http: angular.IHttpService,
readonly $interpolate: angular.IInterpolateService) {
// do stuff with Typeahead / Bloodhound.
const bloodhoundSuggestions = new Bloodhound({
datumTokenizer: _ => Bloodhound.tokenizers.obj
.whitespace(_[this.inputValue]),
queryTokenizer: Bloodhound.tokenizers.whitespace
});
}
}
I'm trying to integrate ag-Grid with Angular2 but I'm stuck at following error:
zone.js:101 GET http://localhost:4200/node_modules/ag-grid-ng2/main.js
404 (Not Found)
I'm importing the third party component using:
import {AgGridNg2} from 'ag-grid-ng2/main';
...
directives: [AgGridNg2]
This is my system-config.ts file:
"use strict";
// SystemJS configuration file, see links for more information
// https://github.com/systemjs/systemjs
// https://github.com/systemjs/systemjs/blob/master/docs/config-api.md
/***********************************************************************************************
* User Configuration.
**********************************************************************************************/
/** Map relative paths to URLs. */
const map: any = {
// ag libraries
'ag-grid-ng2': 'node_modules/ag-grid-ng2',
'ag-grid': 'node_modules/ag-grid',
'ag-grid-enterprise' : 'node_modules/ag-grid-enterprise'
};
/** User packages configuration. */
const packages: any = {
'ag-grid-ng2': {
defaultExtension: "js"
},
'ag-grid': {
defaultExtension: "js"
},
'ag-grid-enterprise': {
defaultExtension: "js"
}
};
////////////////////////////////////////////////////////////////////////////////////////////////
/***********************************************************************************************
* Everything underneath this line is managed by the CLI.
**********************************************************************************************/
const barrels: string[] = [
// Angular specific barrels.
'#angular/core',
'#angular/common',
'#angular/compiler',
'#angular/forms',
'#angular/http',
'#angular/router',
'#angular/platform-browser',
'#angular/platform-browser-dynamic',
// Thirdparty barrels.
'rxjs',
// App specific barrels.
'app',
'app/shared',
'app/full-width-renderer',
/** #cli-barrel */
];
const cliSystemConfigPackages: any = {};
barrels.forEach((barrelName: string) => {
cliSystemConfigPackages[barrelName] = { main: 'index' };
});
/** Type declaration for ambient System. */
declare var System: any;
// Apply the CLI SystemJS configuration.
System.config({
map: {
'#angular': 'vendor/#angular',
'rxjs': 'vendor/rxjs',
'main': 'main.js'
},
packages: cliSystemConfigPackages
});
// Apply the user's configuration.
System.config({ map, packages });
I can see the dependency under the /node_modules/ag-grid-ng2 folder:
Any help is strongly appreciated.
I haven't used the enterprise grid, but for using ag-grid with Angular 2 you will need to include this in the map section of your System.config:
'ag-grid': 'node_modules/ag-grid',
'ag-grid-ng2': 'node_modules/ag-grid-ng2'
Also make sure you have these modules in your node_modules package, else make sure to include these descriptions in your package.json and run 'npm install' first.
I am looking to run Angular 2 from CDN links with SystemJS and also want to setup unit testing with Jasmine.
I have managed to get it loading the application and setup Jasmine in my code which is shown below:
/**
* based on systemjs.config.js in angular.io
* System configuration for Angular 2 samples
* Adjust as necessary for your application needs.
*/
(function(global) {
var addRouting = false;
//map tells the System loader where to look for things
var map = {
'app': 'bundles/core/src', // 'dist',
'rxjs': 'https://npmcdn.com/rxjs#' + rxJsVersion,
'angular2-in-memory-web-api': 'https://npmcdn.com/angular2-in-memory-web-api', // get latest
'ts': 'https://npmcdn.com/plugin-typescript#' + typescriptPluginVersion + '/lib/plugin.js',
'typescript': 'https://npmcdn.com/typescript#' + typescriptVersion + '/lib/typescript.js'
};
//packages tells the System loader how to load when no filename and/or no extension
var packages = {
'app': { main: 'main.ts', defaultExtension: 'ts' },
'rxjs': { defaultExtension: 'js' },
'angular2-in-memory-web-api': { defaultExtension: 'js' },
};
var packageNames = [
'#angular/common',
'#angular/compiler',
'#angular/core',
'#angular/http',
'#angular/platform-browser',
'#angular/platform-browser-dynamic',
'#angular/testing',
'#angular/upgrade',
'#angular/forms',
]
// add map entries for angular packages in the form '#angular/common': 'https://npmcdn.com/#angular/common#0.0.0-3'
packageNames.forEach(function(pkgName) {
map[pkgName] = 'https://npmcdn.com/' + pkgName + '#' + angularVersion;
});
// 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' };
});
if ( addRouting ){
// Router API
map['#angular/router'] = 'https://npmcdn.com/#angular/router#' + angularRouterVersion;
packages['#angular/router'] = { main: 'index.js', defaultExtension: 'js' };
}
var config = {
transpiler: 'ts',
typescriptOptions: {
emitDecoratorMetadata: true,
module: "commonjs",
experimentalDecorators: true
},
meta: {
'typescript': {
"exports": "ts"
}
},
map: map,
packages: packages
}
// filterSystemConfig - index.html's chance to modify config before we register it.
if (global.filterSystemConfig) { global.filterSystemConfig(config); }
System.config(config);
})(this);
This loads the Angular 2 library sucessfully and I am able to see Angular render in the page using the following markup:
<script src="{{ asset('bundles/core/js/config.js') }}"></script>
<script>
function loadTestingScripts(){
return Promise.all([
System.import('bundles/core/src/app/app.spec.ts')
]);
}
Promise.all([
System.import('app')
])
.then( loadTestingScripts() )
.then( window.onload )
.catch( console.error.bind(console) );
</script>
However when I try and run the following test code:
import { ComponentFixture, TestBed } from '#angular/core/testing/index';
import { By } from '#angular/platform-browser/index';
import { DebugElement } from '#angular/core/index';
import { AppComponent } from './app.component';
let comp: AppComponent;
let fixture: ComponentFixture<AppComponent>;
let el: DebugElement;
describe('1st tests', () => {
it('true is true', () => expect(true).toBe(true));
});
describe('AppComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [ AppComponent ], // declare the test component
});
fixture = TestBed.createComponent(AppComponent);
});
});
I receive an error 'TypeError: callback.apply is not a function' (zone.js#0.6.21:192).
However I have seen this achieved here with a beta version of the library:
http://embed.plnkr.co/vUjNLCVG8SVRYK6ZnKG0/
Is there any reason why the latest version cannot run unit testing with Angular 2 via a CDN url?
I am running Angular 2 final (2.0.0).
Below shows what I am trying to achieve:
https://embed.plnkr.co/7CCtow/
There seems to be two parts to this question, so I'll call them out and answer them individually.
Can we run jasmine unit testing with angular2 from CDN running systemjs?
Yes. I've created a plunker that seems to do what you wanted to do.
At the time of this answer, the systemjs.config.js in this plunk has been pretty hacked to help illustrate the changes, but I've copied the important parts below in case I clean it up in the future. The main changes that I needed to make to go from an older RC to the "latest" angular2 release version (2.4 at the time of writing) was to resolve the testing dependencies from the CDN for:
#angular/core/testing
#angular/platform-browser-dynamic/testing
#angular/platform-browser/testing
#angular/compiler/testing
And here's the appropriate fragment
var map = {
...
"#angular/core/testing": "https://npmcdn.com/#angular/core#2.4.0/bundles/core-testing.umd.js",
"#angular/platform-browser-dynamic/testing": "https://npmcdn.com/#angular/platform-browser-dynamic#2.4.0/bundles/platform-browser-dynamic-testing.umd.js",
"#angular/platform-browser/testing": "https://npmcdn.com/#angular/platform-browser#2.4.0/bundles/platform-browser-testing.umd.js",
"#angular/compiler/testing": "https://npmcdn.com/#angular/compiler#2.4.0/bundles/compiler-testing.umd.js",
...
};
Note: I am mapping the /testing dependencies to the umd format packages in the /bundles location. It looks like you're trying to map to the index.js inside #angular/core/testing/index which from what I can tell isn't the dependency that you're looking for, we want umd in this case.
Is there any reason why the latest version cannot run unit testing with Angular 2 via a CDN url?
Regarding the second part of your question, It seems you may be referencing the latest zone.js dependency as opposed to angular2.
No, there isn't a reason I can see. With the right configuration it works perfectly well with the version I tested:
0.6.21
0.6.23
0.6.25 which was the latest 0.6.x (at the time of writing)
I did find that there were a lot of changes and a few issues were raised in the zone.js project around this time, though many seem to be resolved by the versions we're talking about. the right configuration and order were important in my test running page where I have the fragment.
<script src="https://npmcdn.com/zone.js#0.6.25?main=browser"></script>
<script src="https://npmcdn.com/zone.js#0.6.25/dist/long-stack-trace-zone.js?main=browser"></script>
<script src="https://npmcdn.com/zone.js#0.6.25/dist/async-test.js?main=browser"></script>
<script src="https://npmcdn.com/zone.js#0.6.25/dist/fake-async-test.js?main=browser"></script>
<script src="https://npmcdn.com/zone.js#0.6.25/dist/sync-test.js?main=browser"></script>
<script src="https://npmcdn.com/zone.js#0.6.25/dist/proxy.js?main=browser"></script>
<script src="https://npmcdn.com/zone.js#0.6.25/dist/jasmine-patch.js?main=browser"></script>
Since I upgraded to Angular2 RC.0, all the modules are now loaded individually (600 HTTP requests on the application loading) which is very long and almost unusable. The beta17 loads all the modules at once (or at least one file for each core, http, rxjs...).
I have followed the official quickstart guide for beta and RC.
Could you tell me how to use the same mechanism as the beta or what the new mechanism is to use aggregate modules with the RC.0 ?
I have the same issue, and resolved by 'systemjs-builder'. but havn't test detailly. for you as a reference. https://github.com/A-hsien/Angular2-systemjs-builder
thx for comment from #Gaurav.
following code will package '#angular' by each folder under '#angular'.
just save them to a whateverthename.js file.
var Builder = require('systemjs-builder');
var packages = {};
var packageNames = [
'#angular/common',
'#angular/compiler',
'#angular/core',
'#angular/http',
'#angular/platform-browser',
'#angular/platform-browser-dynamic',
'#angular/router-deprecated',
'#angular/upgrade',
];
packageNames.forEach(function(pkgName) {
packages[pkgName] = { main: 'index.js' };
});
var builder = new Builder({
baseURL: '/node_modules',
defaultJSExtensions: true,
packages: packages
});
packageNames.forEach(function(pkgName) {
builder.bundle(pkgName, 'assets/'+ pkgName+'.js')
.then(function() {
console.log(pkgName+'Build complete');
})
.catch(function(err) {
console.log(pkgName+'Build error');
console.log(err);
});
});
then execute the command node whateverthename.js.
modeues will be build to assets folder.
By using the answer from #A-Hsiao and adding rxjs dependency, I have sucessfully combine all js files into one minified file. The following node script must be executed.
var Builder = require('systemjs-builder');
var packages = {
'rxjs': {main: 'Rx.js'}
};
var packageNames = [
'#angular/common',
'#angular/compiler',
'#angular/core',
'#angular/http',
'#angular/platform-browser',
'#angular/platform-browser-dynamic',
'#angular/router-deprecated',
];
packageNames.forEach(function (pkgName) {
packages[pkgName] = {main: 'index.js'};
});
packageNames.push('rxjs');
var builder = new Builder({
baseURL: '/node_modules',
defaultJSExtensions: true,
packages: packages
});
packageNames.forEach(function (pkgName) {
builder.bundle(pkgName, 'build/assets/' + pkgName + '.js')
.then(function () {
console.log(pkgName + ' Build complete');
})
.catch(function (err) {
console.log(pkgName + ' Build error');
console.log(err);
});
});
All the generated file can be combined and minified. Then the following systemjs.config.js must be imported after the bundled file.
(function (global) {
var map = {
'app': 'app'
};
var packages = {
'app': {main: 'main.js'},
'rxjs': {main: 'Rx.js'}
};
var packageNames = [
'#angular/common',
'#angular/compiler',
'#angular/core',
'#angular/http',
'#angular/platform-browser',
'#angular/platform-browser-dynamic',
'#angular/router-deprecated'
];
packageNames.forEach(function (pkgName) {
packages[pkgName] = {main: 'index.js'};
});
var config = {
map: map,
packages: packages,
defaultJSExtensions: true
};
if (global.filterSystemConfig) {
global.filterSystemConfig(config);
}
System.config(config);
})(this);
I want to build a quick nodejs script to package a Typescript app as SystemJS modules, a lot like what Angular2 bundles look like.
I tried different configurations but I can't seem to put my finger on it, and haven't found clear enough documentation as of yet.
Note that for this "test", I am not using Gulp or Jspm at all, just systemjs-builder for the time being (and don't plan on using jspm at all either)
Here's what my "project" looks like:
---- Project's Root
-------- index.ts // export * from './modules/index' and eventually more
-------- modules
------------ index.ts // export * from './menu/index'
------------ menu
---------------- menu.component.ts // export class
---------------- menu.service.ts // export class
I want to package this under a single file, where I will have multiple SystemRegister modules that can be consumed in an app thereafter
I tried the following without success:
var Builder = require('systemjs-builder');
// optional constructor options
// sets the baseURL and loads the configuration file
var builder = new Builder('./modules');
builder.bundle('./modules/index.ts', {
/* SystemJS Configuration Here */
baseURL: './modules',
transpiler: 'typescript',
typescriptOptions: {
"module": "system",
"emitDecoratorMetadata": true,
"experimentalDecorators": true
},
defaultExtension: 'ts',
packages: {
'modules': {
defaultExtension: 'ts'
}
}
}, 'infrastructure.js')
.then(function() {
console.log('Build complete');
})
.catch(function(err) {
console.error(err);
})
First of all, the defaultExtension options doesn't seem to work at all
So when I do import {something} from 'filePath'; (without extension), it tries to load filePath, instead of filePath.ts;
Second, if I try adding the .ts extension in my imports (which I don't want to do), it complains that the code is invalid (unexpected token #, unexpected token menuItem and so forth)
Anyone have a good example or some explanations on how this is supposed to work?
Thank you
here you have an example: angular typescript skeleton
build task looks like this:
const path = require('path');
const Builder = require('jspm').Builder;
const builder = new Builder();
const packageJson = require(path.join(config.projectDir, 'package.json'));
return beginBuild()
.then(buildSFX)
.catch((err) => console.log('Build Failed', err));
function beginBuild() {
builder.reset();
return builder.loadConfig(path.join(config.projectDir, packageJson.jspm.configFile))
}
function buildSFX() {
const appName = packageJson.name;
const distFileName = `${appName}.min.js`;
const outFile = path.join(config.distDir, distFileName);
const moduleName = 'app';
const buildConfig = {
format: 'global',
minify: true,
sourceMaps: true
};
return builder.buildStatic(moduleName, outFile, buildConfig);
}
and jspm conf looks like this:
System.config({
defaultJSExtensions: true,
transpiler: "typescript",
typescriptOptions: {
"tsconfig": "src/tsconfig.json"
},
paths: {
"github:*": "vendor/jspm_packages/github/*",
"npm:*": "vendor/jspm_packages/npm/*",
"app": "src/index"
}
/// ...
}
Why do you want to bundle typescript? Bundling is a method used for optimizing the delivery of source code to the browser. The browser doesn't know typescript, it only knows javascript (unless you do on the fly transpiling).