Angular 2,Webpack,Express,HMR

我正在使用Webpack和HMR开发我的Angular 2应用程序。 在这个阶段有一个静态的应用程序,不与后端交互。 所有数据都是静态的虚拟数据。

我已经到了开始添加express / node后端的时候了,所以我可以和数据库进行交互,但是我不想失去HMR的function。

是否可以这样设置:

  1. 我可以使用express和jade来从Node服务Angular 2应用程序。
  2. 我对Angular 2应用程序进行了更改,HMR启动并将代码热插入浏览器窗口。

目前我的webpack安装被分成三个文件(dev,prod,common)。 我在下面的开发和通用文件,因为他们是最相关的。

启动命令

webpack-dashboard -- webpack-dev-server --inline --hot --progress --port 8080 

webpack.dev.js

 var webpackMerge = require('webpack-merge'); var commonConfig = require('./webpack.common.js'); var helpers = require('./helpers'); module.exports = webpackMerge(commonConfig, { devtool: 'cheap-module-eval-source-map', output: { path: helpers.root('dist'), publicPath: 'http://localhost:8080/', filename: '[name].js', chunkFilename: '[id].chunk.js' }, devServer: { historyApiFallback: true, stats: 'minimal' } }); 

webpack.common.js

 var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); var helpers = require('./helpers'); module.exports = { entry: { 'styles': './src/styles/main.scss', 'polyfills': './src/polyfills.ts', 'vendor': './src/vendor.ts', 'app': './src/main.ts' }, resolve: { extensions: ['', '.js', '.ts', 'scss'] }, module: { loaders: [ { test: /\.ts$/, loaders: ['ts', 'angular2-template-loader'] }, { test: /\.html$/, loader: 'html' }, { test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/, loader: 'file?name=assets/[name].[hash].[ext]' } , { test: /\.scss$/, loaders: ['style', 'css', 'sass'] } ] }, plugins: [ new webpack.optimize.CommonsChunkPlugin({ name: ['app', 'vendor', 'polyfills', 'styles'] }), new HtmlWebpackPlugin({ template: 'src/index.html' }) ] }; 

的package.json

 { "name": "Raceloop", "version": "1.0.0", "scripts": { "start": "webpack-dashboard -- webpack-dev-server --inline --hot --progress --port 8080", "build": "rimraf dist && webpack --config config/webpack.prod.js --progress --profile --bail", "postinstall": "typings install", "typings": "typings" }, "dependencies": { "@angular/common": "2.0.0-rc.6", "@angular/compiler": "2.0.0-rc.6", "@angular/core": "2.0.0-rc.6", "@angular/forms": "2.0.0-rc.6", "@angular/http": "2.0.0-rc.6", "@angular/platform-browser": "2.0.0-rc.6", "@angular/platform-browser-dynamic": "2.0.0-rc.6", "@angular/router": "^3.0.0-rc.2", "@angular2-material/button": "^2.0.0-alpha.8-1", "@angular2-material/button-toggle": "^2.0.0-alpha.8-1", "@angular2-material/card": "^2.0.0-alpha.8-1", "@angular2-material/checkbox": "^2.0.0-alpha.8-1", "@angular2-material/core": "^2.0.0-alpha.8-1", "@angular2-material/grid-list": "^2.0.0-alpha.8-1", "@angular2-material/icon": "^2.0.0-alpha.8-1", "@angular2-material/input": "^2.0.0-alpha.8-1", "@angular2-material/list": "^2.0.0-alpha.8-1", "@angular2-material/menu": "^2.0.0-alpha.8-1", "@angular2-material/progress-bar": "^2.0.0-alpha.8-1", "@angular2-material/progress-circle": "^2.0.0-alpha.8-1", "@angular2-material/radio": "^2.0.0-alpha.8-1", "@angular2-material/sidenav": "^2.0.0-alpha.8-1", "@angular2-material/slide-toggle": "^2.0.0-alpha.8-1", "@angular2-material/slider": "^2.0.0-alpha.8-1", "@angular2-material/tabs": "^2.0.0-alpha.8-1", "@angular2-material/toolbar": "^2.0.0-alpha.8-1", "@angular2-material/tooltip": "^2.0.0-alpha.8-1", "@ngrx/core": "1.1.0", "@ngrx/effects": "2.0.0-beta.3", "@ngrx/store": "2.1.2", "@types/hammerjs": "^2.0.32", "angular2-apollo": "^0.4.5", "apollo-client": "^0.4.14", "core-js": "2.4.1", "hammerjs": "2.0.8", "immutable": "3.8.1", "moment": "^2.15.0", "reflect-metadata": "0.1.8", "rxjs": "5.0.0-beta.11", "typed-immutable-record": "0.0.5", "zone.js": "0.6.17" }, "devDependencies": { "angular2-template-loader": "0.5.0", "codelyzer": "0.0.28", "css-loader": "0.25.0", "extract-text-webpack-plugin": "1.0.1", "file-loader": "0.9.0", "html-loader": "0.4.3", "html-webpack-plugin": "2.22.0", "json-loader": "0.5.4", "node-sass": "^3.9.3", "null-loader": "0.1.1", "raw-loader": "0.5.1", "rimraf": "2.5.4", "sass-loader": "^4.0.2", "style-loader": "0.13.1", "ts-loader": "0.8.2", "tslint": "^3.15.1", "typescript": "2.1.0-dev.20160903", "typings": "1.3.3", "webpack": "2.1.0-beta.21", "webpack-dashboard": "0.1.8", "webpack-dev-server": "2.1.0-beta.3", "webpack-merge": "0.14.1", "worker-loader": "0.7.1" } } 

