Невозможно встряхнуть дерево в веб-пакете, проект TypeScript

Моя цель состоит в том, чтобы встряхнуть дерево lodash (среди прочих) в моем webpack.prod.js, Вот мои файлы конфигурации. Для полноты картины я также включу webpack.dev.js, webpack.common.js, tsconfig.json а также package.json:

webpack.common.js:

const path = require('path');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    module: {
        rules: [
            {
                test: /\.(png|svg|jpg|gif|obj)$/,
                use: [
                    'file-loader'
                ]
            },
            {
                test: /\.glsl$/,
                loader: 'webpack-glsl-loader'
            },
            {
                test: /\.tsx?$/,
                use: 'ts-loader',
                exclude: /node_modules/
            },
            {
                test: /\.ts$/,
                enforce: 'pre',
                loader: 'tslint-loader',
                options: { failOnHint: true }
            }
        ]
    },
    resolve: {
        extensions: [".tsx", ".ts", ".js"]
    },
    entry: {
        app: './src/index.ts'
    },
    plugins: [
        new CleanWebpackPlugin(['dist']),
        new HtmlWebpackPlugin({
            title: 'Production'
        })
    ],
    output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, 'dist')
    }
};

webpack.dev.js:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const JarvisPlugin = require("webpack-jarvis");
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

module.exports = {
    module: {
        rules: [
            {
                test: /\.(png|svg|jpg|gif|obj)$/,
                use: [
                    'file-loader'
                ]
            },
            {
                test: /\.glsl$/,
                loader: 'webpack-glsl-loader'
            },
            {
                test: /\.tsx?$/,
                use: 'ts-loader',
                exclude: /node_modules/
            },
            {
                test: /\.ts$/,
                enforce: 'pre',
                loader: 'tslint-loader',
                options: { failOnHint: true }
            }
        ]
    },
    resolve: {
        extensions: [".tsx", ".ts", ".js"]
    },
    entry: {
        app: './src/index.ts'
    },
    devtool: 'inline-source-map',
    devServer: {
        contentBase: './dist'
    },
    plugins: [
        new HtmlWebpackPlugin({ title: 'urknall-core dev' }),
        new BundleAnalyzerPlugin({ analyzerPort: 8888 }),
        new JarvisPlugin({ port: 1337 }),
    ],
    output: {
        filename: '[name].bundle.js',
        publicPath: '/'
    }
};

webpack.prod.js:

const webpack = require('webpack');
const merge = require('webpack-merge');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const common = require('./webpack.common.js');

module.exports = merge(common, {
    devtool: 'source-map',
    plugins: [
        new UglifyJSPlugin({
            sourceMap: true,
            test: /\.js($|\?)/i,
            uglifyOptions: {
                compress: true
            }
        }),
        new webpack.LoaderOptionsPlugin({
            minimize: true,
            debug: false
        }),
        new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify('production')
        }),
    ]
});

tsconfig.json:

{
  "compilerOptions": {
    "outDir": "./dist/",
    "declaration": true,
    "declarationDir": "./types",
    "sourceMap": true,
    "noImplicitAny": true,
    "module": "commonjs",
    "target": "es6",
  }
}

package.json:

{
  "name": "bla",
  "version": "0.0.1",
  "description": "",
  "main": "index.ts",
  "types": "./dist/types/",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --config webpack.prod.js",
    "start": "webpack-dev-server --open --config webpack.dev.js",
    "watch": "webpack --watch"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@types/gl-matrix": "^2.4.0",
    "@types/lodash": "^4.14.104",
    "@types/node": "^8.9.4",
    "@types/webgl2": "^0.0.2",
    "@types/webpack-dev-middleware": "^1.12.3",
    "clean-webpack-plugin": "^0.1.18",
    "file-loader": "^0.11.2",
    "html-webpack-plugin": "^2.30.1",
    "image-webpack-loader": "^3.6.0",
    "style-loader": "^0.18.2",
    "ts-loader": "^2.3.7",
    "ts-node": "^3.3.0",
    "tslint": "^5.9.1",
    "tslint-loader": "^3.5.3",
    "typescript": "^2.7.1",
    "uglifyjs-webpack-plugin": "^1.2.2",
    "webpack": "^3.11.0",
    "webpack-bundle-analyzer": "^2.11.0",
    "webpack-dev-middleware": "^1.12.0",
    "webpack-dev-server": "^2.11.2",
    "webpack-glsl-loader": "^1.0.1",
    "webpack-jarvis": "^0.3.0",
    "webpack-merge": "^4.1.2"
  },
  "dependencies": {
    "gl-matrix": "^2.4.0",
    "lodash-es": "^4.17.5"
  }
}

С этой конфигурацией app.bundle.js приводит к файлу 507 КБ и app.bundle.js.map составляет 1,6 МБ. Если я не уменьшу вывод сборки, я вижу, что вся библиотека lodash записывается в файл. Я также вижу некоторые другие функции от т.е. gl-matrix записывается в файл, хотя я ими даже не пользуюсь.

Тоже бегу webpack-bundle-analyzer в разработке и выпуске не отличается от производства. Только мини-файл из-за минимизации составляет ~1,4 МБ вместо 1,6 МБ.

Я загружаю lodash только дважды во всем проекте, например:

import { some, find, cloneDeep } from 'lodash';

Больше не надо lodash функции когда-либо используются. Почему Webpack раздувать мой app.bundle.js?

Есть ли проблемы с моей конфигурацией?

1 ответ

Решение

Учитывая существующий стиль экспорта стандарта lodash Пакет у вас есть два варианта решения этой проблемы:

  1. Перейдите к пакету lodash, который использует экспорт таким образом, который будет вставлен непосредственно в ваш шаблон импорта. Как упомянуто @ alex-rokabilis в комментарии, один из доступных пакетов для этого - lodash-es
  2. Обновите свой импорт, чтобы работать экспорт, используемый стандартом lodash пакет. Если вы посмотрите на страницу npm от lodash, то увидите, что они предоставляют поддержку выбора метода вишни из путей.

    import some from 'lodash/fp/some';
    import find from 'lodash/fp/find';
    import cloneDeep from 'lodash/fp/cloneDeep';
    
Другие вопросы по тегам