systemjs - "system.import" fails if file contains "use strict" - javascript

I would like to use systemjs as a module loader in a new project. Everything works fine until I add 'use strict'; to the top of the file which should be loaded.
script.js
System.import('loadme.js').then(function(m) {
console.log('loaded');
console.log(app);
})
loadme.js
'use strict'; //if I remove this line the import works fine
var app={
version:'0.0.0',
name:'just a test'
};
I have a plunkr here https://plnkr.co/edit/bhSTkcZw9XaKszXuIYZQ

It's expecting a module to be passed back with the data, and not a global variable (see documentation on strict mode globals).
Here's something you could do, if you just want it to work:
https://plnkr.co/edit/pVKqfGkcCagyLixtmziB?p=preview
'use strict';
var app = {
version: '0.0.0',
name: 'just a test'
};
module.exports = app;
/*
You can also do
module.exports = {
app: app,
foo: foo,
bar: bar
.
.
.
}
and then in your script.js have module.app, module.foo
*/

Related

How to make VS Code show error in JS ES6 class?

I have two modules in one folder, mod1.js:
'use strict';
export class MyClass {
constructor() {
}
lala() {
alert(1);
}
}
And mod2.js:
'use strict';
import {MyClass} from './mod1';
let c = new MyClass();
c.lala2(); //HERE I WANT TO SEE ERROR
The problem is that Visual Studio Code doesn't show error in mod2. How to make it show the error, if it is possible?

How to set Tealium-Angular configuration in a karma test

