Chrome extension packages are essentially a zip file with all the source code, assets and the manifest inside of it. Assuming the following directory for the chrome extension:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
.
├── README.md
├── build.py (script that will build the zip file)
├── package.json
├── src
│   ├── _locales
│   │   └── en
│   │       └── messages.json
│   ├── icons
│   │   ├── icon-128.png
│   │   └── icon-64.png
│   ├── manifest.json
│   └── scripts
│       ├── background.js
│       └── background.ts
├── tsconfig.json
└── yarn.lock

The script(build.py) assumes the source code for the extension is located inside src directory and it’ll:

  • go over the files and process only the ones we’re interested in;
  • build/clean the build directory;
  • generate the zipped package for the chrome extension
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#! /usr/bin/python3

''' Creates a zip file from src folder into a build directory  '''

import os
import zipfile
import glob

APP_NAME = 'Fluctus'
BUILD_DIR = 'build' # where zip package will be stored
FILE_EXT_TO_IGNORE = ('.ts',) # file extensions to keep out of the zip extension package

if not(os.path.exists(f'{BUILD_DIR}')):
    print('Creating build directory..\n')
    os.mkdir(f'./{BUILD_DIR}')
else:
    # clean build folder
    print('cleaning directory.. \n')
    for file in glob.glob(f'{BUILD_DIR}/*'):
        os.unlink(file)

# create zipfile
with zipfile.ZipFile(f'{BUILD_DIR}/{APP_NAME}.zip', 'w', zipfile.ZIP_DEFLATED) as zip:
    # walk down subdirs of src and get the files that will go into the zip file
    for (path, dirs, files) in os.walk('src'):
        if(len(files) < 1):
            continue
        for file in files:
            file_path = os.path.join(path, file)
            print(f'File found: {file_path}')

            # skip ignored files
            # get file extension(eg: '.json') & check if it's in the ignore list
            if(file[file.find('.'):] in FILE_EXT_TO_IGNORE):
                print('ignoring file... \n')
                continue

            # name for file in zipfile
            # remove 'src' folder from file so only contents of src will be in the final zip
            zipped_file_name = file_path[4:]
            print(f'zipping file as: {zipped_file_name} \n')
            zip.write(file_path, arcname=zipped_file_name)

We can then run the script:

1
2
3
4
# make it executable
sudo chmod +x build.py

./build.py