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
dist
node_modules
.vscode-test-web/
.vscode-test/
*.vsix
dist/
node_modules/
out/

21
.vscode/launch.json vendored
View File

@ -6,30 +6,33 @@
"version": "0.2.0",
"configurations": [
{
"name": "Run Extension",
"type": "extensionHost",
"name": "Run Web Extension ",
"type": "pwa-extensionHost",
"debugWebWorkerHost": true,
"request": "launch",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}"
"--extensionDevelopmentPath=${workspaceFolder}",
"--extensionDevelopmentKind=web"
],
"outFiles": [
"${workspaceFolder}/dist/**/*.js"
"${workspaceFolder}/dist/web/**/*.js"
],
"preLaunchTask": "${defaultBuildTask}"
"preLaunchTask": "npm: watch-web"
},
{
"name": "Extension Tests",
"type": "extensionHost",
"debugWebWorkerHost": true,
"request": "launch",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}",
"--extensionTestsPath=${workspaceFolder}/out/test/suite/index"
"--extensionDevelopmentKind=web",
"--extensionTestsPath=${workspaceFolder}/dist/web/test/suite/index"
],
"outFiles": [
"${workspaceFolder}/out/**/*.js",
"${workspaceFolder}/dist/**/*.js"
"${workspaceFolder}/dist/web/**/*.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.
{
"files.exclude": {
"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": {
"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"
"files.exclude": {
"out": false // set this to true to hide the "out" folder with the compiled JS files
},
"search.exclude": {
"out": true // set this to false to include "out" folder in search results
},
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
"typescript.tsc.autoDetect": "off"
}

40
.vscode/tasks.json vendored
View File

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

View File

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

View File

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

View File

@ -1,8 +1,8 @@
# 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
* generate uuid

2247
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,7 @@
"categories": [
"Other"
],
"main": "./dist/extension.js",
"browser": "./dist/web/extension.js",
"capabilities": {
"virtualWorkspaces": true,
"untrustedWorkspaces": {
@ -66,30 +66,30 @@
}
},
"scripts": {
"vscode:prepublish": "npm run package",
"compile": "webpack",
"watch": "webpack --watch",
"package": "webpack --mode production --devtool hidden-source-map",
"compile-tests": "tsc -p . --outDir out",
"watch-tests": "tsc -p . -w --outDir out",
"pretest": "npm run compile-tests && npm run compile && npm run lint",
"test": "vscode-test-web --browserType=chromium --extensionDevelopmentPath=. --extensionTestsPath=dist/web/test/suite/index.js",
"pretest": "npm run compile-web",
"vscode:prepublish": "npm run package-web",
"compile-web": "webpack",
"watch-web": "webpack --watch",
"package-web": "webpack --mode production --devtool hidden-source-map",
"lint": "eslint src --ext ts",
"test": "node ./out/test/runTest.js"
"run-in-browser": "vscode-test-web --browserType=chromium --extensionDevelopmentPath=. ."
},
"devDependencies": {
"@types/vscode": "^1.65.0",
"@types/glob": "^7.2.0",
"@types/mocha": "^9.1.0",
"@types/node": "14.x",
"@typescript-eslint/eslint-plugin": "^5.12.1",
"@typescript-eslint/parser": "^5.12.1",
"eslint": "^8.9.0",
"glob": "^7.2.0",
"mocha": "^9.2.1",
"typescript": "^4.5.5",
"ts-loader": "^9.2.6",
"webpack": "^5.69.1",
"webpack-cli": "^4.9.2",
"@vscode/test-electron": "^2.1.2"
"@types/vscode": "^1.86.0",
"@types/mocha": "^10.0.6",
"@types/assert": "^1.5.10",
"eslint": "^8.56.0",
"@typescript-eslint/eslint-plugin": "^6.19.1",
"@typescript-eslint/parser": "^6.19.1",
"mocha": "^10.2.0",
"typescript": "^5.3.3",
"@vscode/test-web": "^0.0.51",
"ts-loader": "^9.5.1",
"webpack": "^5.90.0",
"webpack-cli": "^5.1.4",
"@types/webpack-env": "^1.18.4",
"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';
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) {
const editor = vscode.window.activeTextEditor;
@ -35,9 +16,25 @@ function applyEdit(transform: Function) {
}
}
export function activate(context: vscode.ExtensionContext) {
console.log('Recombobulator is activated!');
function base64(a: string) {
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', () => {
applyEdit(base64);
}));

View File

@ -5,7 +5,7 @@ import * as assert from 'assert';
import * as vscode from 'vscode';
// import * as myExtension from '../../extension';
suite('Extension Test Suite', () => {
suite('Web Extension Test Suite', () => {
vscode.window.showInformationMessage('Start all tests.');
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": {
"module": "commonjs",
"module": "Node16",
"target": "ES2020",
"outDir": "dist",
"lib": [
"ES2020"
"ES2020", "WebWorker"
],
"sourceMap": true,
"rootDir": "src",

View File

@ -2,31 +2,27 @@
## What's in the folder
* This folder contains all of the files necessary for your extension.
* `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/extension.ts` - this is the main file where you will provide the implementation of your command.
* 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`.
* 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.
* `src/web/extension.ts` * this is the main file for the browser
* `webpack.config.js` * the webpack config file for the web main
## 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
* Press `F5` to open a new window with your extension loaded.
* Run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Hello World`.
* Set breakpoints in your code inside `src/extension.ts` to debug your extension.
* Find output from your extension in the debug console.
* Run `npm install`.
* Place breakpoints in `src/web/extension.ts`.
* Debug via F5 (Run Web Extension).
* Execute extension code via `F1 > Hello world`.
## 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.
## Explore the API
* 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`.
* 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.
* 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`.
* You can create folders inside the `test` folder to structure your tests any way you want.
## 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).
* [Publish your extension](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) on the VSCode extension marketplace.
* [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.
* 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).

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
'use strict';
const path = require('path');
//@ts-check
/** @typedef {import('webpack').Configuration} WebpackConfig **/
/** @type WebpackConfig */
const extensionConfig = {
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')
const path = require('path');
const webpack = require('webpack');
entry: './src/extension.ts', // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/
output: {
// the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/
path: path.resolve(__dirname, 'dist'),
filename: 'extension.js',
libraryTarget: 'commonjs2'
},
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/
// modules added here also need to be added in the .vscodeignore file
},
resolve: {
// support reading TypeScript and JavaScript files, 📖 -> https://github.com/TypeStrong/ts-loader
extensions: ['.ts', '.js']
},
module: {
rules: [
{
test: /\.ts$/,
exclude: /node_modules/,
use: [
{
loader: 'ts-loader'
}
]
}
]
},
devtool: 'nosources-source-map',
infrastructureLogging: {
level: "log", // enables logging required for problem matchers
},
/** @type WebpackConfig */
const webExtensionConfig = {
mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production')
target: 'webworker', // extensions run in a webworker context
entry: {
'extension': './src/web/extension.ts',
'test/suite/index': './src/web/test/suite/index.ts'
},
output: {
filename: '[name].js',
path: path.join(__dirname, './dist/web'),
libraryTarget: 'commonjs',
devtoolModuleFilenameTemplate: '../../[resource-path]'
},
resolve: {
mainFields: ['browser', 'module', 'main'], // look for `browser` entry point in imported node modules
extensions: ['.ts', '.js'], // support ts-files and js-files
alias: {
// provides alternate implementation for node module and source files
},
fallback: {
// Webpack 5 no longer polyfills Node.js core modules automatically.
// see https://webpack.js.org/configuration/resolve/#resolvefallback
// for the list of Node.js core module polyfills.
'assert': require.resolve('assert')
}
},
module: {
rules: [{
test: /\.ts$/,
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 ];