【问题标题】:webpack + Angular 2 (rc5) - components not rendering in production buildwebpack + Angular 2 (rc5) - 组件未在生产构建中呈现
【发布时间】:2016-08-24 13:12:50
【问题描述】:

我一直在尝试使用带有 Angular 2 (RC5) 的 WebPack 进行生产构建。

在此处关注启动项目 https://github.com/AngularClass/angular2-webpack-starter

到目前为止,我已经能够完成以下工作:

  1. 开发构建、本地运行、实时重新加载等都没有问题
  2. 生产版本需要注意的是我的 Abngular 2 组件不渲染。控制台中没有错误(弃用警告除外)

那么,进入细节。

这是我的 webpack.config.common.js

const webpack = require('webpack');
const helpers = require('./webpack.helpers');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin;

const METADATA = {
  title: 'Angular2 Webpack Starter by @gdi2290 from @AngularClass',
  baseUrl: '/',
  isDevServer: helpers.isWebpackDevServer()
};

module.exports = {

  metadata: METADATA,

  entry: {
    'polyfills': './src/polyfills.ts',
    'vendor':    './src/vendor.ts',
    'main':      './src/main.ts'
  },

  resolve: {

    extensions: ['', '.ts', '.js', '.json'],

    root: __dirname + './src',

    modulesDirectories: ['node_modules'],

  },

  module: {

    preLoaders: [],

    loaders: [{
      test: /\.ts$/,
      loaders: [
        'awesome-typescript-loader',
        'angular2-template-loader',
        '@angularclass/hmr-loader'
      ],
      exclude: [/\.(spec|e2e)\.ts$/]
    }, {
      test: /\.less/,
      loader: "to-string!css!less"
    }, {
      test: /\.html$/,
      loader: 'raw-loader',
      exclude: [__dirname + './src/index.html']
    }, {
      test: /\.(jpg|png|gif)$/,
      loader: 'file'
    }]
  },

  plugins: [

    new ForkCheckerPlugin(),

    new webpack.optimize.OccurenceOrderPlugin(true),

    new webpack.optimize.CommonsChunkPlugin({
      name: ['polyfills', 'vendor'].reverse()
    }),

    new CopyWebpackPlugin([{
      from: './src/components/bootstrap/images/favicon.png',
      to: './assets/images/favicon.png'
    }, {  //TODO add using import?
      from: './node_modules/bootstrap/dist/css/bootstrap.min.css',
      to: './assets/vendor/bootstrap.min.css'
    }, {  //TODO add using import?
      context: './node_modules/bootstrap/dist/fonts/',
      from: '*',
      to: './assets/fonts/'  //bootstrap hardcoded path to fonts one directory up from the CSS... >:
    }, {  //TODO add using import?
      context: './node_modules/ckeditor/',
      from: '**/**',
      to: './assets/vendor/ckeditor/'
    }]),


    new HtmlWebpackPlugin({
      template: 'src/index.html',
      chunksSortMode: 'dependency'
    }),

  ],

  node: {
    global: 'window',
    crypto: 'empty',
    process: true,
    module: false,
    clearImmediate: false,
    setImmediate: false
  }

};

这是我的 webpack.config.dev.js

const helpers = require('./webpack.helpers');
const webpackMerge = require('webpack-merge');
const commonConfig = require('./webpack.config.common.js');
const DefinePlugin = require('webpack/lib/DefinePlugin');
const ENV = process.env.ENV = process.env.NODE_ENV = 'development';
const HOST = process.env.HOST || 'localhost';
const PORT = process.env.PORT || 3000;
const HMR = helpers.hasProcessFlag('hot');
const METADATA = webpackMerge(commonConfig.metadata, {
  host: HOST,
  port: PORT,
  ENV: ENV,
  HMR: HMR
});

