question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Use Angular to build (and live reload) chrome extension

See original GitHub issue

Describe the bug I try to use angular to build chrome extension. To run, extension must have a background script. I place a background.ts file in the src folder, and add custom build to angular.json serve command:

        "serve": {
          "builder": "@angular-builders/custom-webpack:browser",
          "options": {
            "customWebpackConfig": {
              "path": "./custom-webpack.config.js",
              "replaceDuplicatePlugins": true,
              "mergeStrategies": {
                "externals": "prepend"
              }
            },
            "outputPath": "dist",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.app.json",
            "aot": true,
            "assets": ["src/favicon.ico", "src/assets", "src/manifest.json"],
            "styles": ["src/styles.styl"],
            "scripts": []
          },

the custom-webpack.config.js file with the new background “entry” to enhance webpack build:

const ExtensionReloader = require('webpack-extension-reloader')

module.exports = {
  watch: true,
  entry: {
    background: './src/background/index.ts'
  },
  output: {
    filename: '[name].bundle.js'
  },
  plugins: [new ExtensionReloader({ reloadPage: true })]
}

the result seems to be good:

chunk {background} background.bundle.js, background.bundle.js.map (background) 41.2 kB [initial] [rendered]
chunk {main} main.bundle.js, main.bundle.js.map (main) 29.9 kB [initial] [rendered]
chunk {polyfills} polyfills.bundle.js, polyfills.bundle.js.map (polyfills) 582 kB [initial] [rendered]
chunk {runtime} runtime.bundle.js, runtime.bundle.js.map (runtime) 6.08 kB [entry] [rendered]
chunk {styles} styles.bundle.js, styles.bundle.js.map (styles) 16.8 kB [initial] [rendered]
chunk {vendor} vendor.bundle.js, vendor.bundle.js.map (vendor) 2.92 MB [initial] [rendered]

but the compiled script is not executed when loaded by chrome extension (via manifest.json file)

{
  ...,
  "background": {
    "scripts": ["background.bundle.js"],
    "persistent": true
  },
  "permissions": [
    "tabs",
    "activeTab",
    "background",
    "webNavigation",
    "webRequest",
    "storage"
  ]
}

To Reproduce Steps to reproduce the behavior:

  1. Generate new ng app (angular 8)
  2. modify angular.json serve cmd to not serve but output files on dist and add chrome reloader webpack module

Expected behavior Background to be executed

Screenshots script is well loaded by extension: Capture d’écran 2019-06-12 à 23 44 26 But nothing exectuded: Capture d’écran 2019-06-12 à 23 44 32

Additional context package.json

{
  "name": "extension-ng8",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "~8.0.0",
    "@angular/common": "~8.0.0",
    "@angular/compiler": "~8.0.0",
    "@angular/core": "~8.0.0",
    "@angular/forms": "~8.0.0",
    "@angular/platform-browser": "~8.0.0",
    "@angular/platform-browser-dynamic": "~8.0.0",
    "@angular/router": "~8.0.0",
    "@types/chrome": "^0.0.86",
    "rxjs": "~6.4.0",
    "tslib": "^1.9.0",
    "webpack-extension-reloader": "^1.1.0",
    "zone.js": "~0.9.1"
  },
  "devDependencies": {
    "@angular-builders/custom-webpack": "^8.0.2",
    "@angular-devkit/build-angular": "~0.800.0",
    "@angular/cli": "~8.0.2",
    "@angular/compiler-cli": "~8.0.0",
    "@angular/language-service": "~8.0.0",
    "@types/jasmine": "~3.3.8",
    "@types/jasminewd2": "~2.0.3",
    "@types/node": "~8.9.4",
    "codelyzer": "^5.0.0",
    "jasmine-core": "~3.4.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~4.1.0",
    "karma-chrome-launcher": "~2.2.0",
    "karma-coverage-istanbul-reporter": "~2.0.1",
    "karma-jasmine": "~2.0.1",
    "karma-jasmine-html-reporter": "^1.4.0",
    "protractor": "~5.4.0",
    "ts-node": "~7.0.0",
    "tslint": "~5.15.0",
    "typescript": "~3.4.3",
    "webpack-chrome-extension-reloader": "^1.3.0"
  }
}

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:12 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
just-jebcommented, Jun 18, 2019

Ok, it took me a while but I figured out what your problem is. If you take a look at the resulting bundle (background.bundle.js) you’ll see this code at the end of the bundle:

(window["webpackJsonp"] = window["webpackJsonp"] || []).push([["background"],{

/***/ "./src/background/index.ts":
/*!*********************************!*\
  !*** ./src/background/index.ts ***!
  \*********************************/
/*! no static exports found */
/***/ (function(module, exports) {

console.log('will i be executed? Will I?');


/***/ })

},[["./src/background/index.ts","runtime"]]]);

This code adds your chunk as a webpack module but it doesn’t actually run your module. Who does? runtime.bundle.js. This chunk is responsible for setting up webpack environment and installing JSONP callback for chunks loading. This code will eventually execute your chunk once it is loaded.
Thus, just add runtime.bundle.js to your manifest background.scripts array and you’re good to go.

Boy I’m gonna write a blog post about this stuff.

Another insight - don’t abuse ng serve. You use custom-webpack:browser builder for serve target, which is technically fine but very confusing. Instead, use build target for that and run it with ng build --watch. This way you keep your serve clean and also can build your extension with or w/o watching. Just don’t forget to remove watch: true from your webpack config.

I’ve tested it, it works, the background page reloads when you change the file.
Best of luck!

1reaction
just-jebcommented, Jun 20, 2019

Well, there are actually two options:

  1. Use configurations. You can have two Webpack configs: first that just adds an entry for background bundle (this will be used for the regular build) and second extending it (in which you place all the live reload stuff, watch etc.). Then you can add development configuration under build target and specify a different (the second one) webpack config in there. At last, run ng build --development to use this configuration.
  2. You can use Custom webpack config function which receives Webpack config built by Angular CLI and check the watch property in it. If it’s there push ExtensionReloader into plugins array.
Read more comments on GitHub >

github_iconTop Results From Across the Web

Use Angular to build (and live reload) chrome extension #341
I try to use angular to build chrome extension. To run, extension must have a background script. ... Steps to reproduce the behavior:...
Read more >
Chrome Extension with Angular — from zero to a ... - Just Jeb
In this article we're going to review Chrome Extensions architecture and learn ... Now let's run ng build again and reload our extension:....
Read more >
Chrome extension with Angular — from zero to a little hero
Build & reload the extension, go to http://google.com and you're back to see this beautiful picture: Background page live reload? Who said live...
Read more >
Chrome Extension to react to angular page changes / reload ...
Chrome Extension to react to angular page changes / reload upon changes · So do you have control over the new Angular 8...
Read more >
Using Angular's Live Reload Web Server to Refresh Pages on ...
Turns out - there's an easier way: It's quite easy set up the WebPack Web Server to externally expose an IP address, which...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found