首页 > 解决方案 > 如何导出全局工作的模块并用于 ES6 导入

问题描述

目前我正在像这样导出:

module.exports = ReactCrop;
module.exports.getPixelCrop = getPixelCrop;
module.exports.makeAspectCrop = makeAspectCrop;
module.exports.containCrop = containCrop;

基本上采用一个类(函数)并将非默认导出添加到它。

这样做的好处是默认导出是一个函数ReactCrop。这意味着当它通过<script>标签全局包含时,这window.ReactCrop就是您所期望的。

但是,如果我将其更改为 ES6:

export {
  ReactCrop,
  ReactCrop as default,
  getPixelCrop,
  makeAspectCrop,
  containCrop,
};

它作为对象导出。这让eslint和 typescript 更快乐。否则,您必须:

import * as ReactCrop from...

要使 babel 将其转换为对象,就目前而言,这是行不通的:

import { getPixelCrop } from... 

但是,当全局使用该模块时,它会输出:

window.ReactCrop
{ReactCrop: ƒ, default: ƒ, getPixelCrop: ƒ, makeAspectCrop: ƒ, __esModule: true}

即用户必须做window.ReactCrop.ReactCrop才能访问该类。

问题:我怎样才能满足这两种情况,以便在全局范围内它仍然是一个函数,因为window.ReactCrop.ReactCrop它很恶心,但允许{ partialImports }并保持 eslint 和 typescript 高兴,因为他们找到了一个具有默认导出的对象?

PS 我正在使用 webpack 像这样导出:

output: {
  path: path.resolve('dist'),
  library: 'ReactCrop',
  libraryTarget: 'umd',
  filename: minified ? 'ReactCrop.min.js' : 'ReactCrop.js',
}

标签: javascriptwebpackecmascript-6babeljs

解决方案


我怎样才能满足这两种情况,以便在全球范围内它仍然是一个函数

如果您使用命名空间导入,这是不可能的。命名空间对象永远不是函数。

但是你可以这样做

import ReactCrop, * as ReactCropNs from "…";
Object.assign(ReactCrop, ReactCropNs);
window.ReactCrop = ReactCrop;

如果您想以这种形式在全球范围内使用它。我认为导出为全局时没有 webpack 选项可以自动执行此操作。

因为window.ReactCrop.ReactCrop很恶心

你可以window.ReactCrop.default改用。


推荐阅读