Skip to content

feat: added supports for supports() and layer() in @import #843

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 47 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class MiniCssExtractPlugin {
identifier,
identifierIndex,
content,
layer,
supports,
media,
sourceMap,
assets,
Expand All @@ -61,6 +63,8 @@ class MiniCssExtractPlugin {
this._identifier = identifier;
this._identifierIndex = identifierIndex;
this.content = content;
this.layer = layer;
this.supports = supports;
this.media = media;
this.sourceMap = sourceMap;
this.assets = assets;
Expand Down Expand Up @@ -108,6 +112,8 @@ class MiniCssExtractPlugin {
updateCacheModule(module) {
if (
this.content !== module.content ||
this.layer !== module.layer ||
this.supports !== module.supports ||
this.media !== module.media ||
this.sourceMap !== module.sourceMap ||
this.assets !== module.assets ||
Expand All @@ -116,6 +122,8 @@ class MiniCssExtractPlugin {
this._needBuild = true;

this.content = module.content;
this.layer = module.layer;
this.supports = module.supports;
this.media = module.media;
this.sourceMap = module.sourceMap;
this.assets = module.assets;
Expand Down Expand Up @@ -150,6 +158,12 @@ class MiniCssExtractPlugin {
const hash = webpack.util.createHash(hashFunction);

hash.update(this.content);

if (this.layer) {
hash.update(this.layer);
}

hash.update(this.supports || "");
hash.update(this.media || "");
hash.update(this.sourceMap || "");

Expand All @@ -169,6 +183,8 @@ class MiniCssExtractPlugin {
write(this._identifier);
write(this._identifierIndex);
write(this.content);
write(this.layer);
write(this.supports);
write(this.media);
write(this.sourceMap);
write(this.assets);
Expand Down Expand Up @@ -203,16 +219,19 @@ class MiniCssExtractPlugin {
const identifier = read();
const identifierIndex = read();
const content = read();
const layer = read();
const supports = read();
const media = read();
const sourceMap = read();
const assets = read();
const assetsInfo = read();

const dep = new CssModule({
context: contextModule,
identifier,
identifierIndex,
content,
layer,
supports,
media,
sourceMap,
assets,
Expand All @@ -239,7 +258,7 @@ class MiniCssExtractPlugin {
// eslint-disable-next-line no-shadow
class CssDependency extends webpack.Dependency {
constructor(
{ identifier, content, media, sourceMap },
{ identifier, content, layer, supports, media, sourceMap },
context,
identifierIndex
) {
Expand All @@ -248,6 +267,8 @@ class MiniCssExtractPlugin {
this.identifier = identifier;
this.identifierIndex = identifierIndex;
this.content = content;
this.layer = layer;
this.supports = supports;
this.media = media;
this.sourceMap = sourceMap;
this.context = context;
Expand All @@ -271,6 +292,8 @@ class MiniCssExtractPlugin {

write(this.identifier);
write(this.content);
write(this.layer);
write(this.supports);
write(this.media);
write(this.sourceMap);
write(this.context);
Expand Down Expand Up @@ -302,6 +325,8 @@ class MiniCssExtractPlugin {
{
identifier: read(),
content: read(),
layer: read(),
supports: read(),
media: read(),
sourceMap: read(),
},
Expand Down Expand Up @@ -1024,10 +1049,22 @@ class MiniCssExtractPlugin {
source.add(header);
}

if (module.supports) {
source.add(`@supports (${module.supports}) {\n`);
}

if (module.media) {
source.add(`@media ${module.media} {\n`);
}

const needLayer = typeof module.layer !== "undefined";

if (needLayer) {
source.add(
`@layer${module.layer.length > 0 ? ` ${module.layer}` : ""} {\n`
);
}

const { path: filename } = compilation.getPathWithInfo(
filenameTemplate,
pathData
Expand Down Expand Up @@ -1056,9 +1093,17 @@ class MiniCssExtractPlugin {

source.add("\n");

if (needLayer) {
source.add("}\n");
}

if (module.media) {
source.add("}\n");
}

if (module.supports) {
source.add("}\n");
}
}
}

Expand Down
48 changes: 26 additions & 22 deletions src/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,29 +119,33 @@ export function pitch(request) {
if (!Array.isArray(exports)) {
dependencies = [[null, exports]];
} else {
dependencies = exports.map(([id, content, media, sourceMap]) => {
let identifier = id;
let context;
if (compilation) {
const module = findModuleById(compilation, id);
identifier = module.identifier();
({ context } = module);
} else {
// TODO check if this context is used somewhere
context = this.rootContext;
}
dependencies = exports.map(
([id, content, media, sourceMap, supports, layer]) => {
let identifier = id;
let context;
if (compilation) {
const module = findModuleById(compilation, id);
identifier = module.identifier();
({ context } = module);
} else {
// TODO check if this context is used somewhere
context = this.rootContext;
}

return {
identifier,
context,
content: Buffer.from(content),
media,
sourceMap: sourceMap
? Buffer.from(JSON.stringify(sourceMap))
: // eslint-disable-next-line no-undefined
undefined,
};
});
return {
identifier,
context,
content: Buffer.from(content),
media,
supports,
layer,
sourceMap: sourceMap
? Buffer.from(JSON.stringify(sourceMap))
: // eslint-disable-next-line no-undefined
undefined,
};
}
);
}

addDependencies(dependencies);
Expand Down
105 changes: 105 additions & 0 deletions test/TestCache.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,111 @@ describe("TestCache", () => {
});
});

it('should work with the "filesystem" cache #2', async () => {
const casesDirectory = path.resolve(__dirname, "cases");
const directoryForCase = path.resolve(casesDirectory, "at-import-layer");
// eslint-disable-next-line import/no-dynamic-require, global-require
const webpackConfig = require(path.resolve(
directoryForCase,
"webpack.config.js"
));
const outputPath = path.resolve(__dirname, "js/cache-filesystem-1");
const fileSystemCacheDirectory = path.resolve(
__dirname,
"./js/.cache/type-filesystem-1"
);

await del([outputPath, fileSystemCacheDirectory]);

const compiler1 = webpack({
...webpackConfig,
mode: "development",
context: directoryForCase,
cache: {
type: "filesystem",
cacheDirectory: fileSystemCacheDirectory,
idleTimeout: 0,
idleTimeoutForInitialStore: 0,
},
output: {
path: outputPath,
},
});

await new Promise((resolve, reject) => {
compiler1.run((error, stats) => {
if (error) {
reject(error);

return;
}

compiler1.close(() => {
expect(Object.keys(stats.compilation.assets).sort())
.toMatchInlineSnapshot(`
Array [
"main.css",
"main.js",
]
`);
expect(Array.from(stats.compilation.emittedAssets).sort())
.toMatchInlineSnapshot(`
Array [
"main.css",
"main.js",
]
`);
expect(stats.compilation.warnings).toHaveLength(0);
expect(stats.compilation.errors).toHaveLength(0);

resolve();
});
});
});

const compiler2 = webpack({
...webpackConfig,
mode: "development",
context: directoryForCase,
cache: {
type: "filesystem",
cacheDirectory: fileSystemCacheDirectory,
idleTimeout: 0,
idleTimeoutForInitialStore: 0,
},
output: {
path: outputPath,
},
});

await new Promise((resolve, reject) => {
compiler2.run((error, stats) => {
if (error) {
reject(error);

return;
}

compiler2.close(() => {
expect(Object.keys(stats.compilation.assets).sort())
.toMatchInlineSnapshot(`
Array [
"main.css",
"main.js",
]
`);
expect(
Array.from(stats.compilation.emittedAssets).sort()
).toMatchInlineSnapshot(`Array []`);
expect(stats.compilation.warnings).toHaveLength(0);
expect(stats.compilation.errors).toHaveLength(0);

resolve();
});
});
});
});

it('should work with the "filesystem" cache and asset modules', async () => {
const casesDirectory = path.resolve(__dirname, "cases");
const directoryForCase = path.resolve(casesDirectory, "asset-modules");
Expand Down
48 changes: 48 additions & 0 deletions test/cases/at-import-layer/expected/main.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
@layer framework {
@layer base {.bottom {
background: blue;
}
}
}
@layer framework {
@layer base {
.middle {
background: green;
}
}

}
@layer {
.color {
color: red;
}

}
@supports (display: flex) {
@media (prefers-color-scheme: dark) {
@layer default {
@supports (display: grid) {@media screen and (min-width: 900px) {@layer base {.foo {
color: red;
}
}}}
}
}
}
@supports (display: flex) {
@media (prefers-color-scheme: dark) {
@layer default {
/* prettier-ignore */

.bar {
color: blue;
}

}
}
}
/* prettier-ignore */

.top {
background: red;
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/* prettier-ignore */
@import url("./zzz.css") layer(base) supports(display: grid) screen and (min-width: 900px);

.bar {
color: blue;
}
7 changes: 7 additions & 0 deletions test/cases/at-import-layer/import-with-layer.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@import url("./test.css") layer(base);

@layer base {
.middle {
background: green;
}
}
1 change: 1 addition & 0 deletions test/cases/at-import-layer/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import "./style.css";
8 changes: 8 additions & 0 deletions test/cases/at-import-layer/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
@import url("./import-with-layer.css") layer(framework);
@import url("./unnamed-layer.css") layer;
/* prettier-ignore */
@import url("./import-with-layer-and-supports-and-media.css") layer(default) supports(display: flex) (prefers-color-scheme: dark);

.top {
background: red;
}
Loading