samuelsimoes / chrome-extension-webpack-boilerplate

A basic foundation boilerplate for rich Chrome Extensions using Webpack to help you write modular and modern Javascript code, load CSS easily and automatic reload the browser on code changes.
MIT License
1.7k stars 347 forks source link

How to use "web_accessible_resources" option in manifest.json to inject CSS and JS? #58

Open JakubKoralewski opened 5 years ago

JakubKoralewski commented 5 years ago

I've done this sucessfully in my chrome extension project before changing it as per the boilerplate.

I have a CSS file and a JS file declared in the "web_accessible_resources" option. This is how I inject it inside of a content script:

// js/content-script.js

//js
const s = document.createElement('script');
s.src = chrome.runtime.getURL('js/script.js');
document.body.appendChild(s);
s.onload = function() {
    this.remove();
};

//css
var style = document.createElement('link');
style.rel = 'stylesheet';
style.type = 'text/css';
style.href = chrome.runtime.getURL('css/style.css');
(document.head || document.documentElement).appendChild(style);

Is this possible with the current state the project is in? I don't know Webpack at all, so maybe all I have to do is transfer the files I need to the /build folder somehow?

EDIT: Previously used File Manager Webpack plugin but this can be easily done with the currently used Copy Webpack Plugin.

new CopyWebpackPlugin([{
        from: 'src/manifest.json',
        transform: function (content, path) {
            // generates the manifest file using the package.json informations
            return Buffer.from(JSON.stringify({
                description: process.env.npm_package_description,
                version: process.env.npm_package_version,
                ...JSON.parse(content.toString())
            }));
        }
    },
    {
        from: path.join(__dirname, 'src', 'injected', 'script.js'),
    }
]),

However it would be great if this was automatically generated from the "web_accessible_resources" option in manifest.json. Additionally, I don't know how you'd apply Babel etc. to these files? Or something like SASS.

Moreover, hot reload on these files doesn't work.

JakubKoralewski commented 5 years ago

Here's how to make SASS (.scss) files work with "web_accesible_resources" (with working hot reload).

  1. Declare the compiled .css in "web_accessible_resources" option:
    
    //manifest.json

"web_accessible_resources": ["globalStyles.css"],


1. Install and Require [MiniCssExtractPlugin](https://github.com/webpack-contrib/mini-css-extract-plugin).
```javascript
\\webpack.config.js

var MiniCssExtractPlugin = require('mini-css-extract-plugin');
options.plugins: [
    new MiniCssExtractPlugin({
        // Options similar to the same options in webpackOptions.output
        // both options are optional
        filename: '[name].css',
        chunkFilename: '[id].css'
    }),
]
  1. Make popup.scss and options.scss compile as normal, but make the web_accessible_file be compiled by MiniCssExtractPlugin to a separate file.
    
    \\webpack.config.js

options.module.rules: [ { test: /.(s*)css$/, use: ['style-loader', 'css-loader', 'sass-loader'], exclude: /node_modules/ }, { // where globalStyles.css is the file you have declared in web_accessible_resources! test: /globalStyles.scss$/, use: [{ loader: MiniCssExtractPlugin.loader, options: { // you can specify a publicPath here // by default it use publicPath in webpackOptions.output publicPath: 'dist/' } }, 'css-loader', 'sass-loader' ] }, ]


EDIT: Problem is there is an unnecessary 'globalStyles.bundle.js' file generated.

I had to again turn to the [File Manager Webpack Plugin](https://github.com/gregnb/filemanager-webpack-plugin):
```javascript
new FileManagerWebpackPlugin({
    onEnd: {
        delete: ['build/globalStyles.bundle.js']
    }
}),