Skip to content

Commit

Permalink
feat: add css hmr for rsbuild (#80)
Browse files Browse the repository at this point in the history
  • Loading branch information
tmkx authored Jul 7, 2024
1 parent 870ea85 commit a9ef2de
Show file tree
Hide file tree
Showing 10 changed files with 62 additions and 41 deletions.
7 changes: 7 additions & 0 deletions .changeset/strange-clocks-complain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@webx-kit/modernjs-plugin": patch
"@webx-kit/rsbuild-plugin": patch
"@webx-kit/core-plugin": patch
---

feat: add css hmr for rsbuild
8 changes: 8 additions & 0 deletions packages/core-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
"types": "./src/manifest.ts",
"default": "./src/manifest.ts"
},
"./shadow-root": {
"types": "./src/shadow-root/index.ts",
"default": "./src/shadow-root/index.ts"
},
"./tailwind": {
"types": "./src/tailwind.ts",
"default": "./src/tailwind.ts"
Expand Down Expand Up @@ -69,6 +73,10 @@
"types": "./dist/manifest.d.ts",
"default": "./dist/manifest.js"
},
"./shadow-root": {
"types": "./dist/shadow-root/index.d.ts",
"default": "./dist/shadow-root/index.js"
},
"./tailwind": {
"types": "./dist/tailwind.d.ts",
"default": "./dist/tailwind.js"
Expand Down
30 changes: 30 additions & 0 deletions packages/core-plugin/src/shadow-root/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import path from 'node:path';
import { Rspack } from '@rsbuild/shared';
import { ROOT_NAME, STYLE_ROOT_NAME } from '../constants';

export const PLUGIN_NAME = 'webx:content-script-shadow-root';

const shadowRootLoader = path.resolve(
__dirname,
process.env.NODE_ENV === 'development' ? 'shadow-root-loader-dev.js' : 'shadow-root-loader.js'
);

export class CSSExtractPatchPlugin {
constructor(readonly resourceRegExp: RegExp) {}

apply(compiler: Rspack.Compiler) {
new compiler.webpack.NormalModuleReplacementPlugin(this.resourceRegExp, (resolveData) => {
resolveData.request = `${shadowRootLoader}!${resolveData.request}`;
}).apply(compiler);
}
}

export function patchCSSLoadingCode(code: string): string {
return code
.replace(
/document\.(querySelectorAll|getElementsByTagName)/g,
// if ROOT_NAME is a ShadowRoot, there is no getElementsByTagName method
`(globalThis.${ROOT_NAME}||document).querySelectorAll`
)
.replace(/document\.head/g, `(globalThis.${STYLE_ROOT_NAME}||document.head)`);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { webpack as webpackNS } from '@modern-js/app-tools';
import { ROOT_NAME } from '@webx-kit/core-plugin/constants';
import type { Rspack } from '@rsbuild/core';
import { ROOT_NAME } from '../constants';

const loader: webpackNS.LoaderDefinition = function (code, sourceMap, additionalData) {
const loader: Rspack.LoaderDefinition = function (code, sourceMap, additionalData) {
this.callback(
null,
code.replace(/document\.querySelectorAll/g, `(globalThis.${ROOT_NAME}||document).querySelectorAll`),
Expand Down
3 changes: 1 addition & 2 deletions packages/modernjs-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@
},
"dependencies": {
"@types/chrome": "^0.0.268",
"@webx-kit/core-plugin": "workspace:^",
"jiti": "^1.21.6"
"@webx-kit/core-plugin": "workspace:^"
},
"devDependencies": {
"@modern-js/app-tools": "^2.54.1",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
import path from 'node:path';
import type { webpack as webpackNS } from '@modern-js/app-tools';
import { ROOT_NAME, STYLE_ROOT_NAME } from '@webx-kit/core-plugin/constants';
import type { Rspack, webpack as webpackNS } from '@modern-js/app-tools';
import { PLUGIN_NAME, CSSExtractPatchPlugin, patchCSSLoadingCode } from '@webx-kit/core-plugin/shadow-root';
import { ContentScriptBasePlugin } from './base-plugin';

export const PLUGIN_NAME = 'webx:content-script-shadow-root';

const shadowRootLoader = path.resolve(
__dirname,
process.env.NODE_ENV === 'development' ? 'shadow-root-loader-dev.js' : 'shadow-root-loader.js'
);
export { PLUGIN_NAME };

export class ContentScriptShadowRootPlugin extends ContentScriptBasePlugin {
name = PLUGIN_NAME;
Expand All @@ -23,12 +17,9 @@ export class ContentScriptShadowRootPlugin extends ContentScriptBasePlugin {
});
});

new compiler.webpack.NormalModuleReplacementPlugin(
/mini-css-extract-plugin\/dist\/hmr\/hotModuleReplacement\.js$/,
(resolveData) => {
resolveData.request = `${shadowRootLoader}!${resolveData.request}`;
}
).apply(compiler);
new CSSExtractPatchPlugin(/mini-css-extract-plugin\/dist\/hmr\/hotModuleReplacement\.js$/).apply(
compiler as unknown as Rspack.Compiler
);
}
}

Expand All @@ -37,8 +28,6 @@ function patchCSSLoadingRuntimeModule(module: webpackNS.RuntimeModule) {
module.generate = function (this: webpackNS.RuntimeModule) {
const originalCode = originalGenerate.call(this);
if (originalCode === null) return originalCode;
return originalCode
.replace(/document\.querySelectorAll/g, `(globalThis.${ROOT_NAME}||document).querySelectorAll`)
.replace(/document\.head/g, `(globalThis.${STYLE_ROOT_NAME}||document.head)`);
return patchCSSLoadingCode(originalCode);
};
}
1 change: 0 additions & 1 deletion packages/modernjs-plugin/tsup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ export default defineConfig({
...sharedConfig,
entry: {
index: './src/index.ts',
'shadow-root-loader': './src/plugins/content-scripts/shadow-root-loader.ts',
manifest: './src/manifest.ts',
tailwind: './src/tailwind.ts',
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Rspack } from '@rsbuild/shared';
import { ROOT_NAME, STYLE_ROOT_NAME } from '@webx-kit/core-plugin/constants';
import { PLUGIN_NAME, CSSExtractPatchPlugin, patchCSSLoadingCode } from '@webx-kit/core-plugin/shadow-root';
import { ContentScriptBasePlugin } from './base-plugin';
import type { JsRuntimeModule } from '../../utils/types';

export const PLUGIN_NAME = 'webx:content-script-shadow-root';
export { PLUGIN_NAME };

export class ContentScriptShadowRootPlugin extends ContentScriptBasePlugin {
name = PLUGIN_NAME;
Expand All @@ -14,25 +14,17 @@ export class ContentScriptShadowRootPlugin extends ContentScriptBasePlugin {
compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
compilation.hooks.runtimeModule.tap(PLUGIN_NAME, (module, chunk) => {
if (!isEnabledForChunk(chunk)) return;
if (module.name === 'css_loading') patchCSSLoadingRuntimeModule(module);
if (module.name === 'css loading') patchCSSLoadingRuntimeModule(module);
});
});

new CSSExtractPatchPlugin(/css-extract\/hmr\/hotModuleReplacement\.js$/).apply(compiler);
}
}

function patchCSSLoadingRuntimeModule(module: JsRuntimeModule) {
if (!module.source) return;
module.name = 'content-scripts css loading';
const originCode = module.source.source.toString('utf-8');

module.source.source = Buffer.from(
originCode
.replace(
/document\.(querySelectorAll|getElementsByTagName)/g,
// if ROOT_NAME is a ShadowRoot, there is no getElementsByTagName method
`(globalThis.${ROOT_NAME}||document).querySelectorAll`
)
.replace(/document\.head/g, `(globalThis.${STYLE_ROOT_NAME}||document.head)`),
'utf-8'
);
module.source.source = Buffer.from(patchCSSLoadingCode(originCode), 'utf-8');
}
3 changes: 0 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit a9ef2de

Please sign in to comment.