Visual Studio 2017 年在 MVC 应用程序上使用 SystemJs 和 Webpack
Using SystemJs and Webpack on an MVC application in Visual Studio 2017
我正在使用 Visual Studio 2017 开发托管在 MVC 应用程序 (.Net 4.6) 中的 Angular 4.1 SPA 应用程序。我使用 @angular/cli 创建了 Angular 部分,然后将其合并到现有的 MVC 应用程序中。它的结构如 CandorDeveloper 文章 (http://candordeveloper.com/2017/04/12/how-to-use-angular-cli-with-visual-studio-2017/) 中所述。
这一切都很好,但由于@angular/cli 使用 Webpack,它非常慢。对 Html、typescript 或 css 的任何更改都需要大约 4 分钟的构建。我以前有一个设置相同但没有使用 @angular/cli 或 Webpack 的应用程序。它仍然是一个 Visual Studio 2017 MVC 应用程序(.Net 4.6)托管一个 Angular 4.1 SPA 应用程序,但它使用了 SystemJs。它的构建速度非常快,我在 VS2017 中拥有与任何 .net Web 应用程序相同的出色调试体验。因此,我想我会尝试同时使用 SystemJs 和 Webpack。
我的想法是在 VS2017 "Debug" 模式下使用 SystemJs 构建应用程序以获得速度和便利性,然后使用 Webpack for "Release" 模式构建生产版本并能够使用 AOT .为了尝试实现这一点,我将以下内容放入我的 _Layout.cshtml 文件中:
@if(!HttpContext.Current.IsDebuggingEnabled)
{
<script type="text/javascript" src="~/Scripts/NgApp/inline.bundle.js"></script>
<script type="text/javascript" src="~/Scripts/NgApp/polyfills.bundle.js"></script>
<script type="text/javascript" src="~/Scripts/NgApp/styles.bundle.js"></script>
<script type="text/javascript" src="~/Scripts/NgApp/vendor.bundle.js"></script>
<script type="text/javascript" src="~/Scripts/NgApp/main.bundle.js"></script>
}
else
{
<!-- 1. Load libraries -->
<!-- Polyfill(s) for older browsers -->
<script src="~/MyAppCli/node_modules/core-js/client/shim.min.js"></script>
<script src="~/MyAppCli/node_modules/zone.js/dist/zone.js"></script>
<script src="~/MyAppCli/node_modules/systemjs/dist/system.src.js"></script>
<script src="~/MyAppCli/src/systemjs.config.js"></script>
<script>
System.import('src/main.js')
.catch(function (err) { console.error(err); });
</script>
}
我在项目的预构建事件中添加了:
if $(ConfigurationName) == Release (
echo "cd $(SolutionDir)MyApp\MyAppCli" &&^
cd "$(SolutionDir)MyApp\MyAppCli" &&^
echo "building v" &&^
npm run build
)
然后我将 systemjs 添加到 package.json 文件的 devDependencies 并创建了一个合适的 systemjs.config.js 文件。
我的systemjs.config.js:
(function (global)
{
System.config({
paths: {
// paths serve as alias
'npm:': MyAppCli/node_modules/'
},
// map tells the System loader where to look for things
map: {
// our app is within the app folder
'app': 'src',
// angular bundles
'@angular/animations': 'npm:@angular/animations/bundles/animations.umd.js',
'@angular/animations/browser': 'npm:@angular/animations/bundles/animations-browser.umd.js',
'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common/bundles/common.umd.js',
'@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
'@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'@angular/platform-browser/animations': 'npm:@angular/platform-browser/bundles/platform-browser-animations.umd.js',
'@angular/http': 'npm:@angular/http/bundles/http.umd.js',
'@angular/router': 'npm:@angular/router/bundles/router.umd.js',
'@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
// other libraries
'cldr-data': 'npm:cldr-data',
'rxjs': 'npm:rxjs',
'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js',
'jszip': 'npm:jszip',
'systemjs-plugin-json': 'npm:systemjs-plugin-json',
// Kendo UI for Angular scopes
'@progress': 'npm:@progress',
'@telerik': 'npm:@telerik'
},
meta: {
'*.json': {
loader: 'systemjs-plugin-json'
}
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
app: {
defaultExtension: 'js',
meta: {
'./*.js': {
loader: 'systemjs-angular-loader.js'
}
}
},
rxjs: {
defaultExtension: 'js'
},
jszip: {
defaultExtension: 'js',
main: './dist/jszip.js'
},
'systemjs-plugin-json': {
defaultExtension: 'js',
main: 'json.js'
},
// Kendo UI for Angular packages
'npm:@progress/kendo-angular-buttons': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-charts': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-dateinputs': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-dropdowns': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-dialog': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-grid': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-inputs': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-intl': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-l10n': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-excel-export': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-layout': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-scrollview': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-sortable': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-popup': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-resize-sensor': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-upload': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-charts': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-data-query': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-date-math': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-drawing': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-file-saver': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-intl': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-ooxml': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-popup-common': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@telerik/kendo-draggable': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@telerik/kendo-dropdowns-common': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@telerik/kendo-intl': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@telerik/kendo-inputs-common': {
main: './dist/npm/main.js',
defaultExtension: 'js'
}
}
});
})(this);
该项目可以在 "Release" 中找到(使用 Webpack),并且可以使用 @angular/cli 构建或提供服务。问题是尝试使用 SystemJs 在 "Debug" 中 运行 它。它开始正常并加载 main.js 文件但无法加载 app.module。我收到错误:
“(SystemJS) XHR 错误(404 未找到)加载 http://localhost/MyApp/MyAppCli/src/app/app.module
从 http://localhost/MyApp/MyAppCli/src/main.js"
将 http://localhost/MyApp/MyAppCli/src/app/app.module 加载为 "./app/app.module" 时出错
主要文件和应用程序结构是:
MyApp
|-----MyAppCli
| |----src
| | |----app
| | | |----app.module.js
| | |
| | |----main.js
| | |----systemjs.config.js
| | |----systemjs-angular-loader.js
| |
| |----node_modules
| |----package.json
|
|-----Views
| |----Shared
| |----_Layout.cshtml
|
|-----web.config
是否可以同时使用 Systemjs 和 Webpack?如果可以,我该如何让它工作?
请帮忙。
谢谢yurzui!你的最后一条评论解决了这个问题。一旦我有 'map': { app: 'MyAppCli/src' 在 systemjs.config.js 和 System.import('app/main') 在 _Layout.cshtml (我没有使用Index.html) 它起作用了。我现在可以在我的项目中同时使用 Systemjs 和 Webpack。唯一奇怪的是,IE11 加载速度非常慢,但可以快速关闭,而 Chrome 加载速度非常快,但关闭 VS2017 调试器需要很长时间。我猜这是一个 VS2017 错误,它们具有针对 IE 和 Chrome 的新调试功能,因为 Firefox 加载和卸载速度很快,但在 VS2017 中没有断点调试。
再次感谢!
我正在使用 Visual Studio 2017 开发托管在 MVC 应用程序 (.Net 4.6) 中的 Angular 4.1 SPA 应用程序。我使用 @angular/cli 创建了 Angular 部分,然后将其合并到现有的 MVC 应用程序中。它的结构如 CandorDeveloper 文章 (http://candordeveloper.com/2017/04/12/how-to-use-angular-cli-with-visual-studio-2017/) 中所述。
这一切都很好,但由于@angular/cli 使用 Webpack,它非常慢。对 Html、typescript 或 css 的任何更改都需要大约 4 分钟的构建。我以前有一个设置相同但没有使用 @angular/cli 或 Webpack 的应用程序。它仍然是一个 Visual Studio 2017 MVC 应用程序(.Net 4.6)托管一个 Angular 4.1 SPA 应用程序,但它使用了 SystemJs。它的构建速度非常快,我在 VS2017 中拥有与任何 .net Web 应用程序相同的出色调试体验。因此,我想我会尝试同时使用 SystemJs 和 Webpack。
我的想法是在 VS2017 "Debug" 模式下使用 SystemJs 构建应用程序以获得速度和便利性,然后使用 Webpack for "Release" 模式构建生产版本并能够使用 AOT .为了尝试实现这一点,我将以下内容放入我的 _Layout.cshtml 文件中:
@if(!HttpContext.Current.IsDebuggingEnabled)
{
<script type="text/javascript" src="~/Scripts/NgApp/inline.bundle.js"></script>
<script type="text/javascript" src="~/Scripts/NgApp/polyfills.bundle.js"></script>
<script type="text/javascript" src="~/Scripts/NgApp/styles.bundle.js"></script>
<script type="text/javascript" src="~/Scripts/NgApp/vendor.bundle.js"></script>
<script type="text/javascript" src="~/Scripts/NgApp/main.bundle.js"></script>
}
else
{
<!-- 1. Load libraries -->
<!-- Polyfill(s) for older browsers -->
<script src="~/MyAppCli/node_modules/core-js/client/shim.min.js"></script>
<script src="~/MyAppCli/node_modules/zone.js/dist/zone.js"></script>
<script src="~/MyAppCli/node_modules/systemjs/dist/system.src.js"></script>
<script src="~/MyAppCli/src/systemjs.config.js"></script>
<script>
System.import('src/main.js')
.catch(function (err) { console.error(err); });
</script>
}
我在项目的预构建事件中添加了:
if $(ConfigurationName) == Release (
echo "cd $(SolutionDir)MyApp\MyAppCli" &&^
cd "$(SolutionDir)MyApp\MyAppCli" &&^
echo "building v" &&^
npm run build
)
然后我将 systemjs 添加到 package.json 文件的 devDependencies 并创建了一个合适的 systemjs.config.js 文件。
我的systemjs.config.js:
(function (global)
{
System.config({
paths: {
// paths serve as alias
'npm:': MyAppCli/node_modules/'
},
// map tells the System loader where to look for things
map: {
// our app is within the app folder
'app': 'src',
// angular bundles
'@angular/animations': 'npm:@angular/animations/bundles/animations.umd.js',
'@angular/animations/browser': 'npm:@angular/animations/bundles/animations-browser.umd.js',
'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common/bundles/common.umd.js',
'@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
'@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'@angular/platform-browser/animations': 'npm:@angular/platform-browser/bundles/platform-browser-animations.umd.js',
'@angular/http': 'npm:@angular/http/bundles/http.umd.js',
'@angular/router': 'npm:@angular/router/bundles/router.umd.js',
'@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
// other libraries
'cldr-data': 'npm:cldr-data',
'rxjs': 'npm:rxjs',
'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js',
'jszip': 'npm:jszip',
'systemjs-plugin-json': 'npm:systemjs-plugin-json',
// Kendo UI for Angular scopes
'@progress': 'npm:@progress',
'@telerik': 'npm:@telerik'
},
meta: {
'*.json': {
loader: 'systemjs-plugin-json'
}
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
app: {
defaultExtension: 'js',
meta: {
'./*.js': {
loader: 'systemjs-angular-loader.js'
}
}
},
rxjs: {
defaultExtension: 'js'
},
jszip: {
defaultExtension: 'js',
main: './dist/jszip.js'
},
'systemjs-plugin-json': {
defaultExtension: 'js',
main: 'json.js'
},
// Kendo UI for Angular packages
'npm:@progress/kendo-angular-buttons': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-charts': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-dateinputs': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-dropdowns': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-dialog': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-grid': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-inputs': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-intl': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-l10n': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-excel-export': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-layout': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-scrollview': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-sortable': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-popup': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-resize-sensor': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-angular-upload': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-charts': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-data-query': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-date-math': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-drawing': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-file-saver': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-intl': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-ooxml': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@progress/kendo-popup-common': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@telerik/kendo-draggable': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@telerik/kendo-dropdowns-common': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@telerik/kendo-intl': {
main: './dist/npm/main.js',
defaultExtension: 'js'
},
'npm:@telerik/kendo-inputs-common': {
main: './dist/npm/main.js',
defaultExtension: 'js'
}
}
});
})(this);
该项目可以在 "Release" 中找到(使用 Webpack),并且可以使用 @angular/cli 构建或提供服务。问题是尝试使用 SystemJs 在 "Debug" 中 运行 它。它开始正常并加载 main.js 文件但无法加载 app.module。我收到错误: “(SystemJS) XHR 错误(404 未找到)加载 http://localhost/MyApp/MyAppCli/src/app/app.module 从 http://localhost/MyApp/MyAppCli/src/main.js"
将 http://localhost/MyApp/MyAppCli/src/app/app.module 加载为 "./app/app.module" 时出错主要文件和应用程序结构是:
MyApp
|-----MyAppCli
| |----src
| | |----app
| | | |----app.module.js
| | |
| | |----main.js
| | |----systemjs.config.js
| | |----systemjs-angular-loader.js
| |
| |----node_modules
| |----package.json
|
|-----Views
| |----Shared
| |----_Layout.cshtml
|
|-----web.config
是否可以同时使用 Systemjs 和 Webpack?如果可以,我该如何让它工作?
请帮忙。
谢谢yurzui!你的最后一条评论解决了这个问题。一旦我有 'map': { app: 'MyAppCli/src' 在 systemjs.config.js 和 System.import('app/main') 在 _Layout.cshtml (我没有使用Index.html) 它起作用了。我现在可以在我的项目中同时使用 Systemjs 和 Webpack。唯一奇怪的是,IE11 加载速度非常慢,但可以快速关闭,而 Chrome 加载速度非常快,但关闭 VS2017 调试器需要很长时间。我猜这是一个 VS2017 错误,它们具有针对 IE 和 Chrome 的新调试功能,因为 Firefox 加载和卸载速度很快,但在 VS2017 中没有断点调试。
再次感谢!