首页 文章

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

提问于
浏览
299

我想在这个线程中跟踪和更新最新的(并且希望是最简单的)方法来捆绑Angular(版本2,4,...)以便在实时Web服务器上进行 生产环境 .

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

10 回答

  • 53

    具有Angular CLI的

    2. x,4.x,5.x,6.x,7.x(TypeScript)

    OneTime设置

    • npm install -g @angular/cli

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

    捆绑步骤

    • ng build --prod (当目录为 projectFolder 时在命令行中运行)

    标记 prod 生产环境 包(请参阅Angular documentation以获取 生产环境 标志中包含的选项列表) .

    for i in dist/*; do brotli $i; done

    捆绑包默认生成 projectFolder/dist(/$projectFolder for 6)

    输出

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

    • dist/main.[hash].bundle.js 您的应用程序已捆绑[大小:174 KB,新Angular CLI应用程序为空, 43 KB 压缩] .

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

    • dist/index.html 您的申请的入口点 .

    • dist/inline.[hash].bundle.js webpack loader

    • dist/style.[hash].bundle.css 样式定义
      从Angular CLI资产配置复制的

    • dist/assets 资源

    部署

    您可以使用启动本地HTTP服务器的 ng serve --prod 命令预览应用程序,以便可以使用http://localhost:4200访问包含 生产环境 文件的应用程序 .

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

  • 13

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


    OneTime设置

    • npm install (当direcory为projectFolder时在cmd中运行)

    捆绑步骤

    • npm run bundle (当direcory为projectFolder时在cmd中运行)

    捆绑生成 projectFolder / bundles /

    输出

    • bundles/dependencies.bundle.js [ size: ~ 1 MB (尽可能小)]

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

    • bundles/app.bundle.js [ size: depends on your project ,我的 ~ 0.5 MB ]

    • 包含您的项目

    文件结构

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

    • projectFolder / 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 (与Quickstart guide相同,只显示了捆绑所需的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 (与Quickstart guide相同,暂不提供)
    (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 ( 生产环境 ) - 脚本标签的顺序至关重要 . 在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 是引导程序的位置 .

    我能做的最好:)

  • 313

    带Webpack的Angular 2(无CLI设置)

    1 - Angular2团队的教程

    Angular2团队使用Webpack发布了tutorial

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

    Instructions

    • npm install

    • npm start . 为了发展 . 这将创建一个虚拟的"dist"文件夹,该文件夹将在您的localhost地址中进行实时加载 .

    • npm run build . 用于 生产环境 . "This will create a physical " dist“可以发送到网络服务器的文件夹版本.dist文件夹是7.8MB,但实际上只需要234KB即可在网络浏览器中加载页面 .

    2 - Webkit入门套件

    这个Webpack Starter Kit提供了比上面的教程更多的测试功能,看起来很受欢迎 .

  • 0

    使用SystemJs构建器和gulp的Angular 2 生产环境 工作流程

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

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

    • 清理typescripts编译的js文件和dist文件夹

    • 编译app文件夹中的打字稿文件

    • 使用SystemJs bundler将所有内容捆绑到dist文件夹,生成的哈希值用于浏览器缓存刷新

    • 使用gulp-html-replace将index.html脚本替换为捆绑版本并复制到dist文件夹

    • 将assets文件夹中的所有内容复制到dist文件夹

    节点:虽然你总是可以创建自己的构建过程,但我强烈建议使用angular-cli,因为它具有所有需要的工作流程,现在它可以很好地工作 . 我们已经在 生产环境 中使用它,并且根本没有与angular-cli有任何问题 .

  • 14

    Angular CLI 1.x.x(适用于Angular 4.x.x,5.x.x)

    这支持:

    • Angular2.x和4.x.

    • 最新的Webpack 2.x.

    • Angular AoT编译器

    • 路由(正常和懒惰)

    • SCSS

    • 自定义文件捆绑(资产)

    • 其他开发工具(短绒,单元和端到端测试设置)

    初始设置

    ng new project-name --routing
    

    您可以为SASS .scss支持添加 --style=scss .

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

    创建项目后,CLI将自动为您运行 npm install . 如果你想使用Yarn,或者只是想在没有安装的情况下查看项目框架,check how to do it here .

    捆绑步骤

    在项目文件夹中:

    ng build -prod
    

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

    这也为更小的bundle执行AoT编译(没有Angular编译器,而是生成的编译器输出) . 如果你使用Angular 4,那么使用AoT时捆绑包要小得多,因为生成的代码较小 .
    您可以通过运行 ng build --aot 在开发模式(源图,无缩小)和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.<content-hash>.bundle.js
      包含所有生成/导入的.js脚本的主.js文件

    • ./dist/styles.<content-hash>.bundle.js
      当您使用CSS的CSSpack加载器(这是CLI方式)时,它们通过JS加载

    在旧版本中,它还创建了用于检查其大小的gzip压缩版本以及 .map sourcemaps文件,但由于人们不断要求删除这些文件,因此不再发生这种情况 .

    其他文件

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

    • ./out-tsc/
      来自 ./src/tsconfig.jsonoutDir

    • ./out-tsc-e2e/
      来自 ./e2e/tsconfig.jsonoutDir

    • ./dist/ngfactory/
      来自AoT编译器(从beta 16开始不配置CLI而不配置)

  • 1

    截至今天,我仍然发现Ahead-of-Time Compilation cookbook是 生产环境 捆绑的最佳配方 . 你可以在这里找到它:https://angular.io/docs/ts/latest/cookbook/aot-compiler.html

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

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

    我制作了一个简单的视频,在这里我演示了Dev开发中的Angular 2应用程序的下载大小,文件数量等对比AoT版本 - 您可以在此处看到:

    https://youtu.be/ZoZDCgQwnmQ

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

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

  • 22
    **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.
    
  • 5

    您可以使用angular-cli-ghpagesgithub 上部署角度应用程序

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

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

    GH-页

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

  • 2

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

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

    对于单个包我会考虑Rollup,或Closure编译器,如果你感到勇敢:-)

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

    代码可以在这里找到:https://github.com/thelgevold/angular-2-samples

    角度版本:4.1.x

  • 2

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

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

相关问题