I'm trying to require the xml-js
module (https://www.npmjs.com/package/xml-js) to do some XML parsing in my existing Electron + Typescript project.
What I'm slightly confused about is why it is throwing an error.
First of all, the tsconfig.json
file is the following:
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": false,
"outDir": "dist"
},
"exclude": [
"node_modules"
]
}
the relevant part of the systemjs config is here:
paths: {
'npm:': 'node_modules/'
},
map: {
'xml-js': 'npm:xml-js'
},
packages: {
app: {
main: './main.js',
defaultExtension: 'js'
},
rxjs: {
defaultExtension: 'js'
}
}
So the module is located in node_modules/xml-js (like many others).
When I build my application, I get the following error:
file://<path>/Documents/projectFolder/electron-angular2-rc6/ng2-electron/node_modules/xml-js Failed to load resource: net::ERR_FILE_NOT_FOUND
and :
index.html:18 Error: (SystemJS) XHR error loading file://<path>/Documents/projectFolder/electron-angular2-rc6/ng2-electron/node_modules/xml-js
I'm attempting to load the module through:
const parser = require("xml-js");
(so, as vanilla JS), in my typescript component (application.component.ts).
The relevant part of my index.html is:
<script src="systemjs.config.js"></script>
<script>
System.import('app').catch(function(err){ console.error(err); });
document.addEventListener('dragover',function(event){
event.preventDefault();
return false;
},false);
document.addEventListener('drop',function(event){
event.preventDefault();
return false;
},false);
</script>
The module has been installed through:
npm install xml-js --save-dev
And exists in the directory node_modules/xml-js
I have tons of other modules (including rxjs and angular-in-memory-web-api) along with the regular @angular ones: all of them are working properly and throwing no error, but the xml-js one seems to be not working whatsoever.
After a couple of hours of documentation and, being honest, disappointment, I've found out that you can't directly include node modules with systems, because systemjs cannot interprete them directly.
I had to change the whole library, and relied on this one: https://www.npmjs.com/package/jxon which says "A complete, bidirectional, JXON (lossless JavaScript XML Object Notation) library. Packed as UMD.". I've check what "UMD" means, which means "Universal Module Definition": https://github.com/umdjs/umd
So, you likely can use the UMD tools to wrap the modules in your application, else you can rely on existing ones available somewhere.
In my case, using jxon, I had to change my code a bit:
'jxon':'npm:jxon'
packages: { jxon: { defaultExtension: 'js', main: 'jxon.min.js' } }
import * as jxonparser from 'jxon'
, though I've used: const jxon_parser = require('jxon');
So, in a very concise nutshell: you can't include node modules with systemjs unless they are either as UMD or that can be interpreted from systemjs. If you want to check the formats supported by systemjs, check this: https://github.com/systemjs/systemjs/blob/master/docs/module-formats.md