Lesson 02 – Integrating Webpack for Chrome Extension

Tram Ho

Hi everybody! 👋👋👋

Welcome to the series / tutorial Programming the Chrome extension with Typescript + Vue.js .

In today’s article, we will continue to fix issues when building the Chrome Extension in the previous article . My solution will be to use Webpack like in the Viblo Browser Extension .

First look

Last post, if you notice, yarn serve , yarn build actually script alias to vue-cli-service . Vue CLI Service also uses webpack, but at the present time, customize with webpack still has some limitations:

  • Multi entrypoints with webpack
  • Config webpack according to document but not receive new webpack configuration

Hopefully in the future we can customize it better.

We use vue-cli-service to build Vue.js and TypeScript into “pure” js very quickly. So really, what does vue-cli-service do for us? Here are some typical things:

  1. Compile Vue.js + TypeScript and extract it into dist/js/app.[hash].js
  2. Compile SASS / CSS and extract it into dist/css/app.[hash].css
  3. Inject JavaScript and CSS files after successful build into dist/index.html file
  4. Package shared libraries between Vue components into chunk-vendors.[hash].js . For example: Vue.js, vue-class-component

Install dependency

Install Webpack

Because of the above limitation, I will use Webpack directly without using vue-cli-service as before. We need to configure a bit with the webpack to do the things that vue-cli-service did above. At the same time solve the problems encountered in the previous article.

Now, let me install the latest version is v4.41.5. And we will continue to install via yarn :

The $ character is a command prompt on your terminal, please ignore it.

Install Loaders for webpack

Because I do not use vue-cli-service , I will need to install some loaders to compile necessary files such as .vue|.ts|.ts|.css|.scss .


  • vue-loader : compile Vue.js
  • ts-loader : compile code TypeScript
  • css-loader node-sass sass-loader : for compile CSS, SASS.

Install Webpack Plugins

Next, we install other necessary webpack plugins, mini-css-extract-plugin , html-webpack-plugin , copy-webpack-plugin and cross-env :

Refactor code & folder structure

Use templates / popup.html

Do not use vue-cli-service to build, so the public folder is a bit redundant, I will move public/index.html to templates/popup.html , and then delete the no longer needed public folder.

Remove unused link tags in templates/popup.html , eventually the content will look like this:

Update NPM scripts

The build and serve commands are also passed via webpack:


  • webpack -w will add a watcher file, which will automatically rebuild the source code whenever the source code file is modified
  • cross-env helps me define environment variable like NODE_ENV

Now the serve command no longer serves the web server we access via http: // localhost: 8080 as before, but just a watcher to rebuild the code on our own. Therefore, I will change the command alias from serve to start .

Refactor folder structure

Because normally, a browser extension can have many components, not just the popup. To be a little more neat, we will make a little more neat like the Viblo Browser Extension that is moving the popup code into a separate folder named src/popup . By the way, we have created a src/content-scripts folder with a main.ts file inside with the content:

The src directory structure will now become:

Webpack configuration

Create webpack.config.js file

As you can see, we are going to setup webpack to compile the code for the two components in the extension:

  • src/content-scripts
  • src/popup

We need to compile them into two separate files, so we will need to create two entrypoints for the webpack. Sorry, webpack only supports 1 entrypoint only. Therefore we have to configure separate webpacks for each one.

Config webpack for content-scripts

I will have a next article about the components in the browser extension, as well as their functions and effects for people to understand so in this article, let’s temporarily understand content-scripts will be my scripts to perform operations. with the DOM of a web page you are visiting. For example, when we go to the Viblo page and want to change the background of the page from white to black, that processing code will be placed in content-scripts and declared in manifest.json for the browser to execute.

My content scripts are also quite simple because they are TypeScript code, therefore, we only need to use babel-loader and ts-loader in webpack. The configuration file will look like this:

Temporarily we can comment lines 2 and 6 in webpack.config.js like this to test build:

Config webpack for Popup

Popup is a little more config because it has to do a lot of things with Vue.js, TypeScript, Images, SASS.

In particular, I use MiniCssExtractPlugin to extract css into .css file, HtmlPlugin to generate /popup/index.html file ( /popup/js/index.js both /popup/js/index.js and /popup/css/main.css .

Uncomment the webpack.config.js comment so we can run the webpack build to try both popup and content-scripts :

So it has succeeded! 😆

Automatically create manifest.json and logo images

At this point, there is one problem that we have not solved is the automatic copy of the manifest.json file, static into dist after each build source code.

This time, we’ll use the copy-webpack-plugin to automatically generate generate manifest.json and copy the static directory each time we build.

If you notice, the two webpack configuration files will have different ouput folders. For popup it will be dist/popup and content-scripts will be dist . Because manifest.json and static files need to be copied to root, this time I will add webpack/content-scripts webpack configuration.

The above code uses the transform function of copy-webpack-plugin , helping me to insert the new version name at each release. We only need to return the Buffer in the transform function, and our version will be taken from the package.json file for release.

Try the last rebuild:

You see in the log build there will be manifest.json , static/images/logo-*.png added successfully. However, when opening the extension, the File Not Found error appears, because we have moved the index.html file into the popup/index so the manifest.json configuration file has become corrupted. Change the link to default_popup: "popup/index.html" and rebuild it.

So the issues have been resolved. You can then reopen the extension and see that it works normally. 😃 If you are following this tutorial and have a problem, please leave a comment for me to discuss. I wish you success and see you later!


Reference links:

If you find this series interesting and useful, do not forget to share , upvote, folow yourself to read my next articles on Viblo!

You can also subscribe to Vue and Typescript tags on Viblo to get more of the latest posts on these topics on Vbilo! Viblo uses the data that you folow, interested in the system to suggest, so please folow your favorite topics so that the system will recommend more interesting and useful articles from thousands of articles on Viblo that you have never been read!

Share the news now

Source : Viblo