📜 ⬆️ ⬇️

Develop Chrome Extension with Angular CLI

I have been developing extensions to Chrome for a long time, and during that time I have gone a whole way from Greasemonkey user scripts to a full-fledged Angular application in the chrome-extension shell. My task is that I patch some already working sites in order to change their functionality and automate some processes on these sites. Sometimes my application grows to a large scale and it becomes difficult to maintain a plain-js extension (there are a lot of settings in the application, CRUD functionality, etc.). And here comes Angular to the rescue.

In this article I will tell you how I made friends with the Chrome Extension and Angular CLI , and set up the development process, as well as what difficulties I encountered and how I solved them.
Create a new folder and initialize a new application in it.

mkdir new-project cd new-project ng new frontend --routing=true --skipGit=true --style=scss --skipTests=true 

In the developmental stage, Angular generates a dynamic html-file in which development takes place, and the Chromov extension needs to be fed a static html-file in order to see the result of the work. Of course, you can separately assemble the Angulyarovsky project and then build a version in addition, but it will be convenient if this happens automatically.
')
After generating the new application, go to the frontend folder and in the file package.json in the scripts section add a new script to build our project

 "developing": "ng build --watch --deploy-url /frontend/dist/frontend/ --base-href /frontend/dist/frontend/index.html?/" 

Note the deploy-url and base-href .

Then in the root of the project we create another extension folder and in it we will create the extension.js file, which will be the background script for our extension. Current project structure:

 | new-project/ | | extension/ | | | extension.js | | frontend/ | | | ... 

Content extension.js

 const ANGULAR_HTML_URL = "../../frontend/dist/frontend/index.html"; chrome.browserAction.onClicked.addListener(function () { chrome.tabs.create({ url: chrome.runtime.getURL(ANGULAR_HTML_URL) }); }); 

This will be a browserAction , which will open a new tab with our angular application, which will be stored in the assembled form along this path.

Let's add manifest.json to our project
 { "manifest_version": 2, "name": "Simple Chrome Ext", "description": "Simple Chrome Extension as an example", "version": "1.00", "author": "Bogdan", "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'", "background": { "persistent": true, "scripts": ["/extension/extension.js"] }, "browser_action": { "default_title": "Chrome ext" } } 


Now we can build our project into an extension. Go to chrome: // extensions / , turn on developer mode and select Download unpacked extension .

Result
image

Convenience is that we have almost hot-reloading. We started ng build with the watch flag and when the code changes, the project will be rebuilt and the js-files will be replaced. That is, on the extension page, we just need to reload the page and all updates will pick up. This greatly accelerates the development of add-ons.

Another thing I ate at the dog, is that in the routing configuration:

 { useHash: true } 

as well as returning above, we specified base-href for the build as /frontend/dist/frontend/index.html?/ - pay attention to the question mark before the last slash. The fact is that on some systems, when clicking on links in an Angulyarov application, everything crashes without this sign. Apparently, the static web server of the chrome engine perceived the URL change as a request to another file (even though useHash: true) and returned 404 error when refreshing the page. Only in this combination, I was able to achieve stable operation on all systems.

Let's go back to the package.json of our application and add another script.

 "prod": "ng build --sourceMap false --prod true --deploy-url /frontend/dist/frontend/ --base-href /frontend/dist/frontend/index.html?/" 

This will be a script to build our application for the production version.

In the Chrome Web Store, a zip-archive with an extension is posted, and to simplify the build, I made a script for this purpose.

update.sh
 #!/bin/bash rm -rf ./prod-build mkdir -p prod-build/frontend cd frontend npm run prod cd .. cp -R ./frontend/dist ./prod-build/frontend cp -R ./extension ./prod-build cp ./manifest.json ./prod-build zip -r prod-build{.zip,} rm -rf ./prod-build 

Source code can be viewed here .

Total: we created a blank for the development of the Angular Chrome Extension with the correct routing and convenient update / build of the application.

PS: to get rid of such / frontend / dist / frontend / paths, you can set up the environment and prescribe the path in a production assembly in a different way, but this is no longer the key point.

Source: https://habr.com/ru/post/458556/


All Articles