There is a tagging library here: https://github.com/Tealium/integration-angularjs/blob/master/tealium_angular.js .
We integrated it into our application. During app initialisation we need to provide some configuration for this library. This is done like this:
Our app.js:
angular.module('appname', [ 'TealiumHelper' ])
.config(function (tealiumProvider) {
tealiumProvider.setConfig({
account: 'accountxx',
profile: 'profilexx',
environment: 'dev'
});
})
There is a karma test similar to this:
(function () {
'use strict';
describe('controllertest', function () {
beforeEach(module('appname','TealiumHelper'));
it('bla', function () {
//test code
}
}
}
When I start the test, I get the following error coming from tealium_angular.js:
"account or profile value not set. Please configure Tealium first"
How can I set these config values in my karma test?
In the test you can provide your own implementation for TealiumHelper module like
describe('controllertest', function () {
beforeEach(module('appname'))
angular.module('TealiumHelper', []).provider('tealium', {
$get: function () {},
setConfig: function () {}
});
/*** test starts here ***/
})
The solution was (my colleague Andrea Fűrész fixed it actually):
She created a js file with the following content:
function TealiumConfig() {
'use strict';
module('TealiumHelper', function (tealiumProvider) {
tealiumProvider.setConfig({
account: 'foooooo',
profile: 'baaaar',
environment: 'dev'
})
});
}
Then in karma config it was added into the "files" configuration. Then it worked.

Load JavaScript file in angular2 app

I'm working on a angular2 application written in TypeScript.
This works:
I have a module called plugin-map.ts which looks something like this:
import { Type } from '#angular/core';
import { SomeComponent } from './plugins/some.component';
export const PluginMap: { [key: string]: Type<any> } = {
'e690bec6-f8d1-46a5-abc4-ed784e4f0058': SomeComponent
};
It gets transpiled to a plugin-map.js which looks something like this:
"use strict";
var some_component_1 = require('./plugins/some.component');
exports.PluginMap = {
'e690bec6-f8d1-46a5-abc4-ed784e4f0058': some_component_1.SomeComponent
};
//# sourceMappingURL=plugin-map.js.map
And in other modules I'm importing my PluginMap like this:
import { PluginMap } from './plugin-map';
What I want:
Now I want to create plugin-map.js at runtime when my server starts. So I want to get rid of my plugin-map.ts and instead have only a (generated) plugin-map.js. And I don't want to have any transpile-time dependencies to that plugin-map.js.
What I tried:
In modules where I need to access the PluginMap I replaced the import statement with a declaration like this:
declare const PluginMap: { [key: string]: Type<any> };
Now of course at runtime I get a Error: (SystemJS) 'PluginMap' is undefined. So my next step was to load plugin-map.js explicitly from my index.html like this:
...
<script src="js/system.src.js"></script>
<script src="systemjs.config.js"></script>
<script>
System.import('./app/plugins/plugin-map.js').catch(function (err) { console.error(err); });
System.import('app').catch(function(err){ console.error(err); });
</script>
...
When I start my application I can see that the browser actually requests the plugin-map.js file. But I still get the Error: (SystemJS) 'PluginMap' is undefined.
Question:
How/where do I have to load my generated plugin-map.js so that this works?
I had to make sure that PluginMap is available in the global context. So the generated plugin-map.js has to look like this:
var some_component_1 = require('./plugins/some.component');
PluginMap = {
'e690bec6-f8d1-46a5-abc4-ed784e4f0058': some_component_1.SomeComponent
};
and not like this:
"use strict";
var some_component_1 = require('./plugins/some.component');
exports.PluginMap = {
'e690bec6-f8d1-46a5-abc4-ed784e4f0058': some_component_1.SomeComponent
};
//# sourceMappingURL=plugin-map.js.map
Now it seems to work.

How do I use SystemJS Builder buildStatic?

I am trying to do a simple example using SystemJS Builder by building a SFX bundle, but I cannot get it to work. I cannot figure out how to call exported functions that were in the bundle. Am I missing something obvious?
index.html
<html>
<head>
<script src="app.bundle.js"></script>
<script>
all();
</script>
</head>
<body>
</body>
</html>
gulpfile.js
var path = require('path');
var gulp = require('gulp');
var Builder = require('systemjs-builder');
gulp.task('default', function(cb) {
var builder = new Builder('.', './jspm.config.js');
builder.buildStatic('src/app.js', 'dist/app.bundle.js').then(cb());
});
app.js
import { hello } from 'src/app/hello';
export function all() {
hello();
}
hello.js
export function hello() {
console.log("hello");
};
When I try to load index.html, it loads the app.bundle.js file correctly, but I can't seem to figure out how to call all() and I get Uncaught ReferenceError: all is not defined in Chrome.
The bundle file looks reasonable, I think:
// ... Some minified SystemJS content...
(["1"], [], function($__System) {
$__System.register("2", [], function (_export) {
"use strict";
_export("hello", hello);
function hello() {
console.log("hello");
}
return {
setters: [],
execute: function () {
;
}
};
});
$__System.register('1', ['2'], function (_export) {
'use strict';
var hello;
_export('all', all);
function all() {
hello();
}
return {
setters: [function (_) {
hello = _.hello;
}],
execute: function () {}
};
});
})
(function(factory) {
if (typeof define == 'function' && define.amd)
define([], factory);
else if (typeof module == 'object' && module.exports && typeof require == 'function')
module.exports = factory();
else
factory();
});
Exporting the all function does not mean it's accessible by the global object (window in the browser).
It just means that it can be imported using a module loaded (e.g. systemjs).
When creating a self-executing bundle you should just load the bundle file in the browser (as you already do) and do all bootstrapping also in the js files that are going to be in the bundle.
If you really need to access the all function in that script tag you must add the function to the global object.
in your app.js
window.all = all;
But i don't think this is the way its intended to be used.

How do I import a named SystemJS module from a bundle file?

I've got one file (app.js) with two named modules in it ("foo", and "bar" - where "bar" depends on "foo").
Question: How to I load "bar" it in the browser?
Disclaimer: I'm new to SystemJS and the docs look a little intimidating.
app.js
System.register("foo", [], function(exports_1) {
"use strict";
var App;
return {
setters:[],
execute: function() {
App = (function () {
function App() {
this.bar = 'Hello world.';
console.log(this.bar);
}
return App;
})();
exports_1("App", App);
;
}
}
});
System.register("bar", ["foo"], function(exports_1) {
"use strict";
var App;
return {
setters:[],
execute: function() {
App = (function () {
function App() {
this.bar = 'Mony a mickle maks a muckle.';
console.log(this.bar);
}
return App;
})();
exports_1("App", App);
;
}
}
});
Got the results I wanted by doing the following:
Added the <script src="app.js"> tag to my index file.
Also added System.import('bar'); to the page.
I wonder if this is the standard/recommended way of doing it.
Edit:
The issue with this approach is that I need two strategies for development and production.
In development I don't add the <script> tag and I import the module using System.import('path/app.js');
I think using a bare bones seed can help you out by showing a simple working example, this seed has a PRODUCTION and DEV MODE and you dont need to have 2 strategies, just choose between running it bundled or not
try:
npm i -g slush-jspm-react-seed

Categories

Resources