diff --git a/.changeset/README.md b/.changeset/README.md new file mode 100644 index 00000000000..e5b6d8d6a67 --- /dev/null +++ b/.changeset/README.md @@ -0,0 +1,8 @@ +# Changesets + +Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works +with multi-package repos, or single-package repos to help you version and publish your code. You can +find the full documentation for it [in our repository](https://github.com/changesets/changesets) + +We have a quick list of common questions to get you started engaging with this project in +[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/.changeset/changelog-generator.mjs b/.changeset/changelog-generator.mjs new file mode 100644 index 00000000000..605634c897d --- /dev/null +++ b/.changeset/changelog-generator.mjs @@ -0,0 +1,133 @@ +import { getInfo, getInfoFromPullRequest } from "@changesets/get-github-info"; + +/** @typedef {import("@changesets/types").ChangelogFunctions} ChangelogFunctions */ + +/** + * @returns {{ GITHUB_SERVER_URL: string }} value + */ +function readEnv() { + const GITHUB_SERVER_URL = + process.env.GITHUB_SERVER_URL || "https://github.com"; + return { GITHUB_SERVER_URL }; +} + +/** @type {ChangelogFunctions} */ +const changelogFunctions = { + getDependencyReleaseLine: async ( + changesets, + dependenciesUpdated, + options + ) => { + if (!options.repo) { + throw new Error( + 'Please provide a repo to this changelog generator like this:\n"changelog": ["@changesets/changelog-github", { "repo": "org/repo" }]' + ); + } + if (dependenciesUpdated.length === 0) return ""; + + const changesetLink = `- Updated dependencies [${( + await Promise.all( + changesets.map(async (cs) => { + if (cs.commit) { + const { links } = await getInfo({ + repo: options.repo, + commit: cs.commit + }); + return links.commit; + } + }) + ) + ) + .filter(Boolean) + .join(", ")}]:`; + + const updatedDependenciesList = dependenciesUpdated.map( + (dependency) => ` - ${dependency.name}@${dependency.newVersion}` + ); + + return [changesetLink, ...updatedDependenciesList].join("\n"); + }, + getReleaseLine: async (changeset, type, options) => { + const { GITHUB_SERVER_URL } = readEnv(); + if (!options || !options.repo) { + throw new Error( + 'Please provide a repo to this changelog generator like this:\n"changelog": ["@changesets/changelog-github", { "repo": "org/repo" }]' + ); + } + + /** @type {number | undefined} */ + let prFromSummary; + /** @type {string | undefined} */ + let commitFromSummary; + /** @type {string[]} */ + const usersFromSummary = []; + + const replacedChangelog = changeset.summary + .replace(/^\s*(?:pr|pull|pull\s+request):\s*#?(\d+)/im, (_, pr) => { + const num = Number(pr); + if (!Number.isNaN(num)) prFromSummary = num; + return ""; + }) + .replace(/^\s*commit:\s*([^\s]+)/im, (_, commit) => { + commitFromSummary = commit; + return ""; + }) + .replace(/^\s*(?:author|user):\s*@?([^\s]+)/gim, (_, user) => { + usersFromSummary.push(user); + return ""; + }) + .trim(); + + const [firstLine, ...futureLines] = replacedChangelog + .split("\n") + .map((l) => l.trimEnd()); + + const links = await (async () => { + if (prFromSummary !== undefined) { + let { links } = await getInfoFromPullRequest({ + repo: options.repo, + pull: prFromSummary + }); + if (commitFromSummary) { + const shortCommitId = commitFromSummary.slice(0, 7); + links = { + ...links, + commit: `[\`${shortCommitId}\`](${GITHUB_SERVER_URL}/${options.repo}/commit/${commitFromSummary})` + }; + } + return links; + } + const commitToFetchFrom = commitFromSummary || changeset.commit; + if (commitToFetchFrom) { + const { links } = await getInfo({ + repo: options.repo, + commit: commitToFetchFrom + }); + return links; + } + return { + commit: null, + pull: null, + user: null + }; + })(); + + const users = usersFromSummary.length + ? usersFromSummary + .map( + (userFromSummary) => + `[@${userFromSummary}](${GITHUB_SERVER_URL}/${userFromSummary})` + ) + .join(", ") + : links.user; + + let suffix = ""; + if (links.pull || links.commit || users) { + suffix = `(${users ? `by ${users} ` : ""}in ${links.pull || links.commit})`; + } + + return `\n\n- ${firstLine} ${suffix}\n${futureLines.map((l) => ` ${l}`).join("\n")}`; + } +}; + +export default changelogFunctions; diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 00000000000..5fcacb00918 --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,10 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.1.2/schema.json", + "changelog": ["./changelog-generator.mjs", { "repo": "webpack/webpack" }], + "fixed": [], + "linked": [], + "access": "public", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": [] +} diff --git a/.editorconfig b/.editorconfig index 0c2b037f084..424ca2bf5cf 100644 --- a/.editorconfig +++ b/.editorconfig @@ -21,5 +21,11 @@ trim_trailing_whitespace = false [test/cases/parsing/bom/bomfile.{css,js}] charset = utf-8-bom +[test/configCases/asset-modules/bytes/file.text] +insert_final_newline = false + +[test/configCases/asset-modules/bytes/file.svg] +insert_final_newline = false + [test/configCases/css/no-extra-runtime-in-js/source.text] insert_final_newline = false diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index 5e7c7b6d7a6..00000000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1 +0,0 @@ -open_collective: webpack diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index 3b257921146..00000000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,24 +0,0 @@ - - - - -**Do you want to request a _feature_ or report a _bug_?** - - - - - - -**What is the current behavior?** - -**If the current behavior is a bug, please provide the steps to reproduce.** - - - - - -**What is the expected behavior?** - -**If this is a feature request, what is motivation or use case for changing the behavior?** - -**Please mention other relevant information such as the browser version, Node.js version, webpack version, and Operating System.** diff --git a/.github/ISSUE_TEMPLATE/Bug_report.md b/.github/ISSUE_TEMPLATE/Bug_report.md deleted file mode 100644 index de70ffd482d..00000000000 --- a/.github/ISSUE_TEMPLATE/Bug_report.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve ---- - - - - -# Bug report - - - - - - -**What is the current behavior?** - -**If the current behavior is a bug, please provide the steps to reproduce.** - - - - - - - - -**What is the expected behavior?** - - - - -**Other relevant information:** -webpack version: -Node.js version: -Operating System: -Additional tools: diff --git a/.github/ISSUE_TEMPLATE/Feature_request.md b/.github/ISSUE_TEMPLATE/Feature_request.md deleted file mode 100644 index 704020c0671..00000000000 --- a/.github/ISSUE_TEMPLATE/Feature_request.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project ---- - - - -## Feature request - - - - - - - -**What is the expected behavior?** - -**What is motivation or use case for adding/changing the behavior?** - -**How should this be implemented in your opinion?** - -**Are you willing to work on this yourself?** -yes diff --git a/.github/ISSUE_TEMPLATE/Other.md b/.github/ISSUE_TEMPLATE/Other.md deleted file mode 100644 index 3faf967c321..00000000000 --- a/.github/ISSUE_TEMPLATE/Other.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -name: Other -about: Something else ---- - - - - - - diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 89efe54b7d5..00000000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - -**What kind of change does this PR introduce?** - - - -**Did you add tests for your changes?** - - - -**Does this PR introduce a breaking change?** - - - -**What needs to be documented once your changes are merged?** - - - diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 7b3e3b3ec5d..c1c202195bf 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,9 +3,7 @@ updates: - package-ecosystem: npm directory: "/" schedule: - interval: daily - time: "04:00" - timezone: Europe/Berlin + interval: "weekly" open-pull-requests-limit: 20 labels: - dependencies @@ -23,9 +21,11 @@ updates: - package-ecosystem: "github-actions" directory: "/" schedule: - interval: daily - time: "04:00" - timezone: Europe/Berlin + interval: "weekly" open-pull-requests-limit: 20 labels: - dependencies + groups: + dependencies: + patterns: + - "*" diff --git a/.github/scripts/publish-to-pkg-pr-new.mjs b/.github/scripts/publish-to-pkg-pr-new.mjs new file mode 100644 index 00000000000..f84aae84a6e --- /dev/null +++ b/.github/scripts/publish-to-pkg-pr-new.mjs @@ -0,0 +1,129 @@ +/* eslint-disable no-console */ +/* eslint-disable camelcase */ + +import fs from "fs"; + +/** + * @param {{ github: EXPECTED_ANY, context: EXPECTED_ANY }} params params + */ +export async function run({ github, context }) { + const output = JSON.parse(fs.readFileSync("output.json", "utf8")); + + const sha = + context.eventName === "pull_request" + ? context.payload.pull_request.head.sha + : context.sha; + + const commitUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/commit/${sha}`; + + const botCommentIdentifier = ""; + const body = `${botCommentIdentifier} +This PR is packaged and the instant preview is available (${commitUrl}). + +Install it locally: + +- npm + +\`\`\`shell +npm i -D webpack@${output.packages.map((p) => p.url).join(" ")} +\`\`\` + +- yarn + +\`\`\`shell +yarn add -D webpack@${output.packages.map((p) => p.url).join(" ")} +\`\`\` + +- pnpm + +\`\`\`shell +pnpm add -D webpack@${output.packages.map((p) => p.url).join(" ")} +\`\`\` +`; + + /** + * @param {number=} issueNumber PR number + * @returns {Promise} comments + */ + async function findBotComment(issueNumber) { + if (!issueNumber) return null; + const comments = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issueNumber + }); + return comments.data.find( + (comment) => + // Prevent unintentional overwriting + comment.user && + comment.user.login === "github-actions[bot]" && + comment.body.includes(botCommentIdentifier) + ); + } + + /** + * @param {number=} issueNumber issue number + * @returns {Promise} + */ + async function createOrUpdateComment(issueNumber) { + if (!issueNumber) { + console.log("No issue number provided. Cannot post or update comment."); + return; + } + + const existingComment = await findBotComment(issueNumber); + + if (existingComment) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: existingComment.id, + body + }); + } else { + await github.rest.issues.createComment({ + issue_number: issueNumber, + owner: context.repo.owner, + repo: context.repo.repo, + body + }); + } + } + + /** + * @returns {void} + */ + function logPublishInfo() { + console.log(`\n${"=".repeat(50)}`); + console.log("Publish Information"); + console.log("=".repeat(50)); + console.log("\nPublished Packages:"); + console.log(output.packages); + console.log("\nTemplates:"); + console.log(output.templates); + console.log(`\nCommit URL: ${commitUrl}`); + console.log(`\n${"=".repeat(50)}`); + } + + if (context.eventName === "pull_request") { + if (context.issue.number) { + await createOrUpdateComment(context.issue.number); + } + } else if (context.eventName === "push") { + const { data: prs } = + await github.rest.repos.listPullRequestsAssociatedWithCommit({ + owner: context.repo.owner, + repo: context.repo.repo, + commit_sha: sha + }); + + if (prs.length > 0) { + await createOrUpdateComment(prs[0].number); + } else { + console.log( + "No open pull request found for this push. Logging publish information to console:" + ); + logPublishInfo(); + } + } +} diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml new file mode 100644 index 00000000000..5eb75fd9995 --- /dev/null +++ b/.github/workflows/benchmarks.yml @@ -0,0 +1,54 @@ +name: Benchmarks + +on: + push: + branches: [main] + pull_request: + branches: [main] + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + benchmark: + strategy: + fail-fast: false + matrix: + shard: [1/4, 2/4, 3/4, 4/4] + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-tags: true + fetch-depth: 0 + + - name: Use Node.js + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + with: + node-version: lts/* + cache: yarn + + - run: yarn --frozen-lockfile + + - run: yarn link --frozen-lockfile || true + + - run: yarn link webpack --frozen-lockfile + + - name: Run benchmarks + uses: CodSpeedHQ/action@df47568b033d58cefcc54680a649123fc87b7573 # v4.10.1 + with: + run: yarn benchmark --ci + mode: "simulation" + token: ${{ secrets.CODSPEED_TOKEN }} + env: + LAST_COMMIT: 1 + NEGATIVE_FILTER: on-schedule + SHARD: ${{ matrix.shard }} diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 4db2a128537..4f4ddcf973a 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -1,6 +1,7 @@ -name: "Dependency Review" +name: Dependency Review -on: [pull_request] +on: + pull_request: permissions: contents: read @@ -9,12 +10,22 @@ jobs: dependency-review: runs-on: ubuntu-latest steps: - - name: "Checkout Repository" - uses: actions/checkout@v4 - - name: "Dependency Review" - uses: actions/dependency-review-action@v4 + - name: Checkout Repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Dependency Review + uses: actions/dependency-review-action@3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261 # v4.8.2 with: - allow-dependencies-licenses: "pkg:npm/@cspell/dict-en-common-misspellings, pkg:npm/flatted, pkg:npm/parse-imports, pkg:npm/prettier, pkg:npm/type-fest, pkg:npm/abbrev, pkg:npm/@pkgjs/parseargs, pkg:npm/cookie-signature" + allow-dependencies-licenses: | + pkg:npm/@cspell/dict-django, + pkg:npm/@cspell/dict-en-common-misspellings, + pkg:npm/flatted, + pkg:npm/parse-imports, + pkg:npm/prettier, + pkg:npm/type-fest, + pkg:npm/abbrev, + pkg:npm/@pkgjs/parseargs, + pkg:npm/cookie-signature allow-licenses: | 0BSD, AFL-1.1, diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index 3d2f8b96ec2..707e287932e 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -1,34 +1,41 @@ -name: "Update examples" +name: Update examples on: + workflow_dispatch: schedule: - cron: "0 0 * * 0" -permissions: - contents: read - jobs: examples: runs-on: ubuntu-latest permissions: + contents: write pull-requests: write + steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: + fetch-tags: true fetch-depth: 0 + - name: Use Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version: lts/* - cache: "yarn" + cache: yarn + - run: yarn --frozen-lockfile + - run: yarn link --frozen-lockfile || true + - run: yarn link webpack --frozen-lockfile + - run: yarn build:examples + - name: Create Pull Request - uses: peter-evans/create-pull-request@v7 + uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0 with: - token: ${{ secrets.PAT }} + token: ${{ secrets.GITHUB_TOKEN }} delete-branch: true commit-message: | docs: update examples diff --git a/.github/workflows/publish-to-pkg-pr-new.yml b/.github/workflows/publish-to-pkg-pr-new.yml new file mode 100644 index 00000000000..0fb9acfb860 --- /dev/null +++ b/.github/workflows/publish-to-pkg-pr-new.yml @@ -0,0 +1,41 @@ +name: Publish to pkg.pr.new + +on: + pull_request: + branches: [main] + push: + branches: [main] + tags: ["!**"] + +permissions: + issues: write + pull-requests: write + +jobs: + publish: + if: | + github.repository == 'webpack/webpack' && + (github.event_name != 'pull_request' || + github.event.pull_request.head.repo.full_name == github.repository) + name: Publish to pkg.pr.new + runs-on: ubuntu-latest + outputs: + sha: ${{ steps.publish.outputs.sha }} + urls: ${{ steps.publish.outputs.urls }} + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - run: corepack enable + - name: Use Node.js + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + with: + node-version: lts/* + cache: yarn + - run: yarn --frozen-lockfile + - run: npx pkg-pr-new publish --compact --json output.json --comment=off + - name: Add metadata to output + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const { run } = await import('${{ github.workspace }}/.github/scripts/publish-to-pkg-pr-new.mjs'); + await run({ github, context }); diff --git a/.github/workflows/release-announcement.yml b/.github/workflows/release-announcement.yml new file mode 100644 index 00000000000..31eda4e8276 --- /dev/null +++ b/.github/workflows/release-announcement.yml @@ -0,0 +1,22 @@ +name: Release Announcement + +on: + release: + types: [published] + +jobs: + github-releases-to-discord: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: GitHub Releases to Discord + uses: SethCohen/github-releases-to-discord@b96a33520f8ad5e6dcdecee6f1212bdf88b16550 # v1.19.0 + with: + webhook_url: ${{ secrets.DISCORD_WEBHOOK }} + color: "2105893" + username: "webpack Release Changelog" + avatar_url: "https://github.com/webpack/media/blob/90b54d02fa1cfc8aa864a8322202f74ac000f5d2/logo/icon.png" + content: "||<@&1450591255485743204>||" + footer_title: "Changelog" + reduce_headings: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000000..263b20c39f7 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,40 @@ +name: Release + +on: + push: + branches: + - main + +concurrency: ${{ github.workflow }}-${{ github.ref }} + +permissions: + id-token: write # Required for OIDC + contents: write + pull-requests: write + +jobs: + release: + if: github.repository == 'webpack/webpack' + name: Release + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Use Node.js + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + with: + node-version: lts/* + cache: yarn + + - run: yarn --frozen-lockfile + + - name: Create Release Pull Request or Publish to npm + id: changesets + uses: changesets/action@c48e67d110a68bc90ccf1098e9646092baacaa87 # v1.6.0 + with: + publish: node ./node_modules/.bin/changeset publish + commit: "chore(release): new release" + title: "chore(release): new release" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: "" # https://github.com/changesets/changesets/issues/1152#issuecomment-3190884868 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d64874cc3bb..162f95d900e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,12 +2,13 @@ name: Github Actions on: push: - branches: - - main + branches: [main] pull_request: - branches: - - main - workflow_dispatch: + branches: [main] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true permissions: contents: read @@ -16,123 +17,120 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - name: Use Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version: lts/* - cache: "yarn" + cache: yarn + - run: yarn --frozen-lockfile + - name: Cache prettier result - uses: actions/cache@v4 + uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2 with: path: ./node_modules/.cache/prettier/.prettier-cache key: lint-prettier-${{ runner.os }}-node-${{ hashFiles('**/yarn.lock', '**/.prettierrc.js') }} restore-keys: lint-prettier- + - name: Cache eslint result - uses: actions/cache@v4 + uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2 with: path: .eslintcache key: lint-eslint-${{ runner.os }}-node-${{ hashFiles('**/yarn.lock', '**/eslint.config.mjs') }} restore-keys: lint-eslint- + - name: Cache cspell result - uses: actions/cache@v4 + uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2 with: path: .cspellcache key: lint-cspell-${{ runner.os }}-node-${{ hashFiles('**/yarn.lock', '**/cspell.json') }} restore-keys: lint-cspell- + - run: yarn lint + - name: Validate types using old typescript version run: | yarn upgrade typescript@5.0 @types/node@20 yarn --frozen-lockfile yarn validate:types + validate-legacy-node: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - name: Use Node.js - uses: actions/setup-node@v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Use Node.js 10.x + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version: 10.x - cache: "yarn" + cache: yarn + # Remove `devDependencies` from `package.json` to avoid `yarn install` compatibility error - run: node -e "const content = require('./package.json');delete content.devDependencies;require('fs').writeFileSync('package.json', JSON.stringify(content, null, 2));" + - run: yarn install --production --frozen-lockfile - benchmark: - strategy: - fail-fast: false - matrix: - shard: [1/4, 2/4, 3/4, 4/4] - runs-on: ubuntu-latest - permissions: - issues: write - pull-requests: write - steps: - - uses: actions/checkout@v4 - with: - fetch-tags: true - fetch-depth: 0 - - name: Use Node.js - uses: actions/setup-node@v4 - with: - node-version: lts/* - cache: "yarn" - - run: yarn --frozen-lockfile - - run: yarn link --frozen-lockfile || true - - run: yarn link webpack --frozen-lockfile - - name: Run benchmarks - uses: CodSpeedHQ/action@v3 - with: - run: yarn benchmark --ci - token: ${{ secrets.CODSPEED_TOKEN }} - env: - LAST_COMMIT: 1 - NEGATIVE_FILTER: on-schedule - SHARD: ${{ matrix.shard }} + basic: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - name: Use Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version: lts/* - cache: "yarn" + cache: yarn + - run: yarn --frozen-lockfile + - run: yarn link --frozen-lockfile || true + - run: yarn link webpack --frozen-lockfile + - run: yarn test:basic --ci + unit: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - name: Use Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version: lts/* - cache: "yarn" + cache: yarn + - run: yarn --frozen-lockfile + - run: yarn link --frozen-lockfile || true + - run: yarn link webpack --frozen-lockfile - - uses: actions/cache@v4 + + - name: Cache jest result + uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2 with: path: .jest-cache key: jest-unit-${{ env.GITHUB_SHA }} restore-keys: jest-unit-${{ hashFiles('**/yarn.lock', '**/jest.config.js') }} + - run: yarn cover:unit --ci --cacheDirectory .jest-cache - - uses: codecov/codecov-action@v5 + + - name: Codecov + uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2 with: flags: unit env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + integration: needs: basic strategy: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] - node-version: [10.x, 20.x, 22.x, 24.x] + node-version: [10.x, 20.x, 22.x, 24.x, 25.x] part: [a, b] include: # Test with main branches of webpack dependencies @@ -159,8 +157,9 @@ jobs: part: a runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 - - uses: actions/github-script@v7 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 id: calculate_architecture with: result-encoding: string @@ -170,41 +169,55 @@ jobs: } else { return '' } + - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version: ${{ matrix.node-version }} architecture: ${{ steps.calculate_architecture.outputs.result }} - cache: "yarn" + cache: yarn + # Install old `jest` version and deps for legacy node versions - run: | - yarn upgrade jest@^27.5.0 jest-circus@^27.5.0 jest-cli@^27.5.0 jest-diff@^27.5.0 jest-environment-node@^27.5.0 jest-junit@^13.0.0 @types/jest@^27.4.0 pretty-format@^27.0.2 husky@^8.0.3 lint-staged@^13.2.1 cspell@^6.31.1 open-cli@^7.2.0 coffee-loader@^1.0.0 babel-loader@^8.1.0 style-loader@^2.0.0 css-loader@^5.0.1 less-loader@^8.1.1 mini-css-extract-plugin@^1.6.1 nyc@^15.1.0 --ignore-engines + yarn upgrade jest@^27.5.0 jest-circus@^27.5.0 jest-cli@^27.5.0 jest-diff@^27.5.0 jest-environment-node@^27.5.0 jest-junit@^13.0.0 @types/jest@^27.4.0 pretty-format@^27.0.2 husky@^8.0.3 lint-staged@^13.2.1 cspell@^6.31.1 open-cli@^7.2.0 coffee-loader@^1.0.0 babel-loader@^8.1.0 style-loader@^2.0.0 css-loader@^5.0.1 less-loader@^8.1.1 mini-css-extract-plugin@^1.6.1 nyc@^15.1.0 memfs@4.14.0 --ignore-engines yarn --frozen-lockfile --ignore-engines if: matrix.node-version == '10.x' || matrix.node-version == '12.x' || matrix.node-version == '14.x' + - run: | yarn upgrade jest@^27.5.0 jest-circus@^27.5.0 jest-cli@^27.5.0 jest-diff@^27.5.0 jest-environment-node@^27.5.0 jest-junit@^13.0.0 @types/jest@^27.4.0 pretty-format@^27.0.2 husky@^8.0.3 lint-staged@^13.2.1 nyc@^15.1.0 coffee-loader@1.0.0 babel-loader@^8.1.0 style-loader@^2.0.0 css-loader@^5.0.1 less-loader@^8.1.1 mini-css-extract-plugin@^1.6.1 --ignore-engines yarn --frozen-lockfile if: matrix.node-version == '16.x' + - run: | yarn upgrade cspell@^8.8.4 lint-staged@^15.2.5 --ignore-engines yarn --frozen-lockfile if: matrix.node-version == '18.x' + # Install main version of our deps - run: yarn upgrade enhanced-resolve@webpack/enhanced-resolve#main loader-runner@webpack/loader-runner#main webpack-sources@webpack/webpack-sources#main watchpack@webpack/watchpack#main tapable@webpack/tapable#main if: matrix.use_main_branches == '1' + # Install dependencies for LTS node versions - run: yarn --frozen-lockfile if: matrix.node-version != '10.x' && matrix.node-version != '12.x' && matrix.node-version != '14.x' && matrix.node-version != '16.x' + - run: yarn link --frozen-lockfile || true + - run: yarn link webpack --frozen-lockfile - - uses: actions/cache@v4 + + - name: Cache jest result + uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2 with: path: .jest-cache key: jest-integration-${{ env.GITHUB_SHA }} restore-keys: jest-integration-${{ hashFiles('**/yarn.lock', '**/jest.config.js') }} + - run: yarn cover:integration:${{ matrix.part }} --ci --cacheDirectory .jest-cache || yarn cover:integration:${{ matrix.part }} --ci --cacheDirectory .jest-cache -f - - run: yarn cover:merge - - uses: codecov/codecov-action@v5 + + - run: yarn report:cover:merge + + - name: Codecov + uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2 with: flags: integration env: diff --git a/.prettierignore b/.prettierignore index 0d57d80513e..59b64901eec 100644 --- a/.prettierignore +++ b/.prettierignore @@ -34,7 +34,9 @@ declarations/WebpackOptions.d.ts schemas/**/*.check.js # Ignore example fixtures -examples/ +examples/**/* +!examples/* !examples/**/webpack.config.js +!examples/**/test.filter.js .vscode/**/*.* diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000000..719631024f1 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,98 @@ +# webpack + +## 5.105.0 + +### Minor Changes + +- Allow resolving worker module by export condition name when using `new Worker()` (by [@hai-x](https://github.com/hai-x) in [#20353](https://github.com/webpack/webpack/pull/20353)) + +- Detect conditional imports to avoid compile-time linking errors for non-existent exports. (by [@hai-x](https://github.com/hai-x) in [#20320](https://github.com/webpack/webpack/pull/20320)) + +- Added the `tsconfig` option for the `resolver` options (replacement for `tsconfig-paths-webpack-plugin`). Can be `false` (disabled), `true` (use the default `tsconfig.json` file to search for it), a string path to `tsconfig.json`, or an object with `configFile` and `references` options. (by [@alexander-akait](https://github.com/alexander-akait) in [#20400](https://github.com/webpack/webpack/pull/20400)) + +- Support `import.defer()` for context modules. (by [@ahabhgk](https://github.com/ahabhgk) in [#20399](https://github.com/webpack/webpack/pull/20399)) + +- Added support for array values ​​to the `devtool` option. (by [@hai-x](https://github.com/hai-x) in [#20191](https://github.com/webpack/webpack/pull/20191)) + +- Improve rendering node built-in modules for ECMA module output. (by [@hai-x](https://github.com/hai-x) in [#20255](https://github.com/webpack/webpack/pull/20255)) + +- Unknown import.meta properties are now determined at runtime instead of being statically analyzed at compile time. (by [@xiaoxiaojx](https://github.com/xiaoxiaojx) in [#20312](https://github.com/webpack/webpack/pull/20312)) + +### Patch Changes + +- Fixed ESM default export handling for `.mjs` files in Module Federation (by [@y-okt](https://github.com/y-okt) in [#20189](https://github.com/webpack/webpack/pull/20189)) + +- Optimized `import.meta.env` handling in destructuring assignments by using cached stringified environment definitions. (by [@xiaoxiaojx](https://github.com/xiaoxiaojx) in [#20313](https://github.com/webpack/webpack/pull/20313)) + +- Respect the `stats.errorStack` option in stats output. (by [@samarthsinh2660](https://github.com/samarthsinh2660) in [#20258](https://github.com/webpack/webpack/pull/20258)) + +- Fixed a bug where declaring a `module` variable in module scope would conflict with the default `moduleArgument`. (by [@xiaoxiaojx](https://github.com/xiaoxiaojx) in [#20265](https://github.com/webpack/webpack/pull/20265)) + +- Fix VirtualUrlPlugin to set resourceData.context for proper module resolution. Previously, when context was not set, it would fallback to the virtual scheme path (e.g., `virtual:routes`), which is not a valid filesystem path, causing subsequent resolve operations to fail. (by [@xiaoxiaojx](https://github.com/xiaoxiaojx) in [#20390](https://github.com/webpack/webpack/pull/20390)) + +- Fixed Worker self-import handling to support various URL patterns (e.g., `import.meta.url`, `new URL(import.meta.url)`, `new URL(import.meta.url, import.meta.url)`, `new URL("./index.js", import.meta.url)`). Workers that resolve to the same module are now properly deduplicated, regardless of the URL syntax used. (by [@xiaoxiaojx](https://github.com/xiaoxiaojx) in [#20381](https://github.com/webpack/webpack/pull/20381)) + +- Reuse the same async entrypoint for the same Worker URL within a module to avoid circular dependency warnings when multiple Workers reference the same resource. (by [@xiaoxiaojx](https://github.com/xiaoxiaojx) in [#20345](https://github.com/webpack/webpack/pull/20345)) + +- Fixed a bug where a self-referencing dependency would have an unused export name when imported inside a web worker. (by [@samarthsinh2660](https://github.com/samarthsinh2660) in [#20251](https://github.com/webpack/webpack/pull/20251)) + +- Fix missing export generation when concatenated modules in different chunks share the same runtime in module library bundles. (by [@hai-x](https://github.com/hai-x) in [#20346](https://github.com/webpack/webpack/pull/20346)) + +- Fixed `import.meta.env.xxx` behavior: when accessing a non-existent property, it now returns empty object instead of full object at runtime. (by [@xiaoxiaojx](https://github.com/xiaoxiaojx) in [#20289](https://github.com/webpack/webpack/pull/20289)) + +- Improved parsing error reporting by adding a link to the loader documentation. (by [@gaurav10gg](https://github.com/gaurav10gg) in [#20244](https://github.com/webpack/webpack/pull/20244)) + +- Fix typescript types. (by [@alexander-akait](https://github.com/alexander-akait) in [#20305](https://github.com/webpack/webpack/pull/20305)) + +- Add declaration for unused harmony import specifier. (by [@hai-x](https://github.com/hai-x) in [#20286](https://github.com/webpack/webpack/pull/20286)) + +- Fix compressibility of modules while retaining portability. (by [@dmichon-msft](https://github.com/dmichon-msft) in [#20287](https://github.com/webpack/webpack/pull/20287)) + +- Optimize source map generation: only include `ignoreList` property when it has content, avoiding empty arrays in source maps. (by [@xiaoxiaojx](https://github.com/xiaoxiaojx) in [#20319](https://github.com/webpack/webpack/pull/20319)) + +- Preserve star exports for dependencies in ECMA module output. (by [@hai-x](https://github.com/hai-x) in [#20293](https://github.com/webpack/webpack/pull/20293)) + +- Consider asset modulem to be side-effect free. (by [@hai-x](https://github.com/hai-x) in [#20352](https://github.com/webpack/webpack/pull/20352)) + +- Avoid generating JavaScript modules for CSS exports that are not used, reducing unnecessary output and bundle size. (by [@xiaoxiaojx](https://github.com/xiaoxiaojx) in [#20337](https://github.com/webpack/webpack/pull/20337)) + +## 5.104.1 + +### Patch Changes + +- 2efd21b: Reexports runtime calculation should not accessing **WEBPACK_IMPORT_KEY** decl with var. +- c510070: Fixed a user information bypass vulnerability in the HttpUriPlugin plugin. + +## 5.104.0 + +### Minor Changes + +- d3dd841: Use method shorthand to render module content in `__webpack_modules__` object. +- d3dd841: Enhance `import.meta.env` to support object access. +- 4baab4e: Optimize dependency sorting in updateParent: sort each module only once by deferring to finishUpdateParent(), and reduce traversal count in sortWithSourceOrder by caching WeakMap values upfront. +- 04cd530: Handle more at-rules for CSS modules. +- cafae23: Added options to control the renaming of at-rules and various identifiers in CSS modules. +- d3dd841: Added `base64url`, `base62`, `base58`, `base52`, `base49`, `base36`, `base32` and `base25` digests. +- 5983843: Provide a stable runtime function variable `__webpack_global__`. +- d3dd841: Improved `localIdentName` hashing for CSS. + +### Patch Changes + +- 22c48fb: Added module existence check for informative error message in development mode. +- 50689e1: Use the fully qualified class name (or export name) for `[fullhash]` placeholder in CSS modules. +- d3dd841: Support universal lazy compilation. +- d3dd841: Fixed module library export definitions when multiple runtimes. +- d3dd841: Fixed CSS nesting and CSS custom properties parsing. +- d3dd841: Don't write fragment from URL to filename and apply fragment to module URL. +- aab1da9: Fixed bugs for `css/global` type. +- d3dd841: Compatibility `import.meta.filename` and `import.meta.dirname` with `eval` devtools. +- d3dd841: Handle nested `__webpack_require__`. +- 728ddb7: The speed of identifier parsing has been improved. +- 0f8b31b: Improve types. +- d3dd841: Don't corrupt `debugId` injection when `hidden-source-map` is used. +- 2179fdb: Re-validate HttpUriPlugin redirects against allowedUris, restrict to http(s) and add a conservative redirect limit to prevent SSRF and untrusted content inclusion. Redirects failing policy are rejected before caching/lockfile writes. +- d3dd841: Serialize `HookWebpackError`. +- d3dd841: Added ability to use built-in properties in dotenv and define plugin. +- 3c4319f: Optimizing the regular expression character class by specifying ranges for runtime code. +- d3dd841: Reduce collision for local indent name in CSS. +- d3dd841: Remove CSS link tags when CSS imports are removed. diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index 4faf227c455..00000000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1 +0,0 @@ -[Code of Conduct](https://github.com/openjs-foundation/code-and-learn/blob/master/CODE_OF_CONDUCT.md) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7ade9adab17..b7700430148 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,20 +10,27 @@ work is not in vain. Most of the time, if webpack is not working correctly for you, it is a simple configuration issue. If you are still having difficulty after looking over your configuration carefully, please post -a question to [StackOverflow with the webpack tag](https://stackoverflow.com/tags/webpack). Questions +a question to [Discussions](https://github.com/webpack/webpack/discussions), [StackOverflow with the webpack tag](https://stackoverflow.com/tags/webpack) or ask this in our [Discord](https://discord.gg/5sxFZPdx2k). Questions that include your webpack.config.js, relevant files, and the full error message are more likely to receive responses. +> ⚠️ Note on dependency vulnerability warnings +> +> Tools like `npm audit` may report vulnerabilities originating from development-only dependencies +> (for example `webpack-dev-server`). These warnings do not always indicate a security issue +> in your production bundle. +> +> Before opening an issue, please check whether the warning comes from a dev dependency +> and whether an update or workaround already exists. + **If you have discovered a bug or have a feature suggestion, please [create an issue on GitHub](https://github.com/webpack/webpack/issues/new).** -Do you want to fix an issue? Look at the issues with a tag of [X5: work required (PR / Help Wanted)](https://github.com/webpack/webpack/labels/X5%3A%20work%20required%20%28PR%20%2F%20Help%20Wanted%29). Here are some of the key labels you may encounter: +Do you want to fix an issue? Look at the issues with a tag of [Send a PR](https://github.com/webpack/webpack/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22Send%20a%20PR%22). Here are some of the key labels you may encounter: - **bug**: An unexpected problem or unintended behavior. - **enhancement**: A suggestion for a new feature or improvement. - **question**: Requests for clarification or more information. - **documentation**: Issues related to improving or adding documentation. -> **Note:** Previous references to labels such as `D0: My First Commit`, `D1: Easy`, `D2: Medium`, and `D3: Hard` have been removed as these are not currently in use. If you would like to see difficulty labels added, please open a suggestion or discuss with maintainers. - ## Contributing to the webpack ecosystem If you have created your own loader/plugin please include it on the relevant documentation pages: @@ -72,7 +79,7 @@ Then, automatically generate the type declarations by running `yarn fix` locally ## Discussions -Gitter is only for small questions. To discuss a subject in detail, please send a link to your forum or blog in the Gitter chat. +For discussions please use our [Discussions](https://github.com/webpack/webpack/discussions). ## Join the development diff --git a/README.md b/README.md index a4b1440cbef..f866c6331bd 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ [![builds1][builds1]][builds1-url] [![dependency-review][dependency-review]][dependency-review-url] [![coverage][cover]][cover-url] +[![pkg.pr.new](https://pkg.pr.new/badge/webpack/webpack)](https://pkg.pr.new/~/webpack/webpack) [![PR's welcome][prs]][prs-url] [![compatibility-score](https://api.dependabot.com/badges/compatibility_score?dependency-name=webpack&package-manager=npm_and_yarn&previous-version=5.72.1&new-version=5.73.0)](https://docs.github.com/en/code-security/dependabot/dependabot-security-updates/about-dependabot-security-updates#about-compatibility-scores) [![downloads](https://img.shields.io/npm/dm/webpack.svg)](https://npmcharts.com/compare/webpack?minimal=true) @@ -20,6 +21,7 @@ [![contributors](https://img.shields.io/github/contributors/webpack/webpack.svg)](https://github.com/webpack/webpack/graphs/contributors) [![discussions](https://img.shields.io/github/discussions/webpack/webpack)](https://github.com/webpack/webpack/discussions) [![discord](https://img.shields.io/discord/1180618526436888586?label=discord&logo=discord&logoColor=white&style=flat)](https://discord.gg/5sxFZPdx2k) +[![LFX Health Score](https://insights.linuxfoundation.org/api/badge/health-score?project=webpack)](https://insights.linuxfoundation.org/project/webpack)

