@chocolateboy/uncommonjs
Version:
A minimum viable shim for module.exports
128 lines (102 loc) • 2.56 kB
JavaScript
const {
assign: __assign,
defineProperty: __defineProperty,
is: __is,
keys: __keys
} = Object;
const {
get: __get,
ownKeys: __ownKeys
} = Reflect;
const ignore = () => false;
const toString = {}.toString;
const isPlainObject = value => {
return value && toString.call(value) === '[object Object]' && (value.constructor || Object) === Object;
};
const assign = (descriptors, name, descriptor) => {
let unique;
if (typeof name === 'symbol') {
unique = name;
} else {
for (let i = 0, assigned;; ++i) {
unique = name + (i === 0 ? '' : `_${i}`);
assigned = descriptors.hasOwnProperty(unique) && descriptors[unique];
if (assigned) {
if (descriptor.get === assigned.get && __is(descriptor.value, assigned.value)) {
return true;
}
} else {
break;
}
}
}
descriptors[unique] = descriptor;
return true;
};
const defaultRequire = id => {
throw new Error(`Can't require ${id}: require is not implemented`);
};
var index = ((options = {}) => {
let _require = options.require || defaultRequire;
const descriptors = {};
const $exports = new Proxy(descriptors, {
defineProperty: assign,
get(target, name, receiver) {
if (!target.hasOwnProperty(name)) {
return __get(target, name);
}
const {
get,
value
} = target[name];
return get ? get.call(receiver) : value;
},
preventExtensions: ignore,
set(target, name, value) {
return assign(target, name, {
value,
configurable: true,
enumerable: true,
writable: true
});
},
setPrototypeOf: ignore
});
const $require = function require(id) {
return _require(id);
};
const $module = {
get exported() {
return __ownKeys(descriptors).reduce((acc, name) => {
return __defineProperty(acc, name, __assign({}, descriptors[name], {
enumerable: true
}));
}, {});
},
get exports() {
return $exports;
},
set exports(value) {
if (isPlainObject(value)) {
for (const key of __keys(value)) {
$exports[key] = value[key];
}
}
const key = typeof value === 'function' && value.name ? value.name : 'default';
$exports[key] = value;
},
get require() {
return $require;
},
set require(fn) {
_require = fn;
}
};
return {
exports: $exports,
module: $module,
require: $require
};
});
module.exports = index;
;