【问题标题】:How to use webpack and ES6 with dependencies using a CommonJS module?如何通过 CommonJS 模块使用 webpack 和 ES6 与依赖项?
【发布时间】:2020-01-27 04:27:51
【问题描述】:

我正在使用 laravel 开发一个项目,该项目使用(因为它是默认的)webpack 来捆绑其资产。在那里,我确实依赖于一个包,而这个包又依赖于 lodash 和 deepdash。

由于 deepdash 是作为 lodash 的 mixin 提供的,因此它的用法(根据文档)如下所示:

// load Lodash if you need it
const _ = require('lodash');
//mixin all the methods into Lodash object
require('deepdash')(_);

或者,如果你想使用 ES6 语法(至少这是我的理解),它会转化为:

import _ from 'lodash';
import deepdash from 'deepdash';

deepdash(_);

完成之后,我现在尝试使用 webpack 创建一个捆绑包,以便在浏览器中使用。我的问题是,由于某种原因,webpack 似乎用一些“__webpack_require__”魔术功能替换了 lodash 的导入,这导致 lodash 不再是一个函数,并且浏览器这样说:

为了更好地演示我的问题,我创建了一个演示 github 存储库,只是尝试 webpack deepdash 和 lodash:ArSn/webpack-deepdash 这是浏览器抱怨的行:https://github.com/ArSn/webpack-deepdash/blob/master/dist/main.js#L17219

我在大量添加 babel 配置方面玩了很多,感觉我最好的选择是插件 babel-plugin-transform-commonjs-es2015-modules。我试过了,结果还是一样。

我觉得要么我对情况有深刻的误解,要么我错过了一件小事。然而,我一生都无法弄清楚它是哪一个,是什么。

旁注:

  • 我知道还有一个 ES6 版本的 deepdash,显然当同时使用这两个时,webpack 机制工作正常(正如在 deepdash 对 github issue I opened 的回复中所述),但依赖项我我使用的是不使用那些。此外,我并没有真正看到(或理解?)首先在那里拥有专用 ES6 版本的意义。
  • 同样的代码(以这种方式与 lodash 一起使用 deepdash)在 node.js 上执行时工作得很好,之前它没有与 webpack 捆绑,很明显。我应该提到它在这里使用了 require-syntax。

【问题讨论】:

  • import * as deepdash from 'deepdash'; 但我见过一些捆绑器将 glob 转换为对象,即使 module.exports 是一个函数。
  • 导致几乎(!)完全相同的错误,只有“不是函数”之前的(...)现在不显示
  • 你用的是什么版本?我在样板中遇到了同样的问题 "webpack": "^4.16.4", "webpack-cli": "^3.1.0"
  • 在示例 repo(重现问题)中,我使用的是 webpack 4.40.2 和 webpack-cli 3.3.9 - 都应该是最新的。我还没有发现关于 webpack 项目的报告问题,但也许我只是错过了它(或者是第一个发现它的人)
  • 我刚刚升级到 webpack 4.41.0 - 所以必须是最新的 - 但它产生的结果完全相同

标签: javascript webpack ecmascript-6 lodash commonjs


【解决方案1】:

在运行 deepdash 网站上的示例之一时,明确指向 deepdash 主模块对我有用:

import _ from 'lodash';
import deepdash from 'deepdash/deepdash';

deepdash(_);

Webpack uses 默认为 browser 条目:

  "main": "deepdash.js",
  "module": "es/standalone.js",
  "browser": "browser/deepdash.min.js",

这不适用于 Webpack 和静态导入 - 因为没有任何东西真正“导出”。

另外:通常这些条目并不指向缩小版本。这些通常仅适用于 CDN 用例,不适用于捆绑程序。

相反'deepdash/deepdash.js' 导出装饰器函数。

deepdash-es 构建基本上做同样的事情,只是它使用 es6 导出。也许这就是 treeshaking 可以开箱即用的方式。不太清楚……

为了规避“浏览器”问题 - deepdash 的作者可以简单地将其修改为使用“deepdash.js”或将其删除:

https://github.com/defunctzombie/package-browser-field-spec

如果您的模块是纯 javascript 并且可以在客户端和服务器环境中运行,那么您不需要浏览器字段。

【讨论】:

  • 这就像一个魅力!你能详细说明为什么这是必要的,或者更好的是,说 deepdash 必须改变什么,这样他们就不会破坏当前界面,而且它会以“标准方式”import deepdash from 'deepdash' 工作? deepdash 的维护者似乎非常愿意进行更改以使这项工作正常进行,因此我很乐意在 deepdash 上打开拉取请求,当然无论如何我都会接受您的回答
  • 我更新了我的答案。阅读这个很有趣。就捆绑的内部结构而言,我并不是真正的专家。
  • 你结束了我试图解决这个问题的晚上,但不幸失败了,非常感谢!
  • 您好,谢谢您的帮助。你在 Github 有同样的昵称吗?只是想将您添加到贡献者列表中
  • 我在 Github 中拥有相同的句柄。
猜你喜欢
  • 2021-11-27
  • 1970-01-01
  • 2017-10-27
  • 2018-03-17
  • 2015-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-10
相关资源
最近更新 更多