Skip to content

Commit

Permalink
Fix content_scripts not working in production (#172)
Browse files Browse the repository at this point in the history
* Fix content_scripts CSS not working on production
  • Loading branch information
cezaraugusto authored Sep 6, 2024
1 parent d9362e1 commit fcd1d23
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 121 deletions.
36 changes: 18 additions & 18 deletions examples/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,28 +29,28 @@ const JS_TEMPLATES: Template[] = [
// hasEnv: false,
// configFiles: ['babel.config.json']
// },
// {
// name: 'content-extension-config',
// uiContext: ['content'],
// uiFramework: 'react',
// css: 'css',
// hasBackground: true,
// hasEnv: false,
// configFiles: [
// 'extension.config.js',
// 'tsconfig.json',
// 'postcss.config.js',
// 'tailwind.config.js'
// ]
// },
{
name: 'content-extension-config',
uiContext: ['content'],
uiFramework: 'react',
css: 'css',
hasBackground: true,
hasEnv: false,
configFiles: [
'extension.config.js',
'tsconfig.json',
'postcss.config.js',
'tailwind.config.js'
]
},
{
name: 'config-stylelint',
uiContext: ['newTab'],
uiFramework: undefined,
css: 'css',
css: 'sass',
hasBackground: false,
hasEnv: false,
configFiles: ['stylelint.config.json']
configFiles: ['.stylelintrc.json']
},
{
name: 'content',
Expand Down Expand Up @@ -101,7 +101,7 @@ const JS_TEMPLATES: Template[] = [
name: 'content-sass-module',
uiContext: ['content'],
uiFramework: undefined,
css: 'css',
css: 'sass',
hasBackground: false,
hasEnv: false,
configFiles: undefined
Expand Down Expand Up @@ -146,7 +146,7 @@ const JS_TEMPLATES: Template[] = [
name: 'new-sass',
uiContext: ['newTab'],
uiFramework: undefined,
css: 'css',
css: 'sass',
hasBackground: false,
hasEnv: false,
configFiles: undefined
Expand Down
3 changes: 2 additions & 1 deletion examples/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ export type ConfigFiles =
| 'postcss.config.js'
| 'tailwind.config.js'
| 'tsconfig.json'
| 'stylelint.config.json'
| '.stylelintrc.json'
| 'extension.config.js'
| 'babel.config.json'

export interface Template {
name: string
Expand Down
2 changes: 1 addition & 1 deletion programs/create/create.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ describe('extension create', () => {
).toBeTruthy()

// Expect [uiContext]/styles.sass|less|css for styles
if (template.name?.includes('sass')) {
if (template.css === 'sass') {
expect(
fileExists(template.name, `${context.toLowerCase()}/styles.scss`)
).toBeTruthy()
Expand Down
8 changes: 6 additions & 2 deletions programs/develop/build.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,10 +196,14 @@ describe('extension build', () => {
browser: SUPPORTED_BROWSERS[0] as 'chrome',
zipSource: true
})

expect(
fs.existsSync(
path.join(templatePath, 'dist', `${template.name}-template-0.0.1-source.zip`)
path.join(
templatePath,
'dist',
`${template.name}-template-0.0.1-source.zip`
)
)
).toBeTruthy()
},
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-query-param-to-imported-css.ts"
)

reload_plugin_files=(
Expand Down
14 changes: 0 additions & 14 deletions programs/develop/webpack/plugin-css/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,6 @@ export class CssPlugin {
test: /\.css$/,
exclude: /\.module\.css$/,
oneOf: [
{
resourceQuery: /is_content_css_import=true/,
use: await commonStyleLoaders(projectPath, {
mode: this.mode,
useMiniCssExtractPlugin: false
})
},
{
use: await commonStyleLoaders(projectPath, {
mode: this.mode,
Expand All @@ -56,13 +49,6 @@ export class CssPlugin {
{
test: /\.module\.css$/,
oneOf: [
{
resourceQuery: /is_content_css_import=true/,
use: await commonStyleLoaders(projectPath, {
mode: this.mode,
useMiniCssExtractPlugin: false
})
},
{
use: await commonStyleLoaders(projectPath, {
mode: this.mode,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import path from 'path'
import {type Compiler, Compilation, sources} from 'webpack'
import {getManifestOverrides} from '../manifest-overrides'
import {getFilename, getManifestContent} from '../../../lib/utils'
Expand Down Expand Up @@ -32,6 +33,34 @@ export class UpdateManifest {
)
}

private applyProdOverrides(
compiler: Compiler,
overrides: Record<string, any>
) {
if (!overrides.content_scripts) return {}

return overrides.content_scripts.map(
(contentObj: {js: string[]; css: string[]}, index: number) => {
if (contentObj.js.length && !contentObj.css.length) {
const outputPath = compiler.options.output?.path || ''

// Make a .css file for every .js file in content_scripts
// so we can later reference it in the manifest.
contentObj.css = contentObj.js.map((js: string) => {
const contentCss = path.join(outputPath, js.replace('.js', '.css'))
return getFilename(
`content_scripts/content-${index}.css`,
contentCss,
{}
)
})
}

return contentObj
}
)
}

apply(compiler: Compiler) {
compiler.hooks.thisCompilation.tap(
'manifest:update-manifest',
Expand Down Expand Up @@ -61,7 +90,17 @@ export class UpdateManifest {
// During development, if user has only CSS files in content_scripts,
// we add a JS file to the content_scripts bundle so that
// these files can be dynamically imported, thus allowing HMR.
if (compiler.options.mode !== 'production') {
if (compiler.options.mode === 'development') {
if (patchedManifest.content_scripts) {
patchedManifest.content_scripts =
this.applyDevOverrides(patchedManifest)
}
}

// During production, webpack styles are bundled in a CSS file,
// and not injected in the page via <style> tag. We need to
// reference these files in the manifest.
if (compiler.options.mode === 'development') {
if (patchedManifest.content_scripts) {
patchedManifest.content_scripts =
this.applyDevOverrides(patchedManifest)
Expand All @@ -74,6 +113,48 @@ export class UpdateManifest {
compilation.updateAsset('manifest.json', rawSource)
}
)

// During development, content_scripts are injected in the page
// via <style> tag. In production, these styles are bundled
// in a content_scripts CSS file, so we need to reference it
// in the manifest.
if (compiler.options.mode === 'production') {
compilation.hooks.afterProcessAssets.tap(
'manifest:update-manifest',
() => {
if (compilation.errors.length > 0) return

const manifest = getManifestContent(
compilation,
this.manifestPath
)

const overrides = getManifestOverrides(
this.manifestPath,
manifest,
this.excludeList || {}
)

const patchedManifest: Manifest = {
// Preserve all uncatched user entries
...manifest,
...JSON.parse(overrides)
}

if (patchedManifest.content_scripts) {
patchedManifest.content_scripts = this.applyProdOverrides(
compiler,
patchedManifest
)
}

const source = JSON.stringify(patchedManifest, null, 2)
const rawSource = new sources.RawSource(source)

compilation.updateAsset('manifest.json', rawSource)
}
)
}
}
)
}
Expand Down
26 changes: 0 additions & 26 deletions programs/develop/webpack/plugin-extension/feature-scripts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,31 +107,5 @@ export class ScriptsPlugin {
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
// is_content_css_import=true query param to CSS imports in
// content_scripts. This skips the MiniCssExtractPlugin loader
// and allows the CSS to be injected in the DOM via <style> tags.
if (compiler.options.mode === 'development') {
compiler.options.module.rules.push({
test: /\.(js|mjs|jsx|mjsx|ts|mts|tsx|mtsx)$/,
include: [path.dirname(this.manifestPath)],
exclude: /node_modules/,
use: [
{
loader: path.resolve(
__dirname,
'./add-query-param-to-imported-css.js'
),
options: {
manifestPath: this.manifestPath,
includeList: this.includeList || {},
excludeList: this.excludeList || {}
}
}
]
})
}
}
}

This file was deleted.

0 comments on commit fcd1d23

Please sign in to comment.