node.js 在开发环境中使用 Angular CLI 连接 express.js

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42895585/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 18:05:41  来源:igfitidea点击:

Hooking up express.js with Angular CLI in dev environment

node.jsangularexpressangular-cli

提问by etayluz

I found a great tutorial that explains how to setup express.js with Angular CLI, but in this tutorial the angular app is compiled into a production dist folder: https://scotch.io/tutorials/mean-app-with-angular-2-and-the-angular-cli

我找到了一个很好的教程,它解释了如何使用 Angular CLI 设置 express.js,但在本教程中,angular 应用程序被编译到一个生产 dist 文件夹中:https: //scotch.io/tutorials/mean-app-with-angular- 2-and-the-angular-cli

How do I integrate express.js with Angular CLI, but I want the express.js to work with the development version of the Angular app and I want the nodemon to restart if I make changes to either the express OR angular app.

如何将 express.js 与 Angular CLI 集成,但我希望 express.js 与 Angular 应用程序的开发版本一起使用,并且如果我对 express 或 angular 应用程序进行更改,我希望 nodemon 重新启动。

Have been spending over eight hours trying to get this working. Thanks!

已经花了超过八个小时试图让这个工作。谢谢!

I don't want to run 'ng build' every time I make a change to the Angular app (this takes too long) - I want instant reloading whenever I save a change to my angular app (as if I was running 'ng serve') or express app.

我不想在每次对 Angular 应用程序进行更改时都运行“ng build”(这需要很长时间)-每当我保存对我的 Angular 应用程序的更改时,我都希望立即重新加载(就像我正在运行 'ng serve 一样) ') 或快递应用程序。

I found a tutorial where you hook up Angular 2 QuickStart with Express, it works but I'm looking to use Angular CLI.

我找到了一个教程,您可以在其中将 Angular 2 QuickStart 与 Express 连接起来,它可以工作,但我希望使用 Angular CLI。

I understand that the Angular CLI uses WebPack whereas the QuickStart uses System.js

我知道 Angular CLI 使用 WebPack 而 QuickStart 使用 System.js

回答by etayluz

NEW ANSWER

新答案

My experience of 15 hours has taught me that trying to serve an Angular app with Express during development is NOT a good idea. The proper way is to run Angular and Express as two different apps on two different ports. Angular will be served on port 4200 and Express on port 3000 as usual. Then configure a proxy for API calls to Express app.

我 15 小时的经验告诉我,在开发过程中尝试使用 Express 服务 Angular 应用程序并不是一个好主意。正确的方法是在两个不同的端口上将 Angular 和 Express 作为两个不同的应用程序运行。Angular 将像往常一样在端口 4200 和 Express 端口 3000 上提供服务。然后为 Express 应用程序的 API 调用配置代理。

Add proxy.config.json to root of Angular project:

将 proxy.config.json 添加到 Angular 项目的根目录:

{
  "/api/*":{
    "target":"http://localhost:3000",
    "secure":false,
    "logLevel":"debug"
  }
}

Open up a new terminal tab and run this command to start Express app:

打开一个新的终端选项卡并运行此命令以启动 Express 应用程序:

nodemon [YOUR_EXPRESS_APP.js] --watch server

nodemon [YOUR_EXPRESS_APP.js] --watch server

(YOUR_EXPRESS_APP.js is usually named server.js or app.js. server is a directory where you keep all your Express app files)

(YOUR_EXPRESS_APP.js 通常被命名为 server.js 或 app.js。server 是您保存所有 Express 应用程序文件的目录)

Open up a second terminal tab and run this command to start Angular app:

打开第二个终端选项卡并运行此命令以启动 Angular 应用程序:

ng serve --proxy-config proxy.config.json

ng serve --proxy-config proxy.config.json

This will ensure that Angular app is rebuilt and browser reloaded when a change is made to any Angular app file. Similarly, Express server will restart when a change is made to any Express app files.

这将确保在对任何 Angular 应用程序文件进行更改时重新构建 Angular 应用程序并重新加载浏览器。同样,当对任何 Express 应用程序文件进行更改时,Express 服务器将重新启动。

Your Angular app is here: http://localhost:4200/

你的 Angular 应用程序在这里:http://localhost:4200/

Watch this video to see how to configure a proxy for your API calls with Angular CLI

观看此视频以了解如何使用 Angular CLI 为 API 调用配置代理

NOTE: this setup only applies for development environment. In production, you will want to run ng buildand place the Angular app inside a dist directory to be served up by Express. In production, there is only ONE app running - an Express app serving up your Angular app.

注意:此设置仅适用于开发环境。在生产环境中,您需要运行ng buildAngular 应用程序并将其放置在由 Express 提供的 dist 目录中。在生产环境中,只有一个应用程序在运行——一个 Express 应用程序为您的 Angular 应用程序提供服务。

PREVIOUS ANSWER

以前的回答

Using input from @echonax I came up with this solution which is quite fast:

使用来自@echonax 的输入,我想出了这个非常快的解决方案:

  • Add Express to Angular 2 app (built with Angular CLI) as in this tutorial
  • Run this in terminal:
  • 将 Express 添加到 Angular 2 应用程序(使用 Angular CLI 构建),如本教程所示
  • 在终端中运行:

