【问题标题】:How to serve an angular2 app in a node.js server如何在 node.js 服务器中提供 angular2 应用程序
【发布时间】:2017-02-12 05:16:30
【问题描述】:

我正在使用 Angular2 构建一个 Web 应用程序,以创建我正在使用 Angular2 CLI webpack 的项目。 Angular2 应用程序也使用其他外部包(例如:Firebase)。除此之外,我需要创建一个在 node.js 上运行的 REST API

如何使用 node.js 服务器同时为 Angular2 应用程序和 REST API 提供服务

【问题讨论】:

  • 您可以使用 Node.js 创建 restful 服务。并从 angular2 应用程序调用该 url。
  • @JohnSiu 的答案现在手动输入浏览器 url(默认路由)

标签: node.js angular angular2-cli


【解决方案1】:
  1. 使用ng build 将您的应用构建到构建目录中。
  2. 创建 nodejs 应用以将构建目录作为静态内容提供服务,然后为 api 创建路由。

以下是使用 express 的 nodejs 应用程序示例,它将为 Angular2 应用程序提供服务:

/*
Put content of angular2 build into 'public' folder.
*/
const html = __dirname + '/public';

const port = 4000;
const apiUrl = '/api';

// Express
const bodyParser = require('body-parser');
const compression = require('compression');
const express = require('express');
var app = express();

app
    .use(compression())
    .use(bodyParser.json())
    // Static content
    .use(express.static(html))
    // Default route
    .use(function(req, res) {
      res.sendFile(html + 'index.html');
    })
    // Start server
    .listen(port, function () {
        console.log('Port: ' + port);
        console.log('Html: ' + html);
    });

// continue with api code below ...

【讨论】:

  • 是的,可能的解决方案是将构建目录中的 index.html 呈现为静态内容。如果有路由它 angular2 应用程序,它可以通过页面中的链接导航,但不能通过更改浏览器 url
  • @yohan 可以通过在 nodejs 应用程序中添加指向索引页面的自定义静态路由来处理 angular2 路由。
  • @yohan 我认为 ng2 cli 生成项目时会自动添加基本 href。
  • 我们可以在构建时通过ng build --base-href /myUrl/指定。即使已更正,我们也无法通过更改浏览器中的 url 来导航。
  • @Yohan 要允许支持浏览器 url,只需添加 .use(function(req, res) { res.sendFile(html + 'index.html'); })
【解决方案2】:

没有一个答案适合我。如果它有效,Angular 路由在重新加载时不起作用。
所以这就是我解决它的方法。 Angular 路由即使在整个页面重新加载时也能正常工作。

function getRoot(request, response) {
   response.sendFile(path.resolve('./public/angular/index.html'));
}

function getUndefined(request, response) {
   response.sendFile(path.resolve('./public/angular/index.html'));
}

// Note the dot at the beginning of the path
app.use(express.static('./public/angular'));

app.get('/', getRoot);
app.get('/*', getUndefined);

不需要角度 base-href 重写!只需使用ng buildng build --prod

【讨论】:

  • 下次请评论完整代码或提供完整代码结构的在线链接
  • @Maddy 没有必要在 node.js 特定问题上发布完整的堆栈示例,尤其是在这种简单的情况下。基本节点设置可以从文档中获得。
【解决方案3】:

这是正在运行的完整后端代码

const express = require('express');
var app = express();
var port = 9999;

function getRoot(request, response) {
    response.sendFile(path.resolve('./public/angular/index.html'));
 }

 function getUndefined(request, response) {
     response.sendFile(path.resolve('./public/angular/index.html'));
 }


 app.use(express.static('./public/angular'));

 app.get('/', getRoot);
 app.get('/*', getUndefined);

 // Start server
 app.listen(port, function () {
    console.log('server running at port: ' + port);
}); 

