2

有没有办法启用“import <module>.js;” 使用Microsoft ClearScript的嵌入式 V8 运行时中的语句?

我找不到任何示例,让我觉得我必须先自己解析脚本文件才能启用它。

4

2 回答 2

2

就在这里。将此问题的答案视为基本方法。这个问题是关于启用 CommonJS Require 的。对于 ES6 模块方法,您将需要这样的东西:

using System;
using Microsoft.ClearScript;
using Microsoft.ClearScript.JavaScript;
using Microsoft.ClearScript.V8;

namespace ConsoleApp1
{
    class Program
    {
        static void Main()
        {
            V8ScriptEngine engine = new V8ScriptEngine();
            engine.DocumentSettings.SearchPath = @"c:\temp\js\";
            engine.DocumentSettings.AccessFlags = DocumentAccessFlags.EnableFileLoading;
            engine.AddHostType(typeof(Console));
            Console.WriteLine("Hello from C#");
            engine.Execute(new DocumentInfo() { Category = ModuleCategory.Standard }, @"
                Console.WriteLine('Hello from Javascript');
                import {print} from 'a.js';
                import {add} from 'b.js';
                print(add(30, 12));
                Console.WriteLine('Javascript signing off...');
            ");
            Console.ReadKey();
        }
    }
}

JS 看起来像这样:

// File c:\temp\js\a.js
export function print(txt) {
    Console.WriteLine('The answer to Life etc is ... ' + txt);
  }

// File c:\temp\js\b.js 
export function add(var1, var2) {
    return var1 + var2;
  } 

结果是:

示例代码的输出

此示例从本地文件系统读取文件,如 AccessFlags = EnableFileLoading 设置所示,SearchPath 设置给出路径,或者路径(如果给出以逗号分隔的路径列表)。

它是启用 ES6 样式模块加载的“ModuleCategory.Standard”选项。

于 2020-12-07T17:30:05.157 回答
1

您还可以使用类似于 node.js 的自己滚动的 require() 函数。我在这里写了一篇博客文章,并且有一个工作的 CodePen来说明这种方法,该方法受到Michele Nasti 的一篇文章的启发,该文章本身基于Marijn Haverbeke 的 Eloquent JavaScript一书的第 10 章中的想法。

这是我的编码示例:

const myCode1 = `
  let utils = function (){
    this.say = function(x){
      log('utils: says = ' + x)
      };
      return this;
  }
  exports.utils = utils;
`;
const myCode2 = `
  let customer = function (){
    this.say = function(x){
      log('Customer: says = ' + x)
      };
      return this;
  }
  exports.customer = customer;
`;
/*

*/  
// I am loading simple source code strings into an array - in the real solution
// you would use some kind of source code fetch / load to string process.
let sourceCode = {c1: myCode1, c2: myCode2};
myRequire.cache = Object.create(null); 

function myRequire(name) {   
    log(`myRequire: You require file ${name}`)
    if (!(name in myRequire.cache)) {
        log(`myRequire: ${name} is not in cache; reading from disk`)
        let code = sourceCode[name]; // load the code - this is bespoke to your env      
        let module = {exports: {}};
        myRequire.cache[name] = module;     
        let wrapper = Function("require, exports, module", code);     
        wrapper(myRequire, module.exports, module);
    }
    log(`myRequire: ${name} is in cache. Returning it...`)
    return myRequire.cache[name].exports;
}

// myRequire() produces an object from the 'exports' object in the loaded code.
//let myExports = new myRequire('c1');
// we can then refer to these as 
// let util = myExports.utils();
// or just use 
// let util = new myRequire('c1').utils();

// So...Require c1 will create an object with exports.
let util = new myRequire('c1').utils();
util.say('I am alive!')
 
log("");

// Require c2 will create an object with exports.
let cust = new myRequire('c2').customer();
cust.say('I am alive too!')

function log(msg){
  $('#log').html($('#log').html() + "<br />" + msg);
}

输出是

myRequire: You require file c1
myRequire: c1 is not in cache; reading from disk
myRequire: c1 is in cache. Returning it...
utils: says = I am alive!

myRequire: You require file c2
myRequire: c2 is not in cache; reading from disk
myRequire: c2 is in cache. Returning it...
Customer: says = I am alive too!
于 2021-06-23T10:38:55.300 回答