Angular 2 + Webpack用于生产部署

3

我希望使用Webpack来压缩所有JS和CSS文件以进行生产部署,但在开发模式下应该是格式化的。由于我对Webpack不熟悉,不确定如何使其工作。以下是我的Webpack配置,请问我如何修改它以便为开发和生产环境分别工作?

var webpack = require('webpack');
var path = require('path');

// Webpack Config
var webpackConfig = {
  entry: {
    'polyfills': './src/polyfills.browser.ts',
    'vendor':    './src/vendor.browser.ts',
    'main':       './src/main.browser.ts',
  },

  output: {
    path: './dist',
  },

  plugins: [
    new webpack.optimize.OccurenceOrderPlugin(true),
    new webpack.optimize.CommonsChunkPlugin({ name: ['main', 'vendor', 'polyfills'], minChunks: Infinity }),
  ],

  module: {
    loaders: [
      // .ts files for TypeScript
      { test: /\.ts$/, loaders: ['awesome-typescript-loader', 'angular2-template-loader'] },
      { test: /\.css$/, loaders: ['to-string-loader', 'css-loader'] },
      { test: /\.html$/, loader: 'raw-loader' },
      { test: /\.json$/, loader: 'json-loader' },
    ]
  }

};


// Our Webpack Defaults
var defaultConfig = {
  devtool: 'cheap-module-source-map',
  cache: true,
  debug: true,
  output: {
    filename: '[name].bundle.js',
    sourceMapFilename: '[name].map',
    chunkFilename: '[id].chunk.js'
  },

  module: {
    preLoaders: [
      {
        test: /\.js$/,
        loader: 'source-map-loader',
        exclude: [
          // these packages have problems with their sourcemaps
          path.join(__dirname, 'node_modules', 'rxjs'),
          path.join(__dirname, 'node_modules', '@angular2-material'),
          path.join(__dirname, 'node_modules', '@angular'),
        ]
      }
    ],
    noParse: [
      path.join(__dirname, 'node_modules', 'zone.js', 'dist'),
      path.join(__dirname, 'node_modules', 'angular2', 'bundles')
    ]
  },

  resolve: {
    root: [ path.join(__dirname, 'src') ],
    extensions: ['', '.ts', '.js', '.json']
  },

  devServer: {
    historyApiFallback: true,
    watchOptions: { aggregateTimeout: 300, poll: 1000 }
  },

  node: {
    global: 1,
    crypto: 'empty',
    module: 0,
    Buffer: 0,
    clearImmediate: 0,
    setImmediate: 0
  },
}

var webpackMerge = require('webpack-merge');
module.exports = webpackMerge(defaultConfig, webpackConfig);

当我启用Angular 2 enableProduction时,webpack也会调用生产代码并压缩JS和CSS。

3个回答

1
您可以创建一个 webpack.config.production.js 文件,然后在主 webpack.config.js 文件中像这样导入生产配置:
var environment = process.env.NODE_ENV ? process.env.NODE_ENV : "local"; var envSpecificConfig = require('./webpack.config.' + environment);
其中,environment 是由 gulp 或您的构建服务器或其他方式设置为环境变量的。
因此,原则上所有通用配置都将放在 webpack.config.js 中,生产配置将放在 webpack.config.production.js 中。
示例配置在此处(首先是 webpack.config.js):
var path = require('path');
var webpack = require('webpack');
var merge = require('extendify')({ isDeep: true, arrays: 'concat' });
var environment = process.env.NODE_ENV ? process.env.NODE_ENV : "local";
var envSpecificConfig = require('./webpack.config.' + environment);

module.exports = merge({

...all your standard stuff you already have here

}, envSpecificConfig);

然后在 webpack.config.production.js 文件中。

var webpack = require('webpack');
var path = require( 'path' );

module.exports = {
    plugins: [
        new webpack.optimize.UglifyJsPlugin({
            compress: { warnings: false },
            minimize: true,
            mangle: false // Due to https://github.com/angular/angular/issues/6678
        })
    ]
};

这样你就可以拥有任意数量的特定环境配置,并且只需设置环境变量以匹配配置文件名。

1

使用webpack和webpack.DefinePlugin设置不同的环境模式

最佳实践是为每个环境创建不同的文件,这样易于维护,并且可以根据环境有不同的配置。我创建了一个angular2 webpack种子项目,在config文件夹中可以找到webpack文件。

  1. webpack.common.js
  2. webpack.dev.js
  3. webpack.prod.js

DefinePlugin

DefinePlugin允许您创建全局常量,这些常量可以在编译时进行配置。这对于允许在开发构建和发布构建之间实现不同行为非常有用。例如,您可能使用全局常量来确定是否进行日志记录;也许您在开发构建中执行日志记录,但在发布构建中不执行。这就是DefinePlugin的作用。

示例

new webpack.DefinePlugin({
    PRODUCTION: JSON.stringify(true),
    VERSION: JSON.stringify("5fa3b9"),
    BROWSER_SUPPORTS_HTML5: true,
    TWO: "1+1",
    "typeof window": JSON.stringify("object")
})

DefinePlugin中传入的每个键都是一个标识符或多个标识符,用..连接。

  • 如果值是字符串,则将其用作代码片段。
  • 如果值不是字符串,则将其字符串化(包括函数)。
  • 如果值是对象,则所有键都以相同的方式定义。
  • 如果在键前加上typeof,则仅对typeof调用进行定义。

这些值将被内联到代码中,允许缩小处理以删除冗余条件。

示例

if (!PRODUCTION)
    console.log('Debug info')
if (PRODUCTION)
    console.log('Production log')

来源

Webpack种子


有没有一种方法可以在我们的Angular应用程序中读取DefinePlugin定义的常量?如果有,那么它是如何工作的? - IcedDante
可以通过将属性嵌套在 process.env 键下来实现:https://stackoverflow.com/questions/47898424/environment-based-properties-for-angular-2-app-served-by-webpack/47925780#47925780 - IcedDante

0

目前,我的做法是手动压缩生产环境的代码。虽然有点麻烦,但至少现在它可以胜任工作了。在配置文件中添加 minimize 参数,在运行监听器时加上该参数,即 webpack --watch --minimize,以下是代码:

...
var path = require('path');
var minimize = process.argv.indexOf('--minimize') !== -1;

...
...
...

if (minimize) {
  webpackConfig.plugins.push(new webpack.optimize.UglifyJsPlugin());
}
var webpackMerge = require('webpack-merge');
module.exports = webpackMerge(defaultConfig, webpackConfig);

为什么你不使用 Angular CLI 和 Webpack? - Nicolas Henneaux

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接