nodejs动态加载代码
使用场景:
将一段nodejs代码字符串执行起来
方法一:
假设存在文件bundle.js,main.js,其中bundle.js中为要执行的代码
//main.js
const fs = require('fs')
fs.readFile = util.promisify(fs.readFile)
const bundle = await fs.readFile('./bundle.js', 'utf-8') //此时的bundle为String
const m = new module.constructor()
m._compile(bundle, 'bundle.js') // 第一个参数为要执行的代码字符串,第二个参数为文件名
//此时就可以通过m.exports来调用bundle.js文件中exports出来的东西
这样做虽然简单,但有很多缺陷,很常见的就是如果你代码中require了一个包,那这种方式就无法解析require,一执行就会报错:
can not found xxx packages,
方法二:
//main.js
const fs = require('fs')
const NativeModule = require('module')
const vm = require('vm')fs.readFile = util.promisify(fs.readFile)
const bundle = await fs.readFile('./bundle.js', 'utf-8') //此时的bundle为Stringconst getModuleFromString = (bundle, filename) => {const m = { exports: {} }const wrapper = NativeModule.wrap(bundle)const script = new vm.Script(wrapper, { filename,displayErrors: true})const result = script.runInThisContext() // 此处可以指定代码的执行环境,此api在nodejs文档中有介绍result.call(m.exports, m.exports, require, m) // 执行wrapper函数,此处传入require就解决了第一种方法不能require的问题return m
}const m = getModuleFromString(bundle, 'bundle.js')
上述代码中,NativeModule.wrap
方法会将bundle包装成如下形式:
`(function (exports, require, module, __filename, __dirname){// bundle code
})`
这样就方便我们传入exports、require、module等参数,这些参数就是bundle代码执行过程中的module.exports,require,module,这样就方便了我们去定制这些参数,注意此时得到的wrapper依然是字符串的形式。然后通过vm模块的vm.Script
方法去执行这段代码。
当用webpack打包一个js文件的时候,webpack会将代码中require的东西都拿出来打包到这个文件中,方便文件在前端环境下执行,但是如果是服务端渲染的时候,那么这个原本要在前端执行的文件就回在后端执行,此时没必要把require的文件全部打包进来因为nodejs中就可以直接require,所以通过webpack的externals配置externals: Object.keys(require('../package.json').dependencies)
避免这些比不必要的打包(而且这可能因为一些对象被重复创建会导致一些错误)。
而在开发环境中,我们通常不会把打包后的文件输出到硬盘,而是输出到内存中(比如可以借助memory-fs模块),这时由于硬盘上不存在真正的打包后的文件,所以不能直接require获取,就需要上述方法。
nodejs动态加载代码相关推荐
- nodejs动态加载路由
Nodejs动态加载路由,Nodejs遍历目录,Nodejs路由工具 工具来源: Nodejs需要手动加载路由文件,如果一个个添加,项目逐渐扩大,比较麻烦. 尤其在项目route目录下,增加模块文件夹 ...
- Vue 使用v-html 动态加载代码 点击事件不管用 解决办法
最近做一个项目,由于数据展示受限制,只能动态拼接代码,但是发现一个问题,在标签上写的@click="xxx()" 不管用,最后专业前端朋友与之解决,话不多说,看解决办法,相信你那么 ...
- Android 实现布局动态加载
Android 动态加载布局 通过使用LayoutInflater 每次点击按钮时候去读取布局文件,然后找到布局文件里面的各个VIEW 操作完VIEW 后加载进我们setContentView 方面里 ...
- app启动页数秒加载 代码_iOS 底层探索 - 应用加载
一.前导知识 以下参考自 WWDC 2016 Optimizing App Startup Time : 1.1 Mach-O Mach-O is a bunch of file types for ...
- js动态载入css文件,原生JS动态加载JS、CSS文件及代码脚本(示例代码)
var DynamciLoadUtil = { // 动态加载外部js文件,并执行回调 loadJS: function(url, callback){ var script = document.c ...
- Windows下动态加载可执行代码原理简述
xiaotie同学比较蛋疼,问C#里面能不能动态加载SIMD的汇编代码.C#我不知道,反正c/c++下面这事情很好做.顺手花了几个小时写了个例子和这篇博客. 总的来说,windows下要动态加载bin ...
- 中动态路径加载_GOT段在linux系统中实现代码动态加载的作用和其他段的说明
上一节我们看到,当程序想调用系统函数时,在编译阶段无法确认被调用函数所在的虚拟地址.因此必须有机制让程序在运行过程中,在调用系统API的时候有办法去确定所调用的系统函数对应的入口地址,这就是代码运行时 ...
- 【OS学习笔记】四十 保护模式十:中断和异常的处理与抢占式多任务对应的汇编代码----动态加载的用户程序/任务二代码
本文是以下几篇文章对应的微型动态加载的用户程序/任务二代码: [OS学习笔记]三十四 保护模式十:中断和异常区别 [OS学习笔记]三十五 保护模式十:中断描述符表.中断门和陷阱门 [OS学习笔记]三十 ...
- 【OS学习笔记】三十九 保护模式十:中断和异常的处理与抢占式多任务对应的汇编代码----动态加载的用户程序/任务一代码
本文是以下几篇文章对应的动态加载的用户程序/任务一代码: [OS学习笔记]三十四 保护模式十:中断和异常区别 [OS学习笔记]三十五 保护模式十:中断描述符表.中断门和陷阱门 [OS学习笔记]三十六 ...
- Node四种动态加载JS代码方法性能对比
背景 我们运行node程序的时候,一般情况下,js代码都是事先写好在js文件里,然后启动的时候加载到内存中执行的.在一些特殊的需求下,我们可能会执行一些动态的js代码. 四种方法 目前我能想到的方法有 ...
最新文章
- 如何利用大数据指导市场营销
- python实战项目_11 个实战项目,掌握 Python 数据可视化
- 十 ubus安装编译
- 北理工2017年爬虫目录
- leetcode第一刷_Combinations
- 【noip模拟赛3】编码
- format 参数说明
- 广西2021普通高考成绩查询,2021广西高考成绩什么时候出
- swf文件在线预览 html,在线浏览swf文件
- DATAGUARD 添加修改REDOLOG大小
- go-cqhttp + noneBot群聊机器人 配置开发
- 【工具】(九):Mac工具整理
- SpringBoot集成Beetl
- 程序员出差如何高效工作?
- 活动|QuarkChain 高TPS悬赏令:看你能有多快!2.4BTC等你拿!
- sqli-labs48关_Open Labs带来48小时骇客马拉松
- 1750. 救生员 Lifeguards S
- spring-mybatis.xml 里mapperLocations 配置多路径
- win10c语言关机,win10如何设置定时关机?
- int和long类型取值范围。 基本数据类型 byte , short , char ,int , long , float ,double,boolean类型取值范围