module.exports = webpackMerge(commonConfig, {

  metadata: METADATA,

  debug: true,

  devtool: 'cheap-module-source-map',

  output: {

    path: __dirname + './build',

    filename: '[name].bundle.js',

    sourceMapFilename: '[name].map',

    chunkFilename: '[id].chunk.js',

    library: 'ac_[name]',
    libraryTarget: 'var',
  },

  plugins: [

    new DefinePlugin({
      'ENV': JSON.stringify(METADATA.ENV),
      'HMR': METADATA.HMR,
      'process.env': {
        'ENV': JSON.stringify(METADATA.ENV),
        'NODE_ENV': JSON.stringify(METADATA.ENV),
        'HMR': METADATA.HMR,
      }
    }),
  ],

  tslint: {
    emitErrors: false,
    failOnHint: false,
    resourcePath: 'src'
  },

  devServer: {
    port: METADATA.port,
    host: METADATA.host,
    historyApiFallback: true,
    watchOptions: {
      aggregateTimeout: 300,
      poll: 1000
    },
    outputPath: __dirname + '/build',
    proxy:{
      '/api/*': {
        target: 'http://analogstudios.thegreenhouse.io',
        secure: false,
        changeOrigin: true
      }
    }
  },

  node: {
    global: 'window',
    crypto: 'empty',
    process: true,
    module: false,
    clearImmediate: false,
    setImmediate: false
  }

});

这是我的 webpack.config.prod.js

const webpackMerge = require('webpack-merge');
const commonConfig = require('./webpack.config.common');
const ProvidePlugin = require('webpack/lib/ProvidePlugin');
const DefinePlugin = require('webpack/lib/DefinePlugin');
const NormalModuleReplacementPlugin = require('webpack/lib/NormalModuleReplacementPlugin');
const DedupePlugin = require('webpack/lib/optimize/DedupePlugin');
const UglifyJsPlugin = require('webpack/lib/optimize/UglifyJsPlugin');
const WebpackMd5Hash = require('webpack-md5-hash');


