Reputation: 803
I'm trying to build a boilerplate template to bootstrap angular 2 applications using express, angular 2, typescript, gulp, and systemjs. For some reason, my index.html file won't recognize my bootstrap.js
file. All my jade
and typescript
is located in src
. I'm using gulp to transpile typescript from src
to dist
, and serving my static assets from node_modules
and jspm_packages
in express. But when it finally comes time to invoke System.import
, like so:
System.import('app').catch(console.error.bind(console))
,
i get:
Error: SyntaxError: Unexpected token <
Evaluating http://localhost:3000/app/bootstrap.js
Error loading http://localhost:3000/app/bootstrap.js
The error seems to be caused in angular2-polyfills.min.js
.
Here is my basic express backend to give you an idea of how my assets and files are served up (I'm suspicious that i'm having a temporary brainfart and my paths are off):
const app = express();
app.use('/jspm_packages', express.static('jspm_packages'));
app.use('/node_modules', express.static('node_modules'));
app.get('*', function(req, res) {
const file = fs.readFileSync('src/index.jade').toString();
const html = jade.render(file);
return res.send(html);
});
app.listen(process.env.PORT || 3000);
My index.html
file is located in dist
, the directory that holds all transpiled javascript. Here is the packages
property on my System.config:
packages: {
"dist": {
"main": "bootstrap",
"format": "system",
"defaultExtension": "js"
}
},
I was under the impression that dist
identifies the folder relative to the BASE_URL
(which in my case is just /
), and the main
property identifies the file name. So I thought that by calling System.import('app')
, it will look inside the app
folder inside dist
and find the bootstrap.js
file to bootstrap my angular2 app, but that doesn't seem to be the case. When i open my up chrome console, bootstrap.js
doesnt show up in my sources, so I'm guessing theres a path error somewhere, but I've tried every variation and can't seem to get it to work.
Any help would be greatly appreciated, thanks.
Update:
Here is my index.html
: https://jsfiddle.net/r02r3jk3/
Here is the folder structure and server-side code that serves up content: https://jsfiddle.net/cejk0jw3/
When I inspect the network Tab for the response to the request for the browser.js
file in angular2/platform
, I get the following:
The request URL is http://localhost:3000/jspm_packages/npm/[email protected]/platform/browser.js
The response has a content-type of Content-Type:text/html; charset=utf-8
but the response is my index.html file :(
Upvotes: 1
Views: 1689
Reputation: 16540
instead of app
in System.import('app')
it should be dist
like this: System.import('dist')
and your packages definition should be:
packages: {
"dist": {
"main": "app/bootstrap",
"format": "system",
"defaultExtension": "js"
}
}
Update
Since your index.html
is in the same folder where app
is dist
. Then you don't need dist
in your packages definition.
Your definition should be:
packages: {
"app": {
"main": "bootstrap",
"format": "system",
"defaultExtension": "js"
}
}
And import like:
System.import('app')
Update
I tried to duplicate your setup, and here are the issues I found:
In your backend code:
You are not serving the files inside dist
. The line is commented out. That way, any request to app/*
will be forwarded to index.html
because of your app.get('*', ...)
You can uncomment your original line:
app.use('/dist', express.static('dist'));
or
app.use('/app',express.static('dist/app'))
Depends on which one you do, the packages
object will be different.
I will go with the latter, app.use('/app',express.static('dist/app'))
. It just makes more since to me to hide the dist
from the requests.
Also, check SystemJS module formats
The packages definition will be:
packages: {
"app": {
"main": "bootstrap",
//"format": "system", // this was causing the main issue
format:"register",
"defaultExtension": "js"
}
},
And lastly:
System.import('app')
Update
The last problem was about the line "angular2": "npm:[email protected]"
:
It was caused by the below two lines in server/index.js
:
app.use(express.static('jspm_packages'));
app.use(express.static('node_modules'));
The problem is that all contents inside jspm_packages
and node_modules
will be served directly from the server. So, if you try to access : http://localhost:3000/angular2
it will be served from node_modules
.
If if you try to access : http://localhost:3000/npm/[email protected]
it will be served from jspm_packages
. So, when you have the lines:
paths: {
...
"npm:*": "jspm_packages/npm/*"
},
map:{
`"angular2": "npm:[email protected]"`
}
every request to angular2
will be translated to: jspm_packages/npm/[email protected]
. But It should've been just /npm/[email protected]
.
It worked when you remove "angular2": "npm:[email protected]"
because angular2
now will be served from inside node_modules
.
So the solution is to change your server/index.js
to:
app.use('jspm_packages',express.static('jspm_packages'));
app.use('node_modules',express.static('node_modules'));
Also, the script tag inside the index.html
should be now:
<script src="jspm_packages/npm/[email protected]/bundles/angular2-polyfills.min.js"></script>
<script src="jspm_packages/system.js"></script>
Upvotes: 4
Reputation: 202156
In fact it depends how to transpile your TypeScript files when building your application:
In your case, it seems that you're in the first case, so you could try this:
System.import('path/to/boot');
Note that if your index.html file is located un the dist folder, you need a sub folder at this level for your JS compiled files. This sub folder needs to be configured into your SystemJS in a "packages" entry.
See this question for more details:
Upvotes: 0