Skip to content
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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(type): css #17097

Merged
merged 3 commits into from Apr 28, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions lib/css/CssGenerator.js
Expand Up @@ -32,6 +32,7 @@ class CssGenerator extends Generator {
generate(module, generateContext) {
const originalSource = module.originalSource();
const source = new ReplaceSource(originalSource);
/** @type {InitFragment[]} */
const initFragments = [];
const cssExports = new Map();

Expand All @@ -51,6 +52,9 @@ class CssGenerator extends Generator {
cssExports
};

/**
* @param {Dependency} dependency dependency
*/
const handleDependency = dependency => {
const constructor = /** @type {new (...args: any[]) => Dependency} */ (
dependency.constructor
Expand Down
11 changes: 9 additions & 2 deletions lib/css/CssLoadingRuntimeModule.js
Expand Up @@ -14,6 +14,7 @@ const compileBooleanMatcher = require("../util/compileBooleanMatcher");
const { chunkHasCss } = require("./CssModulesPlugin");

/** @typedef {import("../Chunk")} Chunk */
/** @typedef {import("../Compilation").RuntimeRequirementsContext} RuntimeRequirementsContext */

/**
* @typedef {Object} JsonpCompilationPluginHooks
Expand Down Expand Up @@ -44,11 +45,13 @@ class CssLoadingRuntimeModule extends RuntimeModule {
return hooks;
}

constructor(runtimeRequirements, runtimeOptions) {
/**
* @param {Set<string>} runtimeRequirements runtime requirements
*/
constructor(runtimeRequirements) {
super("css loading", 10);

this._runtimeRequirements = runtimeRequirements;
this.runtimeOptions = runtimeOptions;
}

/**
Expand Down Expand Up @@ -76,10 +79,13 @@ class CssLoadingRuntimeModule extends RuntimeModule {
const withLoading =
_runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers) &&
hasCssMatcher !== false;
/** @type {boolean} */
const withHmr = _runtimeRequirements.has(
RuntimeGlobals.hmrDownloadUpdateHandlers
);
/** @type {Set<number | string | null>} */
const initialChunkIdsWithCss = new Set();
/** @type {Set<number | string | null>} */
const initialChunkIdsWithoutCss = new Set();
for (const c of chunk.getAllInitialChunks()) {
(chunkHasCss(c, chunkGraph)
Expand Down Expand Up @@ -120,6 +126,7 @@ class CssLoadingRuntimeModule extends RuntimeModule {
: ""
]);

/** @type {(str: string) => number} */
const cc = str => str.charCodeAt(0);

return Template.asString([
Expand Down
61 changes: 54 additions & 7 deletions lib/css/CssModulesPlugin.js
Expand Up @@ -15,6 +15,7 @@ const {
} = require("../ModuleTypeConstants");
const RuntimeGlobals = require("../RuntimeGlobals");
const SelfModuleFactory = require("../SelfModuleFactory");
const WebpackError = require("../WebpackError");
const CssExportDependency = require("../dependencies/CssExportDependency");
const CssImportDependency = require("../dependencies/CssImportDependency");
const CssLocalIdentifierDependency = require("../dependencies/CssLocalIdentifierDependency");
Expand All @@ -32,9 +33,14 @@ const CssParser = require("./CssParser");

/** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("../../declarations/WebpackOptions").CssExperimentOptions} CssExperimentOptions */
/** @typedef {import("../../declarations/WebpackOptions").Output} OutputOptions */
/** @typedef {import("../Chunk")} Chunk */
/** @typedef {import("../ChunkGraph")} ChunkGraph */
/** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
/** @typedef {import("../Compilation")} Compilation */
/** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("../Module")} Module */
/** @typedef {import("../util/memoize")} Memoize */

const getCssLoadingRuntimeModule = memoize(() =>
require("./CssLoadingRuntimeModule")
Expand Down Expand Up @@ -65,6 +71,11 @@ const validateParserOptions = createSchemaValidation(
}
);

/**
* @param {string} str string
* @param {boolean=} omitOptionalUnderscore if true, optional underscore is not added
* @returns {string} escaped string
*/
const escapeCss = (str, omitOptionalUnderscore) => {
const escaped = `${str}`.replace(
// cspell:word uffff
Expand Down Expand Up @@ -219,6 +230,7 @@ class CssModulesPlugin {

if (chunk instanceof HotUpdateChunk) return result;

/** @type {CssModule[] | undefined} */
const modules = orderedCssModulesPerChunk.get(chunk);
if (modules !== undefined) {
result.push({
Expand Down Expand Up @@ -275,9 +287,16 @@ class CssModulesPlugin {
);
}

/**
* @param {Chunk} chunk chunk
* @param {Iterable<Module>} modules unordered modules
* @param {Compilation} compilation compilation
* @returns {Module[]} ordered modules
*/
getModulesInOrder(chunk, modules, compilation) {
if (!modules) return [];

/** @type {Module[]} */
const modulesList = [...modules];

// Get ordered list of modules per chunk group
Expand Down Expand Up @@ -311,6 +330,7 @@ class CssModulesPlugin {

modulesByChunkGroup.sort(compareModuleLists);

/** @type {Module[]} */
const finalModules = [];

for (;;) {
Expand All @@ -320,6 +340,7 @@ class CssModulesPlugin {
// done, everything empty
break;
}
/** @type {Module} */
let selectedModule = list[list.length - 1];
let hasFailed = undefined;
outer: for (;;) {
Expand All @@ -345,18 +366,17 @@ class CssModulesPlugin {
if (compilation) {
// TODO print better warning
compilation.warnings.push(
new Error(
`chunk ${
chunk.name || chunk.id
}\nConflicting order between ${hasFailed.readableIdentifier(
compilation.requestShortener
)} and ${selectedModule.readableIdentifier(
new WebpackError(
`chunk ${chunk.name || chunk.id}\nConflicting order between ${
/** @type {Module} */
(hasFailed).readableIdentifier(compilation.requestShortener)
} and ${selectedModule.readableIdentifier(
compilation.requestShortener
)}`
)
);
}
selectedModule = hasFailed;
selectedModule = /** @type {Module} */ (hasFailed);
}
// Insert the selected module into the final modules list
finalModules.push(selectedModule);
Expand All @@ -374,6 +394,12 @@ class CssModulesPlugin {
return finalModules;
}

/**
* @param {Chunk} chunk chunk
* @param {ChunkGraph} chunkGraph chunk graph
* @param {Compilation} compilation compilation
* @returns {Module[]} ordered css modules
*/
getOrderedChunkCssModules(chunk, chunkGraph, compilation) {
return [
...this.getModulesInOrder(
Expand All @@ -397,6 +423,15 @@ class CssModulesPlugin {
];
}

/**
* @param {Object} options options
* @param {string | undefined} options.uniqueName unique name
* @param {Chunk} options.chunk chunk
* @param {ChunkGraph} options.chunkGraph chunk graph
* @param {CodeGenerationResults} options.codeGenerationResults code generation results
* @param {CssModule[]} options.modules ordered css modules
* @returns {Source} generated source
*/
renderChunk({
uniqueName,
chunk,
Expand All @@ -405,6 +440,7 @@ class CssModulesPlugin {
modules
}) {
const source = new ConcatSource();
/** @type {string[]} */
const metaData = [];
for (const module of modules) {
try {
Expand Down Expand Up @@ -443,6 +479,7 @@ class CssModulesPlugin {
source.add(moduleSource);
source.add("\n");
}
/** @type {Map<string, string> | undefined} */
const exports =
codeGenResult.data && codeGenResult.data.get("css-exports");
let moduleId = chunkGraph.getModuleId(module) + "";
Expand Down Expand Up @@ -482,6 +519,11 @@ class CssModulesPlugin {
return source;
}

/**
* @param {Chunk} chunk chunk
* @param {OutputOptions} outputOptions output options
* @returns {Chunk["cssFilenameTemplate"] | OutputOptions["cssFilename"] | OutputOptions["cssChunkFilename"]} used filename template
*/
static getChunkFilenameTemplate(chunk, outputOptions) {
if (chunk.cssFilenameTemplate) {
return chunk.cssFilenameTemplate;
Expand All @@ -492,6 +534,11 @@ class CssModulesPlugin {
}
}

/**
* @param {Chunk} chunk chunk
* @param {ChunkGraph} chunkGraph chunk graph
* @returns {boolean} true, when the chunk has css
*/
static chunkHasCss(chunk, chunkGraph) {
return (
!!chunkGraph.getChunkModulesIterableBySourceType(chunk, "css") ||
Expand Down
23 changes: 22 additions & 1 deletion lib/css/CssParser.js
Expand Up @@ -34,6 +34,11 @@ const OPTIONALLY_VENDOR_PREFIXED_KEYFRAMES_AT_RULE = /^@(-\w+-)?keyframes$/;
const OPTIONALLY_VENDOR_PREFIXED_ANIMATION_PROPERTY =
/^(-\w+-)?animation(-name)?$/i;

/**
* @param {string} str url string
* @param {boolean} isString is url wrapped in quotes
* @returns {string} normalized url
*/
const normalizeUrl = (str, isString) => {
// Remove extra spaces and newlines:
// `url("im\
Expand Down Expand Up @@ -71,13 +76,20 @@ const normalizeUrl = (str, isString) => {
};

class LocConverter {
/**
* @param {string} input input
*/
constructor(input) {
this._input = input;
this.line = 1;
this.column = 0;
this.pos = 0;
}

/**
* @param {number} pos position
* @returns {LocConverter} location converter
*/
get(pos) {
if (this.pos !== pos) {
if (this.pos < pos) {
Expand Down Expand Up @@ -112,6 +124,10 @@ const CSS_MODE_AT_IMPORT_EXPECT_URL = 3;
const CSS_MODE_AT_IMPORT_EXPECT_LAYER_OR_SUPPORTS_OR_MEDIA = 4;
const CSS_MODE_AT_OTHER = 5;

/**
* @param {number} mode current mode
* @returns {string} description of mode
*/
const explainMode = mode => {
switch (mode) {
case CSS_MODE_TOP_LEVEL:
Expand All @@ -127,7 +143,7 @@ const explainMode = mode => {
case CSS_MODE_AT_OTHER:
return "parsing at-rule";
default:
return mode;
return "parsing css";
}
};

Expand Down Expand Up @@ -163,11 +179,16 @@ class CssParser extends Parser {
const declaredCssVariables = new Set();

const locConverter = new LocConverter(source);
/** @type {number} */
let mode = CSS_MODE_TOP_LEVEL;
/** @type {number} */
let modeNestingLevel = 0;
let modeData = undefined;
/** @type {string | boolean | undefined} */
let singleClassSelector = undefined;
/** @type {[number, number] | undefined} */
let lastIdentifier = undefined;
/** @type {boolean} */
let awaitRightParenthesis = false;
/** @type [string, number, number][] */
let balanced = [];
Expand Down