我创建了一个与 ASP.NET 集成并由IIS提供服务的Angular2应用程序。此应用程序将由多个客户使用,他们希望能够自定义应用程序的外观以适应其品牌。我正在使用 ASP.NET MVC5框架的某些方面来实现这一点。
该应用程序在大多数情况下都按预期工作,但我有两个利用 cli 的绊脚石,我似乎无法弄清楚。
这是应用程序的基本文件夹结构(还有其他文件和目录,但我排除它们,因为我认为它们与问题无关):
Solution.sln
Web
Controllers
dist
Models
src
Views
Shared
_Layout.cshtml
.angular-cli.json
package.json
Web.config
Global.asax
我对.angular-cli.json
文件所做的唯一相关的更新是我将{ apps: { index: '' } }
值更改为"../Views/Shared/_Layout.cshtml"
而不是默认"index.html"
。
当我从Web
目录中运行ng build
时,应用程序会编译,并且正确的script
标记会按预期放置在_Layout.cshtml
文件中,紧接在结束body
标记之前。
我不确定这些问题是否源于相同的根本原因。我假设他们这样做,这就是为什么我把两者都放在这里,但如果它们似乎是单独的问题,我可以将它们分开。
问题 1如果我多次运行ng build
,它不会按预期删除和替换它在_Layout.cshtml
文件中创建的script
标签,而是继续在结束body
标签之前附加新的脚本标签。因此,如果我在开发模式下运行两次ng build
,我将在文件中两次获得同一组script
标记。
关于我需要更改什么才能从ng build
中恢复预期功能的任何想法?
问题 2现在当我运行ng build --watch
时,构建似乎最终陷入了无限循环。它继续一遍又一遍地打包资产。
关于可能导致无限循环的原因以及如何让ng build --watch
使用此设置正常工作的任何想法?
我对index.html
文件都没有这些问题,但不幸的是,我需要使用_Layout.cshtml
文件作为我的索引文件。我可以创建一个自定义prebuild
npm 任务来清理脚本标签,但似乎我不应该这样做。我还没有找到监视任务问题的解决方法。
更新正如我所怀疑的那样,这与它是一个*.cshtml
文件的事实无关,而是因为apps/index
位置在src文件夹之外。
重现步骤:
npm install @angular/cli
node_modules/.bin/ng new test-custom-index
- 将
test-custom-index/src/index.html
移至test-custom-index/index.html
- 更新
.angular-cli.json
,以便索引属性"index": "../index.html"
而不是"索引":"索引.html"> - 从
test-custom-index
目录中连续运行两次node_modules/.bin/ng build
,您将在index.html
文件中看到重复的脚本条目。 或者运行node_modules/.bin/ng build --watch
,看着它陷入无限循环。
任何帮助将不胜感激!!
我通过将角度索引页面设置为部分并加载到剃须刀布局中来解决此问题。
在 cli 配置中:
"index": "index.cshtml",
但该文件实际上是空白的。然后,在使用所需布局的 razor 文件中:
@section scripts
{
<base href="~/">
@Html.Partial("~/js/dist/index.cshtml")
}
您也可以将该部分直接放入布局中。唯一的问题是,如果index.cshtml
位于您的 View 文件夹之外,您需要让它继承自MvcWebPage
,最简单的方法是将 web.config 文件从您的 View 文件夹复制到一个文件夹中从index.cshtml
文件。
目前,我有一个解决方法,如果其他人遇到同样的问题,我想分享。
我仍然想知道是否有更好的方法来解决这个问题,因为这对我来说似乎有点笨拙。
在与src
目录相同的级别,我创建了一个build
目录。在其中,我有两个文件:
prebuild.js
var fs = require('fs');
var path = require('path');
var inputFilePath = path.join(__dirname, '../Views/Shared/_Layout.cshtml');
var outputFilePath = path.join(__dirname, '../src/_Layout.cshtml');
fs.readFile(inputFilePath, 'utf8', function (err,data) {
if (err) {
return console.log(err);
}
var result = data.replace(/</app-faculty-profile>[sS]*</body>/g, '</app-faculty-profile>nr</body>');
fs.writeFile(outputFilePath, result, 'utf8', function (err) {
if (err) return console.log(err);
});
});
postbuild.js
var fs = require('fs');
var path = require('path');
var inputFilePath = path.join(__dirname, '../dist/_Layout.cshtml');
var outputFilePath = path.join(__dirname, '../Views/Shared/_Layout.cshtml');
fs.readFile(inputFilePath, 'utf8', function (err,data) {
if (err) {
return console.log(err);
}
fs.writeFile(outputFilePath, data, 'utf8', function (err) {
if (err) return console.log(err);
});
});
然后在我的package.json
文件中,我添加了一些脚本:
"ng": "ng",
"prebuild": "node build/prebuild.js",
"build": "ng build",
"postbuild": "node build/postbuild.js",
"watch": "npm run build && ng build --watch"
现在,当我从命令行运行npm run watch
时,它将执行build
脚本。按照惯例,npm 脚本将在执行build
脚本之前运行prebuild
,并在执行postbuild
脚本之后运行。prebuild
脚本从中删除脚本标记,然后将_Layout.cshtml
文件复制到src
目录中。然后,postbuild
脚本将_Layout.cshtml
文件复制回 ASP.NET 期望它所在的位置。完成所有这些操作后,npm 脚本将启动带有--watch
标志的ng build
命令。这迫使角度构建过程在手表实际生效之前执行两次,但这是我迄今为止能够使其工作的唯一方法。
@user917170
唯一的问题是,如果index.cshtml位于外部 您的视图文件夹,您需要使其继承自 MvcWebPage,以及 最简单的方法是从视图中复制 web.config 文件 文件夹到从 index.cshtml 文件向上的文件夹中。
您只需将该行添加到 index.cshtml 中:
@inherits System.Web.Mvc.WebViewPage