Skip to content

Commit

Permalink
Fix main world extension not working
Browse files Browse the repository at this point in the history
  • Loading branch information
cezaraugusto committed Aug 19, 2024
1 parent 65b64c8 commit f273416
Show file tree
Hide file tree
Showing 14 changed files with 107 additions and 88 deletions.
2 changes: 0 additions & 2 deletions examples/content-main-world/background.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
console.log('hello from background script')

chrome.runtime.onMessage.addListener((request, sender) => {
if (request.action === 'changeBackgroundColor') {
changeBackgroundColor(request.color, sender.tab.id)
Expand Down
1 change: 1 addition & 0 deletions examples/content-main-world/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"manifest_version": 3,
"version": "0.0.1",
"name": "Content Scripts Main World",
"id": "phfmcihmgbbaemimookenmjjkoicadnb",
"description": "An Extension.js example.",
"icons": {
"16": "images/extension_16.png",
Expand Down
1 change: 0 additions & 1 deletion programs/develop/install_scripts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ resolve_plugin_files=(
scripts_plugin_files=(
"$(dirname "$0")/webpack/plugin-extension/feature-scripts/steps/inject-content-css-during-dev.ts"
"$(dirname "$0")/webpack/plugin-extension/feature-scripts/steps/add-hmr-accept-code.ts"
"$(dirname "$0")/webpack/plugin-extension/feature-scripts/steps/add-dynamic-public-path.ts"
"$(dirname "$0")/webpack/plugin-extension/feature-scripts/steps/add-query-param-to-imported-css.ts"
)

Expand Down
2 changes: 1 addition & 1 deletion programs/develop/webpack/dev-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export async function devServer(
// Shows a full-screen overlay in the browser
// when there are compiler errors or warnings.
overlay: false
},
},
headers: {
'Access-Control-Allow-Origin': '*'
},
Expand Down
9 changes: 9 additions & 0 deletions programs/develop/webpack/lib/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -643,3 +643,12 @@ export function defaultPortInUse(manifestName: string, port: number) {
`Default port ${port} in use, choose a new port. `
)
}

export function noExtensionIdError(manifestName: string) {
return (
`${getLoggingPrefix(manifestName, 'error')} No Extension Id Specified\n\n` +
`For MAIN world content scripts, you must specify an extension ID.\n` +
`Otherwise, the content script won't reload on changes.\n` +
`Add an ${brightYellow('id')} field to your manifest.json file and try again.`
)
}
4 changes: 1 addition & 3 deletions programs/develop/webpack/plugin-css/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ export class CssPlugin {
private async configureOptions(compiler: Compiler) {
const projectPath = path.dirname(this.manifestPath)

const plugins: WebpackPluginInstance[] = [
new MiniCssExtractPlugin()
]
const plugins: WebpackPluginInstance[] = [new MiniCssExtractPlugin()]

plugins.forEach((plugin) => plugin.apply(compiler))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {Schema} from 'schema-utils/declarations/validate'
import {transformSource} from './transform-source'
import {emitResolverModule} from './emit-resolver-module'
import {ResolvePluginContext} from './loader-types'
import {type Manifest} from '../../../../types'

const schema: Schema = {
type: 'object',
Expand All @@ -16,6 +17,25 @@ const schema: Schema = {
}
}

function getContentScripts(manifest: Manifest, manifestDir: string): string[] {
if (!manifest.content_scripts) {
return []
}

const scripts: string[] = []

manifest.content_scripts.forEach((contentScript) => {
if (contentScript.js) {
contentScript.js.forEach((script) => {
// Resolve each script path relative to the manifest directory
scripts.push(path.resolve(manifestDir, script))
})
}
})

return scripts
}

export default function resolveLoader(
this: ResolvePluginContext,
source: string
Expand All @@ -36,6 +56,19 @@ export default function resolveLoader(
) {
return source
}

// Get the directory of the manifest file
const manifestDir = path.dirname(options.manifestPath)
// Get the content scripts, resolved relative to the manifest directory
const contentScripts = getContentScripts(
require(options.manifestPath) as Manifest,
manifestDir
)

if (contentScripts.some((script) => script === this.resourcePath)) {
return source
}

const transformedSource = transformSource(source, options)
const resolverAbsolutePath = path.join(__dirname, resolverName)

Expand Down
31 changes: 15 additions & 16 deletions programs/develop/webpack/plugin-extension/feature-scripts/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import path from 'path'
import type webpack from 'webpack'
import {type FilepathList, type PluginInterface} from '../../webpack-types'
import {
type Manifest,
type FilepathList,
type PluginInterface
} from '../../webpack-types'
import {AddScripts} from './steps/add-scripts'
import {AddPublicPathRuntimeModule} from './steps/add-public-path-runtime-module'
import {AddPublicPathForMainWorld} from './steps/add-public-path-for-main-world'
import {DevOptions} from '../../../module'

/**
* ScriptsPlugin is responsible for handiling all possible JavaScript
Expand All @@ -22,11 +28,13 @@ import {AddPublicPathRuntimeModule} from './steps/add-public-path-runtime-module
*/
export class ScriptsPlugin {
public readonly manifestPath: string
public readonly browser?: DevOptions['browser']
public readonly includeList?: FilepathList
public readonly excludeList?: FilepathList

constructor(options: PluginInterface) {
this.manifestPath = options.manifestPath
this.browser = options.browser || 'chrome'
this.includeList = options.includeList
this.excludeList = options.excludeList
}
Expand Down Expand Up @@ -97,21 +105,12 @@ export class ScriptsPlugin {

// 4 - Fix the issue where assets imported via content_scripts
// running in the MAIN world could not find the correct public path.
// compiler.options.module.rules.push({
// test: /\.(js|mjs|jsx|mjsx|ts|mts|tsx|mtsx)$/,
// include: [path.dirname(this.manifestPath)],
// exclude: [path.join(path.dirname(this.manifestPath), 'node_modules')],
// use: [
// {
// loader: path.resolve(__dirname, './add-dynamic-public-path.js'),
// options: {
// manifestPath: this.manifestPath,
// includeList: this.includeList || {},
// excludeList: this.excludeList || {}
// }
// }
// ]
// })
new AddPublicPathForMainWorld({
manifestPath: this.manifestPath,
browser: this.browser || 'chrome',
includeList: this.includeList || {},
excludeList: this.excludeList || {}
}).apply(compiler)

// 5 - Fix the issue of content_scripts not being able to import
// CSS files via import statements. This loader adds the
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import type webpack from 'webpack'
import {
type FilepathList,
type PluginInterface,
type Manifest
} from '../../../webpack-types'
import * as messages from '../../../lib/messages'
import {DevOptions} from '../../../../module'

export class AddPublicPathForMainWorld {
public readonly manifestPath: string
public readonly browser: DevOptions['browser']
public readonly includeList: FilepathList
public readonly excludeList: FilepathList

constructor(options: PluginInterface) {
this.manifestPath = options.manifestPath
this.browser = options.browser || 'chrome'
this.includeList = options.includeList || {}
this.excludeList = options.excludeList || {}
}

public apply(compiler: webpack.Compiler): void {
const manifest: Manifest = require(this.manifestPath)
if (
manifest.content_scripts?.some(
// @ts-expect-error - TS doesn't know about content_scripts
(cs) => cs.world && cs.world.toLowerCase() === 'main'
)
) {
if (!manifest.id) {
console.error(messages.noExtensionIdError(manifest.name || ''))
process.exit(1)
}

if (this.browser === 'firefox') {
compiler.options.output.publicPath = `moz-extension://${manifest.id}/`
return
}

compiler.options.output.publicPath = `${this.browser}-extension://${manifest.id}/`
}
}
}
1 change: 1 addition & 0 deletions programs/develop/webpack/plugin-extension/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export class ExtensionPlugin {
// Get all scripts (bg, content, sw) declared in manifest
new ScriptsPlugin({
manifestPath,
browser: this.browser,
includeList: {
...manifestFieldsData.scripts,
...specialFoldersData.scripts
Expand Down
1 change: 0 additions & 1 deletion programs/develop/webpack/plugin-static-assets/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ export class StaticAssetsPlugin {
}

public async apply(compiler: Compiler) {

// Define the default SVG rule
const defaultSvgRule: RuleSetRule = {
test: /\.svg$/i,
Expand Down
2 changes: 1 addition & 1 deletion programs/develop/webpack/webpack-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export default function webpackConfig(
environment: {
bigIntLiteral: true,
dynamicImport: true
},
}
},
resolve: {
modules: ['node_modules', path.join(projectPath, 'node_modules')],
Expand Down
1 change: 1 addition & 0 deletions programs/develop/webpack/webpack-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export interface LoaderContext {
getOptions: () => {
test: string
manifestPath: string
browser?: DevOptions['browser']
includeList?: FilepathList
excludeList?: FilepathList
}
Expand Down

0 comments on commit f273416

Please sign in to comment.