使用webpack-hot-middleware插件实际上非常简单。

webpack.express.config.js

 var webpack = require('webpack'); var HtmlWebpackPlugin = require('html-webpack-plugin'); var ExtractTextPlugin = require('extract-text-webpack-plugin'); var helpers = require('./helpers'); var hotMiddlewareScript = 'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000&reload=true'; module.exports = { context: __dirname, // Include the hot middleware with each entry point entry: { // Add the client which connects to our middleware 'styles': ['../src/styles/main.scss', hotMiddlewareScript], 'polyfills': ['../src/app/polyfills.ts', hotMiddlewareScript], 'vendor': ['../src/app/vendor.ts', hotMiddlewareScript], 'manager': ['../src/app/main-manager.ts', hotMiddlewareScript], 'authenticator': ['../src/app/main-authenticator.ts', hotMiddlewareScript] }, output: { path: __dirname, publicPath: '/', filename: '[name].js', chunkFilename: '[id].chunk.js' }, resolve: { extensions: ['', '.js', '.ts', 'scss'] }, module: { loaders: [ { test: /\.ts$/, loaders: ['ts', 'angular2-template-loader'] }, { test: /\.html$/, loader: 'html' }, { test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/, loader: 'file?name=assets/[name].[hash].[ext]' }, { test: /\.scss$/, loaders: ['style', 'css', 'sass'] } ] }, devtool: 'cheap-module-eval-source-map', plugins: [ new webpack.optimize.CommonsChunkPlugin({ name: ['mainapp', 'vendor', 'polyfills', 'styles'] }), //new HtmlWebpackPlugin({ // template: '../src/index.html' //}), new webpack.optimize.OccurrenceOrderPlugin(), new webpack.HotModuleReplacementPlugin(), new webpack.NoErrorsPlugin() ], }; 

Server.Js

 /// <reference path="../typings/index.d.ts" /> let http = require('http'); let express = require('express'); let morgan = require('morgan'); let app = express(); app.use(morgan('short')); app.set('view engine', 'pug'); // ************************************ // This is the real meat of the example // ************************************ (function() { let webpack = require('webpack'); let webpackDevMiddleWare = require('webpack-dev-middleware'); let webpackHotMiddleWare = require('webpack-hot-middleware'); // Step 1: Create & configure a webpack compiler let webpackConfig = require(process.env.WEBPACK_CONFIG ? process.env.WEBPACK_CONFIG : '../webpack.config'); let compiler = webpack(webpackConfig); // Step 2: Attach the dev middleware to the compiler & the server app.use(webpackDevMiddleWare(compiler, { noInfo: true, publicPath: webpackConfig.output.publicPath })); // Step 3: Attach the hot middleware to the compiler & the server app.use(webpackHotMiddleWare(compiler, { log: console.log, path: '/__webpack_hmr', heartbeat: 10 * 1000 })); })(); // Do anything you like with the rest of your express application. app.get("/", function(req, res) { res.sendFile(__dirname + '/app/index-manager.html'); }); app.get("/multientry", function(req, res) { res.sendFile(__dirname + '/app/index-multientry.html'); }); if (require.main === module) { let server = http.createServer(app); server.listen(process.env.PORT || 4200, function() { console.log("Listening on %j", server.address()); }); }