问题

pnpm vsce package

直接执行上面的命令会报错

npm error missing: core-js@^2.6.12, required by is-weakset@2.0.4
npm error missing: encoding@^0.1.13, required by is-weakset@2.0.4
npm error missing: es5-shim@^4.6.7, required by is-weakset@2.0.4
npm error missing: es6-shim@^0.35.8, required by is-weakset@2.0.4
npm error missing: in-publish@^2.0.1, required by is-weakset@2.0.4
npm error missing: npmignore@^0.3.1, required by is-weakset@2.0.4
npm error missing: nyc@^10.3.2, required by is-weakset@2.0.4
npm error missing: safe-publish-latest@^2.0.0, required by is-weakset@2.0.4
npm error missing: tape@^5.9.0, required by is-weakset@2.0.4
npm error missing: ava@^3.15.0, required by yocto-queue@1.2.1
npm error missing: tsd@^0.17.0, required by yocto-queue@1.2.1

解决办法

根据官方文档和网络上搜索,得出方法是首先将所有依赖和插件本身打包成一个js文件,再执行pnpm vsce --no-dependencies即可

根据官方文档使用esbuild(直接用tsc 会导致依赖无法导入),创建esbuild.js

const esbuild = require('esbuild');

const production = process.argv.includes('--production');
const watch = process.argv.includes('--watch');

async function main() {
   const ctx = await esbuild.context({
       entryPoints: ['src/extension.ts'],
       bundle: true,
       format: 'cjs',
       minify: production,
       sourcemap: !production,
       sourcesContent: false,
       platform: 'node',
       outfile: 'dist/extension.js',
       external: ['vscode'],
       logLevel: 'warning',
       plugins: [
           /* add to the end of plugins array */
           esbuildProblemMatcherPlugin
      ]
  });
   if (watch) {
       await ctx.watch();
  } else {
       await ctx.rebuild();
       await ctx.dispose();
  }
}

/**
* @type {import('esbuild').Plugin}
*/
const esbuildProblemMatcherPlugin = {
   name: 'esbuild-problem-matcher',

   setup(build) {
       build.onStart(() => {
           console.log('[watch] build started');
      });
       build.onEnd(result => {
           result.errors.forEach(({ text, location }) => {
               console.error(`✘ [ERROR] ${text}`);
               if (location == null) return;
               console.error(`   ${location.file}:${location.line}:${location.column}:`);
          });
           console.log('[watch] build finished');
      });
  }
};

main().catch(e => {
   console.error(e);
   process.exit(1);
});

修改package.json的入口文件(反过来修改esbuild输出文件也可以)

"main": "./dist/extension.js",

修改package.json scripts部分(仅示例)

  "scripts": {
   "vscode:prepublish": "pnpm run compile-production",
   "watch": "tsc -watch -p ./",
   "pretest": "pnpm run compile && pnpm run lint",
   "lint": "eslint src",
   "format": "prettier --write .",
   "format:check": "prettier --check .",
   "build": "pnpm run format && pnpm run lint && pnpm run compile",
   "compile-production": "node esbuild.js --production",
   "compile": "tsc -p ./",
   "package": "pnpm vsce package --no-dependencies"
},

打包执行 pnpm run package

使用ESbuild后,调试问题

因为我们把入口修改了,所以调试的时候如果还用tsc不做任何修改实际使用的是打包后的产物.

我们的解决方法是调试使用esbuild打包,官方给的esbuild.js已经包含了watch模式,package.json watch脚本修改如下:

"watch": "node esbuild.js --watch ./",

此外还需要修改.vscode/tasks.json,用来适配esbuild的输出

// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
{
  "version": "2.0.0",
  "tasks": [
    {
      "type": "npm",
      "script": "dev:extension",
      "problemMatcher": {
        "pattern": [
          {
            "regexp": "^$",
            "file": 1,
            "location": 2,
            "message": 3
          }
        ],
        "background": {
          "activeOnStart": true,
          "beginsPattern": "^\\[watch\\] build started",
          "endsPattern": "^\\[watch\\] build finished"
        }
      },
      "isBackground": true,
      "presentation": {
        "reveal": "never"
      },
      "group": {
        "kind": "build",
        "isDefault": true
      }
    }
  ]
}

Angel,请你不要放开我的手