使用 Webpack 优化 VS Code 插件加载性能
The following article is from 玩转VS Code Author Neo
Webpack 这一 JS 模块打包神器相信大家都不陌生了。由于 VS Code 插件大部分也都是 JS/TS 代码 + 依赖库的形式,因此也可以使用 Webpack 打包,优化性能。
经过实测,经过 Webpack 打包优化后的插件,其加载耗时可缩短几倍甚至数十倍之多,先来看下效果:
Webpack 优化效果
我们以 Java Test Runner 这一插件为例:
在使用 Webpack 后,安装包的大小由原先的 9.8M 缩减到了 1.9M (在这其中还包含了一些 .jar 文件,真正的 extension.js 在解压后,仅为 900KB 左右)。
性能上,我们利用 VS Code 自带的性能检测工具查看插件加载所用的时间,在我的电脑上,Java Test Runner 的加载时间由原先的 2000ms 缩短到了 200ms 左右,前后相差近 10 倍,可以说效果非常显著了。
VS Code 插件的开发者们不妨尝试一下 Webpack 为自己插件所带来的惊喜!下面就来聊聊如何将 Webpack 应用到自己的插件项目当中吧!
增加 Webpack 相关依赖库
npm install --save-dev webpack webpack-cli ts-loader
使用 ts-loader 是由于我的插件是基于 TypeScript 编写的。
添加 Webpack 配置文件
//@ts-check
'use strict';
const path = require('path');
/**@type {import('webpack').Configuration}*/
const config = {
// VS Code 插件运行于 Node.js 上下文中
// 📖 -> https://webpack.js.org/configuration/node/
node: {
__dirname: false,
__filename: false,
},
// 插件的运行入口。
// 📖 -> https://webpack.js.org/configuration/entry-context/
entry: './src/extension.ts',
// 我们将打包后的文件保存于 'dist' 目录下
// 📖 -> https://webpack.js.org/configuration/output/
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'extension.js',
libraryTarget: "commonjs2",
devtoolModuleFilenameTemplate: "../[resource-path]",
},
externals: {
// 'vscode'模块由 VS Code 运行时提供,可以将其排除避免打包文件过大
// 📖 -> https://webpack.js.org/configuration/externals/
vscode: "commonjs vscode",
},
devtool: 'source-map',
// 解析 TypeScript 和 JavaScript 文件
// 📖 -> https://github.com/TypeStrong/ts-loader
resolve: {
extensions: ['.ts', '.js'],
},
module: {
rules: [{
test: /\.ts$/,
exclude: /node_modules/,
use: [{
loader: 'ts-loader',
}]
}]
},
}
module.exports = config;
由于我们会使用打包后的输出文件作为插件的代码,因此务必要记得修改 package.json 中的插件主程序入口,例如:"main": "./out/src/extension" 修改为 "main": "./dist/extension"。 不要忘记将 dist 目录添加到 .gitignore 中。
优化开发体验
另外,我们可以更新开发插件时所用的 Launch Configuration 来优化开发体验:
更新 launch.json
launch.json 文件存放了我们平时调试插件时的配置信息:
{
"version": "0.1.0",
"configurations": [
{
"name": "Launch Extension",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": ["--extensionDevelopmentPath=${workspaceRoot}" ],
"stopOnEntry": false,
"sourceMaps": true,
// 注意这里需要使用 Webpack 的输出文件路径。
"outFiles": [ "${workspaceRoot}/dist/**/*.js" ],
// 在 Launch 之前的前置任务,定义见下文。
"preLaunchTask": "npm: watch"
}
]
}
定义 npm:watch 并创建 tasks.json
首先我们在 package.json 中定义 watch 任务:
"scripts:" {
...
"watch": "webpack --mode development --watch --info-verbosity verbose"
...
}
这里我们让 Webpack 以 watch 模式监听我们对代码的修改,并实时地对代码进行打包,并让其以 verbose 模式输出更多的打包信息。这是为什么呢?因为我们可以利用这些输出信息让 VS Code 知道打包已经完成了。
为了做到这一点,我们需要在 task.json 中创建一个监听输出的任务,这样就可让 VS Code 在 Webpack 完成打包后,自动启动我们的插件进行调试:
{
"version": "2.0.0",
"tasks": [
{
// 定义 npm: watch
"type": "npm",
"script": "watch",
"problemMatcher": {
"owner": "typescript",
"pattern":[
{
"regexp": "\\[tsl\\] ERROR",
"file": 1,
"location": 2,
"message": 3
}
],
"background": {
"activeOnStart": true,
// 通过对 Webpack 的输出内容进行匹配,得知编译是否完成
"beginsPattern": "Compilation \\w+ starting…",
"endsPattern": "Compilation\\s+finished"
}
},
"isBackground": true,
"presentation": {
"reveal": "never"
},
"group": {
"kind": "build",
"isDefault": true
}
}
]
更新 vscode:prepublish 脚本
vscode:prepublish 是定义在 package.json 中的一段脚本,这段脚本会在生成 VS Code 插件安装包之前执行:
"scripts:" {
...
// 使用 VSCE 生成插件时的前置脚本,让 Webpack 打包
"vscode:prepublish": "webpack --mode production"
...
}
更新 .vscodeignore
类似于 .gitignore, .vscodeignore 列出了在生成 VS Code 插件安装包时,所有不需要放入安装包中的文件及目录,这里我们可以增加下列几项:
dist/**/*.map:.map 文件仅在本地调试时需要用到。
webpack.config.js:Webpack 的配置文件也不需要放入安装包当中。
node_modules:由于使用 Webpack 对依赖库进行了打包,因此我们不再需要将 node_modules 放入安装包当中了,这将极大缩小安装包的大小。
最后
VS Code Team 官方提供了使用 Webpack 的样例代码,感兴趣的读者可以直接查看。