How to import only small part of npm module in JS/TS using Webpack?

Viewed 1110

I want to use an npm module called typescript-collections in my project. But I only want to use a single class called LinkedList from that module. The problem is, when I use webpack to compile my project, it imports all of the 16 classes in the module. This seems like unnecessary bloat to me.

I have tried using:

import {LinkedList} from "typescript-collections"

But Webpack insists on bundling all other classes too:

Hash: 5c6a6a87ac1d30bb1baa
Version: webpack 3.8.1
Time: 1500ms
Asset                          Size      Chunks         Chunk Names
bundle.js                      120 kB     0  [emitted]  main
[8] ./src/main.ts              4.34 kB   {0} [built]
[9] ./src/GameObjectManager.ts 876 bytes {0} [built]
    + 16 hidden modules

I am pretty certain that LinkedList.ts does not depend on all 16 classes as I have commented out all exports apart from LinkedList.ts in Index.ts as a random test:

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
// Copyright 2013 Basarat Ali Syed. All Rights Reserved.
//
// Licensed under MIT open source license http://opensource.org/licenses/MIT
//
// Orginal javascript code was by Mauricio Santos
/*
var _arrays = require("./arrays");
exports.arrays = _arrays;
var Bag_1 = require("./Bag");
exports.Bag = Bag_1.default;
var BSTree_1 = require("./BSTree");
exports.BSTree = BSTree_1.default;
var Dictionary_1 = require("./Dictionary");
exports.Dictionary = Dictionary_1.default;
var Heap_1 = require("./Heap");
exports.Heap = Heap_1.default;
var LinkedDictionary_1 = require("./LinkedDictionary");
exports.LinkedDictionary = LinkedDictionary_1.default;*/
var LinkedList_1 = require("./LinkedList");
exports.LinkedList = LinkedList_1.default;
/*var MultiDictionary_1 = require("./MultiDictionary");
exports.MultiDictionary = MultiDictionary_1.default;
var FactoryDictionary_1 = require("./FactoryDictionary");
exports.FactoryDictionary = FactoryDictionary_1.default;
var FactoryDictionary_2 = require("./FactoryDictionary");
exports.DefaultDictionary = FactoryDictionary_2.default;
var Queue_1 = require("./Queue");
exports.Queue = Queue_1.default;
var PriorityQueue_1 = require("./PriorityQueue");
exports.PriorityQueue = PriorityQueue_1.default;
var Set_1 = require("./Set");
exports.Set = Set_1.default;
var Stack_1 = require("./Stack");
exports.Stack = Stack_1.default;
var MultiRootTree_1 = require("./MultiRootTree");
exports.MultiRootTree = MultiRootTree_1.default;
var _util = require("./util");
exports.util = _util;
//# sourceMappingURL=index.js.map

When I compile the project with the modified Index.ts file, Webpack does not include all of the classes and the program still works fine.

    Hash: 34703e4a9ff9a5f140d8
    Version: webpack 3.8.1
    Time: 1505ms
    Asset                         Size        Chunks             Chunk Names
bundle.js                         32 kB       0  [emitted]  main
   [1] ./src/main.ts              4.34 kB    {0} [built]
   [2] ./src/GameObjectManager.ts 876 bytes  {0} [built]
    + 4 hidden modules

So what I am asking is if there is proper a way to import a subset of a module without resorting to hacky methods. Also I am just getting into Frontend development, so the chance is high that I am overlooking something completely obvious. Thanks in advance.

Edit 1: This is my webpack.config.js file

const path = require('path');

module.exports = {
  entry: './src/main.ts',
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/
      }
    ]
  },
  resolve: {
    extensions: [ '.tsx', '.ts', '.js' ]
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  }
};

Edit 2: I have tried using the following flag

webpack --optimize-minimize

Which, as far as I understand, should also do "tree-shaking", but by searching through the bundle.js I still found definitions of classes that should not be needed.

Edit 3: This is my tsconfig.json

{
"exclude": ["node_modules/",
            "dist"],
"compilerOptions": 
{
    "target": "es5",
    "module": "commonjs",
    "sourceMap": true,
    "outDir": "dist/"
}
}

and my dependecies

  "devDependencies": {
"ts-loader": "^3.1.1",
"typescript": "^2.6.1",
"typescript-collections": "^1.2.5",
"uglifyjs-webpack-plugin": "^1.1.1",
"webpack": "^3.8.1"
 },
1 Answers
Related