Creating Chrome Extensions With TypeScript
Change the background color of a page
In this article
I will cover, what are extensions, the importance of TypeScript, and how to create a simple chrome extension using TypeScript showing the required procedures step by step.
What Are Extensions?
Almost everyone is using extensions on their browsers, especially for blocking those annoying ads.
Some examples of chrome extensions are:
- Password managers
- Ad blockers
- To-do list creators
and many more can be found at the Chrome Web Store.
What Are Extensions Consists Of?
Extensions are built on web technologies such as HTML, JavaScript, and CSS. They run in a separate, sandboxed execution environment and interact with the Chrome browser. Extensions let you “extend” the browser by using APIs to modify browser behavior and access web content.
Why TypeScript?
For starters, TypeScript is a superset of JavaScript meaning that it extends JavaScript. Hence, it solves some problems that JavaScript can’t.
It does not mean TypeScript must be used for only large applications. If you like to code type safely this is a great way to go.
TypeScript achieves its goals in three ways:
- Support for modern JavaScript features
- Advanced type system
- Developer tooling support
With the help of TypeScript, your application can suddenly be type-safe, easy to develop, easy to debug, object-oriented, and well structured.
Enough with the chatter, lets jump into code
Prerequisites
To be able to complete this tutorial you need to have Node and npm installed.
Note
During the demonstration, you will be creating some folders and files. The final folder structure will be like below.
If you are willing to change the folder structure, you will have to adjust the configurations accordingly.
Folder structure
1. Create the project
- Create an empty directory and initialize a project via npm.
~$ mkdir medium-extension
~$ cd medium-extension
~$ npm init -y
- Install the required dependencies.
~$ npm install --save-dev webpack webpack-cli
~$ npm install --save-dev copy-webpack-plugin
~$ npm install --save-dev typescript ts-loader
~$ npm install --save-dev @types/chrome
- Create
tsconfig.json
folder. Thetsconfig.json
file specifies the root files and the compiler options required to compile the project. Feel free to dig deep into configuring TypeScript projects from here.
tsconfig.json
{
"compilerOptions": {
"strict": true,
"module": "commonjs",
"target": "es6",
"esModuleInterop": true,
"sourceMap": true,
"rootDir": "src",
"outDir": "dist/js",
"noEmitOnError": true,
"typeRoots": [ "node_modules/@types" ]
}
}
- Create directories named
src
andwebpack
andpublic
inside the project folder.
Create a webpack.config.js
file inside the webpack
folder and background.ts
file inside the src folder.
webpack.config.js
const path = require('path');
const CopyPlugin = require('copy-webpack-plugin');
module.exports = {
mode: "production",
entry: {
background: path.resolve(__dirname, "..", "src", "background.ts"),
},
output: {
path: path.join(__dirname, "../dist"),
filename: "[name].js",
},
resolve: {
extensions: [".ts", ".js"],
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: "ts-loader",
exclude: /node_modules/,
},
],
},
plugins: [
new CopyPlugin({
patterns: [{from: ".", to: ".", context: "public"}]
}),
],
};
This will direct webpack to load all .ts
files through the ts-loader
, and output a dist
folder containing bundled .js
files in our project.
- Add
build
script in thepackage.json
file.
package.json
{
"name": "medium-extension",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack --config webpack/webpack.config.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {},
"devDependencies": {
"ts-loader": "^9.2.6",
"typescript": "^4.5.4",
"webpack": "^5.66.0",
"webpack-cli": "^4.9.1"
}
}
2. Create the manifest
Every extension has a JSON-formatted manifest file. A manifest file contains metadata of the whole extension application including name, version, descriptions, content scripts, permissions, and many more.
Create a file named manifest.json
. Purposes and usages of each field in the manifest file can be found in the official document.
manifest.json
{
"name": "Medium Extension",
"description": "This extension is made for demonstration purposes",
"version": "1.0",
"manifest_version": 3,
"permissions": [
"activeTab",
"scripting"
],
"background": {
"service_worker": "background.js"
}
}
In this manifest file:
name
, description
, and version
are the same as the name implies.
manifest_version
: determines the version of the manifest file. Which is the latest and the recommended version at the moment.
permissions
: these are required permissions that are needed for your extension’s basic functionality.
service_worker
: Extensions register their background service workers generally when they are first initialized. This configuration allows background.js
functioning as a service worker. A service worker is a script that your browser runs in the background. Your extensions functionality will be handled via a registered service worker.
3. Implement the service worker
We described background.js
in the manifest file. We will create a file named background.ts
and write our code type safely, handing over the bundling and the ts -> js conversion to the webpack
.
background.ts
let active = false;
function makeOrange(color: string): void {
document.body.style.backgroundColor = color;
}
chrome.action.onClicked.addListener((tab) => {
active = !active;
const color = active ? 'orange' : 'white';
chrome.scripting.executeScript({
target: {tabId: tab.id ? tab.id : -1},
func: makeOrange,
args: [color]
}).then();
});
In this code block, with the help of the chrome API, we listen to the click event on the extension action button and change the background color of the currently active tab.
4. Bundle the code
In the root directory of the project, run the following script.
~$ npm run build
This will create a dist
folder containing manifest.json
and background.js
in the project.
5. Load the extension
- Navigate to the
chrome://extensions
in your chrome browser. And make sure that Developer Mode is activated on the top right side of the screen.
- Click Load Unpacked and target the
dist
folder in your project.
It will bring up your extension on the screen.
- Click the extension icon on the right side of the Chrome toolbar. And pin the extension to the toolbar.