reinitialize the project as a web extension

This commit is contained in:
nyanotech 2024-02-16 00:35:28 -08:00
parent 1449af6587
commit 21e028c086
Signed by: nyanotech
GPG Key ID: D2D0A9E8F160472B
17 changed files with 1992 additions and 683 deletions

7
.gitignore vendored
View File

@ -1,5 +1,6 @@
out .vscode-test-web/
dist
node_modules
.vscode-test/ .vscode-test/
*.vsix *.vsix
dist/
node_modules/
out/

21
.vscode/launch.json vendored
View File

@ -6,30 +6,33 @@
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"name": "Run Extension", "name": "Run Web Extension ",
"type": "extensionHost", "type": "pwa-extensionHost",
"debugWebWorkerHost": true,
"request": "launch", "request": "launch",
"args": [ "args": [
"--extensionDevelopmentPath=${workspaceFolder}" "--extensionDevelopmentPath=${workspaceFolder}",
"--extensionDevelopmentKind=web"
], ],
"outFiles": [ "outFiles": [
"${workspaceFolder}/dist/**/*.js" "${workspaceFolder}/dist/web/**/*.js"
], ],
"preLaunchTask": "${defaultBuildTask}" "preLaunchTask": "npm: watch-web"
}, },
{ {
"name": "Extension Tests", "name": "Extension Tests",
"type": "extensionHost", "type": "extensionHost",
"debugWebWorkerHost": true,
"request": "launch", "request": "launch",
"args": [ "args": [
"--extensionDevelopmentPath=${workspaceFolder}", "--extensionDevelopmentPath=${workspaceFolder}",
"--extensionTestsPath=${workspaceFolder}/out/test/suite/index" "--extensionDevelopmentKind=web",
"--extensionTestsPath=${workspaceFolder}/dist/web/test/suite/index"
], ],
"outFiles": [ "outFiles": [
"${workspaceFolder}/out/**/*.js", "${workspaceFolder}/dist/web/**/*.js"
"${workspaceFolder}/dist/**/*.js"
], ],
"preLaunchTask": "tasks: watch-tests" "preLaunchTask": "npm: watch-web"
} }
] ]
} }

18
.vscode/settings.json vendored
View File

@ -1,13 +1,11 @@
// Place your settings in this file to overwrite default and user settings. // Place your settings in this file to overwrite default and user settings.
{ {
"files.exclude": { "files.exclude": {
"out": false, // set this to true to hide the "out" folder with the compiled JS files "out": false // set this to true to hide the "out" folder with the compiled JS files
"dist": false // set this to true to hide the "dist" folder with the compiled JS files },
}, "search.exclude": {
"search.exclude": { "out": true // set this to false to include "out" folder in search results
"out": true, // set this to false to include "out" folder in search results },
"dist": true // set this to false to include "dist" folder in search results // Turn off tsc task auto detection since we have the necessary tasks as npm scripts
}, "typescript.tsc.autoDetect": "off"
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
"typescript.tsc.autoDetect": "off"
} }

38
.vscode/tasks.json vendored
View File

@ -5,39 +5,25 @@
"tasks": [ "tasks": [
{ {
"type": "npm", "type": "npm",
"script": "watch", "script": "compile-web",
"problemMatcher": [
"$ts-webpack-watch",
"$tslint-webpack-watch"
],
"isBackground": true,
"presentation": {
"reveal": "never",
"group": "watchers"
},
"group": { "group": {
"kind": "build", "kind": "build",
"isDefault": true "isDefault": true
} },
"problemMatcher": [
"$ts-webpack",
"$tslint-webpack"
]
}, },
{ {
"type": "npm", "type": "npm",
"script": "watch-tests", "script": "watch-web",
"problemMatcher": "$tsc-watch", "group": "build",
"isBackground": true, "isBackground": true,
"presentation": { "problemMatcher": [
"reveal": "never", "$ts-webpack-watch",
"group": "watchers" "$tslint-webpack-watch"
}, ]
"group": "build"
},
{
"label": "tasks: watch-tests",
"dependsOn": [
"npm: watch",
"npm: watch-tests"
],
"problemMatcher": []
} }
] ]
} }

View File

@ -1,13 +1,14 @@
.vscode/** .vscode/**
.vscode-test/** .vscode-test-web/**
src/**
out/** out/**
node_modules/** node_modules/**
src/**
.gitignore .gitignore
.yarnrc
webpack.config.js
vsc-extension-quickstart.md vsc-extension-quickstart.md
webpack.config.js
.yarnrc
**/tsconfig.json **/tsconfig.json
**/.eslintrc.json **/.eslintrc.json
**/*.map **/*.map
**/*.ts **/*.ts
**/.vscode-test.*

View File

