ChatGPT解决这个技术问题 Extra ChatGPT

如何捆绑 Angular 应用程序进行生产

在实时 Web 服务器上捆绑 Angular(版本 2、4、6,...)以进行生产的最佳方法是什么。

请在答案中包含 Angular 版本,以便我们在它移动到更高版本时更好地跟踪。

rc3 现在提供捆绑文件版本,将请求数量从 300+ 降低到大约 40。
嘿。我也讨厌 WebPack 和一般的构建步骤。只是试图拼凑一个简单的网站有点矫枉过正。因此我做了这个:github.com/schungx/angular2-bundle
谢谢斯蒂芬。对于供应商部分来说,这将是一个简单的解决方案。希望这可以正式提供和更新。我想你对项目的文件使用了像 Gulp 这样的东西?

N
Nicolas Henneaux

使用 Angular CLI 2 到 14(TypeScript)

一次性设置

npm install -g @angular/cli

ng new projectFolder 创建一个新应用程序

捆绑步骤

ng build(当目录为 projectFolder 时在命令行中运行)。用于生产的标记 prod 包现在是默认设置(如果需要,请参阅 Angular 文档以对其进行自定义)。

使用 Brotli 压缩资源 使用以下命令 for i in dist/*/* 压缩资源;做 brotli $i;完毕

v6+ 的包默认生成为 projectFolder/dist(/$projectFolder**

输出

使用 Angular 14.0.2 使用 CLI 14.0.2 和选项 CSS 没有 Angular 路由的大小

dist/main.[hash].js 捆绑您的应用程序 [大小:118 KB 用于新的 Angular CLI 应用程序空,36 KB 压缩]。

dist/polyfill-[es-version].[hash].bundle.js 捆绑的 polyfill 依赖项(@angular,RxJS ...)[大小:34 KB 用于新的 Angular CLI 应用程序为空,11 KB 压缩]。

dist/index.html 应用程序的入口点。

dist/runtime.[hash].bundle.js webpack 加载器

dist/style.[hash].bundle.css 样式定义

从 Angular CLI 资产配置复制的 dist/assets 资源

部署

您可以使用启动本地 HTTP 服务器的 ng serve --prod 命令获取应用程序的预览,以便可以使用 http://localhost:4200 访问带有生产文件的应用程序。 这对于生产用途来说是不安全的。

对于生产用途,您必须部署所选 HTTP 服务器中 dist 文件夹中的所有文件。


运行 npm install -g angular-cli@webpack: npm ERR 时出现错误!请在任何支持请求中包含以下文件:....\npm-debug.log。你知道发生了什么事吗?
@chrismarx 它只生成一个包,包括所有组件及其 html 和样式。
我有一个应用程序,我想使用这种方法,所以我从项目文件夹启动 ng init。我已经完成了其余的步骤,但是当我部署我的应用程序时,它似乎是空的。唯一出现的是“应用程序有效!”消息,是否有一些地方我必须设置我的应用程序文件的位置?
ng-init 已从 Angular cli 中删除。 github.com/angular/angular-cli/issues/5176
我最终将此标记为已接受的答案。尽管其他解决方案也可以工作,甚至提供一些额外的灵活性(我发布了一篇关于在没有 CLI 的情况下使用 Webpack 的文章)。使用 Angular CLI 无疑是一种减少头痛的方法。我最终使用了 Angular CLI 并调整了我的项目,以便我可以更轻松地使用 AoT。
I
Igor

2.0.1 最终使用 Gulp(TypeScript - 目标:ES5)

一次性设置

npm install(当目录为projectFolder时在cmd中运行)

捆绑步骤

npm run bundle(目录为projectFolder时在cmd中运行)bundles生成到projectFolder/bundles/

输出

bundles/dependencies.bundle.js [ size: ~ 1 MB (as small as possible) ] 包含 rxjs 和 angular 依赖项,而不是整个框架

包含 rxjs 和角度依赖,而不是整个框架

bundles/app.bundle.js [大小:取决于你的项目,我的是 ~ 0.5 MB] 包含你的项目

包含您的项目

文件结构

projectFolder / app /(所有组件、指令、模板等)

项目文件夹/gulpfile.js

var gulp = require('gulp'),
  tsc = require('gulp-typescript'),
  Builder = require('systemjs-builder'),
  inlineNg2Template = require('gulp-inline-ng2-template');

gulp.task('bundle', ['bundle-app', 'bundle-dependencies'], function(){});

gulp.task('inline-templates', function () {
  return gulp.src('app/**/*.ts')
    .pipe(inlineNg2Template({ useRelativePaths: true, indent: 0, removeLineBreaks: true}))
    .pipe(tsc({
      "target": "ES5",
      "module": "system",
      "moduleResolution": "node",
      "sourceMap": true,
      "emitDecoratorMetadata": true,
      "experimentalDecorators": true,
      "removeComments": true,
      "noImplicitAny": false
    }))
    .pipe(gulp.dest('dist/app'));
});