module.exports = webpackMerge(commonConfig, {

  debug: false,

  devtool: 'source-map',

  output: {

    path: __dirname + '/build',

    filename: '[name].[chunkhash].bundle.js',

    sourceMapFilename: '[name].[chunkhash].bundle.map',

    chunkFilename: '[id].[chunkhash].chunk.js'

  },

  plugins: [
    new WebpackMd5Hash(),

    new DedupePlugin(),

    new UglifyJsPlugin({
      beautify: false,
      compress: { screw_ie8: true },
      comments: false
    }),


    new NormalModuleReplacementPlugin(
      /angular2-hmr/,
      function() {}
    ),

  ],

  tslint: {
    emitErrors: true,
    failOnHint: true,
    resourcePath: 'src'
  },

  /**
   * Html loader advanced options
   *
   * See: https://github.com/webpack/html-loader#advanced-options
   */
  // TODO: Need to workaround Angular 2's html syntax => #id [bind] (event) *ngFor
  htmlLoader: {
    minimize: true,
    removeAttributeQuotes: false,
    caseSensitive: true,
    customAttrSurround: [
      [/#/, /(?:)/],
      [/\*/, /(?:)/],
      [/\[?\(?/, /(?:)/]
    ],
    customAttrAssign: [/\)?\]?=/]
  },

  //TODO needed?
  /*
   * Include polyfills or mocks for various node stuff
   * Description: Node configuration
   *
   * See: https://webpack.github.io/docs/configuration.html#node
   */
  node: {
    global: 'window',
    crypto: 'empty',
    process: false,
    module: false,
    clearImmediate: false,
    setImmediate: false
  }

});

这是我的主页“视图”HTML

<section class="as-view-home row">

  <div class="row">
    <div class="col-xs-10">

      <h2 class="welcome-text-heading">Welcome to Analog Studios</h2>

      <p class="welcome-text-body">Welcome to the up and coming new version of the Analog Studios website.  We have a
        lot of plans in-store and a lot of great features for sharing music and representing artists.  Over the next
        couple of months, we'll be gradually updating the site with more and more content and interactions.  Please
        keep in touch with us through social media by clicking our links.</p>

      <p>Checkout our latest posts and upcoming events, below!</p>

    </div>
  </div>

  <div class="row">
    <div class="col-xs-12">

      <div class="posts-container">
        <as-posts-list></as-posts-list>
      </div>

      <div class="row">
        <div class="col-xs-12">
          <as-events-calendar></as-events-calendar>
        </div>
      </div>

    </div>
  </div>

</section>

这是我的主页“视图”component.ts

import { Component } from '@angular/core';
import { EventsCalendarComponent } from '../../components/events-calendar/events-calendar.component';
import { PostsComponent } from '../../components/posts-list/posts-list.component';

@Component({
  selector: 'home',
  templateUrl: './home.html',
  styleUrls: [ './home.less' ],
  directives: <any>[EventsCalendarComponent, PostsComponent]
})


export class HomeViewComponent { }

在下面的屏幕截图中,您会注意到 &lt;as-posts-list&gt;&lt;as-event-calendar&gt; 是 DOM 元素,但它们没有内容。静态页面文本显示正常,但其中的组件不显示。这也发生在我的页眉和页脚组件(&lt;router-outlet&gt;&lt;/router-outlet&gt; 之外)

我看到的控制台错误(只是弃用警告)

vendor.0074bf4….bundle.js:1 NgModule t uses e via "entryComponents" but it was neither declared nor imported! This warning will become an error after final.
2016-08-24 10:40:36.707 vendor.0074bf4….bundle.js:1 NgModule t uses e via "entryComponents" but it was neither declared nor imported! This warning will become an error after final.
2016-08-24 10:40:36.707 vendor.0074bf4….bundle.js:1 NgModule t uses t via "entryComponents" but it was neither declared nor imported! This warning will become an error after final.
2016-08-24 10:40:36.707 vendor.0074bf4….bundle.js:1 NgModule t uses t via "entryComponents" but it was neither declared nor imported! This warning will become an error after final.
2016-08-24 10:40:36.707 vendor.0074bf4….bundle.js:1 NgModule t uses e via "entryComponents" but it was neither declared nor imported! This warning will become an error after final.
2016-08-24 10:40:36.707 vendor.0074bf4….bundle.js:1 NgModule t uses t via "entryComponents" but it was neither declared nor imported! This warning will become an error after final.
2016-08-24 10:40:37.000 vendor.0074bf4….bundle.js:1 Angular 2 is running in the development mode. Call enableProdMode() to enable the production mode.
2016-08-24 10:40:37.006 vendor.0074bf4….bundle.js:1 The PLATFORM_DIRECTIVES provider and CompilerConfig.platformDirectives is deprecated. Add the directives to an NgModule instead! (Directives: n,n,n,e,e,e,e,e,e,e,e,e,e,e,e,e)

提前感谢您的帮助!

【问题讨论】:

  • 你在 html 中的拼写选择器是否正确,请在控制台中显示错误
  • 我认为拼写应该没问题,除非从 dev 到 prod build 发生了变化。我将更新以包含弃用警告和 post-list.component.ts

标签: javascript angular webpack


【解决方案1】:

这似乎是新 RC5 版本中的一个错误。当时唯一的解决方法似乎是不要缩小构建。

https://github.com/angular/angular/issues/10618

【讨论】:

  • 谢谢!我一直在关注那个帖子,并且一直在跟进一些线索,包括那个线索。我计划在一切正常后发布(处理其他 RC5 / prod 构建问题),并且可以针对旧版本的代码进行验证,以确定到底需要什么(没有 -p 标志、重新排序组件和 @987654323 @ 在 UglifyJS 插件中)
猜你喜欢
  • 2020-12-21
  • 1970-01-01
  • 2016-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-25
  • 1970-01-01
相关资源
最近更新 更多