VSCode插件开发(三)-如何打出更小的插件安装包

上一篇文章我们介绍了如何使用React、Tailwind CSS、Shadcn和Vite来创建一个复杂的Webview界面,并将其集成到VSCode插件中。但是大家有没注意最后我们打出来的包的大小。

优化前打包尺寸

没错,69.9MB,这对于一个简单的插件来说也太大了。难道这是正常的,没办法优化吗?当然不是,这篇文章就来讨论如何打出更小的插件安装包。

首先我们来看看哪些文件占用了这么多空间。

上图中我们可以看到,webview这个目录占用了绝大部分空间,可以想象里面有个node_modules目录。但是这个webview目录真的还需要么?我们之前已经把这个react项目打包并输出到了out目录,所以这个目录可以直接从最终的安装包中排除。

.vscodeignore文件

如何将webview目录从最终的安装包中排除?我们需要用到这个.vscodeignore文件。这个跟.gitignore文件的作用类似,但是是针对VSCode插件的。我们创建这个插件项目的时候,默认会生成一个.vscodeignore文件,我们可以在这个文件末尾添加一行内容来排除webview目录。

1
webview/**

接着是第二大的node_modules目录。这个目录占用了18.68MB,但是我们现在还不能将它排除,因为我们的插件项目依赖了一些npm包,这些包在最终的安装包中是需要的。

使用esbuild打包

所以我们要引入打包工具来打包我们的插件项目。这里我选择使用esbuild,至于为什么选择esbuild,除了esbuild支持这里所需的所有功能外,最重要的就是一个字——

安装esbuild

首先我们需要安装esbuild。可以使用以下命令安装:

1
npm install --save-dev esbuild

创建打包脚本

接下来我们需要创建一个打包脚本,来使用esbuild打包我们的插件项目。在项目根目录下创建一个build.js文件,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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: 'out/extension.js',
external: ['vscode'],
logLevel: 'warning',
});
if (watch) {
await ctx.watch();
} else {
await ctx.rebuild();
await ctx.dispose();
}
}

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

这个脚本的作用是将src/extension.ts打包到out/extension.js中。其中platform设置为node,这是因为我们的插件项目是一个Node.js模块,而不是一个浏览器模块。

另一个需要关注的参数external,它的作用是告诉esbuild哪些模块是外部依赖,不需要打包到最终的文件中。这里我们将vscode添加到了external数组中,这是因为我们插件运行环境就在vscode中,这个依赖自动存在,不需要打到最终的安装包中。

配置package.json

最后我们需要在package.json中添加一个脚本,来运行我们的打包脚本。在scripts字段中添加以下内容:

1
2
3
4
5
6
7
8
9
{
...
"scripts": {
...
"vscode:prepublish": "node esbuild.js --production",
"package": "vsce package",
...
}
}

因为vscode:prepublish脚本会在vsce开始打插件包之前运行,所以我们在这个时候执行esbuild命令。后面的--production参数会告诉esbuild我们要打出一个生产环境的包,这会开启压缩等优化。结合前面的esbuild.js脚本可以更好理解这个参数的作用。

完成这些后,我们也可以把node_modules目录从最终的安装包中排除了,修改.vscodeignore文件,添加以下内容:

1
node_modules/**

最终效果

经过以上步骤,我们可以运行下面命令再来打包插件:

1
npm run package

优化后打包尺寸

最终打出来的包大小只有366.55KB,只是原来的一个零头。我们测试后结果是ok的。