module-from-string
Load module from string using require
or import
.
Install
npm install module-from-string
Usage
import {
requireFromString,
importFromString,
importFromStringSync
} from 'module-from-string'
requireFromString("module.exports = 'hi'")
requireFromString("exports.greet = 'hi'")
;(async () => {
await importFromString("export default 'hi'")
})()
importFromStringSync(
"export const greet = Buffer.from([0x68, 0x69]).toString('utf8')",
{ globals: { Buffer } }
)
API
import { Context } from 'vm';
import { TransformOptions } from 'esbuild';
interface Options {
filename?: string
dirname?: string
globals?: Context
useCurrentGlobal?: boolean
}
declare const requireFromString: (code: string, options?: Options) => any
declare const createRequireFromString: (options?: Options) => typeof requireFromString
interface ImportOptions extends Options {
transformOptions?: TransformOptions
}
declare const importFromString: (code: string, options?: ImportOptions) => Promise<any>
declare const createImportFromString: (options?: ImportOptions) => typeof importFromString
declare const importFromStringSync: (code: string, options?: ImportOptions) => any
declare const createImportFromStringSync: (options?: ImportOptions) => typeof importFromStringSync
filename
Name, path or URL string of the virtual file for better exception stack trace.
requireFromString(
"throw new Error('boom!')",
{ filename: '/home/foo.js' }
)
dirname
Path or URL string of the directory for resolving require
or import
from relative path.
requireFromString(
"module.exports = require('.')",
{ dirname: path.join(__dirname, "../lib") }
)
If not specified, the default value will be the current file's directory.
globals
Underneath the hood, module-from-string
uses Node.js built-in vm
module to execute code.
vm.runInNewContext(
code,
{
__dirname: contextModule.path,
__filename: contextModule.filename,
exports: contextModule.exports,
module: contextModule,
require: contextModule.require,
...globals
},
Take requireFromString
for example, only the module scope variables are passed into the contextObject
.
In order to use other global objects that are specific to Node.js, they need to be added to option globals
or set option useCurrentGlobal
to true
.
requireFromString(
'module.exports = process.cwd()',
{ globals: { process } }
)
Note: by default the built-in objects have a different prototype.
const error = requireFromString('module.exports = new Error()')
error instanceof Error
useCurrentGlobal
Default to false
. If set to true
, all the available variables from the current global
(or globalThis
) are passed into the context.
transformOptions
Function importFromString
and importFromStringSync
can use esbuild
to transform code syntax. See esbuild Transform API for documentation.
const { greet } = importFromStringSync(
"export const greet: () => string = () => 'hi'",
{ transformOptions: { loader: 'ts' } }
)
greet()
ES modules
Dynamic import()
expression of ES modules is supported by all three functions requireFromString
, importFromString
and importFromStringSync
.
;(async () => {
await requireFromString("module.exports = import('./index.mjs')")
})()
import
statement of ES modules is supported only by asynchronous function importFromString
using Node.js experimental API vm.Module
.
node --experimental-vm-modules index.js
NODE_OPTIONS=--experimental-vm-modules node index.js
await importFromString("export { foo as default } from './index.mjs'")
License
MIT License © 2021 Exuanbo