我正在尝试创建一个不将文件捆绑在一起的构建管道,而是使用<script type="module">
。这样我就可以在不重新绑定的情况下重新编译文件,从而大大缩短开发过程中的构建时间。
我们的项目使用ES6,因此通常很容易。
但是有一个障碍:第三方模块只有CommonJS版本(例如反应)。
有几种方法可以解决这个问题。现在,我有一个转换,将导入名称从react
更改为/node_modules/react
,我的服务器非常智能,然后从dist
找到相应的node_modules
文件并提供服务它了。一切正常。
问题在于,当我尝试执行以下操作时会感到困惑:
import { Component } from 'react';
目前的情况不会起作用(因为它没有默认值而感到困惑)。但是,这将有效:
import * as React from 'react';
const { Component } = React;
我可以手动为所有文件和软件包执行此操作,但是a)会使其不必要地变得丑陋(使用Redux和其他东西,在我们必须执行此操作的许多文件中有六个不同的软件包和b )有很多文件,我不想手动全部更改。
是否有可以自动进行此类转换的Babel转换插件?这似乎不是一种全新的方法,所以我希望有一个插件可以做对我而言,我的Google-fu无法找到。
答案 0 :(得分:0)
我设法让这个工作。我最终不得不编写自己的Babel插件来进行我正在寻找的更改。基本上,对于import
语句的不同版本,它会更改它以便更好地使用UMD和CJS模块。
例如,像这样:
import A, { a, b, c } from 'a';
变成了这样的东西:
import * from __babel_A from 'a';
const A = __babel_A.default && (__babel_A.default.default || __babel_A.default) || __babel_A;
const { a, b, c } = __babel_A.default || __babel_A;
这种格式是基于大多数东西出口的方式而来的。许多人(如React)会将所有内容放入一个对象中,其名称可以module.exports
(如果我提供了假名)或this
或window
。其他人最终没有把事情分组(比如ReactRTE)并且有自己的“默认”,这是default.default
位的来源。
除了这个转换之外,当我的服务器提供第三方文件的dist版本时,它会以一种让我进行export default
的方式将它们包装起来。看起来像这样:
const module = {};
const keys = Object.keys(this || window);
const toExport = (function __auto_wrapper() {
${fileCode}
return module.exports || Object.keys(this).reduce((r, k) => keys.includes(k) ? r : Object.assign(r, { [k]: this[k].default || this[k] }), {});
}).call(this || window);
export default Object.keys(toExport).length === 1 ? Object.entries(toExport)[0][1] : toExport;
同样,不同的方式基于不同项目的输出。一些人在给出它时会使用module.exports
,其他人不会认为module.exports
是真实的,因为我(故意)没有将export
初始化为对象(如果我这样做,那就是尝试使用我不想要的require()
。在我的例子中,ReactRTE只有一个CJS模块而不是UMD,所以我还必须替换它的代码来替换require('react')
和require('react-dom')
而不是引用window
上的对象
这一切都按我想要的方式工作(在浏览器中完全非捆绑式代码加载)。唯一的轻微副作用是React
和朋友都在window
上可用(如果正确捆绑它们通常不会这样),但这很小。