如何在vscode中导入mjs?

问题描述 投票:0回答:1

是否可以制作由 mjs 文件组成的 vscode 扩展?

因为我尝试仅使用 mjs 文件进行扩展,以便在不使用 TypeScript 的情况下拥有完整的 es6 功能。 但它不运行:

如果我使用

$ vsce package
进行扩展,它不会给出任何错误,但它会生成一个在安装时不起作用的扩展:我放入 package.json 中的贡献存在,但 vscode 显示一个错误弹出窗口,其中显示

激活扩展'my.ext'失败:必须使用导入来加载ES模块:c:sext xtension.mjs。

我尝试运行的每个命令都会出错

未找到命令“my.cmd”

如果我在调试器上运行扩展,并且标记了未捕获异常选项上的断点,它将在 /src/vs/workbench/api/node/extHostExtensionService.ts:88 处中断。

经过进一步搜索,我注意到当脚本尝试加载第一个 mjs 模块时,会生成此异常。

我可以做些什么来包含我的 mjs 库文件?

我认为这种行为也可能会影响 npm 模块与 mjs 文件的使用。


编辑

找到(某种)使用 esm 的方法:

这个想法是使用esm来处理es6导入并在导入的模块之间共享vscode对象

这看起来相当棘手,但是当我尝试

import * as vscode from "vscode"
我的 mjs 文件时,vscode 抱怨说 找不到模块 vscode

所以我做了以下事情

  • 添加“esm”作为依赖项
  • 在所有使用vscode的文件中,删除vscode的导入并添加类似这样的功能
var vscode; // will store vscode obj
export function IMPORTVSCODE(vscodeInstance){
    vscode = vscodeInstance
}
  • 在您需要 vscode(使用 Node Native require)和主模块(使用 esm require)的位置创建一个 init 文件
  • 在初始化文件中调用main.IMPORTVSCODE(vscode)
  • 在所有导入需要 vscode 的文件 B 的文件 A 上,在使用文件 B 导出的内容之前,调用 B.IMPORTVSCODE(vscode)

例如

// init.js
const vscode = require("vscode")
const esm = require("esm")(module/*, options*/)
const main = esm("./main.mjs")
main.IMPORTVSCODE(vscode)
module.exports = main

// main.mjs
import * as other from "./other.mjs"
var vscode; // will store vscode obj
export function IMPORTVSCODE(vscodeInstance){
    vscode = vscodeInstance
}
function activate(){
  other.IMPORTVSCODE(vscode)
  other.methodThatNeedsVscode()
}

// other.mjs
var vscode; // will store vscode obj
export function IMPORTVSCODE(vscodeInstance){
    vscode = vscodeInstance
}
export function methodThatNeedsVscode(){
    vscode // ...use vscode
}

我的扩展现在运行良好!

但我认为可以找到更好的想法,所以如果有人有一些最好的解决方案,请分享它们

visual-studio-code es6-modules
1个回答
0
投票

是的,您可以使用纯 ESM(感谢上帝),即使您必须从 CJS 开始。诀窍是使用

await import
:

/**
 * @param {import('vscode').ExtensionContext} context - The context.
 */
async function activate(context) {
  (await import('./register-hello-world.mjs')).activate(context);
  (await import('./register-hello-tensor.mjs')).activate(context);
}
module.exports.activate = activate;

注册-hello-world.mjs:

import {add} from '#customImport';
import {vscode} from '#vscode';
/**
 * This method is called when your extension is activated, which
 * happens the very first time the command is executed.
 * @param {import('vscode').ExtensionContext} context - The context.
 */
export function activate(context) {
  // Use the console to output diagnostic information (console.log) and errors (console.error)
  // This line of code will only be executed once when your extension is activated
  console.log('> register extension.helloWorld');
  // The command has been defined in the package.json file
  // Now provide the implementation of the command with registerCommand
  // The commandId parameter must match the command field in package.json
  const disposable = vscode.commands.registerCommand('extension.helloWorld', () => {
    vscode.window.showInformationMessage(`Hello World! add(10, 20) is ${add(10, 20)}`);
  });
  context.subscriptions.push(disposable);
}

现在您可能想知道 - 那是什么

import {vscode} from '#vscode';

你基本上可以像导入地图一样使用你的

package.json

{
  "name": "vscode-extension-transformers",
  "displayName": "vscode-extension-transformers",
  "description": "Transformers.js example for VS Code",
  "version": "1.0.0",
  "publisher": "kungfooman",
  "repository": "https://github.com/kungfooman/vscode-extension-transformers/",
  "scripts": {
    "watch": "echo Begone, watch build step! Embracing true ESM power!",
    "vscode:prepublish": "echo Begone, prepublish build step! Embracing true ESM power!",
    "lint": "eslint \"src/**/*.js\""
  },
  "engines": {
    "vscode": "^1.74.0"
  },
  "categories": [
    "Other"
  ],
  "activationEvents": [],
  "main": "./src/extension.js",
  "contributes": {
    "commands": [
      {
        "command": "extension.helloWorld",
        "title": "Hello World"
      },
      {
        "command": "extension.helloTensor",
        "title": "Hello Tensor"
      }
    ]
  },
  "devDependencies": {
    "@types/node": "^16.18.34",
    "@types/vscode": "^1.73.0",
    "eslint": "^8.26.0"
  },
  "imports": {
    "#customImport": "./src/customImport.mjs",
    "#vscode": "./src/vscode.mjs"
  },
  "dependencies": {
    "@xenova/transformers": "^2.6.1"
  }
}

并且 ./src/vscode.mjs 必须看起来像这样:

import {createRequire} from 'node:module';
const require = createRequire(import.meta.url);
export const vscode = require('vscode');

Tada,问题已解决 - 享受 ESM 的乐趣。如果您使用 TypeScript,请立即放弃它:它只会通过 AST 转换等造成额外的麻烦。

代码太多?我在这里做了一个完整的测试仓库:

https://github.com/kungfooman/vscode-extension-transformers

© www.soinside.com 2019 - 2024. All rights reserved.