如何使用 Webpack 对 Typescript 文件进行 Uglify

Posted

技术标签:

【中文标题】如何使用 Webpack 对 Typescript 文件进行 Uglify【英文标题】:How to Uglify Typescript files using Webpack 【发布时间】:2017-09-16 15:11:40 【问题描述】:

我有一个 webpack 配置,可以完美地与 typescript 配合使用,直到我必须缩小输出包。我有一个项目正在逐步更新为 typescript - 目前一个文件已迁移到 typescript 并且当我运行 babel-node 和我的开发包(它不使用 Uglify 来缩小 js)时它可以正常工作。但是,一旦我运行我的产品包,我就会收到以下错误:

ERROR in main.ab0b2e37030c63351bb8.js from UglifyJs
SyntaxError: Unexpected token: name (App) [./components/App.ts:12,0]

这是我的 webpack 配置:

const config = 
  context: ROOT,

  output: 
    path: path.resolve(__dirname, '../build/public/assets'),
    publicPath: '/assets/',
    sourcePrefix: '  ',
  ,

  module: 
    loaders: [
      
        test: /\.tsx?$/,
        loader: "awesome-typescript-loader"
      ,
      
        enforce: "pre",
        test: /\.js$/,
        loader: "source-map-loader"
      ,
      
        test: /\.jsx?$/,
        loader: 'babel-loader',
        include: [
          ROOT
        ],
        query: 
          cacheDirectory: DEBUG,

          babelrc: false,
          presets: [
            'react',
            'es2015',
            'stage-0',
          ],
          plugins: [
            'transform-runtime',
            [
              'react-css-modules',
              
                context: ROOT,
                generateScopedName: CSS_SCOPE_NAME
              
            ],
            'transform-decorators-legacy',
            ...DEBUG ? [] : [
              'transform-react-remove-prop-types',
              'transform-react-constant-elements',
              'transform-react-inline-elements'
            ],
          ],
        ,
      ,
      
        test: /\.css/,
        loaders: [
          'isomorphic-style-loader',
          `css-loader?$JSON.stringify(
            sourceMap: DEBUG,
            modules: true,
            importLoaders: 1,
            localIdentName: CSS_SCOPE_NAME,
            minimize: !DEBUG,
          )`,
          'postcss-loader?pack=default',
        ],
      ,
      
        test: /\.scss$/,
        loaders: [
          'isomorphic-style-loader',
          `css-loader?$JSON.stringify( sourceMap: DEBUG, minimize: !DEBUG )`,
          'postcss-loader?pack=sass',
          'sass-loader',
        ],
      ,
      
        test: /\.json$/,
        loader: 'json-loader',
      ,
      
        test: /\.txt$/,
        loader: 'raw-loader',
      ,
      
        test: /\.(png|jpg|jpeg|gif|svg|woff|woff2)$/,
        loader: 'url-loader',
        query: 
          name: DEBUG ? '[path][name].[ext]?[hash]' : '[hash].[ext]',
          limit: 10000,
        ,
      ,
      
        test: /\.(eot|ttf|wav|mp3)$/,
        loader: 'file-loader',
        query: 
          name: DEBUG ? '[path][name].[ext]?[hash]' : '[hash].[ext]',
        ,
      ,
    ],
  ,

  resolve: 
    root: ROOT,
    modulesDirectories: ['node_modules'],
    extensions: ['', '.webpack.js', '.web.js', '.js', '.jsx', '.json', '.ts', '.tsx'],
  ,

  cache: DEBUG,
  debug: DEBUG,

  stats: 
    colors: true,
    reasons: DEBUG,
    hash: VERBOSE,
    version: VERBOSE,
    timings: true,
    chunks: VERBOSE,
    chunkModules: VERBOSE,
    cached: VERBOSE,
    cachedAssets: VERBOSE,
    errorDetails: true
  
  
;

const clientConfig = _.merge(true, , config, 
  entry: './client.js',

  output: 
    filename: DEBUG ? '[name].js?[chunkhash]' : '[name].[chunkhash].js',
    chunkFilename: DEBUG ? '[name].[id].js?[chunkhash]' : '[name].[id].[chunkhash].js',
  ,

  target: 'web',

  plugins: [

    new webpack.DefinePlugin( ...GLOBALS, 'process.env.BROWSER': true ),

    new AssetsPlugin(
      path: path.resolve(__dirname, '../build'),
      filename: 'assets.js',
      processOutput: x => `module.exports = $JSON.stringify(x);`,
    ),

    new webpack.optimize.OccurrenceOrderPlugin(true),

    ...DEBUG ? [] : [

      new webpack.optimize.DedupePlugin(),

      new webpack.optimize.UglifyJsPlugin(
        compress: 
          screw_ie8: true, // jscs:ignore requireCamelCaseOrUpperCaseIdentifiers
          warnings: VERBOSE,
        ,
      ),

      new webpack.optimize.AggressiveMergingPlugin(),
    ],
  ],

  devtool: DEBUG ? 'source-map' : false,
);

App.ts 看起来像这样:

import * as React from 'react';
import  PropTypes  from 'react';
import  connect  from 'react-redux';

const ContextType = 
  store: PropTypes.object.isRequired,
  history: PropTypes.object.isRequired,
  insertCss: PropTypes.func.isRequired,
;


class App extends React.Component<any, any> 

  static propTypes = 
    context: PropTypes.shape(ContextType).isRequired,
    children: PropTypes.element.isRequired,
  ;

  static childContextTypes = ContextType;

  constructor(props: any) 
    super(props);
  

  getChildContext() 
    return this.props.context;
  

  render() 
    return React.Children.only(this.props.children);
  



export default App

【问题讨论】:

你为什么要丑化你的 TS 文件?除非我遗漏了什么,否则您应该丑化它生成的 JS? 是的,这正是我想做的——丑化它生成的 JS。我不知道为什么它首先试图丑化打字稿文件。 遗憾的是我不知道 WebPack 所以不确定你的配置文件是否有错误。希望知道 WebPack 的人能来帮忙。 【参考方案1】:

这是因为目前 UglifyJsPlugin 仅适用于 es5,而您可能使用的是 es6 或 es2017。检查您的 tsconfig.json 文件并确保它已设置为使用 es5

【讨论】:

以上是关于如何使用 Webpack 对 Typescript 文件进行 Uglify的主要内容,如果未能解决你的问题,请参考以下文章

对 CSS/图像资产使用 Webpack 时,Typescript 编译器“找不到模块”

如何在 Typescript 中使用 Webpack 'require' 和 'require.ensure'

如何使用编译器包含的构建(Vue、Typescript、Webpack)

使用源映射和 webpack 调试 typescript

如何防止 jquery 使用 webpack 和 typescript 导入两次?

如何使用 webpack、typescript、phaser 和 angular 配置全局 css 和 sass 样式表