William S William S - 1 month ago 44
TypeScript Question

How do I implement Angular 2 RC (+ TypeScript) in a Chrome Extension (Content Script)

I am struggling to understand how to include Angular 2, a massive framework, into my content script.

My main concern is that every file needs to be included in the content script / manifest.json file. I have tried different variations, but I fail with obscure error messages every time.

I have tried to find some instructions on the internet, but to no avail. The best resource I found was https://www.devbattles.com/en/sand/post-3072-Build_Your_Own_Chrome_Extension_Using_Angular_2__TypeScript but it does not seem to be about content scripts, rather it is about having an isolated webpage. It is also a bit outdated.

This is me struggling with the manifest.json file.. (partial)

{
"matches": [ "https://hp.my.salesforce.com/console*", "https://hp.my.salesforce.com/ui/support/servicedesk/ServiceDeskPage*" ],
"js": [
"ze_modules/systemjs/dist/system.js",
"ze_modules/rxjs/bundles/Rx.js",

"ze_modules/@angular/core/bundles/core.umd.js",
"ze_modules/@angular/common/bundles/common.umd.js",
"ze_modules/requirejs/require.js",

"settings-ui/test.component.js",
"console/includes/jquery-2.2.3.min.js",
"console/includes/toastr.js",
...
...


Does anyone have any pointers? How do I get require to work? How do I get SystemJS to work? It's all a big blur for me.

I've had no issues developing the extension so far, by manually and hastily including some js libs in the manifest.json, but this is just an extreme amount of files.

Some of the error messages..

Uncaught TypeError: Cannot read property 'Subject' of undefined(anonymous function) @ core.umd.js:9194(anonymous function) @ core.umd.js:14(anonymous function) @ core.umd.js:15
common.umd.js:14 Uncaught TypeError: Cannot read property 'Observable' of undefined(anonymous function) @ common.umd.js:14(anonymous function) @ common.umd.js:15

require.js:168 Uncaught Error: Module name "@angular/core" has not been loaded yet for context: _. Use require([])
http://requirejs.org/docs/errors.html#notloaded

Answer

So what I learned here is that chrome extensions differ from regular web development in two major ways:

  • Everything follows CSP policy, meaning dynamic evaluation is more limited and will cause you pain depending on which libraries you want to use (Angular for example, unless you want to utilize AoT which is still beta)
  • Files you use need to be declared in the manifest.json file.

I'm not going to document everything I've learned in how to do the above, but basically you need to get into using Webpack. If you want to use Angular 2 like in my case, you need to use Webpack 2.x and Angular 2.x along with AoT compilation (using angular cli).

Webpack helps you because it bundles all your work into single files, which are a lot easier to declare in your manifest.json file(s, you can have several using webpack config).