Search code examples
typescriptwebpackcommonjs

Webpack builds files which are not imported


Webpack is parsing files which I don't intend it to, and which I have not imported. As a result it throws errors about invalid imports in those files - errors which I do not wish to be concerned with during a build.

For example, from my latest build:

ERROR in ./src/app.e2e.ts
(1,23): error TS2307: Cannot find module 'protractor'.

However the file is not imported anywhere, as shown from profiling. It is prefetched, but I don't have any prefetch plugins configured.

enter image description here

Webpack config:

webpack.dev.js:

var webpack = require('webpack');
var webpackMerge = require('webpack-merge');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var ManifestRevisionPlugin = require('manifest-revision-webpack-plugin');
var commonConfig = require('./webpack.common.js');
var helpers = require('./helpers');

const ENV = process.env.NODE_ENV = process.env.ENV = 'production';

module.exports = webpackMerge(commonConfig, {
  devtool: 'source-map',

  output: {
    path: helpers.root('dist'),
    publicPath: '/static/',
    filename: '[name].[hash].js',
    chunkFilename: '[id].[hash].chunk.js'
  },

  htmlLoader: {
    minimize: false // workaround for ng2
  },

  plugins: [
    new webpack.NoErrorsPlugin(),
    new webpack.optimize.DedupePlugin(),
    new webpack.optimize.UglifyJsPlugin(),
    new ExtractTextPlugin('[name].[hash].css'),
    new webpack.DefinePlugin({
      'process.env': {
        'ENV': JSON.stringify(ENV)
      }
    }),

    new ManifestRevisionPlugin(helpers.root('dist', 'manifest.json'), {
      rootAssetPath: 'src'
    })
  ]
});

webpack.common.js:

var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var helpers = require('./helpers');

module.exports = {
  entry: {
    'polyfills': './src/polyfills.ts',
    'vendor': './src/vendor.ts',
    'app': './src/main.ts'
  },

  resolve: {
    extensions: ['', '.js', '.ts']
  },

  module: {
    loaders: [
      {
        test: /\.ts$/,
        loaders: ['ts', 'angular2-template-loader'],
      },
      {
        test: /\.html$/,
        exclude: helpers.root('src', 'partials'),
        loader: 'html'
      },
      {
        test: /\.html$/,
        include: helpers.root('src', 'partials'),
        loader: 'ngtemplate?relativeTo=' + helpers.root('src') + '&prefix=static!html'
      },
      {
        test: /\.css$/,
        exclude: helpers.root('src', 'app'),
        loader: ExtractTextPlugin.extract('style', 'css?sourceMap')
      },
      {
        test: /\.css$/,
        include: helpers.root('src', 'app'),
        loader: 'raw' // for angular2-template-loader
      },
      {
        test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
        loader: 'file?name=assets/[name].[hash].[ext]'
      }
    ]
  },

  plugins: [
    new webpack.ProvidePlugin({
      $: "jquery",
      jQuery: "jquery",
      jquery: "jquery",
      _: "underscore",
      io: "socket.io-client"
    }),

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

    new webpack.DefinePlugin({
      'RADREPORT_VERSION': JSON.stringify(helpers.loadFile('VERSION.txt'))
    })
  ]
};

Solution

  • Has to do with ManifestRevisionPlugin and rootAssetPath.

    It needs the rootAssetPath because I use it internally to walk that path which detects assets that aren't currently listed under the entry section of the webpack config.

    You might have let's say 1 javascript entry file and a few stylesheets (your main app, some vendor sheets, etc.). This is fine and dandy but what happens if you have 40 images? It would be unreasonable to have to keep a list of images there but without it being listed there then webpack really doesn't understand what to do with those files.

    To overcome that I walk the root path and ignore anything in ignorePaths. For each file it finds, it internally calls webpack.PrefetchPlugin on the file's path. This lets us tag the file with the md5 or whatever you select in your webpack config (outside the scope of this plugin) and have it emit the file.

    https://github.com/nickjj/manifest-revision-webpack-plugin/issues/2#issuecomment-108029177