I am having issues getting Angular2 to load correctly when incorporating RequireJS into the application.
For simplicity wise I am using the very simple Hello World Javascript tutorial on the Angular2 located here : https://angular.io/docs/js/latest/quickstart.html
I have this system working fine using Angular1 but I can't seem to replicate this success using Angular2.
Here is my index.html file:
<html>
<head>
<title>Angular 2 QuickStart JS</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 1. Load RequireJS -->
<script type="text/javascript", src="bower_components/requirejs/require.js", data-main="/require.config.js"></script>
</head>
<!-- 3. Display the application -->
<body>
<ireland-product-app>Loading...</ireland-product-app>
</body>
My require.config.js file:
require([
'assets/requiredPathsAndShim.js'
], function(requirePathsAndShim) {
require.config({
baseUrl: '/',
paths: requirePathsAndShim.paths,
shim: requirePathsAndShim.shim,
/// Kick start app...
deps: ['app/main']
});
});
I use the requiredPathsAndShim.js file to load all the dependencies I see that are required to start an Angular2 application. Here is the file:
"use strict";
(function(define) {
define([], function() {
return {
waitSeconds : 10000,
paths: {
'shim' : 'node_modules/core-js/client/shim.min',
'zone' : 'node_modules/zone.js/dist/zone',
'Reflect' : 'node_modules/reflect-metadata/Reflect',
'Rx' : 'node_modules/rxjs/bundles/Rx.umd',
'core' : 'node_modules/@angular/core/core.umd',
'common' : 'node_modules/@angular/common/common.umd',
'compiler' : 'node_modules/@angular/compiler/compiler.umd',
'platform-browser' : 'node_modules/@angular/platform-browser/platform-browser.umd',
'platform-dynamic' : 'node_modules/@angular/platform-browser-dynamic/platform-browser-dynamic.umd'
},
shim : {
}
}
});
})(define);
I then load the 'app/main' file from my 'required.config' file which will load the bootstrap functionality of Angular2:
"use strict";
(function() {
define([
'app/app.component'
], function(app) {
document.addEventListener('DOMContentLoaded', function() {
ng.platformBrowserDynamic.bootstrap(app.AppComponent);
});
});
})();
The app/app.component file is a file which simply returns my Angular2 component which is passed into the main.js bootstrap function to start the app. this is the file:
"use strict";
(function() {
define([
], function() {
return {
AppComponent : ng.core.Component({
selector : 'ireland-product-app',
template : '<h1>Product App</h1>'
})
.Class({
constructor : function() {}
})
}
});
})();
I have been playing around with this for a few hours and can't seem to get this working. Can anyone point me in the right direction as to why this isn't working? I have a feeling some shims need to be added into the require.config but I have had no success setting script load dependencies as of yet.
Thanks
RequireJS has been a hugely influential and important tool in the JavaScript world. It's still used in many solid, well-written projects today.
RequireJS is a JavaScript library and file loader which manages the dependencies between JavaScript files and in modular programming. It also helps to improve the speed and quality of the code.
As per RequireJS API documentation, shim lets you. Configure the dependencies, exports, and custom initialization for older, traditional "browser globals" scripts that do not use define() to declare the dependencies and set a module value. - Configuring dependencies.
So, RequireJS doesn't support it. From your use case it seems that you don't need synchronous RequireJS, you need to return result asynchronously. AMD pattern allows to define dependencies and load them asynchronously, but module's factory function must return result synchronously.
What you are trying to do isn't possible (well, in software engineering, like in art - everything is possible, but to achieve this you'll need to edit the angular's script, and we don't want this).
Not like Angular1, which was developed in ECMAScript5 (the loved JavaScript language), Angular2 was developed in ECMAScript6 (and in TypeScript).
One of the differences is that in ECMAScript5 in order to load a script file (.js, .ts, etc.) we need to add a <script>
tag with src
attribute, which point to the script file.
The alternative was to use 3rd party library, which loaded the scripts asynchronously (example for libraries like this are: RequireJS, WebPack, SestemJS, etc.).
The main disadvantage of RequireJS, is that it only works on scripts that are written in a AMD format (Asynchronous Module Definition), for example:
define(['dependence_1', 'dependence_2', ...], function(alias_1, alias_2, ...) {
// ...
});
This syntax is very efficient when working with Angular1 and RequireJS.
Now, when we look at Angular2 library we can see that it isn't written in AMD syntax, meaning it can't be loaded using RequireJS - without rewriting the code into AMD format. Angular2 is expecting you use some kind of universal module loader. The keyword here is universal, meaning a module loader that can load all kinds of script formats (AMD modules, CommonJS modules and ES6 modules). Examples of universal module loaders are: WebPack and SystemJS.
Now let's talk about the solution to your problem, I believe that you'll need to migrate from RequireJS to Webpack - since the migration isn't so complicated.
Step#1 - 3rd Party Libraries
When loading 3rd Party Libraries with RequireJS, we are using RequireJS's path
and shims
, that can be easily converted into Webpack's alias
. But this isn't needed: once you are working with Webpack, you have a npm support. This mean that you can run npm install library-name
and now you can use this library without RequireJS.
Step#2 - Application scripts
Fortunately for us we almost don't need to do nothing here. Since Webpack is a universal module loader, it can load scripts in AMD format. So all the application scripts that was developed in the RequireJS format, can be loaded using Webpack without any change.
For more info on how to migrate from RequireJS to Webpack see this article: https://gist.github.com/xjamundx/b1c800e9282e16a6a18e
I was facing same issue what @devoncrazylegs faced..
My solution: Configure paths array used in require.config() in tsconifg.ts --> compilerOptions-->paths
Read below link to understand more
https://www.typescriptlang.org/docs/handbook/module-resolution.html#base-u
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With