webpack

@@ -45,7 +47,7 @@ - [Backers](#backers) - [Special Thanks](#special-thanks-to) -

Install

+## Install Install with npm: @@ -59,7 +61,7 @@ Install with yarn: yarn add webpack --dev ``` -

Introduction

+## Introduction Webpack is a bundler for modules. The main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, @@ -87,7 +89,7 @@ Check out webpack's quick [**Get Started**](https://webpack.js.org/guides/gettin Webpack supports all browsers that are [ES5-compliant](https://kangax.github.io/compat-table/es5/) (IE8 and below are not supported). Webpack also needs `Promise` for `import()` and `require.ensure()`. If you want to support older browsers, you will need to [load a polyfill](https://webpack.js.org/guides/shimming/) before using these expressions. -

Concepts

+## Concepts ### [Plugins](https://webpack.js.org/plugins/) @@ -135,9 +137,9 @@ or are automatically applied via regex from your webpack configuration. #### JSON -| Name | Status | Install Size | Description | -| :---------------------------------------------------------------------------------------------------------------------------------------: | :---------: | :----------: | :------------------------------: | -| | ![cson-npm] | ![cson-size] | Loads and transpiles a CSON file | +| Name | Status | Install Size | Description | +| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------: | :----------: | :------------------------------: | +| | ![cson-npm] | ![cson-size] | Loads and transpiles a CSON file | [cson-npm]: https://img.shields.io/npm/v/cson-loader.svg [cson-size]: https://packagephobia.com/badge?p=cson-loader @@ -146,9 +148,9 @@ or are automatically applied via regex from your webpack configuration. | Name | Status | Install Size | Description | | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-----------: | :------------: | :------------------------------------------------------------------------------------------------ | -| | ![babel-npm] | ![babel-size] | Loads ES2015+ code and transpiles to ES5 using Babel | +| | ![babel-npm] | ![babel-size] | Loads ES2015+ code and transpiles to ES5 using Babel | | | ![type-npm] | ![type-size] | Loads TypeScript like JavaScript | -| | ![coffee-npm] | ![coffee-size] | Loads CoffeeScript like JavaScript | +| | ![coffee-npm] | ![coffee-size] | Loads CoffeeScript like JavaScript | [babel-npm]: https://img.shields.io/npm/v/babel-loader.svg [babel-size]: https://packagephobia.com/badge?p=babel-loader @@ -159,14 +161,14 @@ or are automatically applied via regex from your webpack configuration. #### Templating -| Name | Status | Install Size | Description | -| :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------: | :--------------: | :-------------------------------------------------------------------------------------- | -| | ![html-npm] | ![html-size] | Exports HTML as string, requires references to static resources | -| | ![pug-npm] | ![pug-size] | Loads Pug templates and returns a function | -| | ![pug3-npm] | ![pug3-size] | Compiles Pug to a function or HTML string, useful for use with Vue, React, Angular | -| | ![md-npm] | ![md-size] | Compiles Markdown to HTML | -| | ![posthtml-npm] | ![posthtml-size] | Loads and transforms a HTML file using [PostHTML](https://github.com/posthtml/posthtml) | -| | ![hbs-npm] | ![hbs-size] | Compiles Handlebars to HTML | +| Name | Status | Install Size | Description | +| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------: | :--------------: | :-------------------------------------------------------------------------------------- | +| | ![html-npm] | ![html-size] | Exports HTML as string, requires references to static resources | +| | ![pug-npm] | ![pug-size] | Loads Pug templates and returns a function | +| | ![pug3-npm] | ![pug3-size] | Compiles Pug to a function or HTML string, useful for use with Vue, React, Angular | +| | ![md-npm] | ![md-size] | Compiles Markdown to HTML | +| | ![posthtml-npm] | ![posthtml-size] | Loads and transforms a HTML file using [PostHTML](https://github.com/posthtml/posthtml) | +| | ![hbs-npm] | ![hbs-size] | Compiles Handlebars to HTML | [html-npm]: https://img.shields.io/npm/v/html-loader.svg [html-size]: https://packagephobia.com/badge?p=html-loader @@ -185,14 +187,14 @@ or are automatically applied via regex from your webpack configuration. #### Styling -| Name | Status | Install Size | Description | -| :-------------------------------------------------------------------------------------------------------------------------------------------: | :------------: | :-------------: | :----------------------------------------------------------------------- | -| `\");\n}","import _slicedToArray from \"@babel/runtime/helpers/esm/slicedToArray\";\nexport var token2CSSVar = function token2CSSVar(token) {\n var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';\n return \"--\".concat(prefix ? \"\".concat(prefix, \"-\") : '').concat(token).replace(/([a-z0-9])([A-Z])/g, '$1-$2').replace(/([A-Z]+)([A-Z][a-z0-9]+)/g, '$1-$2').replace(/([a-z])([A-Z0-9])/g, '$1-$2').toLowerCase();\n};\nexport var serializeCSSVar = function serializeCSSVar(cssVars, hashId, options) {\n if (!Object.keys(cssVars).length) {\n return '';\n }\n return \".\".concat(hashId).concat(options !== null && options !== void 0 && options.scope ? \".\".concat(options.scope) : '', \"{\").concat(Object.entries(cssVars).map(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 2),\n key = _ref2[0],\n value = _ref2[1];\n return \"\".concat(key, \":\").concat(value, \";\");\n }).join(''), \"}\");\n};\nexport var transformToken = function transformToken(token, themeKey, config) {\n var cssVars = {};\n var result = {};\n Object.entries(token).forEach(function (_ref3) {\n var _config$preserve, _config$ignore;\n var _ref4 = _slicedToArray(_ref3, 2),\n key = _ref4[0],\n value = _ref4[1];\n if (config !== null && config !== void 0 && (_config$preserve = config.preserve) !== null && _config$preserve !== void 0 && _config$preserve[key]) {\n result[key] = value;\n } else if ((typeof value === 'string' || typeof value === 'number') && !(config !== null && config !== void 0 && (_config$ignore = config.ignore) !== null && _config$ignore !== void 0 && _config$ignore[key])) {\n var _config$unitless;\n var cssVar = token2CSSVar(key, config === null || config === void 0 ? void 0 : config.prefix);\n cssVars[cssVar] = typeof value === 'number' && !(config !== null && config !== void 0 && (_config$unitless = config.unitless) !== null && _config$unitless !== void 0 && _config$unitless[key]) ? \"\".concat(value, \"px\") : String(value);\n result[key] = \"var(\".concat(cssVar, \")\");\n }\n });\n return [result, serializeCSSVar(cssVars, themeKey, {\n scope: config === null || config === void 0 ? void 0 : config.scope\n })];\n};","import _objectSpread from \"@babel/runtime/helpers/esm/objectSpread2\";\n// import canUseDom from 'rc-util/lib/Dom/canUseDom';\nimport useLayoutEffect from \"rc-util/es/hooks/useLayoutEffect\";\nimport * as React from 'react';\n\n// We need fully clone React function here\n// to avoid webpack warning React 17 do not export `useId`\nvar fullClone = _objectSpread({}, React);\nvar useInsertionEffect = fullClone.useInsertionEffect;\n/**\n * Polyfill `useInsertionEffect` for React < 18\n * @param renderEffect will be executed in `useMemo`, and do not have callback\n * @param effect will be executed in `useLayoutEffect`\n * @param deps\n */\nvar useInsertionEffectPolyfill = function useInsertionEffectPolyfill(renderEffect, effect, deps) {\n React.useMemo(renderEffect, deps);\n useLayoutEffect(function () {\n return effect(true);\n }, deps);\n};\n\n/**\n * Compatible `useInsertionEffect`\n * will use `useInsertionEffect` if React version >= 18,\n * otherwise use `useInsertionEffectPolyfill`.\n */\nvar useCompatibleInsertionEffect = useInsertionEffect ? function (renderEffect, effect, deps) {\n return useInsertionEffect(function () {\n renderEffect();\n return effect();\n }, deps);\n} : useInsertionEffectPolyfill;\nexport default useCompatibleInsertionEffect;","import _objectSpread from \"@babel/runtime/helpers/esm/objectSpread2\";\nimport { warning } from \"rc-util/es/warning\";\nimport * as React from 'react';\nvar fullClone = _objectSpread({}, React);\nvar useInsertionEffect = fullClone.useInsertionEffect;\n\n// DO NOT register functions in useEffect cleanup function, or functions that registered will never be called.\nvar useCleanupRegister = function useCleanupRegister(deps) {\n var effectCleanups = [];\n var cleanupFlag = false;\n function register(fn) {\n if (cleanupFlag) {\n if (process.env.NODE_ENV !== 'production') {\n warning(false, '[Ant Design CSS-in-JS] You are registering a cleanup function after unmount, which will not have any effect.');\n }\n return;\n }\n effectCleanups.push(fn);\n }\n React.useEffect(function () {\n // Compatible with strict mode\n cleanupFlag = false;\n return function () {\n cleanupFlag = true;\n if (effectCleanups.length) {\n effectCleanups.forEach(function (fn) {\n return fn();\n });\n }\n };\n }, deps);\n return register;\n};\nvar useRun = function useRun() {\n return function (fn) {\n fn();\n };\n};\n\n// Only enable register in React 18\nvar useEffectCleanupRegister = typeof useInsertionEffect !== 'undefined' ? useCleanupRegister : useRun;\nexport default useEffectCleanupRegister;","function useProdHMR() {\n return false;\n}\nvar webpackHMR = false;\nfunction useDevHMR() {\n return webpackHMR;\n}\nexport default process.env.NODE_ENV === 'production' ? useProdHMR : useDevHMR;\n\n// Webpack `module.hot.accept` do not support any deps update trigger\n// We have to hack handler to force mark as HRM\nif (process.env.NODE_ENV !== 'production' && typeof module !== 'undefined' && module && module.hot && typeof window !== 'undefined') {\n // Use `globalThis` first, and `window` for older browsers\n // const win = globalThis as any;\n var win = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : null;\n if (win && typeof win.webpackHotUpdate === 'function') {\n var originWebpackHotUpdate = win.webpackHotUpdate;\n win.webpackHotUpdate = function () {\n webpackHMR = true;\n setTimeout(function () {\n webpackHMR = false;\n }, 0);\n return originWebpackHotUpdate.apply(void 0, arguments);\n };\n }\n}","import _slicedToArray from \"@babel/runtime/helpers/esm/slicedToArray\";\nimport _toConsumableArray from \"@babel/runtime/helpers/esm/toConsumableArray\";\nimport * as React from 'react';\nimport { pathKey } from \"../Cache\";\nimport StyleContext from \"../StyleContext\";\nimport useCompatibleInsertionEffect from \"./useCompatibleInsertionEffect\";\nimport useEffectCleanupRegister from \"./useEffectCleanupRegister\";\nimport useHMR from \"./useHMR\";\nexport default function useGlobalCache(prefix, keyPath, cacheFn, onCacheRemove,\n// Add additional effect trigger by `useInsertionEffect`\nonCacheEffect) {\n var _React$useContext = React.useContext(StyleContext),\n globalCache = _React$useContext.cache;\n var fullPath = [prefix].concat(_toConsumableArray(keyPath));\n var fullPathStr = pathKey(fullPath);\n var register = useEffectCleanupRegister([fullPathStr]);\n var HMRUpdate = useHMR();\n var buildCache = function buildCache(updater) {\n globalCache.opUpdate(fullPathStr, function (prevCache) {\n var _ref = prevCache || [undefined, undefined],\n _ref2 = _slicedToArray(_ref, 2),\n _ref2$ = _ref2[0],\n times = _ref2$ === void 0 ? 0 : _ref2$,\n cache = _ref2[1];\n\n // HMR should always ignore cache since developer may change it\n var tmpCache = cache;\n if (process.env.NODE_ENV !== 'production' && cache && HMRUpdate) {\n onCacheRemove === null || onCacheRemove === void 0 || onCacheRemove(tmpCache, HMRUpdate);\n tmpCache = null;\n }\n var mergedCache = tmpCache || cacheFn();\n var data = [times, mergedCache];\n\n // Call updater if need additional logic\n return updater ? updater(data) : data;\n });\n };\n\n // Create cache\n React.useMemo(function () {\n buildCache();\n }, /* eslint-disable react-hooks/exhaustive-deps */\n [fullPathStr]\n /* eslint-enable */);\n var cacheEntity = globalCache.opGet(fullPathStr);\n\n // HMR clean the cache but not trigger `useMemo` again\n // Let's fallback of this\n // ref https://github.com/ant-design/cssinjs/issues/127\n if (process.env.NODE_ENV !== 'production' && !cacheEntity) {\n buildCache();\n cacheEntity = globalCache.opGet(fullPathStr);\n }\n var cacheContent = cacheEntity[1];\n\n // Remove if no need anymore\n useCompatibleInsertionEffect(function () {\n onCacheEffect === null || onCacheEffect === void 0 || onCacheEffect(cacheContent);\n }, function (polyfill) {\n // It's bad to call build again in effect.\n // But we have to do this since StrictMode will call effect twice\n // which will clear cache on the first time.\n buildCache(function (_ref3) {\n var _ref4 = _slicedToArray(_ref3, 2),\n times = _ref4[0],\n cache = _ref4[1];\n if (polyfill && times === 0) {\n onCacheEffect === null || onCacheEffect === void 0 || onCacheEffect(cacheContent);\n }\n return [times + 1, cache];\n });\n return function () {\n globalCache.opUpdate(fullPathStr, function (prevCache) {\n var _ref5 = prevCache || [],\n _ref6 = _slicedToArray(_ref5, 2),\n _ref6$ = _ref6[0],\n times = _ref6$ === void 0 ? 0 : _ref6$,\n cache = _ref6[1];\n var nextCount = times - 1;\n if (nextCount === 0) {\n // Always remove styles in useEffect callback\n register(function () {\n // With polyfill, registered callback will always be called synchronously\n // But without polyfill, it will be called in effect clean up,\n // And by that time this cache is cleaned up.\n if (polyfill || !globalCache.opGet(fullPathStr)) {\n onCacheRemove === null || onCacheRemove === void 0 || onCacheRemove(cache, false);\n }\n });\n return null;\n }\n return [times - 1, cache];\n });\n };\n }, [fullPathStr]);\n return cacheContent;\n}","import _slicedToArray from \"@babel/runtime/helpers/esm/slicedToArray\";\nimport _toConsumableArray from \"@babel/runtime/helpers/esm/toConsumableArray\";\nimport _objectSpread from \"@babel/runtime/helpers/esm/objectSpread2\";\nimport hash from '@emotion/hash';\nimport { updateCSS } from \"rc-util/es/Dom/dynamicCSS\";\nimport { useContext } from 'react';\nimport StyleContext, { ATTR_MARK, ATTR_TOKEN, CSS_IN_JS_INSTANCE } from \"../StyleContext\";\nimport { flattenToken, memoResult, token2key, toStyleStr } from \"../util\";\nimport { transformToken } from \"../util/css-variables\";\nimport useGlobalCache from \"./useGlobalCache\";\nvar EMPTY_OVERRIDE = {};\n\n// Generate different prefix to make user selector break in production env.\n// This helps developer not to do style override directly on the hash id.\nvar hashPrefix = process.env.NODE_ENV !== 'production' ? 'css-dev-only-do-not-override' : 'css';\nvar tokenKeys = new Map();\nfunction recordCleanToken(tokenKey) {\n tokenKeys.set(tokenKey, (tokenKeys.get(tokenKey) || 0) + 1);\n}\nfunction removeStyleTags(key, instanceId) {\n if (typeof document !== 'undefined') {\n var styles = document.querySelectorAll(\"style[\".concat(ATTR_TOKEN, \"=\\\"\").concat(key, \"\\\"]\"));\n styles.forEach(function (style) {\n if (style[CSS_IN_JS_INSTANCE] === instanceId) {\n var _style$parentNode;\n (_style$parentNode = style.parentNode) === null || _style$parentNode === void 0 || _style$parentNode.removeChild(style);\n }\n });\n }\n}\nvar TOKEN_THRESHOLD = 0;\n\n// Remove will check current keys first\nfunction cleanTokenStyle(tokenKey, instanceId) {\n tokenKeys.set(tokenKey, (tokenKeys.get(tokenKey) || 0) - 1);\n var cleanableKeyList = new Set();\n tokenKeys.forEach(function (value, key) {\n if (value <= 0) cleanableKeyList.add(key);\n });\n\n // Should keep tokens under threshold for not to insert style too often\n if (tokenKeys.size - cleanableKeyList.size > TOKEN_THRESHOLD) {\n cleanableKeyList.forEach(function (key) {\n removeStyleTags(key, instanceId);\n tokenKeys.delete(key);\n });\n }\n}\nexport var getComputedToken = function getComputedToken(originToken, overrideToken, theme, format) {\n var derivativeToken = theme.getDerivativeToken(originToken);\n\n // Merge with override\n var mergedDerivativeToken = _objectSpread(_objectSpread({}, derivativeToken), overrideToken);\n\n // Format if needed\n if (format) {\n mergedDerivativeToken = format(mergedDerivativeToken);\n }\n return mergedDerivativeToken;\n};\nexport var TOKEN_PREFIX = 'token';\n/**\n * Cache theme derivative token as global shared one\n * @param theme Theme entity\n * @param tokens List of tokens, used for cache. Please do not dynamic generate object directly\n * @param option Additional config\n * @returns Call Theme.getDerivativeToken(tokenObject) to get token\n */\nexport default function useCacheToken(theme, tokens) {\n var option = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n var _useContext = useContext(StyleContext),\n instanceId = _useContext.cache.instanceId,\n container = _useContext.container;\n var _option$salt = option.salt,\n salt = _option$salt === void 0 ? '' : _option$salt,\n _option$override = option.override,\n override = _option$override === void 0 ? EMPTY_OVERRIDE : _option$override,\n formatToken = option.formatToken,\n compute = option.getComputedToken,\n cssVar = option.cssVar;\n\n // Basic - We do basic cache here\n var mergedToken = memoResult(function () {\n return Object.assign.apply(Object, [{}].concat(_toConsumableArray(tokens)));\n }, tokens);\n var tokenStr = flattenToken(mergedToken);\n var overrideTokenStr = flattenToken(override);\n var cssVarStr = cssVar ? flattenToken(cssVar) : '';\n var cachedToken = useGlobalCache(TOKEN_PREFIX, [salt, theme.id, tokenStr, overrideTokenStr, cssVarStr], function () {\n var _cssVar$key;\n var mergedDerivativeToken = compute ? compute(mergedToken, override, theme) : getComputedToken(mergedToken, override, theme, formatToken);\n\n // Replace token value with css variables\n var actualToken = _objectSpread({}, mergedDerivativeToken);\n var cssVarsStr = '';\n if (!!cssVar) {\n var _transformToken = transformToken(mergedDerivativeToken, cssVar.key, {\n prefix: cssVar.prefix,\n ignore: cssVar.ignore,\n unitless: cssVar.unitless,\n preserve: cssVar.preserve\n });\n var _transformToken2 = _slicedToArray(_transformToken, 2);\n mergedDerivativeToken = _transformToken2[0];\n cssVarsStr = _transformToken2[1];\n }\n\n // Optimize for `useStyleRegister` performance\n var tokenKey = token2key(mergedDerivativeToken, salt);\n mergedDerivativeToken._tokenKey = tokenKey;\n actualToken._tokenKey = token2key(actualToken, salt);\n var themeKey = (_cssVar$key = cssVar === null || cssVar === void 0 ? void 0 : cssVar.key) !== null && _cssVar$key !== void 0 ? _cssVar$key : tokenKey;\n mergedDerivativeToken._themeKey = themeKey;\n recordCleanToken(themeKey);\n var hashId = \"\".concat(hashPrefix, \"-\").concat(hash(tokenKey));\n mergedDerivativeToken._hashId = hashId; // Not used\n\n return [mergedDerivativeToken, hashId, actualToken, cssVarsStr, (cssVar === null || cssVar === void 0 ? void 0 : cssVar.key) || ''];\n }, function (cache) {\n // Remove token will remove all related style\n cleanTokenStyle(cache[0]._themeKey, instanceId);\n }, function (_ref) {\n var _ref2 = _slicedToArray(_ref, 4),\n token = _ref2[0],\n cssVarsStr = _ref2[3];\n if (cssVar && cssVarsStr) {\n var style = updateCSS(cssVarsStr, hash(\"css-variables-\".concat(token._themeKey)), {\n mark: ATTR_MARK,\n prepend: 'queue',\n attachTo: container,\n priority: -999\n });\n style[CSS_IN_JS_INSTANCE] = instanceId;\n\n // Used for `useCacheToken` to remove on batch when token removed\n style.setAttribute(ATTR_TOKEN, token._themeKey);\n }\n });\n return cachedToken;\n}\nexport var extract = function extract(cache, effectStyles, options) {\n var _cache = _slicedToArray(cache, 5),\n realToken = _cache[2],\n styleStr = _cache[3],\n cssVarKey = _cache[4];\n var _ref3 = options || {},\n plain = _ref3.plain;\n if (!styleStr) {\n return null;\n }\n var styleId = realToken._tokenKey;\n var order = -999;\n\n // ====================== Style ======================\n // Used for rc-util\n var sharedAttrs = {\n 'data-rc-order': 'prependQueue',\n 'data-rc-priority': \"\".concat(order)\n };\n var styleText = toStyleStr(styleStr, cssVarKey, styleId, sharedAttrs, plain);\n return [order, styleId, styleText];\n};","var unitlessKeys = {\n animationIterationCount: 1,\n borderImageOutset: 1,\n borderImageSlice: 1,\n borderImageWidth: 1,\n boxFlex: 1,\n boxFlexGroup: 1,\n boxOrdinalGroup: 1,\n columnCount: 1,\n columns: 1,\n flex: 1,\n flexGrow: 1,\n flexPositive: 1,\n flexShrink: 1,\n flexNegative: 1,\n flexOrder: 1,\n gridRow: 1,\n gridRowEnd: 1,\n gridRowSpan: 1,\n gridRowStart: 1,\n gridColumn: 1,\n gridColumnEnd: 1,\n gridColumnSpan: 1,\n gridColumnStart: 1,\n msGridRow: 1,\n msGridRowSpan: 1,\n msGridColumn: 1,\n msGridColumnSpan: 1,\n fontWeight: 1,\n lineHeight: 1,\n opacity: 1,\n order: 1,\n orphans: 1,\n tabSize: 1,\n widows: 1,\n zIndex: 1,\n zoom: 1,\n WebkitLineClamp: 1,\n // SVG-related properties\n fillOpacity: 1,\n floodOpacity: 1,\n stopOpacity: 1,\n strokeDasharray: 1,\n strokeDashoffset: 1,\n strokeMiterlimit: 1,\n strokeOpacity: 1,\n strokeWidth: 1\n};\n\nexport default unitlessKeys;\n","export var MS = '-ms-'\nexport var MOZ = '-moz-'\nexport var WEBKIT = '-webkit-'\n\nexport var COMMENT = 'comm'\nexport var RULESET = 'rule'\nexport var DECLARATION = 'decl'\n\nexport var PAGE = '@page'\nexport var MEDIA = '@media'\nexport var IMPORT = '@import'\nexport var CHARSET = '@charset'\nexport var VIEWPORT = '@viewport'\nexport var SUPPORTS = '@supports'\nexport var DOCUMENT = '@document'\nexport var NAMESPACE = '@namespace'\nexport var KEYFRAMES = '@keyframes'\nexport var FONT_FACE = '@font-face'\nexport var COUNTER_STYLE = '@counter-style'\nexport var FONT_FEATURE_VALUES = '@font-feature-values'\nexport var LAYER = '@layer'\nexport var SCOPE = '@scope'\n","/**\n * @param {number}\n * @return {number}\n */\nexport var abs = Math.abs\n\n/**\n * @param {number}\n * @return {string}\n */\nexport var from = String.fromCharCode\n\n/**\n * @param {object}\n * @return {object}\n */\nexport var assign = Object.assign\n\n/**\n * @param {string} value\n * @param {number} length\n * @return {number}\n */\nexport function hash (value, length) {\n\treturn charat(value, 0) ^ 45 ? (((((((length << 2) ^ charat(value, 0)) << 2) ^ charat(value, 1)) << 2) ^ charat(value, 2)) << 2) ^ charat(value, 3) : 0\n}\n\n/**\n * @param {string} value\n * @return {string}\n */\nexport function trim (value) {\n\treturn value.trim()\n}\n\n/**\n * @param {string} value\n * @param {RegExp} pattern\n * @return {string?}\n */\nexport function match (value, pattern) {\n\treturn (value = pattern.exec(value)) ? value[0] : value\n}\n\n/**\n * @param {string} value\n * @param {(string|RegExp)} pattern\n * @param {string} replacement\n * @return {string}\n */\nexport function replace (value, pattern, replacement) {\n\treturn value.replace(pattern, replacement)\n}\n\n/**\n * @param {string} value\n * @param {string} search\n * @param {number} position\n * @return {number}\n */\nexport function indexof (value, search, position) {\n\treturn value.indexOf(search, position)\n}\n\n/**\n * @param {string} value\n * @param {number} index\n * @return {number}\n */\nexport function charat (value, index) {\n\treturn value.charCodeAt(index) | 0\n}\n\n/**\n * @param {string} value\n * @param {number} begin\n * @param {number} end\n * @return {string}\n */\nexport function substr (value, begin, end) {\n\treturn value.slice(begin, end)\n}\n\n/**\n * @param {string} value\n * @return {number}\n */\nexport function strlen (value) {\n\treturn value.length\n}\n\n/**\n * @param {any[]} value\n * @return {number}\n */\nexport function sizeof (value) {\n\treturn value.length\n}\n\n/**\n * @param {any} value\n * @param {any[]} array\n * @return {any}\n */\nexport function append (value, array) {\n\treturn array.push(value), value\n}\n\n/**\n * @param {string[]} array\n * @param {function} callback\n * @return {string}\n */\nexport function combine (array, callback) {\n\treturn array.map(callback).join('')\n}\n\n/**\n * @param {string[]} array\n * @param {RegExp} pattern\n * @return {string[]}\n */\nexport function filter (array, pattern) {\n\treturn array.filter(function (value) { return !match(value, pattern) })\n}\n","import {IMPORT, LAYER, COMMENT, RULESET, DECLARATION, KEYFRAMES, NAMESPACE} from './Enum.js'\nimport {strlen} from './Utility.js'\n\n/**\n * @param {object[]} children\n * @param {function} callback\n * @return {string}\n */\nexport function serialize (children, callback) {\n\tvar output = ''\n\n\tfor (var i = 0; i < children.length; i++)\n\t\toutput += callback(children[i], i, children, callback) || ''\n\n\treturn output\n}\n\n/**\n * @param {object} element\n * @param {number} index\n * @param {object[]} children\n * @param {function} callback\n * @return {string}\n */\nexport function stringify (element, index, children, callback) {\n\tswitch (element.type) {\n\t\tcase LAYER: if (element.children.length) break\n\t\tcase IMPORT: case NAMESPACE: case DECLARATION: return element.return = element.return || element.value\n\t\tcase COMMENT: return ''\n\t\tcase KEYFRAMES: return element.return = element.value + '{' + serialize(element.children, callback) + '}'\n\t\tcase RULESET: if (!strlen(element.value = element.props.join(','))) return ''\n\t}\n\n\treturn strlen(children = serialize(element.children, callback)) ? element.return = element.value + '{' + children + '}' : ''\n}\n","import {from, trim, charat, strlen, substr, append, assign} from './Utility.js'\n\nexport var line = 1\nexport var column = 1\nexport var length = 0\nexport var position = 0\nexport var character = 0\nexport var characters = ''\n\n/**\n * @param {string} value\n * @param {object | null} root\n * @param {object | null} parent\n * @param {string} type\n * @param {string[] | string} props\n * @param {object[] | string} children\n * @param {object[]} siblings\n * @param {number} length\n */\nexport function node (value, root, parent, type, props, children, length, siblings) {\n\treturn {value: value, root: root, parent: parent, type: type, props: props, children: children, line: line, column: column, length: length, return: '', siblings: siblings}\n}\n\n/**\n * @param {object} root\n * @param {object} props\n * @return {object}\n */\nexport function copy (root, props) {\n\treturn assign(node('', null, null, '', null, null, 0, root.siblings), root, {length: -root.length}, props)\n}\n\n/**\n * @param {object} root\n */\nexport function lift (root) {\n\twhile (root.root)\n\t\troot = copy(root.root, {children: [root]})\n\n\tappend(root, root.siblings)\n}\n\n/**\n * @return {number}\n */\nexport function char () {\n\treturn character\n}\n\n/**\n * @return {number}\n */\nexport function prev () {\n\tcharacter = position > 0 ? charat(characters, --position) : 0\n\n\tif (column--, character === 10)\n\t\tcolumn = 1, line--\n\n\treturn character\n}\n\n/**\n * @return {number}\n */\nexport function next () {\n\tcharacter = position < length ? charat(characters, position++) : 0\n\n\tif (column++, character === 10)\n\t\tcolumn = 1, line++\n\n\treturn character\n}\n\n/**\n * @return {number}\n */\nexport function peek () {\n\treturn charat(characters, position)\n}\n\n/**\n * @return {number}\n */\nexport function caret () {\n\treturn position\n}\n\n/**\n * @param {number} begin\n * @param {number} end\n * @return {string}\n */\nexport function slice (begin, end) {\n\treturn substr(characters, begin, end)\n}\n\n/**\n * @param {number} type\n * @return {number}\n */\nexport function token (type) {\n\tswitch (type) {\n\t\t// \\0 \\t \\n \\r \\s whitespace token\n\t\tcase 0: case 9: case 10: case 13: case 32:\n\t\t\treturn 5\n\t\t// ! + , / > @ ~ isolate token\n\t\tcase 33: case 43: case 44: case 47: case 62: case 64: case 126:\n\t\t// ; { } breakpoint token\n\t\tcase 59: case 123: case 125:\n\t\t\treturn 4\n\t\t// : accompanied token\n\t\tcase 58:\n\t\t\treturn 3\n\t\t// \" ' ( [ opening delimit token\n\t\tcase 34: case 39: case 40: case 91:\n\t\t\treturn 2\n\t\t// ) ] closing delimit token\n\t\tcase 41: case 93:\n\t\t\treturn 1\n\t}\n\n\treturn 0\n}\n\n/**\n * @param {string} value\n * @return {any[]}\n */\nexport function alloc (value) {\n\treturn line = column = 1, length = strlen(characters = value), position = 0, []\n}\n\n/**\n * @param {any} value\n * @return {any}\n */\nexport function dealloc (value) {\n\treturn characters = '', value\n}\n\n/**\n * @param {number} type\n * @return {string}\n */\nexport function delimit (type) {\n\treturn trim(slice(position - 1, delimiter(type === 91 ? type + 2 : type === 40 ? type + 1 : type)))\n}\n\n/**\n * @param {string} value\n * @return {string[]}\n */\nexport function tokenize (value) {\n\treturn dealloc(tokenizer(alloc(value)))\n}\n\n/**\n * @param {number} type\n * @return {string}\n */\nexport function whitespace (type) {\n\twhile (character = peek())\n\t\tif (character < 33)\n\t\t\tnext()\n\t\telse\n\t\t\tbreak\n\n\treturn token(type) > 2 || token(character) > 3 ? '' : ' '\n}\n\n/**\n * @param {string[]} children\n * @return {string[]}\n */\nexport function tokenizer (children) {\n\twhile (next())\n\t\tswitch (token(character)) {\n\t\t\tcase 0: append(identifier(position - 1), children)\n\t\t\t\tbreak\n\t\t\tcase 2: append(delimit(character), children)\n\t\t\t\tbreak\n\t\t\tdefault: append(from(character), children)\n\t\t}\n\n\treturn children\n}\n\n/**\n * @param {number} index\n * @param {number} count\n * @return {string}\n */\nexport function escaping (index, count) {\n\twhile (--count && next())\n\t\t// not 0-9 A-F a-f\n\t\tif (character < 48 || character > 102 || (character > 57 && character < 65) || (character > 70 && character < 97))\n\t\t\tbreak\n\n\treturn slice(index, caret() + (count < 6 && peek() == 32 && next() == 32))\n}\n\n/**\n * @param {number} type\n * @return {number}\n */\nexport function delimiter (type) {\n\twhile (next())\n\t\tswitch (character) {\n\t\t\t// ] ) \" '\n\t\t\tcase type:\n\t\t\t\treturn position\n\t\t\t// \" '\n\t\t\tcase 34: case 39:\n\t\t\t\tif (type !== 34 && type !== 39)\n\t\t\t\t\tdelimiter(character)\n\t\t\t\tbreak\n\t\t\t// (\n\t\t\tcase 40:\n\t\t\t\tif (type === 41)\n\t\t\t\t\tdelimiter(type)\n\t\t\t\tbreak\n\t\t\t// \\\n\t\t\tcase 92:\n\t\t\t\tnext()\n\t\t\t\tbreak\n\t\t}\n\n\treturn position\n}\n\n/**\n * @param {number} type\n * @param {number} index\n * @return {number}\n */\nexport function commenter (type, index) {\n\twhile (next())\n\t\t// //\n\t\tif (type + character === 47 + 10)\n\t\t\tbreak\n\t\t// /*\n\t\telse if (type + character === 42 + 42 && peek() === 47)\n\t\t\tbreak\n\n\treturn '/*' + slice(index, position - 1) + '*' + from(type === 47 ? type : next())\n}\n\n/**\n * @param {number} index\n * @return {string}\n */\nexport function identifier (index) {\n\twhile (!token(peek()))\n\t\tnext()\n\n\treturn slice(index, position)\n}\n","import {COMMENT, RULESET, DECLARATION} from './Enum.js'\nimport {abs, charat, trim, from, sizeof, strlen, substr, append, replace, indexof} from './Utility.js'\nimport {node, char, prev, next, peek, token, caret, alloc, dealloc, delimit, whitespace, escaping, identifier, commenter} from './Tokenizer.js'\n\n/**\n * @param {string} value\n * @return {object[]}\n */\nexport function compile (value) {\n\treturn dealloc(parse('', null, null, null, [''], value = alloc(value), 0, [0], value))\n}\n\n/**\n * @param {string} value\n * @param {object} root\n * @param {object?} parent\n * @param {string[]} rule\n * @param {string[]} rules\n * @param {string[]} rulesets\n * @param {number[]} pseudo\n * @param {number[]} points\n * @param {string[]} declarations\n * @return {object}\n */\nexport function parse (value, root, parent, rule, rules, rulesets, pseudo, points, declarations) {\n\tvar index = 0\n\tvar offset = 0\n\tvar length = pseudo\n\tvar atrule = 0\n\tvar property = 0\n\tvar previous = 0\n\tvar variable = 1\n\tvar scanning = 1\n\tvar ampersand = 1\n\tvar character = 0\n\tvar type = ''\n\tvar props = rules\n\tvar children = rulesets\n\tvar reference = rule\n\tvar characters = type\n\n\twhile (scanning)\n\t\tswitch (previous = character, character = next()) {\n\t\t\t// (\n\t\t\tcase 40:\n\t\t\t\tif (previous != 108 && charat(characters, length - 1) == 58) {\n\t\t\t\t\tif (indexof(characters += replace(delimit(character), '&', '&\\f'), '&\\f', abs(index ? points[index - 1] : 0)) != -1)\n\t\t\t\t\t\tampersand = -1\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t// \" ' [\n\t\t\tcase 34: case 39: case 91:\n\t\t\t\tcharacters += delimit(character)\n\t\t\t\tbreak\n\t\t\t// \\t \\n \\r \\s\n\t\t\tcase 9: case 10: case 13: case 32:\n\t\t\t\tcharacters += whitespace(previous)\n\t\t\t\tbreak\n\t\t\t// \\\n\t\t\tcase 92:\n\t\t\t\tcharacters += escaping(caret() - 1, 7)\n\t\t\t\tcontinue\n\t\t\t// /\n\t\t\tcase 47:\n\t\t\t\tswitch (peek()) {\n\t\t\t\t\tcase 42: case 47:\n\t\t\t\t\t\tappend(comment(commenter(next(), caret()), root, parent, declarations), declarations)\n\t\t\t\t\t\tif ((token(previous || 1) == 5 || token(peek() || 1) == 5) && strlen(characters) && substr(characters, -1, void 0) !== ' ') characters += ' '\n\t\t\t\t\t\tbreak\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tcharacters += '/'\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t// {\n\t\t\tcase 123 * variable:\n\t\t\t\tpoints[index++] = strlen(characters) * ampersand\n\t\t\t// } ; \\0\n\t\t\tcase 125 * variable: case 59: case 0:\n\t\t\t\tswitch (character) {\n\t\t\t\t\t// \\0 }\n\t\t\t\t\tcase 0: case 125: scanning = 0\n\t\t\t\t\t// ;\n\t\t\t\t\tcase 59 + offset: if (ampersand == -1) characters = replace(characters, /\\f/g, '')\n\t\t\t\t\t\tif (property > 0 && (strlen(characters) - length || (variable === 0 && previous === 47)))\n\t\t\t\t\t\t\tappend(property > 32 ? declaration(characters + ';', rule, parent, length - 1, declarations) : declaration(replace(characters, ' ', '') + ';', rule, parent, length - 2, declarations), declarations)\n\t\t\t\t\t\tbreak\n\t\t\t\t\t// @ ;\n\t\t\t\t\tcase 59: characters += ';'\n\t\t\t\t\t// { rule/at-rule\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tappend(reference = ruleset(characters, root, parent, index, offset, rules, points, type, props = [], children = [], length, rulesets), rulesets)\n\n\t\t\t\t\t\tif (character === 123)\n\t\t\t\t\t\t\tif (offset === 0)\n\t\t\t\t\t\t\t\tparse(characters, root, reference, reference, props, rulesets, length, points, children)\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tswitch (atrule) {\n\t\t\t\t\t\t\t\t\t// c(ontainer)\n\t\t\t\t\t\t\t\t\tcase 99:\n\t\t\t\t\t\t\t\t\t\tif (charat(characters, 3) === 110) break\n\t\t\t\t\t\t\t\t\t// l(ayer)\n\t\t\t\t\t\t\t\t\tcase 108:\n\t\t\t\t\t\t\t\t\t\tif (charat(characters, 2) === 97) break\n\t\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\t\toffset = 0\n\t\t\t\t\t\t\t\t\t// d(ocument) m(edia) s(upports)\n\t\t\t\t\t\t\t\t\tcase 100: case 109: case 115:\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (offset) parse(value, reference, reference, rule && append(ruleset(value, reference, reference, 0, 0, rules, points, type, rules, props = [], length, children), children), rules, children, length, points, rule ? props : children)\n\t\t\t\t\t\t\t\telse parse(characters, reference, reference, reference, [''], children, 0, points, children)\n\t\t\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tindex = offset = property = 0, variable = ampersand = 1, type = characters = '', length = pseudo\n\t\t\t\tbreak\n\t\t\t// :\n\t\t\tcase 58:\n\t\t\t\tlength = 1 + strlen(characters), property = previous\n\t\t\tdefault:\n\t\t\t\tif (variable < 1)\n\t\t\t\t\tif (character == 123)\n\t\t\t\t\t\t--variable\n\t\t\t\t\telse if (character == 125 && variable++ == 0 && prev() == 125)\n\t\t\t\t\t\tcontinue\n\n\t\t\t\tswitch (characters += from(character), character * variable) {\n\t\t\t\t\t// &\n\t\t\t\t\tcase 38:\n\t\t\t\t\t\tampersand = offset > 0 ? 1 : (characters += '\\f', -1)\n\t\t\t\t\t\tbreak\n\t\t\t\t\t// ,\n\t\t\t\t\tcase 44:\n\t\t\t\t\t\tpoints[index++] = (strlen(characters) - 1) * ampersand, ampersand = 1\n\t\t\t\t\t\tbreak\n\t\t\t\t\t// @\n\t\t\t\t\tcase 64:\n\t\t\t\t\t\t// -\n\t\t\t\t\t\tif (peek() === 45)\n\t\t\t\t\t\t\tcharacters += delimit(next())\n\n\t\t\t\t\t\tatrule = peek(), offset = length = strlen(type = characters += identifier(caret())), character++\n\t\t\t\t\t\tbreak\n\t\t\t\t\t// -\n\t\t\t\t\tcase 45:\n\t\t\t\t\t\tif (previous === 45 && strlen(characters) == 2)\n\t\t\t\t\t\t\tvariable = 0\n\t\t\t\t}\n\t\t}\n\n\treturn rulesets\n}\n\n/**\n * @param {string} value\n * @param {object} root\n * @param {object?} parent\n * @param {number} index\n * @param {number} offset\n * @param {string[]} rules\n * @param {number[]} points\n * @param {string} type\n * @param {string[]} props\n * @param {string[]} children\n * @param {number} length\n * @param {object[]} siblings\n * @return {object}\n */\nexport function ruleset (value, root, parent, index, offset, rules, points, type, props, children, length, siblings) {\n\tvar post = offset - 1\n\tvar rule = offset === 0 ? rules : ['']\n\tvar size = sizeof(rule)\n\n\tfor (var i = 0, j = 0, k = 0; i < index; ++i)\n\t\tfor (var x = 0, y = substr(value, post + 1, post = abs(j = points[i])), z = value; x < size; ++x)\n\t\t\tif (z = trim(j > 0 ? rule[x] + ' ' + y : replace(y, /&\\f/g, rule[x])))\n\t\t\t\tprops[k++] = z\n\n\treturn node(value, root, parent, offset === 0 ? RULESET : type, props, children, length, siblings)\n}\n\n/**\n * @param {number} value\n * @param {object} root\n * @param {object?} parent\n * @param {object[]} siblings\n * @return {object}\n */\nexport function comment (value, root, parent, siblings) {\n\treturn node(value, root, parent, COMMENT, from(char()), substr(value, 2, -2), 0, siblings)\n}\n\n/**\n * @param {string} value\n * @param {object} root\n * @param {object?} parent\n * @param {number} length\n * @param {object[]} siblings\n * @return {object}\n */\nexport function declaration (value, root, parent, length, siblings) {\n\treturn node(value, root, parent, DECLARATION, substr(value, 0, length), substr(value, length + 1, -1), length, siblings)\n}\n","import devWarning from \"rc-util/es/warning\";\nexport function lintWarning(message, info) {\n var path = info.path,\n parentSelectors = info.parentSelectors;\n devWarning(false, \"[Ant Design CSS-in-JS] \".concat(path ? \"Error in \".concat(path, \": \") : '').concat(message).concat(parentSelectors.length ? \" Selector: \".concat(parentSelectors.join(' | ')) : ''));\n}","import { lintWarning } from \"./utils\";\nfunction isConcatSelector(selector) {\n var _selector$match;\n var notContent = ((_selector$match = selector.match(/:not\\(([^)]*)\\)/)) === null || _selector$match === void 0 ? void 0 : _selector$match[1]) || '';\n\n // split selector. e.g.\n // `h1#a.b` => ['h1', #a', '.b']\n var splitCells = notContent.split(/(\\[[^[]*])|(?=[.#])/).filter(function (str) {\n return str;\n });\n return splitCells.length > 1;\n}\nfunction parsePath(info) {\n return info.parentSelectors.reduce(function (prev, cur) {\n if (!prev) {\n return cur;\n }\n return cur.includes('&') ? cur.replace(/&/g, prev) : \"\".concat(prev, \" \").concat(cur);\n }, '');\n}\nvar linter = function linter(key, value, info) {\n var parentSelectorPath = parsePath(info);\n var notList = parentSelectorPath.match(/:not\\([^)]*\\)/g) || [];\n if (notList.length > 0 && notList.some(isConcatSelector)) {\n lintWarning(\"Concat ':not' selector not support in legacy browsers.\", info);\n }\n};\nexport default linter;","import _slicedToArray from \"@babel/runtime/helpers/esm/slicedToArray\";\nimport canUseDom from \"rc-util/es/Dom/canUseDom\";\nimport { ATTR_MARK } from \"../StyleContext\";\nexport var ATTR_CACHE_MAP = 'data-ant-cssinjs-cache-path';\n\n/**\n * This marks style from the css file.\n * Which means not exist in `