如何使用Webpack运行Angular 2 AOT

时间:2017-06-10 03:24:01

标签: javascript angular webpack webpack-dev-server angular2-aot

更新

在@ developer033提到之后,我正在运行 npm run server:prod ,并且应用程序正在prod模式下运行。但我不确定,我如何验证它是否经过AOT优化?

如果我检查main.bundle.js以检查它是否包含main.browser.aot.ts的代码:

enter image description here

我看到的是main.browser.ts而不是main.browser.aot.ts 所以我不确定我是否正在使用AOT构建。

原帖

好的,我可以使用Webpack在AOT模式下编译我的Angular2项目,它创建了两个文件夹,一个是“dist”,另一个是“编译”,但我不知道如何在编译后运行AOT项目。 / p>

构建命令:

  

“build:aot:prod”:“npm run clean:dist&& npm run clean:aot&& webpack --config config / webpack.prod.js --progress --profile   --bail“

编译后,我运行命令:

  

npm运行webpack-dev-server

现在应用程序运行但我不确定它是否甚至使用AOT编译代码。我发现浏览器中AOT和非AOT应用程序没有区别。

AOT: enter image description here

没有AOT: enter image description here

tsconfig.webpack.json:

 import { platformBrowser } from '@angular/platform-browser';
    import { decorateModuleRef } from './app/environment';
    import { enableProdMode } from '@angular/core';
    import { AppModuleNgFactory } from '../compiled/src/app/app.module.ngfactory';

    if (ENV.toLocaleLowerCase() === 'production' || ENV.toLocaleLowerCase() === 'prod') {
      enableProdMode();
    }
    export function main(): Promise<any> {
      return platformBrowser()
        .bootstrapModuleFactory(AppModuleNgFactory)
        .then(decorateModuleRef)
        .catch(err => console.error(err));
    }

    export function bootstrapDomReady() {
      document.addEventListener('DOMContentLoaded', main);
    }

    bootstrapDomReady();

main.browser.aot.ts:

