WebPack Optimization with Awesome-Typescript-Loader Doesn't See Big Improvement

I am trying to improve my productivity in WebPack, so I disabled TS-Loaderfor Awesome-TypeScript-Loader, and the compilation time increased only slightly. I heard that it ATLshould be much faster, but I just shaved off, maybe a few 100 ms.

Here is my webpack.config.js:

'use strict';

const webpack               = require('webpack');
const path                  = require('path');
const HtmlWebpackPlugin     = require('html-webpack-plugin');
const CommonsChunkPlugin    = webpack.optimize.CommonsChunkPlugin;
const CleanWebpackPlugin    = require('clean-webpack-plugin');
const StyleLintPlugin       = require('stylelint-webpack-plugin');
const WebpackNotifierPlugin = require('webpack-notifier');
const { CheckerPlugin, TsConfigPathsPlugin }     = require('awesome-typescript-loader')

// const ExtractTextPlugin = require('extract-text-webpack-plugin')

// borrowed from the ng2 seed
const entryPoints = ['inline', 'polyfills', 'sw-register', 'styles', 'vendor', 'app'];

const htmlConfig = {
  template: 'client/_index.html',
  filename: 'index.html',
  // borrowed from the ng2 seed
  chunksSortMode: (left, right) => {
    const leftIndex = entryPoints.indexOf(left.names[0]);
    const rightIndex = entryPoints.indexOf(right.names[0]);
    if (leftIndex > rightIndex) {
      return 1;
    } else if (leftIndex < rightIndex) {
      return -1;
    } else {
      return 0;
    }
  }
};

function isExternal(module) {
  const match = typeof module.userRequest === 'string' &&
    /node_modules/.test(module.userRequest.split('!').pop());
  return match;
}

// const extractCSS = new ExtractTextPlugin({ filename: '[name].[hash].css', allChunks: true })
// const extractJS = new ExtractTextPlugin({ filename: '[name].[hash].js', allChunks: true })