@ -1,7 +1,9 @@
# Change Log # Change Log
## [Unreleased] ## 0.0.2
* Initial release - Reinitialize project as a web extension
* rot13
* base64 encode/decode ## 0.0.1
- Initial release

View File

@ -1,8 +1,8 @@
# recombobulator # recombobulator
This is a vscode extension in which I add small things that I wish vscode could do. Small vscode extension in which I features I end up needing.
Currently, those things are: Currently, those are:
* (un)base64 * (un)base64
* generate uuid * generate uuid

2247
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,7 @@
"categories": [ "categories": [
"Other" "Other"
], ],
"main": "./dist/extension.js", "browser": "./dist/web/extension.js",
"capabilities": { "capabilities": {
"virtualWorkspaces": true, "virtualWorkspaces": true,
"untrustedWorkspaces": { "untrustedWorkspaces": {
@ -66,30 +66,30 @@
} }
}, },
"scripts": { "scripts": {
"vscode:prepublish": "npm run package", "test": "vscode-test-web --browserType=chromium --extensionDevelopmentPath=. --extensionTestsPath=dist/web/test/suite/index.js",
"compile": "webpack", "pretest": "npm run compile-web",
"watch": "webpack --watch", "vscode:prepublish": "npm run package-web",
"package": "webpack --mode production --devtool hidden-source-map", "compile-web": "webpack",
"compile-tests": "tsc -p . --outDir out", "watch-web": "webpack --watch",
"watch-tests": "tsc -p . -w --outDir out", "package-web": "webpack --mode production --devtool hidden-source-map",
"pretest": "npm run compile-tests && npm run compile && npm run lint",
"lint": "eslint src --ext ts", "lint": "eslint src --ext ts",
"test": "node ./out/test/runTest.js" "run-in-browser": "vscode-test-web --browserType=chromium --extensionDevelopmentPath=. ."
}, },
"devDependencies": { "devDependencies": {
"@types/vscode": "^1.65.0", "@types/vscode": "^1.86.0",
"@types/glob": "^7.2.0", "@types/mocha": "^10.0.6",
"@types/mocha": "^9.1.0", "@types/assert": "^1.5.10",
"@types/node": "14.x", "eslint": "^8.56.0",
"@typescript-eslint/eslint-plugin": "^5.12.1", "@typescript-eslint/eslint-plugin": "^6.19.1",
"@typescript-eslint/parser": "^5.12.1", "@typescript-eslint/parser": "^6.19.1",
"eslint": "^8.9.0", "mocha": "^10.2.0",
"glob": "^7.2.0", "typescript": "^5.3.3",
"mocha": "^9.2.1", "@vscode/test-web": "^0.0.51",
"typescript": "^4.5.5", "ts-loader": "^9.5.1",
"ts-loader": "^9.2.6", "webpack": "^5.90.0",
"webpack": "^5.69.1", "webpack-cli": "^5.1.4",
"webpack-cli": "^4.9.2", "@types/webpack-env": "^1.18.4",
"@vscode/test-electron": "^2.1.2" "assert": "^2.1.0",
"process": "^0.11.10"
} }
} }

View File

@ -1,23 +0,0 @@
import * as path from 'path';
import { runTests } from '@vscode/test-electron';
async function main() {
try {
// The folder containing the Extension Manifest package.json
// Passed to `--extensionDevelopmentPath`
const extensionDevelopmentPath = path.resolve(__dirname, '../../');
// The path to test runner
// Passed to --extensionTestsPath
const extensionTestsPath = path.resolve(__dirname, './suite/index');
// Download VS Code, unzip it and run the integration test
await runTests({ extensionDevelopmentPath, extensionTestsPath });
} catch (err) {
console.error('Failed to run tests');
process.exit(1);
}
}
main();

View File

@ -1,38 +0,0 @@
import * as path from 'path';
import * as Mocha from 'mocha';
import * as glob from 'glob';
export function run(): Promise<void> {
// Create the mocha test
const mocha = new Mocha({
ui: 'tdd',
color: true
});
const testsRoot = path.resolve(__dirname, '..');
return new Promise((c, e) => {
glob('**/**.test.js', { cwd: testsRoot }, (err, files) => {
if (err) {
return e(err);
}
// Add files to the test suite
files.forEach(f => mocha.addFile(path.resolve(testsRoot, f)));
try {
// Run the mocha test
mocha.run(failures => {
if (failures > 0) {
e(new Error(`${failures} tests failed.`));
} else {
c();
}
});
} catch (err) {
console.error(err);
e(err);
}
});
});
}

View File