gulp.task('bundle-app', ['inline-templates'], function() {
  // optional constructor options
  // sets the baseURL and loads the configuration file
  var builder = new Builder('', 'dist-systemjs.config.js');

  return builder
    .bundle('dist/app/**/* - [@angular/**/*.js] - [rxjs/**/*.js]', 'bundles/app.bundle.js', { minify: true})
    .then(function() {
      console.log('Build complete');
    })
    .catch(function(err) {
      console.log('Build error');
      console.log(err);
    });
});

gulp.task('bundle-dependencies', ['inline-templates'], function() {
  // optional constructor options
  // sets the baseURL and loads the configuration file
  var builder = new Builder('', 'dist-systemjs.config.js');

  return builder
    .bundle('dist/app/**/*.js - [dist/app/**/*.js]', 'bundles/dependencies.bundle.js', { minify: true})
    .then(function() {
      console.log('Build complete');
    })
    .catch(function(err) {
      console.log('Build error');
      console.log(err);
    });
});

projectFolder / package.json(与快速入门指南相同,仅显示捆绑所需的 devDependencies 和 npm-scripts)

{
  "name": "angular2-quickstart",
  "version": "1.0.0",
  "scripts": {
    ***
     "gulp": "gulp",
     "rimraf": "rimraf",
     "bundle": "gulp bundle",
     "postbundle": "rimraf dist"
  },
  "license": "ISC",
  "dependencies": {
    ***
  },
  "devDependencies": {
    "rimraf": "^2.5.2",
    "gulp": "^3.9.1",
    "gulp-typescript": "2.13.6",
    "gulp-inline-ng2-template": "2.0.1",
    "systemjs-builder": "^0.15.16"
  }
}

projectFolder / systemjs.config.js(与快速入门指南相同,不再提供)

(function(global) {

  // map tells the System loader where to look for things
  var map = {
    'app':                        'app',
    'rxjs':                       'node_modules/rxjs',
    'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api',
    '@angular':                   'node_modules/@angular'
  };

  // packages tells the System loader how to load when no filename and/or no extension
  var packages = {
    'app':                        { main: 'app/boot.js',  defaultExtension: 'js' },
    'rxjs':                       { defaultExtension: 'js' },
    'angular2-in-memory-web-api': { defaultExtension: 'js' }
  };

  var packageNames = [
    '@angular/common',
    '@angular/compiler',
    '@angular/core',
    '@angular/forms',
    '@angular/http',
    '@angular/platform-browser',
    '@angular/platform-browser-dynamic',
    '@angular/router',
    '@angular/router-deprecated',
    '@angular/testing',
    '@angular/upgrade',
  ];

  // add package entries for angular packages in the form '@angular/common': { main: 'index.js', defaultExtension: 'js' }
  packageNames.forEach(function(pkgName) {
    packages[pkgName] = { main: 'index.js', defaultExtension: 'js' };
  });

  var config = {
    map: map,
    packages: packages
  };

  // filterSystemConfig - index.asp's chance to modify config before we register it.
  if (global.filterSystemConfig) { global.filterSystemConfig(config); }

  System.config(config);

})(this);

projetcFolder / dist-systemjs.config.js (只是显示了与 systemjs.config.json 的区别)

var map = {
    'app':                        'dist/app',
  };

projectFolder / index.html (production) - 脚本标签的顺序很关键。在 bundle 标记之后放置 dist-systemjs.config.js 标记仍然允许程序运行,但依赖包将被忽略,并且将从 node_modules 文件夹加载依赖项。

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1"/>
  <base href="/"/>
  <title>Angular</title>
  <link rel="stylesheet" type="text/css" href="style.css"/>
</head>
<body>

<my-app>
  loading...
</my-app>

<!-- Polyfill(s) for older browsers -->
<script src="node_modules/core-js/client/shim.min.js"></script>

<script src="node_modules/zone.js/dist/zone.min.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.js"></script>

