动态插件
非模块化的js可以通过<script>标签来加载,可以简单实现动态化插件。在使用js静态打包工具后,所有依赖都在打包期间编译,暂时没有静态打包工具支持动态化。在构建运行时抽象的系统,动态的插件又是必不可缺的部分。
parcel
parcel是一个简化版的webpack,性能等方面也比webpack要强,用来打包系统和插件开箱即用。
插件
hello插件
export default (name) => console.log(`hello ${name}`);
打包 parcel build hello.js
插件加载
将打包后的hello.js源码复制到new Function中,并在头部加入return
const load = (new Function(`return parcelRequire=function(e,r,t,n){var i,o="function"==typeof parcelRequire&&parcelRequire,u="function"==typeof require&&require;function f(t,n){if(!r[t]){if(!e[t]){var i="function"==typeof parcelRequire&&parcelRequire;if(!n&&i)return i(t,!0);if(o)return o(t,!0);if(u&&"string"==typeof t)return u(t);var c=new Error("Cannot find module '"+t+"'");throw c.code="MODULE_NOT_FOUND",c}p.resolve=function(r){return e[t][1][r]||r},p.cache={};var l=r[t]=new f.Module(t);e[t][0].call(l.exports,p,l,l.exports,this)}return r[t].exports;function p(e){return f(p.resolve(e))}}f.isParcelRequire=!0,f.Module=function(e){this.id=e,this.bundle=f,this.exports={}},f.modules=e,f.cache=r,f.parent=o,f.register=function(r,t){e[r]=[function(e,r){r.exports=t},{}]};for(var c=0;c<t.length;c++)try{f(t[c])}catch(e){i||(i=e)}if(t.length){var l=f(t[t.length-1]);"object"==typeof exports&&"undefined"!=typeof module?module.exports=l:"function"==typeof define&&define.amd?define(function(){return l}):n&&(this[n]=l)}if(parcelRequire=f,i)throw i;return f}({"3IlW":[function(require,module,exports) {
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=void 0;var e=function(e){return console.log("hello "+e)};exports.default=e;
},{}]},{},["3IlW"], null)`))();
const moduleName = Object.keys(load.modules)[0];
const loadModule = load(moduleName);
const loadFun = loadModule.default;
// 打印 hello world
loadFun('world');
至此插件加载完成