I'm trying to set up a webpack-based flow for an Angular2 app with a node backend server. After many hours banging my head against it, I've managed to get the client to build happily, but I can not figure out how to now integrate my server build. My server uses generators, so must target ES6, and it needs to point to a different typings file (main.d.ts instead of browser.d.ts)..
My source tree looks like;
/
-- client/
-- -- <all my angular2 bits> (*.ts)
-- server/
-- -- <all my node/express bits> (*.ts)
-- webpack.config.js
-- typings/
-- -- browser.d.ts
-- -- main.d.ts
I thought perhaps just a tsconfig.json in the client and server folders would work, but no luck there. I also can't find a way to get html-webpack-plugin to ignore my server bundle and not inject it into index.html. My current tsconfig and webpack are below, but has anyone succeeded in getting webpack to bundle a setup like this? Any pointers would be much appreciated.
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"declaration": false,
"removeComments": true,
"noEmitHelpers": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true
},
"files": [
"typings/browser.d.ts",
"client/app.ts",
"client/bootstrap.ts",
"client/polyfills.ts"
]
}
and my webpack.config.js;
var Webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var Path = require('path');
module.exports = {
entry: {
'polyfills': Path.join(__dirname, 'client', 'polyfills.ts'),
'client': Path.join(__dirname, 'client', 'bootstrap.ts')
},
output: {
path: Path.join(__dirname, 'dist'),
filename: '[name].bundle.js'
},
resolve: {
extensions: ['', '.js', '.json', '.ts']
},
module: {
loaders: [
{
test: /\.ts$/,
loader: 'ts-loader',
query: {
ignoreDiagnostics: [
2403, // 2403 -> Subsequent variable declarations
2300, // 2300 -> Duplicate identifier
2374, // 2374 -> Duplicate number index signature
2375, // 2375 -> Duplicate string index signature
]
}
},
{ test: /\.json$/, loader: 'raw' },
{ test: /\.html$/, loader: 'raw' },
{ test: /\.css$/, loader: 'raw!postcss' },
{ test: /\.less$/, loSWE: 'raw!postcss!less' }
]
},
plugins: [
new HtmlWebpackPlugin({ template: 'client/index.html', filename: 'index.html' }),
new Webpack.optimize.CommonsChunkPlugin('common', 'common.bundle.js')
]
};
It uses a library called SockJS to emulate a web socket. The Node.js server listens to when files were changed, and triggers events to react accordingly. Webpack dev server is also a separate package that needs to get install via NPM.
Create Webpack server config Open up your webpack.config.js and duplicate your existing client config and name it “server”. We are going to keep both the client and the server config in the file webpack.config.js .
Under the hood, Webpack dev server is a mini Node.js Express server. It uses a library called SockJS to emulate a web socket. The Node.js server listens to when files were changed, and triggers events to react accordingly.
npm start will run the command client webpack-dev-server and tell it to look for the Webpack config. Go ahead and run npm install to install these dependencies. The next step is to work on the webpack config file. In the root of the project I will create a file named webpack.config.js.
Personally, I tend to write my server side code in plain JS (with most of ES2015 available now in Node) and my Angular 2 app in Typescript, so this issue doesn't come up. However, you can get this to work with Webpack.
First, you should have two separate Webpack configs: one for your client-side code and one for the server side. It might be possible to do it with one config, but even if it were, it would likely be more trouble than it's worth. Make sure to set target: 'node'
in your server-side config (target: 'web'
is set automatically for the client side). And make sure you set an entry
point for your server-side files (I don't see one above, but you will ultimately have this in a separate config anyway).
Second, you need to have multiple tsconfig files. By default, ts-loader
will look for tsconfig.json
in your root directory. However, you can tell specify another file by setting configFileName: 'path/to/tsconfig'
in the options object or query string/object.
This may lead to another problem however. Your IDE will also look for your tsconfig.json
file in your root directory. If you have two separate files, you will need some way to tell your IDE which one to use for any given file. The solution to this will depend on your IDE. Personally, I use Atom with atom-typescript
, which is fantastic, but it looks like the multiple tsconfig files thing is still being worked on. Thankfully I have never had to worry about this problem.
As for the html-webpack-plugin
issue, you won't have to worry about it since you won't include the plugin in your server-side config. However, just for reference, you can pass excludeChunks: ['someChunkName']
to omit certain chunks from being included in the script tags.
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