@ -1,24 +1,5 @@
import * as crypto from "crypto";
import * as vscode from 'vscode'; import * as vscode from 'vscode';
function generateUUID(a: string) {
return crypto.randomUUID();
}
function base64(a: string) {
return Buffer.from(a).toString('base64'); // TODO - handle different character encodings
}
function unbase64(a: string) {
return Buffer.from(a, 'base64').toString("utf-8"); // TODO - handle different character encodings
}
function rot13(a: string) {
const alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
const rotatedAlphabet = "nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM";
return a.replace(/[a-zA-Z]/g, letter => rotatedAlphabet[alphabet.indexOf(letter)]);
}
function applyEdit(transform: Function) { function applyEdit(transform: Function) {
const editor = vscode.window.activeTextEditor; const editor = vscode.window.activeTextEditor;
@ -35,9 +16,25 @@ function applyEdit(transform: Function) {
} }
} }
export function activate(context: vscode.ExtensionContext) { function base64(a: string) {
console.log('Recombobulator is activated!'); return btoa(a); // TODO - figure out how to handle different character encodings
}
function unbase64(a: string) {
return atob(a); // TODO - figure out how to handle different character encodings
}
function generateUUID(a: string) {
return crypto.randomUUID();
}
function rot13(a: string) {
const alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
const rotatedAlphabet = "nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM";
return a.replace(/[a-zA-Z]/g, letter => rotatedAlphabet[alphabet.indexOf(letter)]);
}
export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(vscode.commands.registerCommand('recombobulator.base64', () => { context.subscriptions.push(vscode.commands.registerCommand('recombobulator.base64', () => {
applyEdit(base64); applyEdit(base64);
})); }));

View File

@ -5,7 +5,7 @@ import * as assert from 'assert';
import * as vscode from 'vscode'; import * as vscode from 'vscode';
// import * as myExtension from '../../extension'; // import * as myExtension from '../../extension';
suite('Extension Test Suite', () => { suite('Web Extension Test Suite', () => {
vscode.window.showInformationMessage('Start all tests.'); vscode.window.showInformationMessage('Start all tests.');
test('Sample test', () => { test('Sample test', () => {

View File

@ -0,0 +1,30 @@
// Imports mocha for the browser, defining the `mocha` global.
require('mocha/mocha');
export function run(): Promise<void> {
return new Promise((c, e) => {
mocha.setup({
ui: 'tdd',
reporter: undefined
});
// Bundles all files in the current directory matching `*.test`
const importAll = (r: __WebpackModuleApi.RequireContext) => r.keys().forEach(r);
importAll(require.context('.', true, /\.test$/));
try {
// Run the mocha test
mocha.run(failures => {
if (failures > 0) {
e(new Error(`${failures} tests failed.`));
} else {
c();
}
});
} catch (err) {
console.error(err);
e(err);
}
});
}

View File

@ -1,9 +1,10 @@
{ {
"compilerOptions": { "compilerOptions": {
"module": "commonjs", "module": "Node16",
"target": "ES2020", "target": "ES2020",
"outDir": "dist",
"lib": [ "lib": [
"ES2020" "ES2020", "WebWorker"
], ],
"sourceMap": true, "sourceMap": true,
"rootDir": "src", "rootDir": "src",

View File

@ -2,31 +2,27 @@
## What's in the folder ## What's in the folder
* This folder contains all of the files necessary for your extension. * This folder contains all of the files necessary for your web extension.
* `package.json` - this is the manifest file in which you declare your extension and command. * `package.json` * this is the manifest file in which you declare your extension and command.
* The sample plugin registers a command and defines its title and command name. With this information VS Code can show the command in the command palette. It doesnt yet need to load the plugin. * `src/web/extension.ts` * this is the main file for the browser
* `src/extension.ts` - this is the main file where you will provide the implementation of your command. * `webpack.config.js` * the webpack config file for the web main
* The file exports one function, `activate`, which is called the very first time your extension is activated (in this case by executing the command). Inside the `activate` function we call `registerCommand`.
* We pass the function containing the implementation of the command as the second parameter to `registerCommand`.
## Setup ## Setup
* install the recommended extensions (amodio.tsl-problem-matcher and dbaeumer.vscode-eslint) * install the recommended extensions (amodio.tsl-problem-matcher, ms-vscode.extension-test-runner, and dbaeumer.vscode-eslint)
## Get up and running the Web Extension
## Get up and running straight away * Run `npm install`.
* Place breakpoints in `src/web/extension.ts`.
* Press `F5` to open a new window with your extension loaded. * Debug via F5 (Run Web Extension).
* Run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Hello World`. * Execute extension code via `F1 > Hello world`.
* Set breakpoints in your code inside `src/extension.ts` to debug your extension.
* Find output from your extension in the debug console.
## Make changes ## Make changes
* You can relaunch the extension from the debug toolbar after changing code in `src/extension.ts`. * You can relaunch the extension from the debug toolbar after changing code in `src/web/extension.ts`.
* You can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes. * You can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes.
## Explore the API ## Explore the API
* You can open the full set of our API when you open the file `node_modules/@types/vscode/index.d.ts`. * You can open the full set of our API when you open the file `node_modules/@types/vscode/index.d.ts`.
@ -36,12 +32,13 @@
* Open the debug viewlet (`Ctrl+Shift+D` or `Cmd+Shift+D` on Mac) and from the launch configuration dropdown pick `Extension Tests`. * Open the debug viewlet (`Ctrl+Shift+D` or `Cmd+Shift+D` on Mac) and from the launch configuration dropdown pick `Extension Tests`.
* Press `F5` to run the tests in a new window with your extension loaded. * Press `F5` to run the tests in a new window with your extension loaded.
* See the output of the test result in the debug console. * See the output of the test result in the debug console.
* Make changes to `src/test/suite/extension.test.ts` or create new test files inside the `test/suite` folder. * Make changes to `src/web/test/suite/extension.test.ts` or create new test files inside the `test/suite` folder.
* The provided test runner will only consider files matching the name pattern `**.test.ts`. * The provided test runner will only consider files matching the name pattern `**.test.ts`.
* You can create folders inside the `test` folder to structure your tests any way you want. * You can create folders inside the `test` folder to structure your tests any way you want.
## Go further ## Go further
* Reduce the extension size and improve the startup time by [bundling your extension](https://code.visualstudio.com/api/working-with-extensions/bundling-extension). * [Follow UX guidelines](https://code.visualstudio.com/api/ux-guidelines/overview) to create extensions that seamlessly integrate with VS Code's native interface and patterns.
* [Publish your extension](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) on the VSCode extension marketplace. * Check out the [Web Extension Guide](https://code.visualstudio.com/api/extension-guides/web-extensions).
* [Publish your extension](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) on the VS Code extension marketplace.
* Automate builds by setting up [Continuous Integration](https://code.visualstudio.com/api/working-with-extensions/continuous-integration). * Automate builds by setting up [Continuous Integration](https://code.visualstudio.com/api/working-with-extensions/continuous-integration).

View File

@ -1,48 +1,71 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
//@ts-check //@ts-check
'use strict'; 'use strict';
const path = require('path');
//@ts-check //@ts-check
/** @typedef {import('webpack').Configuration} WebpackConfig **/ /** @typedef {import('webpack').Configuration} WebpackConfig **/
/** @type WebpackConfig */ const path = require('path');
const extensionConfig = { const webpack = require('webpack');
target: 'node', // vscode extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/
mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production')
entry: './src/extension.ts', // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/ /** @type WebpackConfig */
output: { const webExtensionConfig = {
// the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/ mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production')
path: path.resolve(__dirname, 'dist'), target: 'webworker', // extensions run in a webworker context
filename: 'extension.js', entry: {
libraryTarget: 'commonjs2' 'extension': './src/web/extension.ts',
}, 'test/suite/index': './src/web/test/suite/index.ts'
externals: { },
vscode: 'commonjs vscode' // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/ output: {
// modules added here also need to be added in the .vscodeignore file filename: '[name].js',
}, path: path.join(__dirname, './dist/web'),
resolve: { libraryTarget: 'commonjs',
// support reading TypeScript and JavaScript files, 📖 -> https://github.com/TypeStrong/ts-loader devtoolModuleFilenameTemplate: '../../[resource-path]'
extensions: ['.ts', '.js'] },
}, resolve: {
module: { mainFields: ['browser', 'module', 'main'], // look for `browser` entry point in imported node modules
rules: [ extensions: ['.ts', '.js'], // support ts-files and js-files
{ alias: {
test: /\.ts$/, // provides alternate implementation for node module and source files
exclude: /node_modules/, },
use: [ fallback: {
{ // Webpack 5 no longer polyfills Node.js core modules automatically.
loader: 'ts-loader' // see https://webpack.js.org/configuration/resolve/#resolvefallback
} // for the list of Node.js core module polyfills.
] 'assert': require.resolve('assert')
} }
] },
}, module: {
devtool: 'nosources-source-map', rules: [{
infrastructureLogging: { test: /\.ts$/,
level: "log", // enables logging required for problem matchers exclude: /node_modules/,
}, use: [{
loader: 'ts-loader'
}]
}]
},
plugins: [
new webpack.optimize.LimitChunkCountPlugin({
maxChunks: 1 // disable chunks by default since web extensions must be a single bundle
}),
new webpack.ProvidePlugin({
process: 'process/browser', // provide a shim for the global `process` variable
}),
],
externals: {
'vscode': 'commonjs vscode', // ignored because it doesn't exist
},
performance: {
hints: false
},
devtool: 'nosources-source-map', // create a source map that points to the original source file
infrastructureLogging: {
level: "log", // enables logging required for problem matchers
},
}; };
module.exports = [ extensionConfig ];
module.exports = [ webExtensionConfig ];