Skip to content

Commit 056627f

Browse files
authored
fix(plugin-sass): pollute the global.location object (#3712)
* feat(plugin-sass): add `patchGlobalLocation` & `unpatchGlobalLocation` to `@modern-js/utils` * fix(plugin-sass): `global.location` object will crash SSR server * feat: move `patch` to `@modern-js/builder-shared` * fix: can't set `GLOBAL_PATCHED_SYMBOL` as prop of a string * feat: add new function `patchCompilerGlobalLocation` * feat: only create href and location variables if `global.location` is not defined * feat: remove assert
1 parent 0a1aa3b commit 056627f

File tree

7 files changed

+73
-106
lines changed

7 files changed

+73
-106
lines changed

.changeset/new-insects-argue.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
'@modern-js/utils': minor
3+
'@modern-js/builder-webpack-provider': patch
4+
'@modern-js/builder-rspack-provider': patch
5+
---
6+
7+
fix(plugin-sass): pollute the `global.location` object
8+
fix(plugin-sass): 污染全局对象 `global.location`

packages/builder/builder-rspack-provider/src/plugins/sass.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,18 @@ import {
22
isUseCssSourceMap,
33
SASS_REGEX,
44
getSassLoaderOptions,
5+
patchCompilerGlobalLocation,
56
} from '@modern-js/builder-shared';
67
import type { BuilderPlugin } from '../types';
78

89
export function builderPluginSass(): BuilderPlugin {
910
return {
1011
name: 'builder-plugin-sass',
11-
setup(api) {
12+
async setup(api) {
13+
api.onAfterCreateCompiler(({ compiler }) => {
14+
patchCompilerGlobalLocation(compiler);
15+
});
16+
1217
api.modifyBundlerChain(async (chain, utils) => {
1318
const config = api.getNormalizedConfig();
1419
const { applyBaseCSSRule } = await import('./css');

packages/builder/builder-shared/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@
107107
"html-webpack-plugin": "5.5.0",
108108
"terser": "^5.14.1",
109109
"typescript": "^4",
110-
"webpack": "^5.82.1"
110+
"webpack": "^5.82.1",
111+
"@rspack/core": "0.0.0-canary-22b006c-20230517164249"
111112
},
112113
"publishConfig": {
113114
"registry": "https://registry.npmjs.org/",

packages/builder/builder-shared/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,4 @@ export * from './apply';
2525
export * from './fallback';
2626
export * from './getLoaderOptions';
2727
export * from './svgo';
28+
export * from './patch';
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import path from 'path';
2+
import { pathToFileURL } from 'url';
3+
import type {
4+
Compiler as WebpackCompiler,
5+
MultiCompiler as WebpackMultiCompiler,
6+
} from 'webpack';
7+
import type {
8+
Compiler as RspackCompiler,
9+
MultiCompiler as RspackMultiCompiler,
10+
} from '@rspack/core';
11+
12+
const GLOBAL_PATCHED_SYMBOL: unique symbol = Symbol('GLOBAL_PATCHED_SYMBOL');
13+
14+
declare global {
15+
interface Location {
16+
[GLOBAL_PATCHED_SYMBOL]?: true;
17+
}
18+
}
19+
20+
/** fix issue about dart2js: https://github.com/dart-lang/sdk/issues/27979 */
21+
export function patchGlobalLocation() {
22+
if (!global.location) {
23+
const href = pathToFileURL(process.cwd()).href + path.sep;
24+
const location = Object.freeze({ [GLOBAL_PATCHED_SYMBOL]: true, href });
25+
global.location = location as unknown as Location;
26+
}
27+
}
28+
29+
export function unpatchGlobalLocation() {
30+
if (global.location?.[GLOBAL_PATCHED_SYMBOL]) {
31+
// @ts-expect-error
32+
delete global.location;
33+
}
34+
}
35+
36+
export function patchCompilerGlobalLocation(
37+
compiler:
38+
| WebpackCompiler
39+
| RspackCompiler
40+
| WebpackMultiCompiler
41+
| RspackMultiCompiler,
42+
) {
43+
// https://github.com/webpack/webpack/blob/136b723023f8f26d71eabdd16badf04c1c8554e4/lib/MultiCompiler.js#L64
44+
compiler.hooks.run.tap('PatchGlobalLocation', patchGlobalLocation);
45+
compiler.hooks.watchRun.tap('PatchGlobalLocation', patchGlobalLocation);
46+
compiler.hooks.watchClose.tap('PatchGlobalLocation', unpatchGlobalLocation);
47+
compiler.hooks.done.tap('PatchGlobalLocation', unpatchGlobalLocation);
48+
}

packages/builder/builder-webpack-provider/src/plugins/sass.ts

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,19 @@
1-
import path from 'path';
2-
import { pathToFileURL } from 'url';
31
import {
42
isUseCssSourceMap,
53
SASS_REGEX,
64
getSassLoaderOptions,
5+
patchCompilerGlobalLocation,
76
} from '@modern-js/builder-shared';
87
import type { BuilderPlugin } from '../types';
98

10-
/** fix issue about dart2js: https://github.com/dart-lang/sdk/issues/27979 */
11-
export function patchGlobalLocation() {
12-
const href = `${pathToFileURL(process.cwd()).href}${path.sep}`;
13-
// @ts-expect-error
14-
global.location ||= {};
15-
global.location.href ||= href;
16-
}
17-
189
export function builderPluginSass(): BuilderPlugin {
1910
return {
2011
name: 'builder-plugin-sass',
21-
setup(api) {
22-
patchGlobalLocation();
12+
async setup(api) {
13+
api.onAfterCreateCompiler(({ compiler }) => {
14+
patchCompilerGlobalLocation(compiler);
15+
});
16+
2317
api.modifyBundlerChain(async (chain, utils) => {
2418
const config = api.getNormalizedConfig();
2519
const { applyBaseCSSRule } = await import('./css');

0 commit comments

Comments
 (0)