gpt4 book ai didi

javascript - 如何从一个 NPM 包中导出多个 ES6 模块

转载 作者:行者123 更新时间:2023-12-01 14:45:56 24 4
gpt4 key购买 nike

我构建了一个相对较小的 NPM 包,其中包含大约 5 个不同的 ES6 类,每个类包含在一个文件中,它们看起来都非常像这样:

export default class MyClass {
// ...
}

然后我为我的包设置了一个入口点,如下所示:
export { default as MyClass } from './my-class.js';
export { default as MyOtherClass } from './my-other-class.js';

然后我通过 webpack 和 babel 运行入口点,最终得到一个转译和缩小的 index.js

安装和导入包工作正常,但是当我从客户端代码执行以下操作时:
import { MyClass } from 'my-package';

它不只是导入“MyClass”,而是导入整个文件,包括每个类的所有依赖项(我的一些类有很大的依赖项)。

我想这就是当你尝试导入已经捆绑的包的一部分时 webpack 的工作方式?所以我设置了我的本地 webpack 配置来运行 node_modules/my-package也通过 babel 然后尝试:
import { MyClass } from 'my-package/src/index.js';

但即便如此,它也会导入 index.js 导出的每一个类。唯一似乎按我想要的方式工作的事情是,如果我这样做:
import MyClass from 'my-package/src/my-class.js';

但我更愿意:
  • 能够导入转译和缩小的文件,这样我就不必告诉 webpack 在 node_modules 和
  • 中运行 babel
  • 能够直接从我的入口点导入每个单独的类,而不必输入每个文件的路径

  • 这里的最佳做法是什么?其他人如何实现类似的设置?我注意到 GlideJS 有一个 ESM 版本的包,它允许你只导入你需要的东西,而不必通过它运行 babel。

    有问题的包裹: https://github.com/powerbuoy/sleek-ui

    webpack.config.js
    const path = require('path');

    module.exports = {
    entry: {
    'sleek-ui': './src/js/sleek-ui.js'
    },
    output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'dist'),
    library: 'sleek-ui', // NOTE: Before adding this and libraryTarget I got errors saying "MyClass() is not a constructor" for some reason...
    libraryTarget: 'umd'
    },
    module: {
    rules: [
    {
    test: /\.js$/,
    exclude: /node_modules/,
    use: [
    {
    loader: 'babel-loader',
    options: {
    presets: ['@babel/preset-env']
    }
    }
    ]
    }
    ]
    }
    };

    包.json
      "name": "sleek-ui",
    "version": "1.0.0",
    "description": "Lightweight SASS and JS library for common UI elements",
    "main": "dist/sleek-ui.js",
    "sideEffects": false, // NOTE: Added this from Abhishek's article but it changed nothing for me :/
    "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --mode production"
    },
    "repository": {
    "type": "git",
    "url": "git+https://github.com/powerbuoy/sleek-ui.git"
    },
    "author": "Andreas Lagerkvist",
    "license": "GPL-2.0-or-later",
    "bugs": {
    "url": "https://github.com/powerbuoy/sleek-ui/issues"
    },
    "homepage": "https://github.com/powerbuoy/sleek-ui#readme",
    "devDependencies": {
    "@babel/core": "^7.8.6",
    "@babel/preset-env": "^7.8.6",
    "babel-loader": "^8.0.6",
    "webpack": "^4.42.0",
    "webpack-cli": "^3.3.11"
    },
    "dependencies": {
    "@glidejs/glide": "^3.4.1",
    "normalize.css": "^8.0.1"
    }
    }

    最佳答案

    I figured this is how webpack works when you try to import parts of an already bundled package?



    是的,您设置它的方式是导入 index.js 中的每个类,然后将其转换为一个文件(如果它以 ES5 为目标,这是最常见的*)。这意味着当该文件被导入另一个文件时,它会完整包含所有这些类。

    如果您想要正确的 tree-shaking,您应该避免将其转换为 CommonJS (ES5) 包。我的建议是将 ES6 模块单独保存或与 ES5 捆绑包分开保存。 This article should help you fully understand this and has recommended instructions.本质上,它归结为使用 preset-env 设置 Babel 环境(如果你还没有使用它,强烈推荐!)到 preserve ES6 syntax .这是相关的 Babel 配置,如果您不想转换为 ES5:

    {
    "presets": [
    [
    "@babel/preset-env",
    {
    "targets": {
    "esmodules": true
    }
    }
    ]
    ]
    }


    本文详细介绍了如何设置 2 个包,每个包都使用不同的模块语法。

    同样值得注意的是,文章中也提到过, you can set the ES module entry point在 package.json 中。这告诉 Webpack/Babel 在哪里可以找到 ES6 模块,这可能是您的用例所需的全部。似乎传统智慧说要做:
    {
    "main": "dist/sleek-ui.js",
    "module": "src/main.js"
    }

    但是 Node 文档将其描述为:
    {
    "type": "module",
    "main": "dist/sleek-ui.js",
    "exports": {
    ".": "dist/sleek-ui.js",
    "./module": "src/main.js"
    }
    }

    如果我有时间,我会玩这个,看看哪个工作正常,但这应该足以让你走上正确的道路。

    *针对 ES5 的包采用 CommonJS 格式,必须包含所有相关文件,因为 ES5 不支持原生模块。那是在 ES2015/ES6 中出现的。

    关于javascript - 如何从一个 NPM 包中导出多个 ES6 模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60507612/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com