【讨论】:

    【解决方案4】:

    基于@NTN-JAVA 的回答,这是一个从 NodeJS 服务器提供 Angular 应用程序的解决方案。

    这是从头开始的摘要:

    1. npm install -g @angular/cli

    2. ng new PROJECT_NAME

    3. cd PROJECT_NAME

    4. npm install nodemon express cookie-parser body-parser morgan method-override --save

    5.创建app.js:

    var express = require('express');
    var app = express();
    var morgan = require('morgan');
    var bodyParser = require('body-parser');
    var port = process.env.PORT || 3000;
    var methodOverride = require('method-override'); // simulate DELETE and PUT (express4)
    var router = express.Router();
    
    console.log('——————————- Run on port '+ port);
    
    /****************************** Router ***************************/
    router.get('*', function(req, res){
        res.sendFile('index.html', { root: __dirname + '/' });
    });
    
    /****************************** /Router ***************************/
    
    //app.use(morgan('dev')); // log every request to the console
    app.use(express.static(__dirname + '/')); // Static (public) folder
    
    app.use(bodyParser.urlencoded({extended:true}));// get information from html forms
    app.use(bodyParser.json());
    app.use(bodyParser.json({ type: 'application/vnd.api+json' }));
    app.use(methodOverride());
    app.use('/', router); // app.use('/parent', router); call all from localhost:port/parent/*
    
    app.listen(port);
    
    1. 编辑package.json文件:
    {
       ...
        "scripts": {
            "start": "ng build; cp app.js dist/app.js; node dist/app.js",
        }
       ...
    }
    
    1. 运行npm start

    此答案还提供了一种从浏览器调用直接 URL 并在您的应用中正确解析它们的解决方案。

    【讨论】:

    • 效果很好!非常感谢!只需要更改开始于package.json -> "scripts": {"start": "ng build && cp app.js dist/app.js && node dist/app.js"}Windows 注释 "scripts": {"start": "ng build && 复制 app.js dist/app.js && node dist/app.js"}
    【解决方案5】:

    按照Express node server with Angular 2 CLI 文档通过 Node.js 服务器为您的应用程序提供服务。该应用程序通过 Node.js 和 REST 完整 API 提供服务。您可以根据自己的要求设计此 REST。

    例如

    使用http://localhost:5000/app服务应用程序

    app.get('/app/*', function(req, res) {
        res.sendFile(path.join(__dirname, 'index.html'))
    });
    

    使用 http://localhost:5000/rest/contacts 提供来自 REST 调用的数据

    app.get('/rest/user', function(req, res) {
        res.send({
            "id": 2,
            "name": "Jhon",
        })
    });
    

    【讨论】:

    • 这也是 angular2 应用作为静态内容服务,问题是,我们无法通过更改 url 在应用路由中导航
    • 你可以通过 url 导航,因为整个应用程序是由 index.html 加载的。检查 angular-cli 1.0.0.19
    【解决方案6】:

    第 1 步:为了获取静态内容,请在您的 Angular 应用目录中运行此命令 -

    ng 构建 --prod

    第二步:第一步会在你的当前目录下创建一个dist文件夹,将dist文件夹中的所有文件移动到public文件夹您的节点应用程序的 -

    第 3 步:创建节点服务器。 App.js -

    var path = require('path');
    var express = require('express');
    var cookieParser = require('cookie-parser');
    var cookieParser = require('cookie-parser');
    
    const allowedExt = [
        '.js',
        '.ico',
        '.css',
        '.png',
        '.jpg',
        '.woff2',
        '.woff',
        '.ttf',
        '.svg',
    ];
    
    var app = express();
    app.use(cookieParser());
    
    function getAngularApp(request, response) {
      response.sendFile(path.resolve('./public/index.html'));
    }
    
    function defaultHandler(request, response) {
      if (allowedExt.filter(ext => req.url.indexOf(ext) > 0).length > 0) {
        response.sendFile(path.resolve(`public/${req.url}`));
      } else {
        response.sendFile(path.resolve('./public/index.html'));
      }
    }
    
    app.use(express.json());
    app.use(express.urlencoded({ extended: false }));
    app.use(cookieParser());
    app.use(express.static(path.join(__dirname, 'public')));
    
    app.get('/', getAngularApp);
    app.get('/*', defaultHandler);
    
    // error handler
    app.use(function(err, req, res, next) {
      // set locals, only providing error in development
      res.locals.message = err.message;
      res.locals.error = req.app.get('env') === 'development' ? err : {};
      // render the error page
      res.status(err.status || 500);
      res.render('error');
    });
    
    module.exports = app;
    

    【讨论】:

      猜你喜欢
      • 2012-08-14
      • 1970-01-01
      • 2011-09-03
      • 1970-01-01
      • 2011-01-20
      • 2021-11-24
      • 2019-02-16
      • 1970-01-01
      • 2018-10-30
      相关资源
      最近更新 更多