前言

最近用到了一个前端库(kityminder), 是使用seajs+grunt进行构建的, 但是在非seajs的项目中, 直接使用import或是require, 是无法引入任何模块的, 但是也不能为了这一个库, 再把seajs引入进来. 本文探索了一种引用seajs模块的方式, 非职业前端, 有问题大家可以留言指出.

kityminder-core的安装

kityminder是百度开源的一个脑图可视化工具, 可以在网页中生成如下的效果

当我们想要在自己的项目中用npm install引入时, 可以直接

1
npm install kityminder-core

引入之后, 可以在node_modules/kityminder-core/中看到.

kityminder的初使用

如果直接使用require/exports, 我们是无法获得这个模块的, 以如下代码为例:

1
2
3
4
5
import * as kity from "kity";
import * as kityminder from "kityminder-core";

console.log("Get kity", kity);
console.log("Get kityminder", kityminder);

会得到这样的结果, 毫无疑问, 之后的kityminder.Minder的调用是一定会出错的, 因为引入的kityminder模块没有任何的属性.

阅读kityminder相关代码

为什么我们的import引用没有成功呢, 明明打包后的代码模块中已经有了kityminder.

node_modules/kityminder-core/dist/kityminder.core.js中, 大致的定义是这样的

1
2
3
4
5
6
7
8
9
10
11
(function () {
// ...
var moduleMapping = {
"expose-kityminder": 34
};

function use(name) {
_p.r([ moduleMapping[name] ]);
}
use('expose-kityminder');
})();

接下来我们再看expose-kityminder:

1
2
3
define('expose-kityminder', function(require, exports, module) {
module.exports = window.kityminder = require('./kityminder');
});

虽然函数里有module.exports, 但是这个函数的module.exports我们在外层是无法得到的. 好在这里有window.kityminder, 替我们保存了这个模块的信息.

可用的方案

因此, 我们不能指望直接import得到的值. 而是应该在import之后, 使用window变量中存储的kityminder.

最后的代码实现如下:

1
2
3
4
5
6
7
8
import "kity";
import "kityminder-core";

const kity = window.kity;
const kityminder = window.kityminder; // The kity has been imported as a window member.

console.log("Get kity", kity);
console.log("Get kityminder", kityminder);

总结

这样可以就可以得到真正的模块了. 我不知道未来是不是还会接触seajs, 按照目前的使用方式 来看, 应该越来越少的库会依赖seajs, 这次也是被迫去查看一下库的代码. 大家需要的话, 甚至可以npm install seajs并查看一下seajs-debug的代码. 作为大型项目, 这种动态加载的另一个Javascript文件的方式可能会为我们所需要.