Skip to content

Commit 40bf1c2

Browse files
authored
Fix self references in CSS module JS assets (#9080)
1 parent f7fedaf commit 40bf1c2

12 files changed

Lines changed: 108 additions & 8 deletions

File tree

packages/core/core/src/AssetGraph.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,10 @@ export default class AssetGraph extends ContentGraph<AssetGraphNode> {
455455
let dependentAsset = assetsByKey.get(dep.specifier);
456456
if (dependentAsset) {
457457
dependentAssets.push(dependentAsset);
458+
if (dependentAsset.id === asset.id) {
459+
// Don't orphan circular dependencies.
460+
isDirect = true;
461+
}
458462
}
459463
}
460464
let id = this.addNode(nodeFromAsset(asset));

packages/core/core/src/public/Asset.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,19 @@ export class MutableAsset extends BaseAsset implements IMutableAsset {
271271
this.#asset.value.sideEffects = sideEffects;
272272
}
273273

274+
get uniqueKey(): ?string {
275+
return this.#asset.value.uniqueKey;
276+
}
277+
278+
set uniqueKey(uniqueKey: ?string): void {
279+
if (this.#asset.value.uniqueKey != null) {
280+
throw new Error(
281+
"Cannot change an asset's uniqueKey after it has been set.",
282+
);
283+
}
284+
this.#asset.value.uniqueKey = uniqueKey;
285+
}
286+
274287
get symbols(): IMutableAssetSymbols {
275288
return new MutableAssetSymbols(this.#asset.options, this.#asset.value);
276289
}

packages/core/integration-tests/test/css-modules.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -715,4 +715,38 @@ describe('css modules', () => {
715715
assert.deepEqual(res[0][0], 'mainJs');
716716
assert(res[0][1].includes('container') && res[0][1].includes('expand'));
717717
});
718+
719+
it('should allow css modules to be shared between targets', async function () {
720+
let b = await bundle([
721+
path.join(__dirname, '/integration/css-module-self-references/a'),
722+
path.join(__dirname, '/integration/css-module-self-references/b'),
723+
]);
724+
725+
assertBundles(b, [
726+
{
727+
name: 'main.css',
728+
assets: ['bar.module.css'],
729+
},
730+
{
731+
name: 'main.css',
732+
assets: ['bar.module.css'],
733+
},
734+
{
735+
name: 'main.js',
736+
assets: ['index.js', 'bar.module.css'],
737+
},
738+
{
739+
name: 'main.js',
740+
assets: ['index.js', 'bar.module.css'],
741+
},
742+
{
743+
name: 'module.js',
744+
assets: ['index.js', 'bar.module.css'],
745+
},
746+
{
747+
name: 'module.js',
748+
assets: ['index.js', 'bar.module.css'],
749+
},
750+
]);
751+
});
718752
});
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import foo from '../bar.module.css';
2+
3+
console.log('a', foo);
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"main": "dist/main.js",
3+
"module": "dist/module.js",
4+
"source": "index.js"
5+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import foo from '../bar.module.css';
2+
3+
console.log('b', foo);
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"main": "dist/main.js",
3+
"module": "dist/module.js",
4+
"source": "index.js"
5+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.foo {
2+
composes: composed;
3+
color: white;
4+
}
5+
6+
.composed {
7+
background: pink;
8+
}

packages/core/types/index.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,12 @@ export interface MutableAsset extends BaseAsset {
749749
* This is initially set by the resolver, but can be overridden by transformers.
750750
*/
751751
sideEffects: boolean;
752+
/**
753+
* When a transformer returns multiple assets, it can give them unique keys to identify them.
754+
* This can be used to find assets during packaging, or to create dependencies between multiple
755+
* assets returned by a transformer by using the unique key as the dependency specifier.
756+
*/
757+
uniqueKey: ?string;
752758
/** The symbols that the asset exports. */
753759
+symbols: MutableAssetSymbols;
754760

packages/packagers/css/src/CSSPackager.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export default (new Packager({
3636
// Hoist unresolved external dependencies (i.e. http: imports)
3737
if (
3838
node.value.priority === 'sync' &&
39+
!bundleGraph.isDependencySkipped(node.value) &&
3940
!bundleGraph.getResolvedAsset(node.value, bundle)
4041
) {
4142
hoistedImports.push(node.value.specifier);

0 commit comments

Comments
 (0)