<script src="dist-systemjs.config.js"></script>
<!-- Project Bundles. Note that these have to be loaded AFTER the systemjs.config script -->
<script src="bundles/dependencies.bundle.js"></script>
<script src="bundles/app.bundle.js"></script>

<script>
    System.import('app/boot').catch(function (err) {
      console.error(err);
    });
</script>
</body>
</html>

projectFolder / app / boot.ts 是引导程序所在的位置。

我能做的最好的:)


嗨,gulp 脚本正在创建捆绑包,但我不确定 boot.ts 文件中应该包含什么?现在不是所有文件都在捆绑包中吗?我们执行捆绑包吗?
嗯,我想我需要再试一次。我尝试切换到 builder.buildStatic 并从 rxjs 收到关于未作为 commonjs 或 amd 模块加载的错误。我会再试一次你的建议
我也不清楚这些捆绑包是如何在这个设置中实际使用的?我似乎在这里遇到了与@chrismarx 完全相同的问题。我可以创建捆绑包,但似乎所有内容仍在从我的转译和复制的应用程序文件夹(位于 dist/app)中加载。如果我查看我的网络面板,我可以看到我的应用相关文件实际上是从那里加载的(组件等),而不是来自 app.bundle.js 的所有应用相关文件。 A_Singh,你能分享你的 boot.ts 吗?看来我在这里遗漏了一些东西,并且希望得到一些澄清。
A_Singh,我不明白这有什么帮助。当 inline-templates 运行时,它内联模板,然后在 dist/app 创建所有应用程序文件夹和文件的副本。然后在 dist-systemjs.config.js 中将 app 映射到 dist/app,如果您将 dist 文件夹用作根目录,则该文件夹将不存在。您不想从 dist 文件夹运行您的应用程序吗?如果是这种情况,您就不会在根 dist 文件夹中嵌套 dist 文件夹。我一定在这里遗漏了其他东西。您不需要告诉 systemjs 使用您的捆绑文件,而不是 dist/app 文件夹中的常用文件吗?
我在您的解决方案中遇到问题,引导在这里不存在,当我将其替换为“应用程序”时,出现错误“模块未定义”。
P
Pat M

Angular 2 和 Webpack(没有 CLI 设置)

1- Angular2 团队的教程

Angular2 团队发布了使用 Webpack 的 tutorial

我创建了教程中的文件并将其放置在一个小的 GitHub seed project 中。因此,您可以快速尝试工作流程。

指示:

npm 安装

npm 开始。为了发展。这将创建一个虚拟的“dist”文件夹,该文件夹将在您的本地主机地址上重新加载。

npm 运行构建。用于生产。 “这将创建一个物理“dist”文件夹版本,而不是可以发送到网络服务器。dist 文件夹是 7.8MB,但实际上只需要 234KB 就可以在网络浏览器中加载页面。

2 - Webkit 入门工具包

Webpack Starter Kit 提供了比上述教程更多的测试功能,并且看起来很受欢迎。


嗨,是否可以使用 angular 2.1.0 更新种子项目?本教程现在使用 angular 2.1.0。我跟着它,无法让它工作。错误是 http 404 - 找不到 app.component.html。
我更新到 angular 2.1.0 没有问题。 app.component.html 从 app.component.ts (templateUrl: './app.component.html') 调用。你有两个文件在同一个应用程序文件夹?
Tree-shaking, Minification & Gzipping 可以在您进行生产时大大减小大小。这是一个很好的例子,blog.mgechev.com/2016/06/26/…
A
Andzej Maciusovic

使用 SystemJs builder 和 gulp 的 Angular 2 生产工作流程

Angular.io 有快速入门教程。我复制了本教程并扩展了一些简单的 gulp 任务,将所有内容捆绑到 dist 文件夹,可以复制到服务器并像那样工作。我尝试优化一切以在 Jenkis CI 上正常运行,因此 node_modules 可以被缓存并且不需要复制。

Github 上带有示例应用程序的源代码:https://github.com/Anjmao/angular2-production-workflow

清理 typescripts 编译的 js 文件和 dist 文件夹 在 app 文件夹中编译 typescript 文件 使用 SystemJs 捆绑器将所有内容捆绑到 dist 文件夹,并生成用于浏览器缓存刷新的哈希 使用 gulp-html-replace 将 index.html 脚本替换为捆绑版本并复制到 dist 文件夹将 assets 文件夹中的所有内容复制到 dist 文件夹

