如何使用 webpack 创建 tree shakable 库

How to create tree shakable library with webpack

我正在尝试使用 webpack 创建一个 tree shakable 库,但它不起作用。无论我做什么,当我在一个单独的项目中使用该库时,整个库都包含在输出中。

图书馆

这里是库的相关文件。

src/sdk/index.ts

export const addOne = function(x: number): number {
  return x + 1;
}

export const addTwo = function(x: number): number {
  return x + 2;
}

export const addThree = function(x: number): number {
  return x + 3;
}

tsconfig.json

{
    "compilerOptions": {
        "target": "es6",
        "module": "es6",
        "declaration": false,
        "sourceMap": false,
        "outDir": "./dist/",
        "strict": true,
        "moduleResolution": "node",
        "allowJs": true,
        "strictPropertyInitialization": false,
        "lib": [
            "es2015", 
            "dom"
        ],
        "typeRoots": [
            "src/customTypes",
            "node_modules/@types"
        ]
    }
}

package.json

{
  "name": "test",
  "version": "0.3.0",
  "description": "",
  "scripts": {
    "build": "webpack --config webpack.prod.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "clean-webpack-plugin": "^3.0.0",
    "ts-loader": "^8.0.14",
    "typescript": "^4.1.3",
    "webpack": "^5.14.0",
    "webpack-cli": "^4.3.1"
  },
  "sideEffects": false
}

webpack.prod.js

const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');



module.exports ={
    mode: 'production',
    entry: {
        'test': './src/sdk/index.ts',
    },
    output: {
        filename: '[name].js',
        path: path.resolve(__dirname, 'dist'),
        libraryTarget: 'umd',
        library: 'test',
        umdNamedDefine: true,
    },
    resolve: {
        extensions: ['.tsx', '.ts', '.js'],
    },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                loader: 'ts-loader',
                exclude: /node_modules/,
            },
        ],
    },
    plugins: [
        new CleanWebpackPlugin(),
    ],
};

示例

这里是使用该库的样本的文件。上述库的输出放在 src 文件夹中,在 sample.js

旁边

sample.js

import { addOne } from './test';

console.log('HELLO')
console.log(addOne(1));

webpack.prod.js

const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');


module.exports = {
    mode: 'production',
    entry: {
        'sample': './src/sample.js',
    },
    output: {
        filename: '[name].js',
        path: path.resolve(__dirname, 'dist'),
        libraryTarget: 'umd',
        library: 'sample',
        umdNamedDefine: true,
    },
    plugins: [
        new CleanWebpackPlugin(),
        new CopyPlugin({
            patterns: [
                { from: 'src/index.html', to: path.resolve(__dirname, 'dist') },
            ]
        })
    ],
};

当我打开示例的输出时,我可以看到库中的所有函数都在那里。它应该只有 addOne,因为这是我导入的唯一一个。

如果我不使用示例中的库,而是创建一个与库内容相同的文件:

export const addOne = function(x){
  return x + 1;
}

export const addTwo = function(x){
  return x + 2;
}

export const addThree = function(x){
  return x + 3;
}

然后 tree shaking 正常工作。 addTwo 和 AddThree 不存在。

所以我认为问题在于我如何生成库以及我将 libraryTarget 设置为 umd,但我没有看到任何指定 esm 的选项。或者可能是其他原因。

原来 Webpack 还不能这样做:https://github.com/webpack/webpack/issues/2933。 希望这将在下一个主要版本中可用。我暂时使用 Rollup。