Webpack, Typescript and Angular2 with Ahead Of Time (AOT) compilation?

后端 未结 2 2051
太阳男子
太阳男子 2020-12-25 14:53

The latest release of Angular2 allows for Ahead of time (AOT) compilation, using this code in your app.bootstrap.ts file:

// The browser platform without a co         


        
相关标签:
2条回答
  • 2020-12-25 15:57

    I got it working finally, see my repo Angular2 Webpack2 DotNET Starter

    There are several tricks necessary. Note that AOT compilation does not support any require() statements in your Angular 2 components. They will need to be converted to import statements.

    First, you need to have a second tsconfig.json file, with special options for AOT compilation. I designate this with .aot.json extension.

    tsconfig.aot.json :

    {
       "compilerOptions": {
          "target": "es5",
          "emitDecoratorMetadata": true,
          "experimentalDecorators": true,
          "allowSyntheticDefaultImports": false,
          "noEmitHelpers": true,
          "pretty": true,
          "strictNullChecks": false,
          "baseUrl": ".",
          "sourceMap": true,
          "sourceRoot": ".",
          "lib": [
             "es6",
             "dom"
          ],
          "types": [
             "lodash",
             "hammerjs",
             "jasmine",
             "node",
             "selenium-webdriver",
             "source-map",
             "uglify-js",
             "webpack",
             "materialize-css",
             "jquery",
             "kendo-ui"
          ],
          "typeRoots": [
             "./node_modules/@types"
          ],
          "outDir": "./compiled/src"
       },
       "exclude": [
          "./node_modules",
          "./**/*.e2e.ts",
          "./**/*.spec.ts",
       ],
       "awesomeTypescriptLoaderOptions": {
          "useWebpackText": true,
          "forkChecker": true,
          "useCache": true
       },
       "compileOnSave": false,
       "buildOnSave": false,
       "atom": {
          "rewriteTsconfig": false
       },
       "angularCompilerOptions": {
          "genDir": "./compiled/aot",
          "debug": true
       }
    }
    

    You'll also need the exact right combination of verions of Angular2. @angular/core@2.0.2 and @angular/common@2.0.2 did NOT work for me, I had to use 2.0.0 for both or ngc failed to compile the AOT files. Here's what I'm using successfully:

    package.json :

      "dependencies": {
        "@angular/core": "2.0.0",
        "@angular/common": "2.0.0",
        "@angular/compiler": "2.0.0",
        "@angular/compiler-cli": "0.6.2",
        "@angular/forms": "^2.0.1",
        "@angular/http": "2.0.0",
        "@angular/platform-browser": "2.0.0",
        "@angular/platform-browser-dynamic": "2.0.0",
        "@angular/platform-server": "2.0.0",
        "@angular/router": "3.0.0",
        "@angular/tsc-wrapped": "0.3.0"
    }
    

    In addition, you'll need a couple nifty webpack loaders, while also allowing webpack to look in the ./src folder as well as the folder your AOT compiled files are output to. (*.component.ngfactory.ts)

    That last part is very important! If you don't tell webpack to include it those folders, it won't work. In this example, the AOT files are output to /aot-compiled in the root folder.

    webpack.common.js

      loaders: [
         {
            test: /\.ts$/,
            include: [helpers.paths.appRoot, helpers.root('./compiled/aot')],
            exclude: [/\.(spec|e2e)\.ts$/],
            loaders: [
               '@angularclass/hmr-loader',
               'awesome-typescript-loader',
               'angular2-template-loader',
               'angular2-router-loader?loader=system',
               "angular2-load-children-loader" // this loader replaces loadChildren value to work with AOT/JIT
            ],
         },
      ]
    

    To generate your AOT files, you'll need an NPM script to do it for you

    package.json

       "scripts": {
          "compile:aot": "./node_modules/.bin/ngc -p ./tsconfig.aot.json",
       }
    

    You'll also need to make your webpack config read the AOT version of app.bootstrap.ts - which is different from the JIT version. I differentiate it with .aot.ts extension so that in production, webpack uses AOT (app.bootstrap.aot.ts), but in dev mode, it uses JIT with webpack-dev-server (app.bootstrap.ts).

    Finally, you run npm run compile:aot FIRST. Once your AOT files are output to disk, you run your webpack build with either webpack or webpack-dev-server.

    For a working example, see my repo Angular2 Webpack2 DotNET Starter. It's integrated with .NET Core 1.0, but for those not using .NET, you can still see how Webpack 2 and Angular 2 are configured.

    0 讨论(0)
  • 2020-12-25 15:58

    tsconfig.json

        {
          "compilerOptions": {
            "target": "es5",
            "module": "es2015",
            "moduleResolution": "node",
            "sourceMap": true,
            "emitDecoratorMetadata": true,
            "experimentalDecorators": true,
            "lib": ["es2015", "dom"],
            "noImplicitAny": true,
            "suppressImplicitAnyIndexErrors": true,
            "typeRoots": [
              "./node_modules/@types/"
            ]
          },
          "angularCompilerOptions": {
            "genDir": "aot",
            "skipMetadataEmit" : true
          }
        }
    

    config/webpack-aot.config.js

    /**
     * webpack2 config file for ng2 AOT compile
     * location : config/webpack.aot.js
     */
    var webpack = require('webpack');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    var ExtractTextPlugin = require('extract-text-webpack-plugin');
    var helpers = require('./helpers');
    
    const ngToolsWebpack = require('@ngtools/webpack');
    const ENV = process.env.NODE_ENV = process.env.ENV = 'production';
    console.log(helpers.root('src', 'app', 'app.module#AppModule'));
    module.exports = {
      devtool: 'source-map',
      entry: {
        'polyfills': './src/polyfills.ts',
        'app': './src/main.ts'
      },
      resolve: {
        extensions: ['*', '.ts', '.js']
      },
      output: {
        path: helpers.root('dist'),
        publicPath: '/',
        filename: '[name].[hash].js',
        chunkFilename: '[id].[hash].chunk.js'
      },
    
      module: {
        rules: [
          {
            test: /\.ts$/,
            loader: '@ngtools/webpack'
          },
          {
            test: /\.html$/,
            loader: 'html-loader'
          },
          {
            test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
            include: helpers.root('public', 'images'),
            loader: 'file-loader',
            options: {
              //name: '/assets/[name].[hash].[ext]'  <-file-loaderError
              name: 'assets/[name].[ext]'
            }
          },
          {
            test: /\.css$/,
            exclude: helpers.root('src', 'app'),
            loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader' })
          },
          {
            test: /\.css$/,
            include: helpers.root('src', 'app'),
            loader: 'raw-loader'
          },
          {
            test: /\.scss$/,
            exclude: /node_modules/,
            loaders: ['raw-loader', 'sass-loader']
          },
          {
            test: /\.sass$/,
            exclude: /node_modules/,
            loaders: ['raw-loader', 'sass-loader']
          }
        ]
      },
    
      plugins: [
        // If you want to use jquery in ng2 uncomment this
        /*
        new webpack.ProvidePlugin({
          $: "jquery",
          jQuery: "jquery"
        }),*/
        new ngToolsWebpack.AotPlugin({
          tsConfigPath: helpers.root('tsconfig-aot.json'),
          basePath: helpers.root(''),
          entryModule: helpers.root('src', 'app', 'app.module#AppModule'),
          mainPath: helpers.root('src', 'main.ts')
        }),
        new webpack.optimize.CommonsChunkPlugin({
          name: ['app', 'polyfills']
        }),
        new webpack.LoaderOptionsPlugin({
          minimize: true,
          options: {
            htmlLoader: {
              minimize: false
            }
          }
        }),
        new HtmlWebpackPlugin({
          template: 'public/index.html'
        }),
        new webpack.optimize.UglifyJsPlugin({
          compress: {
              warnings: false,
              drop_console: true
          },
          output: {
              comments: false
          }
        }),
        new ExtractTextPlugin('[name].[hash].css'),
        new webpack.DefinePlugin({
          'process.env': {
            'ENV': JSON.stringify(ENV)
          }
        })
      ]
    };
    

    I used this webpack config and I did AOT compile with angular2 lazy loading. You can see example app for AOT / JIT compile with angular2 lazy load for production mode and dev mode in this git.

    angular2-webpack2-aot

    0 讨论(0)
提交回复
热议问题