节点:虽然您总是可以创建自己的构建过程,但我强烈建议使用 angular-cli,因为它具有所有需要的工作流程并且现在可以完美运行。我们已经在生产中使用它,并且完全没有 angular-cli 的任何问题。


这就是我要找的。 github 上的示例应用程序非常有用。谢谢
M
Meligy

Angular CLI 1.xx(适用于 Angular 4.xx、5.xx)

这支持:

Angular 2.x 和 4.x

最新的 Webpack 2.x

Angular AoT 编译器

路由(正常和懒惰)

SCSS

自定义文件捆绑(资产)

其他开发工具(linter、单元和端到端测试设置)

最初设定

ng new project-name --routing

您可以添加 --style=scss 以获得 SASS .scss 支持。

您可以添加 --ng4 以使用 Angular 4 而不是 Angular 2。

创建项目后,CLI 会自动为您运行 npm install。如果您想改用 Yarn,或者只想查看项目骨架而不安装,check how to do it here

捆绑步骤

在项目文件夹内:

ng build -prod

在当前版本中,您需要手动指定 --aot,因为它可以在开发模式下使用(尽管由于速度慢,这不实用)。

这也为更小的包执行 AoT 编译(没有 Angular 编译器,而是生成编译器输出)。如果您使用 Angular 4,则使用 AoT 的包要小得多,因为生成的代码更小。
您可以在开发模式下使用 AoT(源地图,不缩小)测试您的应用,并通过运行 ng build --aot 来测试 AoT。

输出

默认输出目录是 ./dist,尽管它可以在 ./angular-cli.json 中更改。

可部署文件

构建步骤的结果如下:

(注意:<content-hash> 指的是文件内容的哈希/指纹,这是一种缓存破坏方式,这是可能的,因为 Webpack 自己编写 script 标签)