const HMR = helpers.hasProcessFlag('hot');
const AOT = helpers.hasNpmFlag('aot');
const METADATA = {
    title: 'Angular2 Webpack Starter by @gdi2290 from @AngularClass',
    baseUrl: '/',
    isDevServer: helpers.isWebpackDevServer()
};
module.exports = function(options) {
    isProd = options.env === 'production';
    return {
        entry: {
            'polyfills': './src/polyfills.browser.ts',
            'vendor': './src/vendor.browser.ts',
            'main': AOT ? './src/main.browser.aot.ts' : './src/main.browser.ts'
        },
        resolve: { extensions: ['.ts', '.js', '.json', '.css', '.scss'], modules: [helpers.root('src'), 'node_modules'], },
        module: {
            rules: [
                {
                    test: /\.ts$/,
                    loaders: [
                        '@angularclass/hmr-loader?pretty=' + !isProd + '&prod=' + isProd,
                        'awesome-typescript-loader',
                        { loader: 'ng-router-loader', options: { loader: 'async-import', genDir: 'compiled', aot: AOT } },
                        'angular2-template-loader'
                    ],
                    exclude: [/\.(spec|e2e)\.ts$/]
                },
                {
                    test: /\.scss$/,
                    exclude: /node_modules/,
                    loaders: ['raw-loader', 'sass-loader'] // sass-loader not scss-loader
                },{ test: /\.json$/, loader: 'json-loader'},
                { test: /\.woff(2)?(\?v=.+)?$/,  use: 'url-loader?limit=10000&mimetype=application/font-woff' },
                { test: /\.(ttf|eot|svg)(\?v=.+)?$/, use: 'file-loader' },
                { test: /bootstrap\/dist\/js\/umd\//, use: 'imports-loader?jQuery=jquery' },
                { test: /\.html$/, loader: 'raw-loader', exclude: [helpers.root('src/index.html')] },
                { test: /\.(jpg|png|gif)$/, loader: 'file' },
            ],
        },
        plugins: [            
            new ngcWebpack.NgcWebpackPlugin({
                disabled: !AOT,
                tsConfig: helpers.root('tsconfig.webpack.json'),
                resourceOverride: helpers.root('config/resource-override.js')
            }),
            new ExtractTextPlugin({ filename: 'initial.css', allChunks: true }),
            new AssetsPlugin({ path: helpers.root('dist'), filename: 'webpack-assets.json', prettyPrint: true }),
            new CheckerPlugin(),
            new CommonsChunkPlugin({ name: 'polyfills', chunks: ['polyfills']  }),
            new CommonsChunkPlugin({ name: 'vendor', chunks: ['main'], minChunks: module => /node_modules/.test(module.resource) }),
            new CommonsChunkPlugin({ name: ['polyfills', 'vendor'].reverse() }),
            new ContextReplacementPlugin( /angular(\\|\/)core(\\|\/)@angular/,  helpers.root('src') ),
            new CopyWebpackPlugin([{ from: 'src/assets', to: 'assets',  }, { from: 'src/meta', }, ]),
            new HtmlWebpackPlugin({ template: 'src/index.html', title: METADATA.title, chunksSortMode: 'dependency',  metadata: METADATA, inject: 'head',
                //csp: "default-src 'self'; child-src 'none'; object-src 'none'"
            }),
            new ScriptExtHtmlWebpackPlugin({ defaultAttribute: 'defer' }),
            new HtmlElementsPlugin({ headTags: require('./head-config.common') }),
            new LoaderOptionsPlugin({}),
            new webpack.ProvidePlugin({
                $: "jquery",
                jQuery: "jquery",
                "window.jQuery": "jquery",
            }),
            // Fix Angular 2
            new NormalModuleReplacementPlugin( /facade(\\|\/)async/, helpers.root('node_modules/@angular/core/src/facade/async.js') ),
            new NormalModuleReplacementPlugin( /facade(\\|\/)collection/, helpers.root('node_modules/@angular/core/src/facade/collection.js') ),
            new NormalModuleReplacementPlugin(  /facade(\\|\/)errors/, helpers.root('node_modules/@angular/core/src/facade/errors.js') ),
            new NormalModuleReplacementPlugin(  /facade(\\|\/)lang/, helpers.root('node_modules/@angular/core/src/facade/lang.js') ),
            new NormalModuleReplacementPlugin( /facade(\\|\/)math/, helpers.root('node_modules/@angular/core/src/facade/math.js') ),
        ],
        node: {  global: true, crypto: 'empty', process: true,  module: false, clearImmediate: false, setImmediate: false }
    };
}

配置/ webpack.common.js:

const ENV = process.env.NODE_ENV = process.env.ENV = 'production';
const API_HOST = process.env.HOST || 'localhost';
const API_PORT = process.env.PORT || 8080;
const METADATA = webpackMerge(commonConfig({ env: ENV }).metadata, { API_HOST: API_HOST, API_PORT: API_PORT,
    ENV: ENV, HMR: false
});

module.exports = function(env) {
    return webpackMerge(commonConfig({ env: ENV }), {
        devtool: 'source-map',
        output: {
            path: helpers.root('dist'),
            filename: '[name].[chunkhash].bundle.js',
            sourceMapFilename: '[name].[chunkhash].bundle.map',
            chunkFilename: '[id].[chunkhash].chunk.js'
        },
        plugins: [
            new WebpackMd5Hash(),
            new DefinePlugin({'API_HOST': JSON.stringify(API_HOST), 'API_PORT': JSON.stringify(API_PORT),
                'ENV': JSON.stringify(METADATA.ENV), 'NODE_ENV': JSON.stringify(METADATA.ENV), 'HMR': METADATA.HMR,
                'process.env': {
                    'API_HOST': JSON.stringify(API_HOST), 'API_PORT': JSON.stringify(API_PORT),
                    'ENV': JSON.stringify(METADATA.ENV), 'NODE_ENV': JSON.stringify(METADATA.ENV), 'HMR': METADATA.HMR,
                }
            }),
            new UglifyJsPlugin({
                beautify: false, //prod
                mangle: {  screw_ie8: true, keep_fnames: true }, //prod
                compress: { screw_ie8: true }, //prod
                comments: false //prod
            }),
            new NormalModuleReplacementPlugin( /angular2-hmr/,  helpers.root('config/modules/angular2-hmr-prod.js') ),
            new LoaderOptionsPlugin({
                debug: false,
                options: {
                    tslint: { emitErrors: true, failOnHint: true, resourcePath: 'src' },
                    htmlLoader: { minimize: true, removeAttributeQuotes: false, caseSensitive: true,
                        customAttrSurround: [ [/#/, /(?:)/], [/\*/, /(?:)/], [/\[?\(?/, /(?:)/] ],
                        customAttrAssign: [/\)?\]?=/]
                    },
                }
            }),
        ],
        node: { global: true, crypto: 'empty', process: false, module: false, clearImmediate: false, setImmediate: false }
    });
}

配置/ webpack.prod.js:

{
  "name": "angular2-webpack-starter",
  "version": "5.1.1",
  "description": "An Angular 2 Webpack Starter kit featuring Angular 2 (Router, Http, Forms, Services, Tests, E2E, Coverage), Karma, Protractor, Jasmine, Istanbul, TypeScript, and Webpack by AngularClass",
  "keywords": [
    "angular2",
    "webpack",
    "typescript"
  ],
  "author": "Patrick Stapleton <patrick@angularclass.com>",
  "homepage": "https://github.com/angularclass/angular2-webpack-starter",
  "license": "MIT",
  "scripts": {
    "build:dev": "webpack --config config/webpack.dev.js --progress --profile",
    "build:docker": "npm run build:prod && docker build -t angular2-webpack-start:latest .",
    "build:prod": "webpack --config config/webpack.prod.js  --progress --profile --bail",
    "build": "npm run build:dev",
    "ci": "npm run lint && npm test && npm run e2e",
    "clean:dist": "npm run rimraf -- dist",
    "clean:install": "npm set progress=false && npm install",
    "clean:start": "npm start",
    "clean": "npm cache clean && npm run rimraf -- node_modules dist",
    "clean:aot": "npm run rimraf -- compiled",
    "docker": "docker",
    "docs": "npm run typedoc -- --options typedoc.json --exclude '**/*.spec.ts' ./src/",
    "e2e:live": "npm run e2e -- --elementExplorer",
    "e2e": "npm run protractor",
    "github-deploy:dev": "webpack --config config/webpack.github-deploy.js --progress --profile --github-dev",
    "github-deploy:prod": "webpack --config config/webpack.github-deploy.js --progress --profile --github-prod",
    "github-deploy": "npm run github-deploy:dev",
    "lint": "npm run tslint \"src/**/*.ts\"",
    "postversion": "git push && git push --tags",
    "prebuild:dev": "npm run clean:dist",
    "prebuild:prod": "npm run clean:dist",
    "preclean:install": "npm run clean",
    "preclean:start": "npm run clean",
    "pree2e": "npm run webdriver:update -- --standalone",
    "preversion": "npm test",
    "protractor": "protractor",
    "rimraf": "rimraf",
    "server:dev:hmr": "npm run server:dev -- --inline --hot",
    "server:dev": "webpack-dev-server --config config/webpack.dev.js --progress --profile --watch --content-base src/",
    "server:prod": "http-server dist --cors",
    "server": "npm run server:dev",
    "start:hmr": "npm run server:dev:hmr",
    "start": "npm run server:dev",
    "test": "karma start",
    "tslint": "tslint",
    "typedoc": "typedoc",
    "version": "npm run build",
    "watch:dev:hmr": "npm run watch:dev -- --hot",
    "watch:dev": "npm run build:dev -- --watch",
    "watch:prod": "npm run build:prod -- --watch",
    "watch:test": "npm run test -- --auto-watch --no-single-run",
    "watch": "npm run watch:dev",
    "build:aot:prod": "npm run clean:dist && npm run clean:aot && webpack --config config/webpack.prod.js  --progress --profile --bail",
    "webdriver-manager": "webdriver-manager",
    "webdriver:start": "npm run webdriver-manager start",
    "webdriver:update": "npm run webdriver-manager update",
    "webpack-dev-server": "webpack-dev-server",
    "webpack": "webpack"
  },
  "dependencies": {
    "@angular/animations": "^4.1.3",
    "@angular/common": "4.1.3",
    "@angular/compiler": "4.1.3",
    "@angular/core": "4.1.3",
    "@angular/forms": "^4.1.3",
    "@angular/http": "4.1.3",
    "@angular/platform-browser": "4.1.3",
    "@angular/platform-browser-dynamic": "4.1.3",
    "@angular/platform-server": "4.1.3",
    "@angular/router": "4.1.3",
    "@angularclass/conventions-loader": "^1.0.2",
    "@angularclass/hmr": "~1.2.0",
    "@angularclass/hmr-loader": "~3.0.2",
    "animate.css": "^3.5.2",
    "assets-webpack-plugin": "^3.4.0",
    "bootstrap": "^4.0.0-alpha.6",
    "bootstrap-loader": "^2.1.0",
    "bootstrap-sass": "^3.3.7",
    "core-js": "^2.4.1",
    "error-stack-parser": "^2.0.1",
    "extract-text-webpack-plugin": "^2.1.0",
    "font-awesome": "^4.7.0",
    "font-awesome-sass-loader": "^2.0.1",
    "http-server": "^0.10.0",
    "ie-shim": "^0.1.0",
    "ionicons": "^3.0.0",
    "jquery": "^3.2.1",
    "lodash": "^4.17.4",
    "ng-snotify": "^1.1.6",
    "ngc-webpack": "^2.0.0",
    "normalize.css": "^7.0.0",
    "primeng": "^4.0.1",
    "resolve-url-loader": "^2.0.2",
    "rxjs": "^5.0.0-rc.1",
    "sourcemapped-stacktrace": "^1.1.6",
    "stacktrace-gps": "^3.0.1",
    "stacktrace-js": "^2.0.0",
    "zone.js": "~0.8.11"
  },
  "devDependencies": {
    "@angular/cli": "^1.1.0",
    "@angular/compiler-cli": "^4.1.3",
    "@ngtools/webpack": "^1.4.1",
    "@types/hammerjs": "^2.0.33",
    "@types/jasmine": "^2.2.34",
    "@types/node": "^7.0.22",
    "@types/protractor": "^4.0.0",
    "@types/selenium-webdriver": "3.0.4",
    "@types/source-map": "^0.5.0",
    "@types/uglify-js": "^2.0.27",
    "@types/webpack": "^2.2.15",
    "angular2-template-loader": "^0.6.0",
    "awesome-typescript-loader": "^3.1.3",
    "codelyzer": "~3.0.1",
    "copy-webpack-plugin": "^4.0.0",
    "css-loader": "^0.28.4",
    "exports-loader": "^0.6.4",
    "expose-loader": "^0.7.1",
    "extract-text-webpack-plugin": "^2.1.0",
    "file-loader": "^0.11.1",
    "gh-pages": "^1.0.0",
    "html-webpack-plugin": "^2.21.0",
    "imports-loader": "^0.7.1",
    "istanbul-instrumenter-loader": "^2.0.0",
    "json-loader": "^0.5.4",
    "karma": "^1.2.0",
    "karma-chrome-launcher": "^2.0.0",
    "karma-coverage": "^1.1.1",
    "karma-jasmine": "^1.0.2",
    "karma-mocha-reporter": "^2.0.0",
    "karma-remap-coverage": "^0.1.1",
    "karma-sourcemap-loader": "^0.3.7",
    "karma-webpack": "2.0.3",
    "ng-router-loader": "^2.1.0",
    "node-sass": "^4.5.3",
    "parse5": "^3.0.2",
    "postcss-loader": "^2.0.5",
    "protractor": "^5.1.2",
    "raw-loader": "0.5.1",
    "resolve-url-loader": "^2.0.2",
    "rimraf": "^2.5.2",
    "sass-loader": "^6.0.5",
    "script-ext-html-webpack-plugin": "^1.3.2",
    "source-map-loader": "^0.2.1",
    "string-replace-loader": "1.2.0",
    "style-loader": "^0.18.1",
    "to-string-loader": "^1.1.4",
    "ts-helpers": "1.1.2",
    "ts-node": "^3.0.4",
    "tslint": "^5.3.2",
    "tslint-loader": "^3.5.3",
    "typedoc": "^0.7.1",
    "typescript": "2.3.4",
    "url-loader": "^0.5.8",
    "webpack": "^2.1.0-beta.25",
    "webpack-dev-middleware": "^1.6.1",
    "webpack-dev-server": "^2.1.0-beta.9",
    "webpack-md5-hash": "^0.0.5",
    "webpack-merge": "^4.1.0"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/angularclass/angular2-webpack-starter.git"
  },
  "bugs": {
    "url": "https://github.com/angularclass/angular2-webpack-starter/issues"
  },
  "engines": {
    "node": ">= 4.2.1",
    "npm": ">= 3"
  }
}

的package.json:

import json
import urllib.request
import pandas

url = urllib.request.urlopen('https://www.cryptocompare.com/api/data/coinlist/')
json_obj = json.load(url)
print(json.dumps(json_obj, sort_keys=True, indent=4))

json_data = json_obj['Data']
print(json.dumps(json_data, sort_keys=True, indent=4))

df = pandas.DataFrame(json_data)
with pandas.option_context('display.max_rows', None, 'display.max_columns', 3):
    print(df)

2 个答案:

答案 0 :(得分:1)

更新:

正如@ developer033指出的那样,ng2-admin最近更新为Angular-cli而不是angular2-webpack-starter。

原始答案:

发布完整答案

运行以下两个命令来构建和运行服务器(如@ developer033所述):

npm run build:prod (npm run clean:dist && npm run clean:aot && webpack --config config/webpack.prod.js --progress --profile --bail)
npm run server:prod

在我的情况下,我在不同的地址上并行运行JIT和AOT:

enter image description here

http://127.0.0.1:8080是JIT,休息是AOT

要验证您的构建是否为AOT,请检查@Maximus提到的主捆绑文件。此外,您可以暂时禁用UglifyJsPlugin优化代码,以检查主捆绑js。

enter image description here

最后我在AOT版本中遇到了以下错误:

  

“未捕获的TypeError:无法读取属性'setGlobalVar'的null”

为了解决这个问题,我简单地评论了disableDebugTools();在我的environment.ts文件中。

注意:
我使用angular2-webpack-starter创建了项目模板,对于AOT我引用了ng2-admin

答案 1 :(得分:0)

正如@ developer033所提到的,在运行npm run build:aot之后,你应该运行npm run server:prod来运行基于dist文件夹的文件。

  

应用程序在运行npm run server:prod后运行,但我该如何验证   如果它的AOT优化

Angular应用程序使用不同的方法来引导应用程序,具体取决于它是AOT还是JIT编译。对于它使用的JIT编译应用程序:

bootstrapModule();

对于编译的AOT,它使用:

bootstrapModuleFactory();

最简单的检查可能是检查加载到浏览器的main.bundle.js并查找这两者中的任何一个。

另一种选择可以简单地将编译器注入任何组件,可能是根组件,并查看Angular是否报告错误,因为默认情况下JIT编译器不包含在包中。