├── src
├── background.ts
├── content_script.tsx
├── index.css
├── options.tsx
└── popup.tsx
├── .gitignore
├── postcss.config.js
├── public
├── icon.png
├── options.html
├── popup.html
└── manifest.json
├── jest.config.js
├── webpack
├── webpack.prod.js
├── webpack.dev.js
└── webpack.common.js
├── tailwind.config.js
├── tsconfig.json
├── README.md
├── LICENSE
└── package.json
/src/background.ts:
--------------------------------------------------------------------------------
1 | // Background Script
--------------------------------------------------------------------------------
/src/content_script.tsx:
--------------------------------------------------------------------------------
1 | // Content Script
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | npm-debug.log
2 | node_modules/
3 | dist/
4 | tmp/
5 | yarn.lock
6 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/public/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sumansid/Chrome-Extension-Starter-React-Typescript-Tailwind/HEAD/public/icon.png
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | "roots": [
3 | "src"
4 | ],
5 | "transform": {
6 | "^.+\\.ts$": "ts-jest"
7 | },
8 | };
9 |
--------------------------------------------------------------------------------
/webpack/webpack.prod.js:
--------------------------------------------------------------------------------
1 | const { merge } = require('webpack-merge');
2 | const common = require('./webpack.common.js');
3 |
4 | module.exports = merge(common, {
5 | mode: 'production'
6 | });
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {
3 | content: ["./src/**/*.{js,tsx, ts}"],
4 | theme: {
5 | extend: {},
6 | },
7 | plugins: [],
8 | };
9 |
--------------------------------------------------------------------------------
/webpack/webpack.dev.js:
--------------------------------------------------------------------------------
1 | const { merge } = require('webpack-merge');
2 | const common = require('./webpack.common.js');
3 |
4 | module.exports = merge(common, {
5 | devtool: 'inline-source-map',
6 | mode: 'development'
7 | });
--------------------------------------------------------------------------------
/public/options.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | My Test Extension Options
5 |
6 |
7 |
8 |
9 | this is the options page
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/public/popup.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Getting Started Extension's Popup
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/options.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import ReactDOM from "react-dom";
3 | import "./index.css";
4 |
5 | const Options = () => {
6 | return Options page
;
7 | };
8 |
9 | ReactDOM.render(
10 |
11 |
12 | ,
13 | document.getElementById("root")
14 | );
15 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "strict": true,
4 | "module": "commonjs",
5 | "target": "es6",
6 | "esModuleInterop": true,
7 | "sourceMap": false,
8 | "rootDir": "src",
9 | "outDir": "dist/js",
10 | "noEmitOnError": true,
11 | "jsx": "react",
12 | "typeRoots": [ "node_modules/@types" ]
13 | }
14 | }
--------------------------------------------------------------------------------
/src/popup.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import ReactDOM from "react-dom";
3 | import "./index.css";
4 |
5 | const Popup = () => {
6 | return (
7 | <>
8 |
9 |
10 | React, Typescript, Tailwind Starter Code
11 |
12 |
13 | >
14 | );
15 | };
16 |
17 | ReactDOM.render(
18 |
19 |
20 | ,
21 | document.getElementById("root")
22 | );
23 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "manifest_version": 3,
3 |
4 | "name": "Chrome Extension TypeScript Starter",
5 | "description": "Chrome Extension, TypeScript, Visual Studio Code",
6 | "version": "1.0",
7 |
8 | "options_ui": {
9 | "page": "options.html"
10 | },
11 |
12 | "action": {
13 | "default_icon": "icon.png",
14 | "default_popup": "popup.html"
15 | },
16 |
17 | "content_scripts": [
18 | {
19 | "matches": [""],
20 | "js": ["js/vendor.js", "js/content_script.js"]
21 | }
22 | ],
23 |
24 | "background": {
25 | "service_worker": "js/background.js"
26 | },
27 |
28 | "permissions": [
29 | "storage"
30 | ],
31 |
32 | "host_permissions": [
33 | ""
34 | ]
35 | }
36 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # create-t3-extension
2 |
3 | Chrome Extension: React + TypeScript + TailWind CSS
4 |
5 | ## Prerequisites
6 |
7 | - [node + npm](https://nodejs.org/) (Current Version)
8 |
9 | ## Includes the following
10 |
11 | - TypeScript
12 | - Webpack
13 | - React
14 | - Tailwind CSS
15 | - Jest
16 |
17 | ## Project Structure
18 |
19 | - src/typescript: TypeScript source files
20 | - src/assets: static files
21 | - dist: Chrome Extension directory
22 | - dist/js: Generated JavaScript files
23 |
24 | ## Setup
25 |
26 | ```
27 | npm install
28 | ```
29 |
30 | ## Build
31 |
32 | ```
33 | npm run build
34 | ```
35 |
36 | ## Build in watch mode
37 |
38 | ```
39 | npm run watch
40 | ```
41 |
42 | ## References
43 | [https://github.com/chibat/chrome-extension-typescript-starter](https://github.com/chibat/chrome-extension-typescript-starter)
44 |
45 | [https://github.com/t3-oss/create-t3-app](https://github.com/t3-oss/create-t3-app)
46 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Tomofumi Chiba
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "chrome-extension-react-typescript-tailwind-starter",
3 | "version": "1.0.0",
4 | "description": "chrome-extension-react-typescript-tailwind-starter",
5 | "main": "index.js",
6 | "scripts": {
7 | "watch": "webpack --config webpack/webpack.dev.js --watch",
8 | "build": "webpack --config webpack/webpack.prod.js",
9 | "clean": "rimraf dist",
10 | "test": "npx jest",
11 | "style": "prettier --write \"src/**/*.{ts,tsx}\""
12 | },
13 | "author": "",
14 | "license": "MIT",
15 | "repository": {
16 | "type": "git",
17 | "url": "https://github.com/sumansid/chrome-extention-react-typescript-tailwind-starter.git"
18 | },
19 | "dependencies": {
20 | "react": "^17.0.1",
21 | "react-dom": "^17.0.1"
22 | },
23 | "devDependencies": {
24 | "@types/chrome": "0.0.158",
25 | "@types/jest": "^27.0.2",
26 | "@types/react": "^17.0.0",
27 | "@types/react-dom": "^17.0.0",
28 | "autoprefixer": "^10.4.7",
29 | "copy-webpack-plugin": "^9.0.1",
30 | "css-loader": "^6.7.1",
31 | "glob": "^7.1.6",
32 | "jest": "^27.2.1",
33 | "postcss": "^8.4.14",
34 | "postcss-loader": "^7.0.0",
35 | "prettier": "^2.2.1",
36 | "rimraf": "^3.0.2 ",
37 | "style-loader": "^3.3.1",
38 | "tailwindcss": "^3.1.4",
39 | "ts-jest": "^27.0.5",
40 | "ts-loader": "^8.0.0",
41 | "typescript": "^4.4.3 ",
42 | "webpack": "^5.61.0",
43 | "webpack-cli": "^4.0.0",
44 | "webpack-merge": "^5.0.0"
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/webpack/webpack.common.js:
--------------------------------------------------------------------------------
1 | const webpack = require("webpack");
2 | const path = require("path");
3 | const CopyPlugin = require("copy-webpack-plugin");
4 | const srcDir = path.join(__dirname, "..", "src");
5 |
6 | module.exports = {
7 | entry: {
8 | popup: path.join(srcDir, "popup.tsx"),
9 | options: path.join(srcDir, "options.tsx"),
10 | background: path.join(srcDir, "background.ts"),
11 | content_script: path.join(srcDir, "content_script.tsx"),
12 | },
13 | output: {
14 | path: path.join(__dirname, "../dist/js"),
15 | filename: "[name].js",
16 | },
17 | optimization: {
18 | splitChunks: {
19 | name: "vendor",
20 | chunks(chunk) {
21 | return chunk.name !== "background";
22 | },
23 | },
24 | },
25 | module: {
26 | rules: [
27 | {
28 | test: /\.tsx?$/,
29 | use: "ts-loader",
30 | exclude: /node_modules/,
31 | },
32 |
33 | {
34 | use: [
35 | "style-loader",
36 | "css-loader",
37 | {
38 | loader: "postcss-loader",
39 | options: {
40 | postcssOptions: {
41 | ident: "postcss",
42 | plugins: ["tailwindcss", "autoprefixer"],
43 | },
44 | },
45 | },
46 | ],
47 | test: /\.css$/i,
48 | },
49 | ],
50 | },
51 | resolve: {
52 | extensions: [".ts", ".tsx", ".js"],
53 | },
54 | plugins: [
55 | new CopyPlugin({
56 | patterns: [{ from: ".", to: "../", context: "public" }],
57 | options: {},
58 | }),
59 | ],
60 | };
61 |
--------------------------------------------------------------------------------