ng build -w & nodemon server.js --watch dist --watch server

ng build -w & nodemon server.js --watch dist --watch server

This will rebuild the Angular app into the dist folder, and the node server will restart each time that happens. However, there is NOT automatic browser refresh with this setup :(

这会将 Angular 应用程序重建到 dist 文件夹中,并且每次发生这种情况时节点服务器都会重新启动。但是,此设置不会自动刷新浏览器:(

More on that here:

更多关于这里:

https://github.com/jprichardson/reload

https://github.com/jprichardson/reload

回答by yusuf

"etayluz" solutionis very good. But I want to add an additional option for NEW ANSWERto not opening two times terminal.

“etayluz”解决方案非常好。但我想为NEW ANSWER添加一个附加选项,以不打开两次终端。

Firstly you have to install concurrently package (https://www.npmjs.com/package/concurrently);

首先你必须同时安装包(https://www.npmjs.com/package/concurrently);

npm install concurrently --save 

Then you could add below codes into your package.json file.

然后您可以将以下代码添加到您的 package.json 文件中。

"start": "concurrently \"npm run serve-api\" \"npm run serve\"",
"serve": "ng serve --port 3333 --proxy-config proxy.config.json", // You could add --port for changing port
"serve-api": "nodemon [YOUR_EXPRESS_APP.js] --watch server",

npm startis enough for running your project.

npm start足以运行您的项目。

回答by eko

Using angular-cli, the ng buildor ng build --prodcommand will give you bundled up files along with an index.html. Make your app.js(node/express) target this file.

使用 angular-cli,ng buildorng build --prod命令将为您提供捆绑的文件以及index.html. 使您的app.js(节点/快递)以此文件为目标。

Example:

例子:

app.use( express.static(__dirname + '/src' ) ); //<- it will automatically search for index.html under src folder.

回答by Clark Brent

Longer Explanation

更长的解释

I've spent a decent amount of time figuring out how to do this in my own development environments. The best I've come up with is a two fold implementation that combines a lot of echonax's, squirrelsareduck's, and Max's solution, but taking advantage of built in Angular CLI strategies to watch frontend/Angular changes, and using nodemon to watch the backend/Express changes. The short of it is you end up running two processes (ng build and nodemon) to get your development environment up and running, but it automatically rebuilds and runs everything under one Express web server.

我花了相当多的时间来弄清楚如何在我自己的开发环境中做到这一点。我想出的最好的是一个双重实现,它结合了很多 echonax、squirrelsereduck 和 Max 的解决方案,但利用内置的 Angular CLI 策略来观察前端/Angular 的变化,并使用 nodemon 来观察后端/表达变化。简而言之,您最终会运行两个进程(ng build 和 nodemon)来启动和运行您的开发环境,但它会自动重建并在一个 Express Web 服务器下运行所有​​内容。

The first process you will need to run will be to build the Angular distfolder, and watch any changes made to the Angular frontend. Luckily for us, Angular CLI can do this natively (Tested on Angular CLI >= 1.5) with the following command:

您需要运行的第一个过程是构建 Angular dist文件夹,并观察对 Angular 前端所做的任何更改。对我们来说幸运的是,Angular CLI 可以使用以下命令本地执行此操作(在 Angular CLI >= 1.5 上测试):

ng build --watch

You'll need to leave this running in the background, but this will watch for any changes made in the Angular code, and rebuild the bundles on the fly.

您需要让它在后台运行,但这将监视 Angular 代码中所做的任何更改,并即时重建包。

The second process involves using nodemon to run your Express server, and may take a little bit more setup and planning depending on how extensive your backend/Express setup is. Just make sure Express is pointing to your index file in the distfolder. The big advantage here is that you can add all of this into a Gulpfile with gulp-nodemon to do even more sequential tasks after running nodemon to watch the backend/Express such as linting your backend, running tests parallel to your builds, minifying your backend, or whatever else you can think of to use Gulp for. Use npmor Yarnto add and install nodemon to your project's dependencies, and then run the following to start your Express server:

第二个过程涉及使用 nodemon 运行您的 Express 服务器,并且可能需要更多的设置和规划,具体取决于您的后端/Express 设置的广泛程度。只需确保 Express 指向dist文件夹中的索引文件。这里的最大优势是,您可以使用 gulp-nodemon 将所有这些添加到 Gulpfile 中,以便在运行 nodemon 以观察后端/Express 后执行更多顺序任务,例如对后端进行 linting、与构建并行运行测试、缩小后端,或者任何你能想到的使用 Gulp 的东西。使用npmYarn将 nodemon 添加并安装到项目的依赖项中,然后运行以下命令启动 Express 服务器:

nodemon app.js

Replace app.jswith whatever file you're using to build your Express backend, and it shouldnow rebuild anytime there are changes made to your backend.

app.js替换为您用于构建 Express 后端的任何文件,它现在应该在后端发生更改时重新构建。

tldr;

tldr;

Run two separate processes in the background to start your development environment. First run:

在后台运行两个单独的进程以启动您的开发环境。第一次运行:

ng build --watch

Second, add nodemon to your project dependencies, and run the following command in the background where app.jsis replaced with whatever your Express file is called:

其次,将 nodemon 添加到您的项目依赖项中,并在后台运行以下命令,其中app.js被替换为您调用的任何 Express 文件:

nodemon app.js

Bonus

奖金

Since you asked how to automatically reload the browser, your best bet will be to take advantage of a browser plugin called LiveReload. Since we're already going to be using nodemon to watch our backend, you might seriously consider using Gulp if you're not already to run both nodemon and LiveReload as two tasks. Your best bet for implementing LiveReload into Gulp is to use the gulp-refresh plugin as this is an updated version of the gulp-livereload plugin. You'll end up with a Gulpfile resembling this:

由于您询问了如何自动重新加载浏览器,因此最好的办法是利用名为 LiveReload 的浏览器插件。由于我们已经将使用 nodemon 来监视我们的后端,如果您还没有将 nodemon 和 LiveReload 作为两个任务运行,您可能会认真考虑使用 Gulp。在 Gulp 中实现 LiveReload 的最佳选择是使用 gulp-refresh 插件,因为这是 gulp-livereload 插件的更新版本。你最终会得到一个类似这样的 Gulpfile:

const defaultAssets = require('./config/assets/default'),
  gulp = require('gulp'),
  gulpLoadPlugins = require('gulp-load-plugins'),
  runSequence = require('run-sequence'),
  plugins = gulpLoadPlugins(),
  semver = require('semver');
  
// I store the locations of my backend js files in a config file, so 
// that I can call them later on. ie; defaultAssets
gulp.task('nodemon', function () {
  // Node.js v7 and newer use different debug argument
  const debugArgument = semver.satisfies(process.versions.node, '>=7.0.0') ? '--inspect' : '--debug';

  return plugins.nodemon({
    script: 'app.js',
    nodeArgs: [debugArgument],
    ext: 'js,html',
    verbose: true,
    watch: defaultAssets.server.allJS
  });
});

// Watch Files For Changes
gulp.task('watch', function () {
  // Start LiveReload
  plugins.refresh.listen();

  // Watch backend for changes
  gulp.watch(defaultAssets.server.allJS).on('change', plugins.refresh.changed);
  // Watch frontend dist folder for changes
  gulp.watch('./dist').on('change', plugins.refresh.changed);
});
  
  
gulp.task('default', function (done) {
  runSequence(['nodemon', 'watch'], done);
});

Now you just run the gulpcommand in place of nodemon app.jsto start your Express server.

现在你只要运行一饮而尽代替命令nodemon app.js启动您的Express服务器。

回答by squirrelsareduck

I was wondering this also. The Udemy course on the MEAN stack by Max Schwarzmüller has a sample code in there for integrating Express and Angular. In that sample code's package.json file, use uses the scripts.build property to give webpack a command which watches the angular files and updates accordingly. I don't want to copy his code here but that's the general idea. The rest will require some discovery work.

我也想知道这个。Max Schwarzmüller 在 MEAN 堆栈上的 Udemy 课程中有一个示例代码,用于集成 Express 和 Angular。在该示例代码的 package.json 文件中, use 使用 scripts.build 属性为 webpack 提供一个命令,该命令监视 angular 文件并相应地更新。我不想在这里复制他的代码,但这是总体思路。其余的将需要一些发现工作。

In the readme file, he suggests running npm run build which runs webpack, and then in a new terminal running npm start for the node server. So in theory, this runs two programs like you suggested in your version of the answer. But, it does a more "scripted"/pre-defined way of starting the Angular build process, instead of navigating to the Angular sub-directory and typing ng build --watch in there, and starting the Express app separately.

在自述文件中,他建议运行运行 webpack 的 npm run build,然后在一个新的终端中为节点服务器运行 npm start。所以理论上,这会运行两个程序,就像你在你的答案版本中建议的那样。但是,它采用了一种更“脚本化”/预定义的方式来启动 Angular 构建过程,而不是导航到 Angular 子目录并在其中键入 ng build --watch,然后单独启动 Express 应用程序。

回答by Hymanchen

May be you can add a dependency called 'concurrently', or (npm-run-all, parallelshell).

也许您可以添加一个名为“并发”的依赖项,或者(npm-run-all, parallelshell)。

npm i concurrently --save-dev

then edit the package.json like this: `

然后像这样编辑 package.json:`

"scripts": {
        "dev": "concurrently \"ng build -w\"  \"cross-env NODE_ENV=development node .\" "
    }

` this may be work.

`这可能是工作。

References:

参考:

concurrentlyexample: https://stackoverflow.com/a/30950298/7421101,

并发示例:https: //stackoverflow.com/a/30950298/7421101

npm-run-allexample: https://stackoverflow.com/a/38213212/7421101,

npm-run-all示例:https: //stackoverflow.com/a/38213212/7421101

parallelshellexample: https://stackoverflow.com/a/42373547/7421101.

并行外壳示例:https: //stackoverflow.com/a/42373547/7421101