Skip to content

feat: add options.experimental_output#51

Merged
Jack-Works merged 4 commits intomasterfrom
cs
Dec 15, 2024
Merged

feat: add options.experimental_output#51
Jack-Works merged 4 commits intomasterfrom
cs

Conversation

@Jack-Works
Copy link
Member

@Jack-Works Jack-Works commented Dec 12, 2024

close #50

options.experimental_output

This is an experimental API. API might change at any time. Please provide feedback!

TLDR: How to use this

string

If you don't strictly rely on run_at,
set it as the following

export default {
  entry: {
    myContentScript: 'src/contentScript.ts',
  },
  // ...
  plugins: [
    // ...
    new WebExtensionPlugin({
      // ...
      experimental_output: {
        myContentScript: 'cs.js'
      },
    })
  ]
}
{
  // ...
  "content_scripts": [
    {
      "matches": ["..."],
      "js": ["cs.js"]
    }
  ]
}
function

If you cannot use asynchronous loading, set up like below.
This setup requires you to have a manifest.json being emitted.

export default {
  entry: {
    myContentScript: 'src/contentScript.ts',
  },
  // ...
  plugins: [
    // ...
    new WebExtensionPlugin({
      // ...
      experimental_output: {
        myContentScript: (manifest, list) => {
          manifest.content_scripts[0].js = list
        }
      },
    })
  ]
}
object
export default {
  entry: {
    background: 'src/contentScript.ts',
  },
  // ...
  plugins: [
    // ...
    new WebExtensionPlugin({
      // ...
      experimental_output: {
        background: {
          file: 'sw.js',
          touch(manifest, file) {
            manifest.background.service_worker = file
          }
        },
      },
    })
  ]
}

Explanation

This is an experimental API.
API might change at any time.
Please provide feedback!

This option helps the initial chunk loading of content scripts/the background service worker,
usually needed when optimization.runtimeChunk or optimization.splitChunks.chunks is used.

This option accepts an object, where the keys are the entry name,
and the value is described below.

This option replaces the HTMLWebpackPlugin where the background service worker and content scripts
do not use HTML to load files.

If the value is a string (an output file name), for content scripts, it creates an extra
entry file to load all initial chunks asynchronously via dynamic import.
This asynchronous loading behavior is limited to the platform limit and breaks
run_at.

If the value is a string (an output file name), for the background service worker (specified
via options.background.serviceWorkerEntry), it creates an extra entry file to load all
initial chunks synchronously.

The file name specified MUST NOT be any existing file.

If the value is a function ((manifest: any, chunks: string[]) => void), it requires
a "manifest.json" in the emitted files and lets you edit it on the fly to include all
the initial chunks. This option does not apply to the background service worker because
manifest.json does not accept multiple files.

If the value is an object ({ file: string; touch(manifest: any, file: string): void }),
it generates a new file (see the behavior of string above) and provides a callback to
edit the manifest.json (see the behavior of function above).

If the value is false, it asserts that this entry does not have more than one initial file,
otherwise, it will be a compile error.

If the value is undefined, it silences the warning for the background service worker.

You can also change your configuration to avoid optimization.runtimeChunk or optimization.splitChunks.chunks,
in this case, webpack only generates 1 initial file so you don't need this option.

README.md Outdated
// ...
contentScript: {
experimental_output: {
myContentScript: 'cs.js'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so cs.js refers to the output file for content_scripts within the root of the output path? like dist/cs.js?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it will be an extra output file.

README.md Outdated
contentScript: {
experimental_output: {
myContentScript: (manifest, list) => {
manifest.content_scripts[0].js = list

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could this handle more than one content_script defined in the manifest file? like which list would this be if I have a manifest.content_scripts[1].js?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is a function, so you can write any code to change your manifest.json (if you defined it via CopyPlugin or other webpack plugins).

{
myContentScript: (manifest, list) => {
    manifest.content_scripts[0].js = list
    manifest.content_scripts[1].js = list
},

myContentScript2: (manifest, list) => {
    manifest.content_scripts[3].js = list
},
}

@Jack-Works Jack-Works changed the title feat: add options.contentScript.experimental_output feat: add options.experimental_output Dec 14, 2024
@Jack-Works
Copy link
Member Author

I have updated the PR to expand the range to the background service worker. The API is not intuitive enough and I have no confidence with it, so I'll keep it experimental.

@Jack-Works Jack-Works merged commit 6d868cb into master Dec 15, 2024
3 checks passed
@Jack-Works Jack-Works deleted the cs branch December 15, 2024 16:16
@Jack-Works
Copy link
Member Author

2.1.0 released, you can have a try!

@cezaraugusto
Copy link

you're a legend!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

content_scripts defined in manifest.json won't update after HMR without a full reload of the web extension

2 participants