./dist/assets 文件按原样从 ./src/assets/** 复制

./dist/index.html 来自 ./src/index.html,添加 webpack 脚本后 源模板文件可在 ./angular-cli.json 中配置

./dist/inline.js 小型 webpack 加载器 / polyfill

./dist/main..bundle.js 包含所有生成/导入的 .js 脚本的主 .js 文件

./dist/styles..bundle.js 当你为 CSS 使用 Webpack 加载器时,这是 CLI 方式,它们在这里通过 JS 加载

在旧版本中,它还创建了 gzipped 版本以检查其大小和 .map sourcemaps 文件,但随着人们不断要求删除这些文件,这种情况不再发生。

其它文件

在某些其他情况下,您可能会发现其他不需要的文件/文件夹:

./out-tsc/ 来自 ./src/tsconfig.json 的 outDir

./out-tsc-e2e/ 来自 ./e2e/tsconfig.json 的 outDir

./dist/ngfactory/ 来自 AoT 编译器(从 beta 16 开始,如果不分叉 CLI,则无法配置)


是否可以将角度库及其依赖项与我的应用程序分开?
不使用 CLI,这是为了让 tree-shaking 起作用。那就是删除所有未在您的应用程序中使用的 Angular EcmaScript 模块。有计划在开发模式下禁用此功能以提高速度(他们将加载的库称为“DLL”),但没有计划在最终结果中分离。如果你在没有 CLI 的情况下滚动你自己的 Webpack 东西,它应该是可以实现的。
如何使用 dist 文件夹检查我的应用程序。如何在我的网络服务器中托管?
您只需将其复制到服务器。这是一个简单的静态网站,无论如何都可以提供服务。如果您使用路由,您可能希望将所有调用重定向到 HTML 文件,为此请检查服务器配置部分 angular.io/docs/ts/latest/guide/… 上的 Angular 部署文档
@Meligy 如果我从产品包中删除 <content-hash> 怎么办。它可能会导致获取最新捆绑包时出现问题?
P
Peter Salomonsen

到今天为止,我仍然认为 Ahead-of-Time Compilation 食谱是生产捆绑的最佳配方。您可以在这里找到它:https://angular.io/docs/ts/latest/cookbook/aot-compiler.html

到目前为止,我对 Angular 2 的体验是,AoT 创建了最小的构建,几乎没有加载时间。最重要的是这里的问题 - 您只需要将几个文件发送到生产环境。

这似乎是因为 Angular 编译器不会随生产版本一起提供,因为模板是“提前”编译的。看到您的 HTML 模板标记转换为很难逆向工程为原始 HTML 的 javascript 指令也非常酷。

我制作了一个简单的视频,我在其中演示了开发与 AoT 构建中 Angular 2 应用程序的下载大小、文件数量等 - 你可以在这里看到:

https://youtu.be/ZoZDCgQwnmQ

您可以在此处找到视频中使用的源代码:

https://github.com/fintechneo/angular2-templates


T
Tushar Tibude
        **Production build with

         - Angular Rc5
         - Gulp
         - typescripts 
         - systemjs**

        1)con-cat all js files  and css files include on index.html using  "gulp-concat".
          - styles.css (all css concat in this files)
          - shims.js(all js concat in this files)

        2)copy all images and fonts as well as html files  with gulp task to "/dist".

        3)Bundling -minify angular libraries and app components mentioned in systemjs.config.js file.
         Using gulp  'systemjs-builder'

            SystemBuilder = require('systemjs-builder'),
            gulp.task('system-build', ['tsc'], function () {
                var builder = new SystemBuilder();
                return builder.loadConfig('systemjs.config.js')
                    .then(function () {
                        builder.buildStatic('assets', 'dist/app/app_libs_bundle.js')
                    })
                    .then(function () {
                        del('temp')
                    })
            });


    4)Minify bundles  using 'gulp-uglify'

jsMinify = require('gulp-uglify'),

    gulp.task('minify', function () {
        var options = {
            mangle: false
        };
        var js = gulp.src('dist/app/shims.js')
            .pipe(jsMinify())
            .pipe(gulp.dest('dist/app/'));
        var js1 = gulp.src('dist/app/app_libs_bundle.js')
            .pipe(jsMinify(options))
            .pipe(gulp.dest('dist/app/'));
        var css = gulp.src('dist/css/styles.min.css');
        return merge(js,js1, css);
    });

5) In index.html for production 

    <html>
    <head>
        <title>Hello</title>

        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta charset="utf-8" />

       <link rel="stylesheet" href="app/css/styles.min.css" />   
       <script type="text/javascript" src="app/shims.js"></script>  
       <base href="/">
    </head>
     <body>
    <my-app>Loading...</my-app>
     <script type="text/javascript" src="app/app_libs_bundle.js"></script> 
    </body>

    </html>

 6) Now just copy your dist folder to '/www' in wamp server node need to copy node_modules in www.

S
Sunil Kumar

您可以使用 angular-cli-ghpagesgithub 上部署您的 Angular 应用程序

查看链接以了解如何使用此 cli 进行部署。

部署的网站通常会存储在 github 的某个分支中

gh页面

use 可以克隆 git 分支并像使用服务器中的静态网站一样使用它


T
TGH

“最佳”取决于场景。有时您只关心最小的单个捆绑包,但在大型应用程序中您可能不得不考虑延迟加载。在某些时候,将整个应用程序作为单个包提供服务变得不切实际。

在后一种情况下,Webpack 通常是最好的方式,因为它支持代码拆分。

对于单个捆绑包,我会考虑 Rollup,或者如果你觉得勇敢的话,我会考虑 Closure 编译器 :-)

我已经创建了我在这里使用过的所有 Angular 捆绑器的示例:http://www.syntaxsuccess.com/viewarticle/angular-production-builds

可在此处找到代码:https://github.com/thelgevold/angular-2-samples

角度版本:4.1.x


Y
Yogesh Waghmare

ng serve 用于为我们的应用程序提供开发服务。生产呢?如果我们查看我们的 package.json 文件,我们可以看到我们可以使用一些脚本:

"scripts": {
  "ng": "ng",
  "start": "ng serve",
  "build": "ng build --prod",
  "test": "ng test",
  "lint": "ng lint",
  "e2e": "ng e2e"
},

构建脚本使用带有 --prod 标志的 Angular CLI 的 ng 构建。现在让我们试试吧。我们可以通过以下两种方式之一来做到这一点:

使用 npm 脚本

npm run build

直接使用cli

ng build --prod

这次我们得到了四个文件而不是五个。 --prod 标志告诉 Angular 让我们的应用程序体积更小。


N
Nicolas Henneaux

只需在一分钟内使用 webpack 3 设置 angular 4,您的开发和生产 ENV 包就会准备就绪,没有任何问题,只需按照下面的 github doc

https://github.com/roshan3133/angular2-webpack-starter


N
Nagnath Mungade

请在当前项目目录中尝试以下 CLI 命令。它将创建 dist 文件夹包。因此您可以上传 dist 文件夹中的所有文件以进行部署。

ng build --prod --aot --base-href。