Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Uglify Typescript files using Webpack

I have a webpack configuration that works perfectly with typescript until I have to minify the output bundle. I have a project that is being incrementally updated to typescript - currently one file has been migrated to typescript and it works properly when I run babel-node and my dev bundle (which doesn't use Uglify to minify the js). However, as soon as I run my prod bundle, I get the following error:

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

This is my webpack config:

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 looks like this:

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
like image 952
pradyuman Avatar asked Apr 20 '17 06:04

pradyuman


1 Answers

That is because at the moment UglifyJsPlugin only works with es5 and you are probably using es6 or es2017. Check your tsconfig.json file and make sure it is setup to use es5

like image 200
Aleks Avatar answered Sep 24 '22 18:09

Aleks