module.exports = {
  cache: true,
  entry: {
    polyfills: './client/app/polyfills.js',
    // base: './client/base.js',
    app: './client/app/app.ts'
  },
  output: {
    // Absolute output directory
    path: path.join(__dirname, '/dist/'),

    // Output path from the view of the page
    // Uses webpack-dev-server in development
    publicPath: '/',

    // Filename for entry points
    // Only adds hash in build mode
    filename: '[name].[hash].js',

    // Filename for non-entry points
    // Only adds hash in build mode
    chunkFilename: '[name].[hash].js'
  },
  resolve: {
    modules: [
      path.resolve(__dirname, 'client'),
      'node_modules'
    ],
    extensions: ['.ts', '.js'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      'vue-router$': 'vue-router/dist/vue-router.esm.js',
      'vuex$': 'vuex/dist/vuex.esm.js',
      'vuex-class$': 'vuex-class/dist/vuex-class.cjs.js',
      'styles': path.resolve(__dirname, 'client/app/styles'),
      'core': path.resolve(__dirname, 'client/app/core'),
      'components': path.resolve(__dirname, 'client/app/components'),
      'containers': path.resolve(__dirname, 'client/app/containers'),
      'assets': path.resolve(__dirname, 'client/assets'),
      'config': path.resolve(__dirname, 'client/config')
    }
  },
  // Use 'source-map' for more accurate source mapping
  // Use 'cheap-module-eval-source-map' for faster rebuilding
  devtool: 'cheap-module-eval-source-map',
  module: {
    rules: [
      {
        // ES LINT LOADER
        // Reference: https://github.com/MoOx/eslint-loader
        // Lint ECMAScript
        enforce: 'pre',
        test: /\.js$/,
        use: [
          { loader: 'eslint-loader', options: { cache: true } }
        ],
        include: [path.resolve(__dirname, 'client')]
      },
      {
        // TS LINT LOADER
        // Reference: https://github.com/wbuchwalter/tslint-loader
        // Lint TypeScript
        enforce: 'pre',
        test: /\.ts$/,
        use: ['tslint-loader'],
        include: [path.resolve(__dirname, 'client')]
      },
      {
        // SOURCE MAP LOADER
        // Reference: https://github.com/webpack-contrib/source-map-loader
        // Extracts SourceMaps for source files that as added as sourceMappingURL comment
        enforce: 'pre',
        test: /\.(j|t|s?(a|c)s)s$/, // ts or js or css or scss or sass (or ass)
        use: ['source-map-loader'],
        exclude: [path.resolve(__dirname, 'node_modules/css-loader/lib/convert-source-map.js')] // There is a sourceMappingURL example in this file that triggers a warning
      },
      {
        // JS LOADER
        // Reference: https://github.com/babel/babel-loader
        // Transpile .js files using babel-loader
        // Compiles ES6 and ES7 into ES5 code
        test: /\.js$/,
        use: [
          { loader: 'babel-loader', options: { sourceMap: true, cacheDirectory: true } }
        ],
        exclude: [path.resolve(__dirname, 'node_modules')]
      },
      {
        // AWESOME TYPESCRIPT LOADER
        // Reference: https://github.com/s-panferov/awesome-typescript-loader
        // Transpile .ts files using awesome-typescript-loader
        // Compiles TS into ES6 code
        test: /\.ts$/,
        use: [
          // { loader: 'babel-loader', options: { sourceMap: true, cacheDirectory: true } },
          // { loader: 'ts-loader' }
          { loader: 'awesome-typescript-loader', options: { sourceMap: true, useCache: true, useBabel: true, useTranspileModule: true } }
        ],
        exclude: [path.resolve(__dirname, 'node_modules')]
      },
      {
        // ASSET LOADER
        // Reference: https://github.com/webpack/url-loader
        // Copy png, jpg, jpeg, gif, svg, woff, woff2, ttf, eot files to output
        // Rename the file using the asset hash
        // Pass along the updated reference to your code
        // You can add here any file extension you want to get copied to your output
        test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot|mp4)([?]?.*)$/,
        use: [
          { loader: 'file-loader', options: { name: 'assets/[name].[hash].[ext]' } }
        ]
      },
      {
        // HTML LOADER
        // Reference: https://github.com/webpack/html-loader
        // Allow loading html through js
        test: /\.html$/,
        use: [
          {
            loader: 'html-loader',
            options: {
              sourceMap: true,
              exportAsEs6Default: true,
              root: path.resolve(__dirname, 'client'),
              // Look for and process the following tag:attr on html elements
              attrs: [
                'img:src',
                'video:src'
              ]
            }
          }
        ]
      },
      {
        // CSS LOADER
        // Reference: https://github.com/webpack-contrib/css-loader
        test: /\.css$/,
        use: [
          'style-loader',
          { loader: 'css-loader', options: { sourceMap: true, importLoaders: 1 } },
          { loader: 'postcss-loader', options: { sourceMap: true } }
        ]
      },
      {
        // SASS LOADER
        // Reference: https://github.com/jtangelder/sass-loader
        test: /\.s(a|c)ss$/,
        use: [
          'style-loader',
          { loader: 'css-loader', options: { sourceMap: true, importLoaders: 2 } },
          { loader: 'postcss-loader', options: { sourceMap: true } },
          { loader: 'sass-loader', options: { sourceMap: true } }
        ]
      }
    ]
  },
  plugins: [
    new webpack.LoaderOptionsPlugin({
      cache: true,
      debug: true,
      minimize: false
    }),
    new webpack.NamedModulesPlugin(),
    new WebpackNotifierPlugin(),
    new TsConfigPathsPlugin(),
    new CheckerPlugin(),
    new StyleLintPlugin({
      files: ['./client/**/*.s?(a|c)ss']
    }),
    // Remove dist and build directories before building
    new CleanWebpackPlugin(['dist']),
    // extractCSS,
    new CommonsChunkPlugin({
      name: 'vendor',
      // Only analyze the app entry point, we don't want to change the others
      chunks: ['app'],
      // Check if module is in node_modules
      minChunks: (module) => {
        return isExternal(module);
      }
    }),
    new HtmlWebpackPlugin(htmlConfig)
  ],
  devServer: {
    historyApiFallback: true,
    compress: false,
    inline: true,
    hot: true
  }
};

And my tsconfig.json:

{
  "compilerOptions": {
    "allowJs": true,
    "target": "ES2017",
    "module": "ES2015",
    "moduleResolution": "Node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "forceConsistentCasingInFileNames": true,
    "allowSyntheticDefaultImports": true,
    "noEmitHelpers": true,
    "importHelpers": true,
    "pretty": true,
    "alwaysStrict": true,
    "lib": [
      "DOM",
      "ES2017",
      "DOM.Iterable",
      "ScriptHost"
    ],
    "baseUrl": ".",
    "paths": {
      "styles/*": ["./client/app/styles/*"],
      "core/*": ["./client/app/core/*"],
      "components/*": ["./client/app/components/*"],
      "containers/*": ["./client/app/containers/*"],
      "assets/*": ["./client/assets/*"],
      "config/*": ["./client/config/*"]
    }
  }
}

And the .babelrc file:

{
  "presets": [
    [
      "env", {
      "modules": false,
      "useBuiltIns": true,
      "debug": true,
      "targets": {
        "browsers": [
          "last 1 Chrome version"
        ]
      }
    }]
  ]
}

I am targeting ES2017 from TS and leaving it to Babel to compile for our target browser; since in the development we want to get additional performance of our own code and less difference transmitted coutput.

It seems like he hanged himself on Babylon, especially when he got stuck in the asset optimization phase.
TS-loader + Babel: ~ 1500 ms
ATL + Babel: ~ 1100ms
ATL - Babel: ~ 800ms

, ATL useCache: true/false useTranspileModule: true/false. , TON .awcache, , (, - ).

webpack-dev- :
webpack-dev-server --watch --hot --progress --open

, .

!

!

+4

Source: https://habr.com/ru/post/1672501/


All Articles